diff --git a/plugin-core/.classpath b/plugin-core/.classpath new file mode 100644 index 0000000..f42fb64 --- /dev/null +++ b/plugin-core/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/plugin-core/.project b/plugin-core/.project new file mode 100644 index 0000000..8094830 --- /dev/null +++ b/plugin-core/.project @@ -0,0 +1,29 @@ + + + plugin-core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + + org.springframework.ide.eclipse.core.springnature + org.maven.ide.eclipse.maven2Nature + org.eclipse.jdt.core.javanature + + diff --git a/plugin-core/.settings/org.eclipse.jdt.core.prefs b/plugin-core/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..b17d662 --- /dev/null +++ b/plugin-core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Mon Oct 06 19:00:00 CEST 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugin-core/.settings/org.maven.ide.eclipse.prefs b/plugin-core/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 0000000..93d86a4 --- /dev/null +++ b/plugin-core/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,8 @@ +#Mon Oct 06 18:55:33 CEST 2008 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +version=1 diff --git a/plugin-core/.springBeans b/plugin-core/.springBeans new file mode 100644 index 0000000..6ab33a2 --- /dev/null +++ b/plugin-core/.springBeans @@ -0,0 +1,14 @@ + + + 1 + + + + + + + src/test/resources/application-context.xml + + + + diff --git a/plugin-core/pom.xml b/plugin-core/pom.xml new file mode 100644 index 0000000..5eb7d21 --- /dev/null +++ b/plugin-core/pom.xml @@ -0,0 +1,56 @@ + + 4.0.0 + org.synyx.plugin + plugin-core + 0.1-SNAPSHOT + + + 2.5.5 + + + + + org.springframework + spring-aop + ${spring-version} + + + org.springframework + spring-context + ${spring-version} + + + + org.springframework + spring-test + ${spring-version} + test + + + junit + junit + 4.4 + test + + + + log4j + log4j + 1.2.15 + test + + + + + + + + maven-compiler-plugin + + 1.5 + 1.5 + + + + + \ No newline at end of file diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/Plugin.java b/plugin-core/src/main/java/org/synyx/plugin/core/Plugin.java new file mode 100644 index 0000000..9fb5638 --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/Plugin.java @@ -0,0 +1,21 @@ +package org.synyx.plugin.core; + +/** + * Central interface for plugins for the system. This interface is meant to be + * extended by concrete plugin interfaces. Its core responsibility is to define + * a delimiter type and a selection callback with the delimiter as parameter. + * The delimiter is some kind of decision object concrete plugin implementations + * can use to decide if they are capable to be executed. + * + * @author Oliver Gierke - gierke@synyx.de + */ +public interface Plugin { + + /** + * Returns if a plugin should be invoked according to the given delimiter. + * + * @param delimiter + * @return if the plugin should be invoked + */ + boolean supports(S delimiter); +} diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/PluginRegistry.java b/plugin-core/src/main/java/org/synyx/plugin/core/PluginRegistry.java new file mode 100644 index 0000000..211cfda --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/PluginRegistry.java @@ -0,0 +1,211 @@ +package org.synyx.plugin.core; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +/** + * Registry for plugins. Allows sophisticated typesafe access to implementations + * of interfaces extending {link Plugin}. + * + * @param the concrete plugin interface + * @param the delimiter type + * @author Oliver Gierke - gierke@synyx.de + */ +public class PluginRegistry, S> implements Iterable { + + // Registered plugins + private List plugins; + + + /** + * Constructor of {@code PluginRegistry}. + */ + public PluginRegistry() { + + plugins = new ArrayList(); + } + + + /** + * Register plugins. + * + * @param plugins the plugins to set + */ + public void setPlugins(List plugins) { + + this.plugins = new ArrayList(); + this.plugins.addAll(plugins); + } + + + /** + * Adds a given plugin to the registry. + * + * @param plugin + */ + public void addPlugin(T plugin) { + + this.plugins.add(plugin); + } + + + /** + * Returns the first plugin found for the given originating system. Thus, + * further configured plugins are ignored. + * + * @param originatingSystem + * @return a plugin for the given originating system or {@code null} if none + * found + */ + public T getPluginFor(S delimiter) { + + List plugins = getPluginsFor(delimiter); + + if (0 < plugins.size()) { + return plugins.get(0); + } + + return null; + } + + + /** + * Returns all plugins for the given delimiter. + * + * @param delimiter + * @return a list of plugins or an empty list if none found + */ + public List getPluginsFor(S delimiter) { + + List result = new ArrayList(); + + for (T plugin : plugins) { + if (plugin.supports(delimiter)) { + result.add(plugin); + } + } + + return result; + } + + + /** + * Retrieves a required plugin from the registry or throw the given + * exception if none can be found. If more than one plugins are found the + * first one will be returned. + * + * @param the exception type to be thrown in case no plugin can be found + * @param delimiter + * @param ex the exception to be thrown in case no plugin can be found + * @return a single plugin for the given delimiter + * @throws E if no plugin can be found for the given delimiter + */ + public T getPluginFor(S delimiter, E ex) throws E { + + T plugin = getPluginFor(delimiter); + + if (null == plugin) { + throw ex; + } + + return plugin; + } + + + /** + * Retrieves all plugins for the given delimiter or throws an exception if + * no plugin can be found. + * + * @param the exception type to be thrown + * @param delimiter + * @param ex + * @return all plugins for the given delimiter + * @throws E if no plugin can be found + */ + public List getPluginsFor(S delimiter, E ex) + throws E { + + List plugins = getPluginsFor(delimiter); + + if (0 == plugins.size()) { + throw ex; + } + + return plugins; + } + + + /** + * Returns the first {@link Plugin} supporting the given delimiter or the + * given plugin if none can be found. + * + * @param delimiter + * @param plugin + * @return a single {@link Plugin} supporting the given delimiter or the + * given {@link Plugin} if none found + */ + public T getPluginFor(S delimiter, T plugin) { + + T candidate = getPluginFor(delimiter); + + return null == candidate ? plugin : candidate; + } + + + /** + * Returns all {@link Plugin}s supporting the given delimiter or the given + * plugins if none found. + * + * @param delimiter + * @param plugins + * @return all {@link Plugin}s supporting the given delimiter or the given + * {@link Plugin}s if none found + */ + public List getPluginsFor(S delimiter, List plugins) { + + List candidates = getPluginsFor(delimiter); + + return candidates.size() == 0 ? plugins : candidates; + } + + + /** + * Returns the number of registered plugins. + * + * @return the number of plugins in the registry + */ + public int countPlugins() { + + return plugins.size(); + } + + + /** + * Returns all registered plugins. Only use this method if you really need + * to access all plugins. For distinguished access to certain plugins favour + * accessor methods like {link #getPluginFor} over this one. This method + * should only be used for testing purposes to check registry configuration. + *

