From 01040cbd619d395ba09e5c4fe15af8da5eaacd3e Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Mon, 2 Mar 2009 10:30:51 +0000 Subject: [PATCH] Introduce Maven support git-svn-id: https://svn.argeo.org/slc/trunk@2212 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../org.argeo.slc.support.maven/.classpath | 10 + runtime/org.argeo.slc.support.maven/.project | 23 + .../.settings/org.eclipse.jdt.core.prefs | 12 + runtime/org.argeo.slc.support.maven/pom.xml | 71 +++ .../java/org/argeo/slc/ant/AntConstants.java | 47 ++ .../argeo/slc/ant/AntExecutionContext.java | 33 ++ .../java/org/argeo/slc/ant/AntRunner.java | 91 ++++ .../org/argeo/slc/ant/AntSlcApplication.java | 514 ++++++++++++++++++ .../java/org/argeo/slc/ant/AntSlcRuntime.java | 157 ++++++ .../argeo/slc/ant/RemoveRootDirMapper.java | 40 ++ .../slc/ant/SlcExecutionBuildListener.java | 205 +++++++ .../argeo/slc/ant/deploy/SlcDeployTask.java | 72 +++ .../argeo/slc/ant/deploy/SlcManagerTask.java | 35 ++ .../org/argeo/slc/ant/deploy/package.html | 6 + .../main/java/org/argeo/slc/ant/package.html | 38 ++ .../slc/ant/spring/AbstractSpringTask.java | 24 + .../org/argeo/slc/ant/spring/ListArg.java | 37 ++ .../java/org/argeo/slc/ant/spring/MapArg.java | 97 ++++ .../org/argeo/slc/ant/spring/OverrideArg.java | 103 ++++ .../org/argeo/slc/ant/spring/SpringArg.java | 163 ++++++ .../argeo/slc/ant/spring/SpringRegister.java | 51 ++ .../org/argeo/slc/ant/spring/package.html | 6 + .../argeo/slc/ant/structure/SAwareTask.java | 160 ++++++ .../org/argeo/slc/ant/structure/package.html | 6 + .../argeo/slc/ant/test/ParentContextType.java | 102 ++++ .../slc/ant/test/SlcCloseTestResultTask.java | 40 ++ .../org/argeo/slc/ant/test/SlcReportTask.java | 40 ++ .../org/argeo/slc/ant/test/SlcTestTask.java | 165 ++++++ .../java/org/argeo/slc/ant/test/package.html | 6 + .../ant/unit/AntSlcApplicationTestCase.java | 39 ++ .../ant/unit/MinimalAntClasspathTestCase.java | 37 ++ .../argeo/slc/ant/defaultAppLog4j.properties | 23 + .../org/argeo/slc/ant/taskdefs.properties | 8 + .../org/argeo/slc/ant/typedefs.properties | 2 + .../java/org/argeo/slc/ant/DummyObject.java | 55 ++ .../java/org/argeo/slc/ant/OverrideTest.java | 64 +++ .../java/org/argeo/slc/ant/SlcAntTest.java | 11 + .../src/test/resources/log4j.properties | 21 + .../org/argeo/slc/ant/acOverride.xml | 43 ++ .../org/argeo/slc/ant/applicationContext.xml | 12 + .../resources/org/argeo/slc/ant/build.xml | 25 + .../org/argeo/slc/ant/buildOverride.xml | 77 +++ .../org/argeo/slc/ant/nonDepContext.xml | 42 ++ 43 files changed, 2813 insertions(+) create mode 100644 runtime/org.argeo.slc.support.maven/.classpath create mode 100644 runtime/org.argeo.slc.support.maven/.project create mode 100644 runtime/org.argeo.slc.support.maven/.settings/org.eclipse.jdt.core.prefs create mode 100644 runtime/org.argeo.slc.support.maven/pom.xml create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntConstants.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntExecutionContext.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntRunner.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcApplication.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcRuntime.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcManagerTask.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/package.html create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/package.html create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/ListArg.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/MapArg.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringArg.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringRegister.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/package.html create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/package.html create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/ParentContextType.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/package.html create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/AntSlcApplicationTestCase.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/MinimalAntClasspathTestCase.java create mode 100644 runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/defaultAppLog4j.properties create mode 100644 runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/taskdefs.properties create mode 100644 runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/typedefs.properties create mode 100644 runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/DummyObject.java create mode 100644 runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/OverrideTest.java create mode 100644 runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/SlcAntTest.java create mode 100644 runtime/org.argeo.slc.support.maven/src/test/resources/log4j.properties create mode 100644 runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/acOverride.xml create mode 100644 runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/applicationContext.xml create mode 100644 runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/build.xml create mode 100644 runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/buildOverride.xml create mode 100644 runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/nonDepContext.xml diff --git a/runtime/org.argeo.slc.support.maven/.classpath b/runtime/org.argeo.slc.support.maven/.classpath new file mode 100644 index 000000000..9653ef0ac --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/runtime/org.argeo.slc.support.maven/.project b/runtime/org.argeo.slc.support.maven/.project new file mode 100644 index 000000000..75a122a3e --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/.project @@ -0,0 +1,23 @@ + + + org.argeo.slc.support.ant + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.maven.ide.eclipse.maven2Nature + + diff --git a/runtime/org.argeo.slc.support.maven/.settings/org.eclipse.jdt.core.prefs b/runtime/org.argeo.slc.support.maven/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..964778b0e --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Fri Aug 29 11:31:46 CEST 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/runtime/org.argeo.slc.support.maven/pom.xml b/runtime/org.argeo.slc.support.maven/pom.xml new file mode 100644 index 000000000..7f7801196 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/pom.xml @@ -0,0 +1,71 @@ + + 4.0.0 + + org.argeo.slc + argeo-slc + 0.11.3-SNAPSHOT + ../../org.argeo.slc + + org.argeo.slc.runtime + org.argeo.slc.support.ant + jar + Argeo SLC Support Ant + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.felix + maven-bundle-plugin + ${version.maven-bundle-plugin} + + + + org.argeo.slc.ant.* + + + + + + + + + org.argeo.slc.runtime + org.argeo.slc.support.simple + + + + org.argeo.dep.osgi + org.argeo.dep.osgi.ant + + + + org.apache.commons + com.springsource.org.apache.commons.net + + + org.apache.oro + com.springsource.org.apache.oro + + + + org.apache.bsf + com.springsource.org.apache.bsf + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntConstants.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntConstants.java new file mode 100644 index 000000000..f89742d61 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntConstants.java @@ -0,0 +1,47 @@ +package org.argeo.slc.ant; + +public interface AntConstants { + // ANT + /** The Ant reference to the Spring application context used. */ + public static final String REF_ROOT_CONTEXT = "slcApplicationContext"; + /** The Ant reference to the SLC structure registry used. */ + public static final String REF_STRUCTURE_REGISTRY = "slcStructureRegistry"; + /** The Ant reference to the TreePath of the current project */ + public static final String REF_PROJECT_PATH = "slcProjectPath"; + /** + * Resource path to the property file listing the SLC specific Ant tasks: + * /org/argeo/slc/ant/taskdefs.properties + */ + public static final String SLC_TASKDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/taskdefs.properties"; + /** + * Resource path to the property file listing the SLC specific Ant types: + * /org/argeo/slc/ant/typedefs.properties + */ + public static final String SLC_TYPEDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/typedefs.properties"; + public static final String REF_SLC_EXECUTION = "slcExecution"; + + // SLC EXECUTION + public static final String EXECTYPE_ANT = "org.apache.tools.ant"; + public static final String EXECTYPE_SLC_ANT = "org.argeo.slc.ant"; + + public final static String EXECATTR_RUNTIME = "slc.runtime"; + public final static String EXECATTR_ANT_FILE = "ant.file"; + public final static String EXECATTR_ANT_TARGETS = "ant.targets"; + + // PROPERTIES + /** Property for the root dir (SLC root property file). */ + public final static String ROOT_DIR_PROPERTY = "slc.rootDir"; + /** Property for the conf dir (SLC root property file). */ + public final static String CONF_DIR_PROPERTY = "slc.confDir"; + /** Property for the work dir (SLC root property file). */ + public final static String WORK_DIR_PROPERTY = "slc.workDir"; + /** Name of the Spring bean used by default */ + public final static String DEFAULT_TEST_RUN_PROPERTY = "slc.defaultTestRun"; + + /** Property for the runtime to use. */ + public final static String RUNTIME_PROPERTY = "slc.runtime"; + + // LOG4J + public final static String MDC_ANT_PROJECT = "slc.ant.project"; + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntExecutionContext.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntExecutionContext.java new file mode 100644 index 000000000..8b1b47ef4 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntExecutionContext.java @@ -0,0 +1,33 @@ +package org.argeo.slc.ant; + +import org.apache.tools.ant.Project; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcExecutionContext; +import org.springframework.context.ApplicationContext; + +public class AntExecutionContext implements SlcExecutionContext { + private final Project project; + + public AntExecutionContext(Project project) { + this.project = project; + } + + public T getBean(String name) { + ApplicationContext context = (ApplicationContext) project + .getReference(AntConstants.REF_ROOT_CONTEXT); + return (T) context.getBean(name); + } + + public T getAntRef(String antId) { + return (T) project.getReference(antId); + } + + public SlcExecution getSlcExecution() { + return (SlcExecution) project + .getReference(AntConstants.REF_SLC_EXECUTION); + } + + public Project getProject() { + return project; + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntRunner.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntRunner.java new file mode 100644 index 000000000..2791fe626 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntRunner.java @@ -0,0 +1,91 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.net.URL; +import java.util.Arrays; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.helper.ProjectHelper2; +import org.argeo.slc.SlcException; + +/** Run regular Ant script (that is, not SLC instrumented) */ +public class AntRunner { + private URL buildFile; + private String[] targets; + private Properties properties; + + public AntRunner() { + + } + + public AntRunner(URL buildFile, String target, Properties properties) { + this(buildFile, new String[] { target }, properties); + } + + public AntRunner(URL buildFile, String[] targets, Properties properties) { + this.buildFile = buildFile; + this.targets = targets; + this.properties = properties; + } + + public void run() { + Project p = new Project(); + + String path = buildFile.getFile(); + p.setUserProperty("ant.file", path); + p.setBaseDir(extractBaseDir(path)); + + p.init(); + ProjectHelper projectHelper = new ProjectHelper2(); + p.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, projectHelper); + projectHelper.parse(p, buildFile); + + if (properties != null) { + for (Map.Entry entry : properties.entrySet()) { + p.setUserProperty(entry.getKey().toString(), entry.getValue() + .toString()); + } + } + + p.fireBuildStarted(); + Throwable exception = null; + try { + if (targets == null) { + p.executeTarget(p.getDefaultTarget()); + } else { + p.executeTargets(new Vector(Arrays.asList(targets))); + } + } catch (Throwable e) { + exception = e; + throw new SlcException("Could not run Ant script " + buildFile, e); + } finally { + p.fireBuildFinished(exception); + } + + } + + private File extractBaseDir(String path) { + String baseDir = null; + if (path.length() > 1) { + int indx = path.lastIndexOf('/', path.length() - 1); + if (indx == -1 || indx == 0) { + baseDir = "/"; + } else { + baseDir = path.substring(0, indx) + "/"; + } + } else { + baseDir = "/"; + } + File file = new File(baseDir); + if (file.exists()) { + return file; + } else { + return new File(System.getProperty("user.dir")); + } + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcApplication.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcApplication.java new file mode 100644 index 000000000..0caa144a0 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcApplication.java @@ -0,0 +1,514 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.log4j.Appender; +import org.apache.log4j.LogManager; +import org.apache.log4j.MDC; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.helper.ProjectHelper2; +import org.argeo.slc.SlcException; +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.structure.tree.TreeSRegistry; +import org.argeo.slc.logging.Log4jUtils; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcApplication; +import org.argeo.slc.runtime.SlcExecutionOutput; +import org.argeo.slc.spring.SpringUtils; +import org.argeo.slc.structure.StructureRegistry; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.SystemPropertyUtils; + +public class AntSlcApplication implements SlcApplication { + private final static String DEFAULT_APP_LOG4J_PROPERTIES = "org/argeo/slc/ant/defaultAppLog4j.properties"; + + private final static Log log = LogFactory.getLog(AntSlcApplication.class); + + private Resource contextLocation; + private ConfigurableApplicationContext parentContext; + + private Resource rootDir; + private Resource confDir; + private File workDir; + + private Resource slcRootFile; + + public void execute(SlcExecution slcExecution, Properties properties, + Map references, + SlcExecutionOutput executionOutput) { + + // Properties and application logging initialization + initSystemProperties(properties); + Log4jUtils.initLog4j("classpath:" + DEFAULT_APP_LOG4J_PROPERTIES); + + log.info("\n###\n### Start SLC execution " + slcExecution.getUuid() + + "\n###\n"); + if (log.isDebugEnabled()) { + log.debug("rootDir=" + rootDir); + log.debug("confDir=" + confDir); + log.debug("workDir=" + workDir); + } + + // Ant coordinates + String scriptRelativePath = findAntScript(slcExecution); + List targets = findAntTargets(slcExecution); + + // Spring initialization + ConfigurableApplicationContext ctx = createExecutionContext(slcExecution); + + // Ant project initialization + Project project = new Project(); + AntExecutionContext executionContext = new AntExecutionContext(project); + project.addReference(AntConstants.REF_ROOT_CONTEXT, ctx); + project.addReference(AntConstants.REF_SLC_EXECUTION, slcExecution); + + try { + initProject(project, properties, references); + parseProject(project, scriptRelativePath); + + // Execute project + initStructure(project, scriptRelativePath); + runProject(project, targets); + + if (executionOutput != null) + executionOutput.postExecution(executionContext); + } finally { + ctx.close(); + } + } + + protected void initSystemProperties(Properties userProperties) { + // Set user properties as system properties so that Spring can access + // them + if (userProperties != null) { + for (Object key : userProperties.keySet()) { + System.setProperty(key.toString(), userProperties + .getProperty(key.toString())); + } + } + + if (System.getProperty(AntConstants.DEFAULT_TEST_RUN_PROPERTY) == null) { + System.setProperty(AntConstants.DEFAULT_TEST_RUN_PROPERTY, + "defaultTestRun"); + } + + try { + if (rootDir != null) + setSystemPropertyForRes(AntConstants.ROOT_DIR_PROPERTY, rootDir); + if (confDir != null) + setSystemPropertyForRes(AntConstants.CONF_DIR_PROPERTY, confDir); + if (workDir != null) + System.setProperty(AntConstants.WORK_DIR_PROPERTY, workDir + .getCanonicalPath()); + + // Additional properties in slc.properties file. Already set sytem + // properties (such as the various directories) can be resolved in + // placeholders. + if (confDir != null) { + Resource slcPropertiesRes = confDir + .createRelative("slc.properties"); + if (slcPropertiesRes.exists()) { + Properties slcProperties = new Properties(); + InputStream in = slcPropertiesRes.getInputStream(); + try { + slcProperties.load(in); + } finally { + IOUtils.closeQuietly(in); + } + + for (Object obj : slcProperties.keySet()) { + String key = obj.toString(); + if (!System.getProperties().containsKey(key)) { + String value = SystemPropertyUtils + .resolvePlaceholders(slcProperties + .getProperty(key)); + System.setProperty(key, value); + } + } + } + } + } catch (Exception e) { + throw new SlcException("Cannot init system properties.", e); + } + } + + /** + * Set property as an absolute file path if the resource can be located on + * the file system, or as an url. + */ + private void setSystemPropertyForRes(String key, Resource res) + throws IOException { + String value = null; + try { + value = res.getFile().getCanonicalPath(); + } catch (IOException e) { + value = res.getURL().toString(); + } + System.setProperty(key, value); + } + + protected ConfigurableApplicationContext createExecutionContext( + SlcExecution slcExecution) { + try { + + // Find runtime definition + Resource runtimeRes = null; + String runtimeStr = slcExecution.getAttributes().get( + AntConstants.EXECATTR_RUNTIME); + if (runtimeStr == null) + runtimeStr = System.getProperty(AntConstants.RUNTIME_PROPERTY, + "default"); + + ResourceLoader rl = new DefaultResourceLoader(getClass() + .getClassLoader()); + try {// tries absolute reference + runtimeRes = rl.getResource(runtimeStr); + } catch (Exception e) { + // silent + } + if (runtimeRes == null || !runtimeRes.exists()) { + if (confDir != null) + runtimeRes = confDir.createRelative("runtime/" + runtimeStr + + ".xml"); + } + + // Find runtime independent application context definition + if (confDir != null && contextLocation == null) { + contextLocation = confDir + .createRelative("applicationContext.xml"); + } + + GenericApplicationContext ctx = new GenericApplicationContext( + parentContext); + ctx.setDisplayName("SLC Execution #" + slcExecution.getUuid()); + + XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx); + if (runtimeRes != null && runtimeRes.exists()) + xmlReader.loadBeanDefinitions(runtimeRes); + else + log.warn("No runtime context defined"); + + if (contextLocation != null && contextLocation.exists()) + xmlReader.loadBeanDefinitions(contextLocation); + else + log.warn("No runtime independent application context defined"); + + // Add property place holder + PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); + ppc.setIgnoreUnresolvablePlaceholders(true); + ctx.addBeanFactoryPostProcessor(ppc); + + ctx.refresh(); + return ctx; + } catch (Exception e) { + throw new SlcException( + "Cannot create SLC execution application context.", e); + } + } + + protected String findAntScript(SlcExecution slcExecution) { + String scriptStr = slcExecution.getAttributes().get( + AntConstants.EXECATTR_ANT_FILE); + if (scriptStr == null) + throw new SlcException("No Ant script provided"); + + return scriptStr; + } + + protected List findAntTargets(SlcExecution slcExecution) { + String targetList = slcExecution.getAttributes().get( + AntConstants.EXECATTR_ANT_TARGETS); + List targets = new Vector(); + if (targetList != null) { + StringTokenizer stTargets = new StringTokenizer(targetList, ","); + while (stTargets.hasMoreTokens()) { + targets.add(stTargets.nextToken()); + } + } + return targets; + } + + protected void initProject(Project project, Properties properties, + Map references) { + if (properties != null) { + for (Map.Entry entry : properties.entrySet()) { + project.setUserProperty(entry.getKey().toString(), entry + .getValue().toString()); + } + } + + if (references != null) { + for (Map.Entry entry : references.entrySet()) { + project.addReference(entry.getKey(), entry.getValue()); + } + } + + // project.addBuildListener(new CommonsLoggingListener()); + + ListableBeanFactory context = (ListableBeanFactory) project + .getReference(AntConstants.REF_ROOT_CONTEXT); + // Register build listeners + Map listeners = BeanFactoryUtils + .beansOfTypeIncludingAncestors(context, BuildListener.class, + false, false); + for (BuildListener listener : listeners.values()) { + project.addBuildListener(listener); + } + + // Register log4j appenders from context + MDC.put(AntConstants.MDC_ANT_PROJECT, project); + Map appenders = context.getBeansOfType( + Appender.class, false, true); + for (Appender appender : appenders.values()) { + LogManager.getRootLogger().addAppender(appender); + } + + project.init(); + addCustomTaskAndTypes(project); + } + + /** Loads the SLC specific Ant tasks. */ + protected void addCustomTaskAndTypes(Project project) { + Properties taskdefs = getDefs(project, + AntConstants.SLC_TASKDEFS_RESOURCE_PATH); + for (Object o : taskdefs.keySet()) { + String name = o.toString(); + String className = taskdefs.getProperty(name); + try { + project.addTaskDefinition(name, Class.forName(className)); + } catch (ClassNotFoundException e) { + log.warn("Unknown class " + className + " for task " + name); + } + } + Properties typedefs = getDefs(project, + AntConstants.SLC_TYPEDEFS_RESOURCE_PATH); + for (Object o : typedefs.keySet()) { + String name = o.toString(); + try { + project.addDataTypeDefinition(name, Class.forName(typedefs + .getProperty(name))); + } catch (ClassNotFoundException e) { + log.error("Unknown class for type " + name, e); + } + } + } + + private Properties getDefs(Project project, String path) { + Properties defs = new Properties(); + try { + InputStream in = project.getClass().getResourceAsStream(path); + defs.load(in); + in.close(); + } catch (IOException e) { + throw new SlcException("Cannot load task definitions", e); + } + return defs; + } + + protected void initStructure(Project project, String scriptRelativePath) { + // Init structure registry + StructureRegistry registry = new TreeSRegistry(); + project.addReference(AntConstants.REF_STRUCTURE_REGISTRY, registry); + + // Lowest levels + StringTokenizer st = new StringTokenizer(scriptRelativePath, "/"); + TreeSPath currPath = null; + while (st.hasMoreTokens()) { + String name = st.nextToken(); + if (currPath == null) { + currPath = TreeSPath.createRootPath(name); + } else { + if (st.hasMoreTokens())// don't register project file + currPath = currPath.createChild(name); + } + registry.register(currPath, new SimpleSElement(name)); + } + + // Project level + String projectName = project.getName() != null + && !project.getName().equals("") ? project.getName() + : "project"; + TreeSPath projectPath = currPath.createChild(projectName); + + String projectDesc = project.getDescription() != null + && !project.getDescription().equals("") ? project + .getDescription() : projectPath.getName(); + + registry.register(projectPath, new SimpleSElement(projectDesc)); + project.addReference(AntConstants.REF_PROJECT_PATH, projectPath); + + if (log.isDebugEnabled()) + log.debug("Project path: " + projectPath); + } + + protected void parseProject(Project project, String scriptRelativePath) { + try { + Resource script = rootDir.createRelative(scriptRelativePath); + File baseDir = null; + try { + File scriptFile = script.getFile(); + baseDir = scriptFile.getParentFile(); + } catch (IOException e) {// resource is not a file + baseDir = new File(System.getProperty("user.dir")); + } + project.setBaseDir(baseDir); + // Reset basedir property, in order to avoid base dir override when + // running in Maven + project.setProperty("basedir", baseDir.getAbsolutePath()); + + ProjectHelper2 projectHelper = new ProjectHelper2(); + project.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, + projectHelper); + projectHelper.parse(project, script.getURL()); + } catch (Exception e) { + throw new SlcException("Could not parse project for script " + + scriptRelativePath, e); + } + + } + + protected void runProject(Project p, List targets) { + p.fireBuildStarted(); + Throwable exception = null; + try { + if (targets.size() == 0) {// no target defined + p.executeTarget(p.getDefaultTarget()); + } else { + p.executeTargets(new Vector(targets)); + } + } catch (Throwable e) { + exception = e; + throw new SlcException("SLC Ant execution failed", exception); + } finally { + p.fireBuildFinished(exception); + } + } + + public void setContextLocation(Resource contextLocation) { + this.contextLocation = contextLocation; + } + + public void setRootDir(Resource rootDir) { + this.rootDir = rootDir; + } + + public void setConfDir(Resource confDir) { + this.confDir = confDir; + } + + public void setWorkDir(File workDir) { + this.workDir = workDir; + } + + public void setParentContext(ConfigurableApplicationContext runtimeContext) { + this.parentContext = runtimeContext; + } + + public void setSlcRootFile(Resource slcRootFile) { + this.slcRootFile = slcRootFile; + } + + /** + * Init all directories based on the SLC root file. TODO: don't override + * already specified dirs. + */ + public void initFromSlcRootFile() { + // AntSlcApplication application = new AntSlcApplication(); + InputStream inRootFile = null; + try { + // Remove basedir property in order to avoid conflict with Maven + // if (all.containsKey("basedir")) + // all.remove("basedir"); + + inRootFile = slcRootFile.getInputStream(); + Properties rootProps = loadFile(inRootFile); + + Resource confDir = null; + File workDir = null; + // Root dir + final Resource rootDir = SpringUtils.getParent(slcRootFile); + + // Conf dir + String confDirStr = rootProps + .getProperty(AntConstants.CONF_DIR_PROPERTY); + if (confDirStr != null) + confDir = new DefaultResourceLoader(getClass().getClassLoader()) + .getResource(confDirStr); + + if (confDir == null || !confDir.exists()) { + // confDir = rootDir.createRelative("../conf"); + confDir = SpringUtils.getParent(rootDir) + .createRelative("conf/"); + } + + // Work dir + String workDirStr = rootProps + .getProperty(AntConstants.WORK_DIR_PROPERTY); + if (workDirStr != null) { + workDir = new File(workDirStr); + } + + if (workDir == null || !workDir.exists()) { + try { + File rootDirAsFile = rootDir.getFile(); + workDir = new File(rootDirAsFile.getParent() + + File.separator + "work").getCanonicalFile(); + } catch (IOException e) { + workDir = new File(System.getProperty("java.io.tmpdir") + + File.separator + "slcExecutions" + File.separator + + slcRootFile.getURL().getPath()); + log.debug("Root dir is not a file: " + e.getMessage() + + ", creating work dir in temp: " + workDir); + } + workDir.mkdirs(); + } + + setConfDir(confDir); + setRootDir(rootDir); + setWorkDir(workDir); + + if (log.isDebugEnabled()) + log.debug("Ant SLC application initialized based on root file " + + slcRootFile); + } catch (IOException e) { + throw new SlcException( + "Could not prepare SLC application for root file " + + slcRootFile, e); + } finally { + IOUtils.closeQuietly(inRootFile); + } + } + + /** Loads the content of a file as Properties. */ + private Properties loadFile(InputStream in) { + Properties p = new Properties(); + try { + p.load(in); + } catch (IOException e) { + throw new SlcException("Cannot read SLC root file", e); + } + return p; + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcRuntime.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcRuntime.java new file mode 100644 index 000000000..d70b80064 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/AntSlcRuntime.java @@ -0,0 +1,157 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcExecutionOutput; +import org.argeo.slc.runtime.SlcRuntime; +import org.argeo.slc.spring.SpringUtils; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; + +public class AntSlcRuntime implements SlcRuntime { + private final static Log log = LogFactory.getLog(AntSlcRuntime.class); + + public final static String SLC_ROOT_FILE_NAME = "slcRoot.properties"; + + /** + * Simplified execution with default runtime, default target, and no + * properties/reference arguments. + * + * @param script + * path to the script + * @param executionOutput + * output + * + * @see #executeScript(String, String, String, Properties, Map, + * SlcExecutionOutput) + */ + public void executeScript(String script, + SlcExecutionOutput executionOutput) { + executeScript(null, script, null, null, null, executionOutput); + } + + /** + * Simplified execution with default runtime, and no properties/reference + * arguments. + * + * @param script + * path to the script + * @param targets + * comma separated list of targets + * @param executionOutput + * output + * @see #executeScript(String, String, String, Properties, Map, + * SlcExecutionOutput) + */ + public void executeScript(String script, String targets, + SlcExecutionOutput executionOutput) { + executeScript(null, script, targets, null, null, executionOutput); + } + + public void executeScript(String runtime, String script, String targets, + Properties properties, Map references, + SlcExecutionOutput executionOutput) { + + Resource scriptRes = findScript(script); + Resource slcRootFile = findSlcRootFile(scriptRes); + if (slcRootFile == null) + throw new SlcException( + "Could not find any SLC root file, " + + "please configure one at the root of your scripts hierarchy."); + + // Create SlcExecution from arguments + SlcExecution slcExecution = createSlcExecution(runtime, slcRootFile, + scriptRes, targets); + + // Init application + AntSlcApplication application = new AntSlcApplication(); + application.setSlcRootFile(slcRootFile); + application.initFromSlcRootFile(); + + // Execute test + application.execute(slcExecution, properties, references, + executionOutput); + } + + protected Resource findScript(String scriptStr) { + Resource scriptRes; + if (new File(scriptStr).exists()) { + scriptRes = new FileSystemResource(scriptStr); + } else { + scriptRes = new DefaultResourceLoader(Thread.currentThread() + .getContextClassLoader()).getResource(scriptStr); + } + return scriptRes; + } + + protected SlcExecution createSlcExecution(String runtimeStr, + Resource slcRootFile, Resource script, String targets) { + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + try { + slcExecution.setHost(InetAddress.getLocalHost().getHostName()); + } catch (UnknownHostException e) { + slcExecution.setHost(SlcExecution.UNKOWN_HOST); + } + + slcExecution.setType(AntConstants.EXECTYPE_SLC_ANT); + + slcExecution.setUser(System.getProperty("user.name")); + + if (runtimeStr != null) + slcExecution.getAttributes().put(AntConstants.EXECATTR_RUNTIME, + runtimeStr); + String scriptRelativePath = SpringUtils.extractRelativePath(SpringUtils + .getParent(slcRootFile), script); + + slcExecution.getAttributes().put(AntConstants.EXECATTR_ANT_FILE, + scriptRelativePath); + if (targets != null) + slcExecution.getAttributes().put(AntConstants.EXECATTR_ANT_TARGETS, + targets); + + slcExecution.setStatus(SlcExecution.STATUS_SCHEDULED); + return slcExecution; + } + + /** + * Recursively scans directories downwards until it find a file name as + * defined by {@link #SLC_ROOT_FILE_NAME}. + */ + protected Resource findSlcRootFile(Resource currDir) { + if (log.isTraceEnabled()) + log.trace("Look for SLC root file in " + currDir); + + try { + Resource slcRootFile = currDir.createRelative(SLC_ROOT_FILE_NAME); + if (slcRootFile.exists()) { + if (log.isDebugEnabled()) + log.debug("Found SLC root file: " + slcRootFile); + return slcRootFile; + } else { + String currPath = currDir.getURL().getPath(); + if (currPath.equals("/") || currPath.equals("")) { + return null; + } else { + return findSlcRootFile(SpringUtils.getParent(currDir)); + } + } + } catch (IOException e) { + throw new SlcException("Problem when looking in SLC root file in " + + currDir, e); + } + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java new file mode 100644 index 000000000..43b247c2b --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java @@ -0,0 +1,40 @@ +package org.argeo.slc.ant; + +import java.util.StringTokenizer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.util.FileNameMapper; + +public class RemoveRootDirMapper implements FileNameMapper { + private Log log = LogFactory.getLog(RemoveRootDirMapper.class); + private String to = "enabled"; + + public String[] mapFileName(String sourceFileName) { + StringTokenizer st = new StringTokenizer(sourceFileName, "/"); + boolean first = true; + boolean skipRoot = !to.equals("disabled"); + StringBuffer buf = new StringBuffer(""); + while (st.hasMoreTokens()) { + if (first && skipRoot) { // skip + st.nextToken(); + first = false; + } else { + buf.append(st.nextToken()).append('/'); + } + } + + if (log.isTraceEnabled()) { + log.trace("Source: " + sourceFileName + " - out: " + buf); + } + return new String[] { buf.toString() }; + } + + public void setFrom(String from) { + } + + public void setTo(String to) { + this.to = to; + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java new file mode 100644 index 000000000..d8c5565d0 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java @@ -0,0 +1,205 @@ +package org.argeo.slc.ant; + +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Level; +import org.apache.log4j.MDC; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; +import org.argeo.slc.SlcException; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.process.SlcExecutionNotifier; +import org.argeo.slc.process.SlcExecutionStep; + +public class SlcExecutionBuildListener extends AppenderSkeleton implements + BuildListener { + private List notifiers = new Vector(); + + private boolean currentStepNotified = true; + + // CUSTOMIZATIONS + /** + * Whether to log Ant initialization stuff before the first target has been + * called. + */ + private boolean logBeforeFirstTarget = false; + /** Whether the first target has been called. */ + private boolean firstTargetStarted = false; + + private boolean logTaskStartFinish = true; + + public SlcExecutionBuildListener() { + // Default log level + setThreshold(Level.INFO); + } + + public void buildStarted(BuildEvent event) { + SlcExecution slcExecution = getSlcExecution(event); + for (SlcExecutionNotifier notifier : notifiers) { + notifier.newExecution(slcExecution); + } + } + + public void buildFinished(BuildEvent event) { + SlcExecution slcExecution = getSlcExecution(event); + String oldStatus = slcExecution.getStatus(); + slcExecution.setStatus(SlcExecution.STATUS_FINISHED); + + for (SlcExecutionNotifier notifier : notifiers) { + notifier.updateStatus(slcExecution, oldStatus, slcExecution + .getStatus()); + } + } + + public void messageLogged(BuildEvent event) { + if (!shouldLog()) + return; + + SlcExecution slcExecution = getSlcExecution(event); + if (slcExecution != null) { + if (currentStepNotified) { + slcExecution.getSteps().add( + new SlcExecutionStep(event.getMessage())); + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } else { + slcExecution.currentStep().addLog(event.getMessage()); + } + } else { + // TODO: log before initialization? + } + } + + public void targetStarted(BuildEvent event) { + if (!firstTargetStarted) + firstTargetStarted = true; + + addLogStep(event, "Target " + event.getTarget().getName() + " started"); + } + + public void targetFinished(BuildEvent event) { + addLogStep(event, "Target " + event.getTarget().getName() + " finished"); + } + + public void taskStarted(BuildEvent event) { + if (!shouldLog()) + return; + + SlcExecution slcExecution = getSlcExecution(event); + if (!currentStepNotified) { + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } + + String msg = null; + if (logTaskStartFinish) + msg = "Task " + event.getTask().getTaskName() + " started"; + + slcExecution.getSteps().add(new SlcExecutionStep(msg)); + + currentStepNotified = false; + } + + public void taskFinished(BuildEvent event) { + if (!shouldLog()) + return; + + SlcExecution slcExecution = getSlcExecution(event); + if (!currentStepNotified) { + + if (logTaskStartFinish) + slcExecution.currentStep().addLog( + "Task " + event.getTask().getTaskName() + " finished"); + + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } + } + + public void setNotifiers(List notifiers) { + this.notifiers = notifiers; + } + + protected SlcExecution getSlcExecution(BuildEvent event) { + return getSlcExecution(event.getProject()); + } + + protected SlcExecution getSlcExecution(Project project) { + SlcExecution slcExecution = (SlcExecution) project + .getReference(AntConstants.REF_SLC_EXECUTION); + + if (slcExecution == null) + throw new SlcException("No SLC Execution registered."); + return slcExecution; + } + + protected void addLogStep(BuildEvent event, String msg) { + SlcExecution slcExecution = getSlcExecution(event); + slcExecution.getSteps().add(new SlcExecutionStep(msg)); + + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } + + protected void notifyStep(SlcExecution slcExecution, SlcExecutionStep step) { + Vector additionalSteps = new Vector(); + additionalSteps.add(step); + notifySteps(slcExecution, additionalSteps); + } + + protected void notifySteps(SlcExecution slcExecution, + List additionalSteps) { + for (SlcExecutionNotifier notifier : notifiers) { + notifier.addSteps(slcExecution, additionalSteps); + } + } + + /* Log4j methods */ + + @Override + protected void append(LoggingEvent event) { + Project project = (Project) MDC.get(AntConstants.MDC_ANT_PROJECT); + if (project == null) { + // TODO: find a way to notify it + //System.err.println("No Ant project registered in Log4j MDC."); + } else { + SlcExecution slcExecution = getSlcExecution(project); + if (currentStepNotified) { + slcExecution.getSteps().add( + new SlcExecutionStep(event.getMessage().toString())); + currentStepNotified = false; + } else { + slcExecution.currentStep() + .addLog(event.getMessage().toString()); + } + } + } + + protected boolean shouldLog() { + return logBeforeFirstTarget || firstTargetStarted; + } + + public void close() { + } + + public boolean requiresLayout() { + return false; + } + + public void setLogBeforeFirstTarget(boolean logBeforeFirstTarget) { + this.logBeforeFirstTarget = logBeforeFirstTarget; + } + + public void setLogTaskStartFinish(boolean logTaskStartFinish) { + this.logTaskStartFinish = logTaskStartFinish; + } + + public void setLogLevel(String logLevel) { + setThreshold(Level.toLevel(logLevel)); + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java new file mode 100644 index 000000000..8ea4d28e2 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java @@ -0,0 +1,72 @@ +package org.argeo.slc.ant.deploy; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; +import org.argeo.slc.ant.spring.SpringArg; +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.build.Distribution; +import org.argeo.slc.deploy.Deployment; +import org.argeo.slc.deploy.DeploymentData; +import org.argeo.slc.deploy.TargetData; + +/** Ant task wrapping a deployment. */ +public class SlcDeployTask extends SAwareTask { + private Log log = LogFactory.getLog(SlcDeployTask.class); + + private String deploymentBean = null; + + private SpringArg deploymentDataArg; + private SpringArg targetDataArg; + private SpringArg distributionArg; + + @Override + public void executeActions(String mode) throws BuildException { + Deployment deployment = (Deployment) getContext().getBean( + deploymentBean); + + // set overridden references + if (distributionArg != null) { + deployment.setDistribution(distributionArg.getInstance()); + log.trace("Overrides distribution"); + } + + if (deploymentDataArg != null) { + deployment.setDeploymentData(deploymentDataArg.getInstance()); + log.trace("Overrides deployment data"); + } + + if (targetDataArg != null) { + deployment.setTargetData(targetDataArg.getInstance()); + log.trace("Overrides target data"); + } + + deployment.execute(); + } + + /** + * The bean name of the test run to use. If not set the default is used. + * + * @see SlcAntConfig + */ + public void setDeployment(String deploymentBean) { + this.deploymentBean = deploymentBean; + } + + /** Creates deployment data sub tag. */ + public SpringArg createDeploymentData() { + deploymentDataArg = new SpringArg(); + return deploymentDataArg; + } + + /** Creates target data sub tag. */ + public SpringArg createTargetData() { + targetDataArg = new SpringArg(); + return targetDataArg; + } + + public SpringArg createDistribution() { + distributionArg = new SpringArg(); + return distributionArg; + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcManagerTask.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcManagerTask.java new file mode 100644 index 000000000..36f5cbb5e --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/SlcManagerTask.java @@ -0,0 +1,35 @@ +package org.argeo.slc.ant.deploy; + +import java.lang.reflect.Method; + +import org.argeo.slc.SlcException; +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.deploy.DeployedSystem; +import org.argeo.slc.deploy.DeployedSystemManager; + +public class SlcManagerTask extends SAwareTask { + private String action; + private String manager; + + @Override + protected void executeActions(String mode) { + DeployedSystemManager systemManager = getBean(manager); + + try { + Method method = systemManager.getClass().getMethod(action, null); + method.invoke(systemManager, null); + } catch (Exception e) { + throw new SlcException("Cannot execute action " + action + + " for manager " + manager, e); + } + } + + public void setAction(String action) { + this.action = action; + } + + public void setManager(String manager) { + this.manager = manager; + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/package.html b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/package.html new file mode 100644 index 000000000..76582d159 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/deploy/package.html @@ -0,0 +1,6 @@ + + + +Integration of SLC Deploy in Ant. + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/package.html b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/package.html new file mode 100644 index 000000000..9f36fb1bf --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/package.html @@ -0,0 +1,38 @@ + + + +Bases classes for SLC Ant extensions. +