+ * TODO: decide whether to make this method public + * + * @return all plugins of the registry + */ + @SuppressWarnings("unused") + private List getPlugins() { + + return plugins; + } + + + /* + * (non-Javadoc) + * + * @see java.lang.Iterable#iterator() + */ + public Iterator iterator() { + + return plugins.iterator(); + } +} diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginListDefinitionParser.java b/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginListDefinitionParser.java new file mode 100644 index 0000000..3250405 --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginListDefinitionParser.java @@ -0,0 +1,47 @@ +package org.synyx.plugin.core.config; + +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedMap; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.w3c.dom.Element; + + +/** + * @author Oliver Gierke - gierke@synyx.de + */ +public class PluginListDefinitionParser extends + AbstractSingleBeanDefinitionParser { + + /* + * (non-Javadoc) + * + * @see + * org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser + * #getBeanClassName(org.w3c.dom.Element) + */ + @Override + protected String getBeanClassName(Element element) { + + return "org.synyx.plugin.core.support.BeanListBeanFactoryPostProcessor"; + } + + + /* + * (non-Javadoc) + * + * @see + * org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser + * #doParse(org.w3c.dom.Element, + * org.springframework.beans.factory.support.BeanDefinitionBuilder) + */ + @Override + @SuppressWarnings("unchecked") + protected void doParse(Element element, BeanDefinitionBuilder builder) { + + ManagedMap map = new ManagedMap(); + map.put(element.getAttribute("id"), element.getAttribute("class")); + + builder.addPropertyValue("lists", map); + } + +} diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginNamespaceHandler.java b/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginNamespaceHandler.java new file mode 100644 index 0000000..3329cf3 --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginNamespaceHandler.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package org.synyx.plugin.core.config; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + + +/** + * Simple namespace handler for {@literal dao-config} namespace. + * + * @author Eberhard Wolff + * @author Oliver Gierke - gierke@synyx.de + */ +public class PluginNamespaceHandler extends NamespaceHandlerSupport { + + /* + * (non-Javadoc) + * + * @see org.springframework.beans.factory.xml.NamespaceHandler#init() + */ + public void init() { + + registerBeanDefinitionParser("list", new PluginListDefinitionParser()); + registerBeanDefinitionParser("registry", + new PluginRegistryDefinitionParser()); + } +} diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginRegistryDefinitionParser.java b/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginRegistryDefinitionParser.java new file mode 100644 index 0000000..7239748 --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/config/PluginRegistryDefinitionParser.java @@ -0,0 +1,23 @@ +package org.synyx.plugin.core.config; + +import org.w3c.dom.Element; + + +/** + * @author Oliver Gierke - gierke@synyx.de + */ +public class PluginRegistryDefinitionParser extends PluginListDefinitionParser { + + /* + * (non-Javadoc) + * + * @see + * org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser + * #getBeanClassName(org.w3c.dom.Element) + */ + @Override + protected String getBeanClassName(Element element) { + + return "org.synyx.plugin.core.support.PluginRegistryBeanFactoryPostProcessor"; + } +} diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/package.html b/plugin-core/src/main/java/org/synyx/plugin/core/package.html new file mode 100644 index 0000000..40faeb5 --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/package.html @@ -0,0 +1,8 @@ + + + +This package contains the core plugin API. It allows other modules implementing +components that extend functionality defined by a plugin interface. Plugin clients +can be equipped with plugin implementations. + + \ No newline at end of file diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/support/BeanListBeanFactoryPostProcessor.java b/plugin-core/src/main/java/org/synyx/plugin/core/support/BeanListBeanFactoryPostProcessor.java new file mode 100644 index 0000000..3e0bb7e --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/support/BeanListBeanFactoryPostProcessor.java @@ -0,0 +1,237 @@ +package org.synyx.plugin.core.support; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.config.ListFactoryBean; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.util.StringUtils; +import org.synyx.plugin.core.PluginRegistry; + + +/** + * @author Oliver Gierke - gierke@synyx.de + */ +public class BeanListBeanFactoryPostProcessor implements + BeanFactoryPostProcessor { + + private static final Log log = + LogFactory.getLog(BeanListBeanFactoryPostProcessor.class); + + private Map> lists = new HashMap>(); + + + /** + * Setter to inject required plugin registry configuration. The map's keys + * will be used as bean ids for the resulting {@link PluginRegistry} + * instances. These registry instances will contain all beans having the + * given type. + * + * @param registryMap + */ + public void setLists(Map> lists) { + + this.lists = lists; + } + + + /* + * (non-Javadoc) + * + * @seeorg.springframework.beans.factory.config.BeanFactoryPostProcessor# + * postProcessBeanFactory + * (org.springframework.beans.factory.config.ConfigurableListableBeanFactory + * ) + */ + public void postProcessBeanFactory( + ConfigurableListableBeanFactory beanFactory) throws BeansException { + + if (!(beanFactory instanceof BeanDefinitionRegistry)) { + throw new IllegalArgumentException( + "Given beanFactory is not a BeanDefinitionRegistry!"); + } + + BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; + + // Do for each required wrapper + for (String wrapperName : lists.keySet()) { + + Class requiredType = lists.get(wrapperName); + + // Find implementations of the component type + List beans = + getBeanReferencesOfType(beanFactory, requiredType); + + registerListBeanDefinition(wrapperName, requiredType, beans, + registry); + } + } + + + /** + * Registers a {@link ListFactoryBean} containing the given beans under the + * given id. Allows subclasses to modify or wrap the actually registered + * bean definition by calling + * {@link #wrapListBeanDefinition(BeanDefinition)} with the bean definition + * of the {Īlinl {@link ListFactoryBean}. + * + * @param id + * @param beans + * @param registry + */ + protected void registerListBeanDefinition(String id, Class type, + List beans, BeanDefinitionRegistry registry) { + + // Create ListFactory bean definition + BeanDefinitionBuilder listDefinitionBuilder = + BeanDefinitionBuilder.rootBeanDefinition(ListFactoryBean.class); + + // Set the implementations as source for the wrapper + listDefinitionBuilder.addPropertyValue("sourceList", beans); + + BeanDefinition beanDefinition = + wrapListBeanDefinition(getSourcedBeanDefinition(listDefinitionBuilder)); + + if (log.isDebugEnabled()) { + log.debug(String.format( + "Registering bean '%s' of type %s containing %s!", id, + beanDefinition.getBeanClassName(), beans.toString())); + } + + // Register wrapper under defined name + registry.registerBeanDefinition(id, beanDefinition); + } + + + /** + * Template method to allow subclasses to wrap the list bean definition into + * another bean definition that will actually be registered. The default + * implementation simply returns the given bean definition. + * + * @param beanDefinition + * @return + */ + protected BeanDefinition wrapListBeanDefinition( + BeanDefinition beanDefinition) { + + return beanDefinition; + } + + + /** + * Returns a {@link BeanDefinitionBuilder}s {@link BeanDefinition} setting + * the current {@link PluginRegistryBeanFactoryPostProcessor} as source. + * + * @param builder + * @return + */ + protected BeanDefinition getSourcedBeanDefinition( + BeanDefinitionBuilder builder) { + + AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); + beanDefinition.setSource(this); + + return beanDefinition; + } + + + /** + * Returns bean references to beans with the given type. + * + * @param beanFactory + * @param type + * @return + */ + @SuppressWarnings("unchecked") + protected List getBeanReferencesOfType( + ConfigurableListableBeanFactory beanFactory, Class type) { + + List beanNames = getBeanCandidates(beanFactory, type); + + List beanReferences = + new ManagedList(beanNames.size()); + + for (String beanName : beanNames) { + + RuntimeBeanReference reference = new RuntimeBeanReference(beanName); + reference.setSource(this); + + beanReferences.add(reference); + } + + return (List) beanReferences; + } + + + /** + * Looks up candidate beans for the given type from the {@link BeanFactory}. + * Does not use Spring type lookup facilities as this initializes + * {@link FactoryBean}s eagerly breaking possible registered + * {@link BeanPostProcessor}s. + *

+ * We traverse the entire {@link BeanFactory} hierarchy to lookup beans. + * + * @param beanFactory + * @param type + * @return + */ + private List getBeanCandidates( + ConfigurableListableBeanFactory beanFactory, Class type) { + + List candidates = new ArrayList(); + + // None given or most top bean factory reached? + if (null == beanFactory) { + return candidates; + } + + String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); + + for (String beanName : beanDefinitionNames) { + + BeanDefinition beanDefinition = + beanFactory.getBeanDefinition(beanName); + + // No bean class available at all + if (!StringUtils.hasText(beanDefinition.getBeanClassName())) { + continue; + } + + try { + Class beanClass = + Class.forName(beanDefinition.getBeanClassName()); + + if (type.isAssignableFrom(beanClass)) { + candidates.add(beanName); + } + + } catch (ClassNotFoundException e) { + continue; + } + } + + // Traverse parent bean factories + if (beanFactory.getParentBeanFactory() instanceof ConfigurableListableBeanFactory) { + candidates.addAll(getBeanCandidates( + (ConfigurableListableBeanFactory) beanFactory + .getParentBeanFactory(), type)); + } + + return candidates; + } +} diff --git a/plugin-core/src/main/java/org/synyx/plugin/core/support/PluginRegistryBeanFactoryPostProcessor.java b/plugin-core/src/main/java/org/synyx/plugin/core/support/PluginRegistryBeanFactoryPostProcessor.java new file mode 100644 index 0000000..030ae2e --- /dev/null +++ b/plugin-core/src/main/java/org/synyx/plugin/core/support/PluginRegistryBeanFactoryPostProcessor.java @@ -0,0 +1,41 @@ +package org.synyx.plugin.core.support; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.synyx.plugin.core.PluginRegistry; + + +/** + * This {@link BeanFactoryPostProcessor} automatically looksup bean instances + * from the {@link BeanFactory} hierarchy and registers {@link PluginRegistry} + * instances for them. + * + * @author Oliver Gierke - gierke@synyx.de + */ +public class PluginRegistryBeanFactoryPostProcessor extends + BeanListBeanFactoryPostProcessor { + + /* + * (non-Javadoc) + * + * @see + * com.synyx.minos.core.plugin.support.BeanListBeanFactoryPostProcessor# + * wrapBeanDefinition + * (org.springframework.beans.factory.config.BeanDefinition) + */ + @Override + protected BeanDefinition wrapListBeanDefinition( + BeanDefinition beanDefinition) { + + // Create PluginRegistry bean definition + BeanDefinitionBuilder builder = + BeanDefinitionBuilder.rootBeanDefinition(PluginRegistry.class); + + // Set list definition + builder.addPropertyValue("plugins", beanDefinition); + + return getSourcedBeanDefinition(builder); + } +} diff --git a/plugin-core/src/test/java/org/synyx/plugin/core/SamplePlugin.java b/plugin-core/src/test/java/org/synyx/plugin/core/SamplePlugin.java new file mode 100644 index 0000000..c8c1651 --- /dev/null +++ b/plugin-core/src/test/java/org/synyx/plugin/core/SamplePlugin.java @@ -0,0 +1,9 @@ +package org.synyx.plugin.core; + +/** + * @author Oliver Gierke - gierke@synyx.de + */ +public interface SamplePlugin extends Plugin { + + void pluginMethod(); +} diff --git a/plugin-core/src/test/java/org/synyx/plugin/core/SamplePluginImplementation.java b/plugin-core/src/test/java/org/synyx/plugin/core/SamplePluginImplementation.java new file mode 100644 index 0000000..9debc7e --- /dev/null +++ b/plugin-core/src/test/java/org/synyx/plugin/core/SamplePluginImplementation.java @@ -0,0 +1,27 @@ +package org.synyx.plugin.core; + +/** + * @author Oliver Gierke - gierke@synyx.de + */ +public class SamplePluginImplementation implements SamplePlugin { + + /* + * (non-Javadoc) + * + * @see org.synyx.plugin.core.Plugin#supports(java.lang.Object) + */ + public boolean supports(String delimiter) { + + return "FOO".equals(delimiter); + } + + + /* + * (non-Javadoc) + * + * @see org.synyx.plugin.core.ISamplePlugin#pluginMethod() + */ + public void pluginMethod() { + + } +} diff --git a/plugin-core/src/test/java/org/synyx/plugin/core/config/PluginConfigurationIntegrationTest.java b/plugin-core/src/test/java/org/synyx/plugin/core/config/PluginConfigurationIntegrationTest.java new file mode 100644 index 0000000..4b68b2a --- /dev/null +++ b/plugin-core/src/test/java/org/synyx/plugin/core/config/PluginConfigurationIntegrationTest.java @@ -0,0 +1,32 @@ +package org.synyx.plugin.core.config; + +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.synyx.plugin.core.PluginRegistry; +import org.synyx.plugin.core.SamplePlugin; + + +/** + * @author Oliver Gierke - gierke@synyx.de + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:application-context.xml") +public class PluginConfigurationIntegrationTest { + + @Autowired + List samplePlugins; + + @Autowired + PluginRegistry pluginRegistry; + + + @Test + public void test() throws Exception { + + } +} diff --git a/plugin-core/src/test/resources/application-context.xml b/plugin-core/src/test/resources/application-context.xml new file mode 100644 index 0000000..a7c13ae --- /dev/null +++ b/plugin-core/src/test/resources/application-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/plugin-core/src/test/resources/log4j.properties b/plugin-core/src/test/resources/log4j.properties new file mode 100644 index 0000000..eb2c175 --- /dev/null +++ b/plugin-core/src/test/resources/log4j.properties @@ -0,0 +1,12 @@ +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=WARN, stdout + +# Hibernate logging options (INFO only shows startup messages) +log4j.logger.org.springframework=INFO +log4j.logger.org.synyx.plugin=DEBUG \ No newline at end of file