Introduction

+SLC Ant allows to integrate Ant and Spring in order to run an +application based on top of SLC. Sequence of actions are defined in Ant +files with specific Ant tasks referencing Spring beans implementing the +SLC interfaces. The properties of these beans can be overridden at +runtime in the Ant scripts. +
+SLC Ant also provides a tree-based implementation of the SLC structure +which allows to uniquely identify and reference the various actions. + +

Installation

+The structure will be first defined by the directory tree where the Ant +files are stored. In order to define the root of this tree, you need to +place in the root directory an +SLC Ant root file +(default name: slcRoot.properties). +
+In this root file you can define a configuration directory and a work +directory (default values are provided if they are not explicitly set). +
+Additional properties can then be defined in files stored under the +configuration directory. +
+For details about the configuration and the various properties, please +refer to {@link org.argeo.slc.ant.SlcAntConfig}. + +

Running SLC Ant

+SLC Ant can be run either via pure Ant scripts or programmatically using +{@link org.argeo.slc.ant.AntRegistryUtil}. In both cases, make sure that +SLC and its dependencies are in the classpath (Spring (always), logging +system such as log4j, Hibernate, etc.). + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java new file mode 100644 index 000000000..8d851ce49 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java @@ -0,0 +1,24 @@ +package org.argeo.slc.ant.spring; + +import org.springframework.context.ApplicationContext; + +import org.apache.tools.ant.Task; + +import org.argeo.slc.ant.AntConstants; +import org.argeo.slc.process.SlcExecution; + +/** Abstract Ant task providing access to a Spring context. */ +public abstract class AbstractSpringTask extends Task { + + /** Gets the related Spring context. */ + protected ApplicationContext getContext() { + return (ApplicationContext) getProject().getReference( + AntConstants.REF_ROOT_CONTEXT); + } + + /** Gets the related slc execution or null if not is registered. */ + protected SlcExecution getSlcExecution() { + return (SlcExecution) getProject().getReference( + AntConstants.REF_SLC_EXECUTION); + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/ListArg.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/ListArg.java new file mode 100644 index 000000000..582346ae6 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/ListArg.java @@ -0,0 +1,37 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Vector; + +import org.argeo.slc.SlcException; + +/** List of overrides */ +public class ListArg { + private List list = new Vector(); + + /** Creates override sub tag. */ + public OverrideArg createOverride() { + OverrideArg overrideArg = new OverrideArg(); + list.add(overrideArg); + return overrideArg; + } + + /** Gets as list of objects. */ + public List getAsObjectList(List originalList) { + if (originalList != null && originalList.size() != list.size()) { + throw new SlcException("Cannot merge lists of different sizes."); + } + + List objectList = new Vector(list.size()); + + for (int i = 0; i < list.size(); i++) { + OverrideArg arg = list.get(i); + + if (originalList != null) + arg.setOriginal(originalList.get(i)); + + objectList.add(arg.getObject()); + } + return objectList; + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/MapArg.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/MapArg.java new file mode 100644 index 000000000..185853ca3 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/MapArg.java @@ -0,0 +1,97 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; + +import org.argeo.slc.SlcException; + +public class MapArg { + private List entries = new Vector(); + private Map map = new TreeMap(); + + public EntryArg createEntry() { + EntryArg arg = new EntryArg(); + entries.add(arg); + return arg; + } + + public Map getAsObjectMap(Map originalMap) { + Map objectMap = new TreeMap(); + for (EntryArg arg : entries) { + String key = arg.getKey(); + + if (objectMap.containsKey(key)) { + throw new SlcException("Key '" + key + "' already set."); + } + + if (originalMap != null && originalMap.containsKey(key) + && arg.getOverrideArg() != null) + arg.getOverrideArg().setOriginal(originalMap.get(key)); + + objectMap.put(key, arg.getObject()); + + } + return objectMap; + } + + /** + * Returns a cached reference if it was already called. This reference could + * have been modified externally and thus not anymore be in line with the + * configuration. + */ + public Map getMap() { + if (map.size() == 0) + map = getAsObjectMap(null); + return map; + } + + public static class EntryArg { + private String key; + private Object valueStr; + private OverrideArg overrideArg; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Object getObject() { + if (overrideArg != null) { + return overrideArg.getObject(); + } else if (valueStr != null) { + return valueStr; + } else { + throw new BuildException("Value not set."); + } + } + + public void setValue(String value) { + check(); + this.valueStr = value; + } + + public OverrideArg createOverride() { + check(); + overrideArg = new OverrideArg(); + return overrideArg; + } + + private void check() { + if (valueStr != null || overrideArg != null) { + throw new BuildException("Value already set"); + } + } + + public OverrideArg getOverrideArg() { + return overrideArg; + } + + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java new file mode 100644 index 000000000..645b59204 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java @@ -0,0 +1,103 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; + +/** Ant type allowing to override bean properties. */ +public class OverrideArg extends SpringArg { + private final static Log log = LogFactory.getLog(OverrideArg.class); + + private String name; + private Object value; + private ListArg overrideList; + private MapArg overrideMap; + + private Boolean merge = false; + + /** The name of the property to override. */ + public String getName() { + return name; + } + + /** Sets the name. */ + public void setName(String name) { + this.name = name; + } + + /** Both value and bean cannot be set. */ + public void setValue(String value) { + checkValueAlreadySet(); + this.value = value; + } + + @Override + public void setBean(String bean) { + checkValueAlreadySet(); + super.setBean(bean); + } + + /** Creates override list sub tag. */ + public ListArg createList() { + checkValueAlreadySet(); + overrideList = new ListArg(); + return overrideList; + } + + public MapArg createMap() { + checkValueAlreadySet(); + overrideMap = new MapArg(); + return overrideMap; + } + + /** + * The related object: the value if a value had been set or an instance of + * the bean if not. + */ + public Object getObject() { + if (value != null) { + if (log.isTraceEnabled()) + log.trace(this + "\t: Returns override object as value"); + return value; + } else if (getBean() != null + || getAntref() != null + // works on original if no collection is defined + || (getOriginal() != null && overrideList == null && overrideMap == null)) { + if (log.isTraceEnabled()) + log.trace(this + "\t: Returns override object as instance"); + return getInstance(); + } else if (overrideList != null) { + if (log.isTraceEnabled()) + log.trace(this + "\t: Returns override object as list"); + return overrideList.getAsObjectList((List) getOriginal()); + } else if (overrideMap != null) { + if (log.isTraceEnabled()) + log.trace(this + "\t: Returns override object as map"); + return overrideMap + .getAsObjectMap((Map) getOriginal()); + } else { + throw new BuildException("Value or bean not set."); + } + } + + protected void checkValueAlreadySet() { + super.checkValueAlreadySet(); + if (value != null || overrideList != null || overrideMap != null) { + if (!getMerge()) { + throw new BuildException("Value already set."); + } + } + } + + public Boolean getMerge() { + return merge; + } + + public void setMerge(Boolean merge) { + this.merge = merge; + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringArg.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringArg.java new file mode 100644 index 000000000..3361805a9 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringArg.java @@ -0,0 +1,163 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.types.DataType; +import org.argeo.slc.SlcException; +import org.argeo.slc.ant.AntConstants; +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; + +/** Abstract Ant type wrapping a Spring bean. */ +public class SpringArg extends DataType { + private final static Log log = LogFactory.getLog(SpringArg.class); + + private List overrides = new Vector(); + + private String bean; + private String antref; + /** + * Reference to the original object, used to merge overrides. this object + * will be modified. + */ + private T original; + + // cache bean instance to avoid reading it twice if it is a prototype + private T instance = null; + + /** The name of the underlying bean, as set through the attribute. */ + public String getBean() { + return bean; + } + + /** Setter for the bean name. */ + public void setBean(String bean) { + checkValueAlreadySet(); + this.bean = bean; + } + + public String getAntref() { + return antref; + } + + /** Sets a reference to an ant data type. */ + public void setAntref(String antref) { + checkValueAlreadySet(); + this.antref = antref; + } + + /** + * Retrieve the instance of the bean, and sets the overridden properties. + * The value is cached. + */ + public T getInstance() { + if (instance == null) { + if (log.isTraceEnabled()) + log.trace(this + "\t: Creates instance"); + + if (bean != null) { + instance = (T) getContext().getBean(bean); + if (instance == null) + throw new SlcException("No object found for Spring bean " + + bean); + } else if (antref != null) { + instance = (T) getProject().getReference(antref); + if (instance == null) + throw new SlcException("No object found for Ant reference " + + antref); + } else if (original != null) { + instance = original; + } else { + throw new SlcException( + "Don't know how to retrieve bean instance"); + } + + setOverridenProperties(instance); + + // FIXME: why are we doing this? Could not find any object using it + if (instance instanceof InitializingBean) { + try { + ((InitializingBean) instance).afterPropertiesSet(); + } catch (Exception e) { + throw new SlcException("Could not initialize bean", e); + } + } + } else { + if (log.isTraceEnabled()) + log.trace(this + "\t: Returns cached instance"); + } + return instance; + } + + protected void setOverridenProperties(Object obj) { + BeanWrapper wrapper = new BeanWrapperImpl(obj); + for (OverrideArg override : overrides) { + if (override.getName() == null) { + throw new SlcException( + "The name of the property to override has to be set."); + } + + if (log.isTraceEnabled()) + log.trace(this + "\t: Overrides property " + override.getName() + + " with " + override); + + if (override.getMerge() == true) { + // if override is marked as merged retrieve the value and set is + // as original + override.setOriginal(wrapper.getPropertyValue(override + .getName())); + } + wrapper.setPropertyValue(override.getName(), override.getObject()); + } + + } + + /** Creates an override subtag. */ + public OverrideArg createOverride() { + OverrideArg propertyArg = new OverrideArg(); + overrides.add(propertyArg); + return propertyArg; + } + + /** The related Spring application context. */ + protected ApplicationContext getContext() { + return (ApplicationContext) getProject().getReference( + AntConstants.REF_ROOT_CONTEXT); + } + + protected void checkValueAlreadySet() { + if (antref != null || bean != null || original != null) { + throw new SlcException("Instance value already defined."); + } + } + + public void setOriginal(T original) { + checkValueAlreadySet(); + this.original = original; + } + + public T getOriginal() { + return original; + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(getClass().getSimpleName()); + if (bean != null) { + buf.append("#bean=").append(bean); + } else if (antref != null) { + buf.append("#antref=").append(antref); + } else if (original != null) { + buf.append("#orig=").append(original.hashCode()); + } else { + buf.append("#noid"); + } + buf.append("#").append(hashCode()); + return buf.toString(); + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringRegister.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringRegister.java new file mode 100644 index 000000000..a7d88f254 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/SpringRegister.java @@ -0,0 +1,51 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; + +public class SpringRegister extends AbstractSpringTask { + private static final Log log = LogFactory.getLog(SpringRegister.class); + + private List beans = new Vector(); + + @Override + public void execute() throws BuildException { + for (BeanArg bean : beans) { + Object instance = bean.getInstance(); + if (bean.getAntid() != null) { + getProject().addReference(bean.getAntid(), instance); + } else { + if (bean.getAntref() != null) { + log + .warn("Cannot register beans with antref (Ant reference " + + bean.getAntref() + ")"); + } else { + getProject().addReference(bean.getBean(), instance); + } + } + } + } + + public BeanArg createObject() { + BeanArg bean = new BeanArg(); + beans.add(bean); + return bean; + } + + protected static class BeanArg extends SpringArg { + private String antid; + + public String getAntid() { + return antid; + } + + public void setAntid(String antid) { + this.antid = antid; + } + + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/package.html b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/package.html new file mode 100644 index 000000000..6d141d993 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/spring/package.html @@ -0,0 +1,6 @@ + + + +Integration of Spring in Ant. + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java new file mode 100644 index 000000000..61a4ae912 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java @@ -0,0 +1,160 @@ +package org.argeo.slc.ant.structure; + +import java.util.List; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Target; +import org.argeo.slc.SlcException; +import org.argeo.slc.ant.AntConstants; +import org.argeo.slc.ant.spring.AbstractSpringTask; +import org.argeo.slc.ant.spring.SpringArg; +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.structure.StructureAware; +import org.argeo.slc.structure.StructureElement; +import org.argeo.slc.structure.StructureRegistry; + +/** Ant task that can be registered within a structure. */ +public abstract class SAwareTask extends AbstractSpringTask { + private String path; + private TreeSPath treeSPath; + private final List sAwareArgs = new Vector(); + + private StructureElementArg structureElementArg; + + @Override + public void init() throws BuildException { + StructureRegistry registry = getRegistry(); + Target target = getOwningTarget(); + + TreeSPath targetPath = createTargetPath(target); + SimpleSElement targetElement = (SimpleSElement) registry + .getElement(createTargetPath(target)); + + if (targetElement == null) { + targetElement = new SimpleSElement(target.getDescription(), + ""); + registry.register(targetPath, targetElement); + } + } + + /** + * Includes this arg in the checks for propagation of structure related + * information. + */ + protected void addSAwareArg(SpringArg arg) { + sAwareArgs.add(arg); + } + + @Override + /** + * Called by Ant at runtime. Decides whether to call the actions depending + * of the mode of the underlying structure registry. + * + * @see #executeActions + * @see StructureRegistry + */ + public final void execute() throws BuildException { + if (path == null) { + // register the task in the structure + TreeSPath targetPath = createTargetPath(getOwningTarget()); + TreeSPath taskPath = targetPath.createChild(getTaskName() + + targetPath.listChildren(getRegistry()).size()); + + treeSPath = taskPath; + } else { + treeSPath = new TreeSPath(path); + } + + if (getRegistry().getElement(treeSPath) == null) { + // No structure element registered. + if (structureElementArg != null) { + getRegistry().register(treeSPath, + structureElementArg.getStructureElement()); + } else { + if (getDescription() != null) { + getRegistry().register(treeSPath, + new SimpleSElement(getDescription())); + } + } + } + + // notify registered args + for (SpringArg arg : sAwareArgs) { + Object obj = arg.getInstance(); + + if (obj instanceof StructureAware) { + StructureAware sAwareT = (StructureAware) obj; + sAwareT.notifyCurrentPath(getRegistry(), treeSPath); + } + } + + // execute depending on the registry mode + String mode = getRegistry().getMode(); + if (mode.equals(StructureRegistry.ALL)) { + executeActions(mode); + } else if (mode.equals(StructureRegistry.ACTIVE)) { + List activePaths = getRegistry().getActivePaths(); + + if (activePaths.contains(treeSPath)) { + if (activePaths.contains(treeSPath)) { + executeActions(mode); + } + } + } + + } + + /** Actions to be executed by the implementor. */ + protected abstract void executeActions(String mode); + + public T getBean(String beanName) { + return (T) getContext().getBean(beanName); + } + + /** Create a reference to an external structure element. */ + public StructureElementArg createStructureElement() { + if (structureElementArg != null) + throw new SlcException("Arg already set."); + structureElementArg = new StructureElementArg(); + return structureElementArg; + } + + /** Gets the underlying structure registry. */ + protected StructureRegistry getRegistry() { + return (StructureRegistry) getProject().getReference( + AntConstants.REF_STRUCTURE_REGISTRY); + } + + /** Creates the treeSPath for a given Ant target. */ + protected static TreeSPath createTargetPath(Target target) { + TreeSPath projectPath = (TreeSPath) target.getProject().getReference( + AntConstants.REF_PROJECT_PATH); + return projectPath.createChild(target.getName()); + } + + /** Gets the treeSPath under which this task is registered. */ + public TreeSPath getTreeSPath() { + return treeSPath; + } + + public String getLabel() { + String description = super.getDescription(); + if (description == null) { + return ""; + } else { + return description; + } + } + + public void setPath(String path) { + this.path = path; + } +} + +class StructureElementArg extends SpringArg { + public StructureElement getStructureElement() { + return (StructureElement) getInstance(); + } +} \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/package.html b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/package.html new file mode 100644 index 000000000..99e45d335 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/structure/package.html @@ -0,0 +1,6 @@ + + + +Integration of SLC Structure in Ant. + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/ParentContextType.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/ParentContextType.java new file mode 100644 index 000000000..83dd5a17f --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/ParentContextType.java @@ -0,0 +1,102 @@ +package org.argeo.slc.ant.test; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.apache.tools.ant.types.DataType; + +import org.argeo.slc.SlcException; +import org.argeo.slc.ant.spring.MapArg; +import org.argeo.slc.core.test.context.ContextUtils; +import org.argeo.slc.test.context.ContextAware; +import org.argeo.slc.test.context.ParentContextAware; + +public class ParentContextType extends DataType implements ParentContextAware { + private MapArg values = null; + private MapArg expectedValues = null; + + private String contextAnyFlag = DEFAULT_ANY_FLAG; + private String contextSkipFlag = DEFAULT_SKIP_FLAG; + + private String basedon = null; + + private List children = new Vector(); + + public MapArg createValues() { + values = new MapArg(); + return values; + } + + public MapArg createExpectedValues() { + expectedValues = new MapArg(); + return expectedValues; + } + + public void addChildContext(ContextAware contextAware) { + children.add(contextAware); + } + + public Collection getChildContexts() { + return children; + } + + public String getContextAnyFlag() { + return contextAnyFlag; + } + + public void setContextAnyFlag(String contextAnyFlag) { + this.contextAnyFlag = contextAnyFlag; + } + + public String getContextSkipFlag() { + return contextSkipFlag; + } + + public void setContextSkipFlag(String contextSkipFlag) { + this.contextSkipFlag = contextSkipFlag; + } + + public Map getExpectedValues() { + if (expectedValues == null) + expectedValues = new MapArg(); + if (basedon != null) { + Map map = getBaseContext().getExpectedValues(); + ContextUtils.putNotContained(expectedValues.getMap(), map); + } + return expectedValues.getMap(); + } + + public Map getValues() { + if (values == null) + values = new MapArg(); + if (basedon != null) { + Map map = getBaseContext().getValues(); + ContextUtils.putNotContained(values.getMap(), map); + } + return values.getMap(); + } + + private ParentContextType getBaseContext() { + return (ParentContextType) getProject().getReference(basedon); + } + + public void setValues(Map values) { + throw new SlcException("Cannot override values map."); + } + + public void setUpdateValues(Map overrideValues) { + getValues().putAll(overrideValues); + } + + public void setUpdateExpectedValues( + Map overrideExpectedValues) { + getExpectedValues().putAll(overrideExpectedValues); + } + + public void setBasedon(String basedon) { + this.basedon = basedon; + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java new file mode 100644 index 000000000..d8de25ab4 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java @@ -0,0 +1,40 @@ +package org.argeo.slc.ant.test; + +import java.util.List; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.ant.spring.SpringArg; +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.structure.StructureRegistry; +import org.argeo.slc.test.TestResult; + +/** Ant tasks closing a given result. */ +public class SlcCloseTestResultTask extends SAwareTask { + private final static Log log = LogFactory + .getLog(SlcCloseTestResultTask.class); + + public List> results = new Vector>(); + + @Override + public void executeActions(String mode) { + if (!mode.equals(StructureRegistry.READ)) { + for (SpringArg result : results) { + try { + result.getInstance().close(); + } catch (RuntimeException e) { + log.error("Could not close result " + + (result.getBean() != null ? result.getBean() + : result.getAntref()), e); + } + } + } + } + + public SpringArg createResult() { + SpringArg result = new SpringArg(); + results.add(result); + return result; + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java new file mode 100644 index 000000000..45d63f651 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java @@ -0,0 +1,40 @@ +package org.argeo.slc.ant.test; + +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.structure.StructureAware; +import org.argeo.slc.structure.StructureRegistry; +import org.argeo.slc.test.TestReport; +import org.argeo.slc.test.TestResult; + +/** Ant tasks generating a report. */ +public class SlcReportTask extends SAwareTask { + private String result; + private String report; + + @Override + public void executeActions(String mode) { + if (!mode.equals(StructureRegistry.READ)) { + TestResult testResult = null; + if (result != null) { + testResult = (TestResult) getContext().getBean(result); + } + TestReport testReport = (TestReport) getContext().getBean(report); + if (testReport instanceof StructureAware) { + ((StructureAware) testReport).notifyCurrentPath(getRegistry(), + null); + } + testReport.generateTestReport(testResult); + } + } + + /** Sets the bean name of the result to close. */ + public void setResult(String bean) { + this.result = bean; + } + + /** Sets the bean name of the report to generate. */ + public void setReport(String report) { + this.report = report; + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java new file mode 100644 index 000000000..66a416c6e --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java @@ -0,0 +1,165 @@ +package org.argeo.slc.ant.test; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; +import org.argeo.slc.ant.AntConstants; +import org.argeo.slc.ant.spring.SpringArg; +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.SimpleResultPart; +import org.argeo.slc.core.test.SimpleTestResult; +import org.argeo.slc.core.test.SimpleTestRun; +import org.argeo.slc.deploy.DeployedSystem; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.spring.SpringUtils; +import org.argeo.slc.structure.StructureAware; +import org.argeo.slc.test.ExecutableTestRun; +import org.argeo.slc.test.TestData; +import org.argeo.slc.test.TestDefinition; +import org.argeo.slc.test.TestResult; +import org.argeo.slc.test.TestResultPart; +import org.argeo.slc.test.TestStatus; +import org.argeo.slc.test.WritableTestRun; +import org.springframework.beans.BeansException; + +/** Ant task wrapping a test run. */ +public class SlcTestTask extends SAwareTask { + private Log log = LogFactory.getLog(SlcTestTask.class); + + private String testRunBean = null; + + private SpringArg testDefinitionArg; + private SpringArg testDataArg; + private SpringArg deployedSystemArg; + private SpringArg testResultArg; + + @Override + public void executeActions(String mode) throws BuildException { + // find test run + final String testRunBeanT; + if (testRunBean != null) { + testRunBeanT = testRunBean; + } else { + testRunBeanT = getProject().getProperty( + AntConstants.DEFAULT_TEST_RUN_PROPERTY); + } + WritableTestRun testRun = null; + + if (testRunBeanT != null) { + try { + testRun = (WritableTestRun) getContext().getBean(testRunBeanT); + if (log.isTraceEnabled()) + log.trace("Load test run bean from bean name " + + testRunBeanT); + } catch (BeansException e) { + // silent, will try defaults + } + } + + if (testRun == null) { + testRun = loadSingleFromContext(WritableTestRun.class); + if (testRun == null) { + testRun = new SimpleTestRun(); + log.trace("Created default simple test run"); + } else { + if (log.isTraceEnabled()) + log.trace("Load test run from scanning Spring context"); + } + } + + // set overridden references + if (testDataArg != null) { + testRun.setTestData(testDataArg.getInstance()); + log.trace("Overrides test data"); + } + + if (testDefinitionArg != null) { + testRun.setTestDefinition(testDefinitionArg.getInstance()); + log.trace("Overrides test definition"); + } + + if (deployedSystemArg != null) { + testRun.setDeployedSystem(deployedSystemArg.getInstance()); + log.trace("Overrides deployed system"); + } + + if (testResultArg != null) { + testRun.setTestResult(testResultArg.getInstance()); + log.trace("Overrides test result"); + } + + // notify path to test result + TestResult result = testRun.getTestResult(); + if (result == null) { + result = loadSingleFromContext(TestResult.class); + if (result == null) { + result = new SimpleTestResult(); + log.warn("Created default simple test result"); + } else { + if (log.isTraceEnabled()) + log.trace("Load test result from scanning Spring context"); + } + testRun.setTestResult(result); + } + + SlcExecution slcExecution = getSlcExecution(); + testRun.notifySlcExecution(slcExecution); + + if (result != null && result instanceof StructureAware) { + ((StructureAware) result).notifyCurrentPath( + getRegistry(), getTreeSPath()); + } + + try { + ((ExecutableTestRun) testRun).execute(); + } catch (RuntimeException e) { + if (result != null) { + SimpleResultPart errorPart = new SimpleResultPart( + TestStatus.ERROR, + "Unexpected exception when running test", e); + result.addResultPart(errorPart); + } + throw e; + } + } + + /** + * The bean name of the test run to use. If not set the default is used. + * + * @see SlcAntConfig + */ + public void setTestRun(String testRunBean) { + this.testRunBean = testRunBean; + } + + /** Creates sub tag. */ + public SpringArg createTestDefinition() { + testDefinitionArg = new SpringArg(); + // only test definitions can add to path + addSAwareArg(testDefinitionArg); + return testDefinitionArg; + } + + /** Creates sub tag. */ + public SpringArg createTestData() { + testDataArg = new SpringArg(); + return testDataArg; + } + + /** Creates sub tag. */ + public SpringArg createDeployedSystem() { + deployedSystemArg = new SpringArg(); + return deployedSystemArg; + } + + /** Creates sub tag. */ + public SpringArg createTestResult() { + testResultArg = new SpringArg(); + return testResultArg; + } + + protected T loadSingleFromContext(Class clss) { + return SpringUtils.loadSingleFromContext(getContext(), clss); + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/package.html b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/package.html new file mode 100644 index 000000000..179159b39 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/test/package.html @@ -0,0 +1,6 @@ + + + +Integration of SLC Test in Ant. + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/AntSlcApplicationTestCase.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/AntSlcApplicationTestCase.java new file mode 100644 index 000000000..df78a225a --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/AntSlcApplicationTestCase.java @@ -0,0 +1,39 @@ +package org.argeo.slc.ant.unit; + +import java.io.File; + +import junit.framework.TestCase; + +import org.argeo.slc.ant.AntExecutionContext; +import org.argeo.slc.ant.AntSlcRuntime; +import org.argeo.slc.runtime.SlcExecutionOutput; + +public abstract class AntSlcApplicationTestCase extends TestCase implements + SlcExecutionOutput { + + /** To be overriden */ + public void postExecution(AntExecutionContext executionContext) { + + } + + protected String getRootDir() { + String rootDirPath = System.getProperty("slc.rootDir", "src/slc/root"); + if(!new File(rootDirPath).exists()) + rootDirPath = "src/main/slc/root";// try older convention + return rootDirPath; + } + + protected String getAbsoluteScript(String relative) { + return getRootDir() + '/' + relative; + } + + protected void execute(String relativeScript) { + execute(relativeScript, null); + } + + protected void execute(String relativeScript, String targets) { + new AntSlcRuntime().executeScript( + getAbsoluteScript(relativeScript), targets, this); + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/MinimalAntClasspathTestCase.java b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/MinimalAntClasspathTestCase.java new file mode 100644 index 000000000..5fdb49f03 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/java/org/argeo/slc/ant/unit/MinimalAntClasspathTestCase.java @@ -0,0 +1,37 @@ +package org.argeo.slc.ant.unit; + +import java.io.File; +import java.util.UUID; + +import org.argeo.slc.ant.AntConstants; +import org.argeo.slc.ant.AntExecutionContext; +import org.argeo.slc.ant.AntSlcApplication; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcExecutionOutput; +import org.argeo.slc.unit.AbstractSpringTestCase; +import org.springframework.core.io.FileSystemResource; + +public class MinimalAntClasspathTestCase extends AbstractSpringTestCase + implements SlcExecutionOutput { + protected void execute(String scriptPath) { + AntSlcApplication slcApp = new AntSlcApplication(); + slcApp.setRootDir(new FileSystemResource(new File("src/test/resources") + .getAbsolutePath() + + File.separator)); + slcApp.setWorkDir(new File(System.getProperty("java.io.tmpdir"))); + slcApp.setParentContext(getContext()); + + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + slcExecution.getAttributes().put(AntConstants.EXECATTR_ANT_FILE, + scriptPath); + slcExecution.setUser("user"); + + slcApp.execute(slcExecution, null, null, this); + } + + /** to be overridden */ + public void postExecution(AntExecutionContext executionContext) { + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/defaultAppLog4j.properties b/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/defaultAppLog4j.properties new file mode 100644 index 000000000..c13c36f80 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/defaultAppLog4j.properties @@ -0,0 +1,23 @@ +log4j.rootLogger=WARN, console, file + +## Levels +log4j.logger.org.argeo=INFO + +## Ant (Ant error logging is to verbose) +log4j.logger.org.apache.tools.ant.UnknownElement=OFF +log4j.logger.org.apache.tools.ant.Target=OFF +log4j.logger.org.apache.tools.ant.Project=OFF + +## Appenders +# console uses PatternLayout. +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n + +# file uses PatternLayout +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.File=${slc.workDir}/log/slcApp.log +log4j.appender.file.MaxFileSize=1MB +log4j.appender.file.MaxBackupIndex=5 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n diff --git a/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/taskdefs.properties b/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/taskdefs.properties new file mode 100644 index 000000000..ac489bf81 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/taskdefs.properties @@ -0,0 +1,8 @@ +# Tasks +slc.test=org.argeo.slc.ant.test.SlcTestTask +slc.deploy=org.argeo.slc.ant.deploy.SlcDeployTask +slc.manager=org.argeo.slc.ant.deploy.SlcManagerTask +slc.closeResult=org.argeo.slc.ant.test.SlcCloseTestResultTask +slc.report=org.argeo.slc.ant.test.SlcReportTask +slc.register=org.argeo.slc.ant.spring.SpringRegister +slc.detached=org.argeo.slc.ant.detached.SlcDetachedTask diff --git a/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/typedefs.properties b/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/typedefs.properties new file mode 100644 index 000000000..0cb3b2c46 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/main/resources/org/argeo/slc/ant/typedefs.properties @@ -0,0 +1,2 @@ +# Types +slc.context=org.argeo.slc.ant.test.ParentContextType diff --git a/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/DummyObject.java b/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/DummyObject.java new file mode 100644 index 000000000..59987600e --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/DummyObject.java @@ -0,0 +1,55 @@ +package org.argeo.slc.ant; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +public class DummyObject { + private String name; + private Long value; + private DummyObject other; + private List children = new Vector(); + private Map map = new TreeMap(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } + + public DummyObject getOther() { + return other; + } + + public void setOther(DummyObject other) { + this.other = other; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/OverrideTest.java b/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/OverrideTest.java new file mode 100644 index 000000000..d49521a31 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/OverrideTest.java @@ -0,0 +1,64 @@ +package org.argeo.slc.ant; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.ant.unit.MinimalAntClasspathTestCase; + +public class OverrideTest extends MinimalAntClasspathTestCase { + private Log log = LogFactory.getLog(getClass()); + + public void testSimpleRun() { + execute("/org/argeo/slc/ant/buildOverride.xml"); + } + + @Override + public void postExecution(AntExecutionContext executionContext) { + log.info("Analyzing context after execution..."); + + DummyObject dummy1UnModified = executionContext + .getAntRef("dummy1.unmodified"); + assertEquals("dummy2", dummy1UnModified.getOther().getName()); + assertEquals(2, dummy1UnModified.getChildren().size()); + assertEquals(2, dummy1UnModified.getMap().size()); + + DummyObject dummy1Modif1 = executionContext.getAntRef("dummy1.modif1"); + assertEquals("dummy1.modif1", dummy1Modif1.getName()); + assertEquals("dummy3", dummy1Modif1.getOther().getName()); + + DummyObject dummy1Modif2 = executionContext.getAntRef("dummy1.modif2"); + assertEquals(1, dummy1Modif2.getChildren().size()); + assertEquals("dummy3", dummy1Modif2.getChildren().get(0).getName()); + + DummyObject dummy1Modif3 = executionContext.getAntRef("dummy1.modif3"); + assertEquals(2, dummy1Modif3.getChildren().size()); + assertEquals("dummy3", dummy1Modif3.getChildren().get(0).getName()); + assertEquals("dummy2", dummy1Modif3.getChildren().get(1).getName()); + + DummyObject dummy1Modif4 = executionContext.getAntRef("dummy1.modif4"); + assertEquals(2, dummy1Modif4.getChildren().size()); + assertEquals("dummy3", dummy1Modif4.getChildren().get(0).getName()); + assertEquals("dummy1.modif1", dummy1Modif4.getChildren().get(0) + .getOther().getName()); + assertEquals("dummy2", dummy1Modif4.getChildren().get(1).getName()); + assertEquals(1, dummy1Modif4.getChildren().get(1).getChildren().size()); + assertEquals("dummy3", dummy1Modif4.getChildren().get(1).getChildren() + .get(0).getName()); + + DummyObject dummy1Modif5 = executionContext.getAntRef("dummy1.modif5"); + assertEquals(2, dummy1Modif5.getMap().size()); + assertEquals("dummy3", dummy1Modif5.getMap().get("key1").getName()); + assertEquals("dummy2", dummy1Modif5.getMap().get("key2").getName()); + + DummyObject dummy1Modif6 = executionContext.getAntRef("dummy1.modif6"); + assertEquals(2, dummy1Modif6.getMap().size()); + assertEquals("dummy2.merged", dummy1Modif6.getMap().get("key1").getName()); + assertEquals("dummy3.merged", dummy1Modif6.getMap().get("key2").getName()); + + } + + @Override + protected String getApplicationContextLocation() { + return inPackage("acOverride.xml"); + } + +} diff --git a/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/SlcAntTest.java b/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/SlcAntTest.java new file mode 100644 index 000000000..5a58f1f95 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/java/org/argeo/slc/ant/SlcAntTest.java @@ -0,0 +1,11 @@ +package org.argeo.slc.ant; + +import org.argeo.slc.ant.unit.MinimalAntClasspathTestCase; + +public class SlcAntTest extends MinimalAntClasspathTestCase { + // private Log log = LogFactory.getLog(getClass()); + + public void testSimpleRun() { + execute("/org/argeo/slc/ant/build.xml"); + } +} diff --git a/runtime/org.argeo.slc.support.maven/src/test/resources/log4j.properties b/runtime/org.argeo.slc.support.maven/src/test/resources/log4j.properties new file mode 100644 index 000000000..a583c59fa --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/resources/log4j.properties @@ -0,0 +1,21 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=WARN, console + +## Levels +# Slc +log4j.logger.org.argeo=DEBUG + +# Castor +log4j.logger.org.exolab.castor=WARN + +# Spring +log4j.logger.org.springframework=WARN + +## Appenders +# A1 is set to be a ConsoleAppender. +log4j.appender.console=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n + diff --git a/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/acOverride.xml b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/acOverride.xml new file mode 100644 index 000000000..c9c391182 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/acOverride.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/applicationContext.xml b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/applicationContext.xml new file mode 100644 index 000000000..6ff9b8522 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/applicationContext.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/build.xml b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/build.xml new file mode 100644 index 000000000..35de7be94 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/build.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/buildOverride.xml b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/buildOverride.xml new file mode 100644 index 000000000..67f889ab5 --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/buildOverride.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/nonDepContext.xml b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/nonDepContext.xml new file mode 100644 index 000000000..56da88a8b --- /dev/null +++ b/runtime/org.argeo.slc.support.maven/src/test/resources/org/argeo/slc/ant/nonDepContext.xml @@ -0,0 +1,42 @@ + + + + + + + + + + toto + + + toto + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- 2.39.2