From 0bc20690292697d0c7950ccd8c3e1e0887d8b88a Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 12 Jun 2008 18:42:13 +0000 Subject: [PATCH] New runtime working end to end git-svn-id: https://svn.argeo.org/slc/trunk@1248 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../org/argeo/slc/ant/AntSlcApplication.java | 309 +++++++++++++++++- .../java/org/argeo/slc/ant/SlcAntConfig.java | 24 +- .../org/argeo/slc/ant/SlcAntConstants.java | 6 + .../slc/ant/SlcExecutionBuildListener.java | 2 +- .../org/argeo/slc/ant/SlcProjectHelper.java | 2 +- .../java/org/argeo/slc/ant/SlcAntTest.java | 20 +- .../resources/org/argeo/slc/ant/build.xml | 17 +- 7 files changed, 346 insertions(+), 34 deletions(-) diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java index 2d2c3ed69..3638340e1 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java @@ -1,34 +1,325 @@ package org.argeo.slc.ant; +import java.io.File; +import java.io.FileInputStream; +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.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.helper.ProjectHelper2; +import org.apache.tools.ant.listener.CommonsLoggingListener; import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.structure.DefaultSRegistry; +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.structure.tree.TreeSRegistry; import org.argeo.slc.runtime.SlcRuntime; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.Resource; public class AntSlcApplication { + private final static Log log = LogFactory.getLog(AntSlcApplication.class); + private SlcRuntime slcRuntime; private Resource contextLocation; + private Resource rootDir; + private Resource confDir; + private Resource workDir; + public void execute(SlcExecution slcExecution, Properties properties, Map references) { - + if (log.isDebugEnabled()) { + log.debug("### Start SLC execution " + slcExecution.getUuid() + + " ###"); + log.debug("rootDir=" + rootDir); + log.debug("confDir=" + confDir); + log.debug("workDir=" + workDir); + } + // Ant coordinates - String script = slcExecution.getAttributes().get(SlcAntConstants.EXECATTR_ANT_FILE); - String targetList = slcExecution.getAttributes().get(SlcAntConstants.EXECATTR_ANT_TARGETS); + Resource script = findAntScript(slcExecution); + List targets = findAntTargets(slcExecution); + + ConfigurableApplicationContext ctx = createExecutionContext(); + + Project project = new Project(); + project.addReference(SlcAntConstants.REF_ROOT_CONTEXT, ctx); + project.addReference(SlcAntConstants.REF_SLC_EXECUTION, slcExecution); + initProject(project, properties, references); + parseProject(project, script); + + initStructure(project, script); + runProject(project, targets); + } + + protected Resource findAntScript(SlcExecution slcExecution) { + String scriptStr = slcExecution.getAttributes().get( + SlcAntConstants.EXECATTR_ANT_FILE); + if (scriptStr == null) + throw new SlcAntException("No Ant script provided"); + + try { + if (log.isTraceEnabled()) + log.trace("scriptStr=" + scriptStr); + Resource script = null; + + if (rootDir != null) { + script = rootDir.createRelative(scriptStr); + if (log.isTraceEnabled()) + log.trace("script(relative)=" + script); + if (script.exists()) + return script; + } + + script = slcRuntime.getRuntimeContext().getResource(scriptStr); + if (log.isTraceEnabled()) + log.trace("script(absolute)=" + script); + if (script.exists()) + return script; + + throw new SlcAntException("Cannot find Ant script " + scriptStr); + } catch (Exception e) { + throw new SlcAntException("Cannot find Ant script " + scriptStr, e); + } + } + + protected List findAntTargets(SlcExecution slcExecution) { + String targetList = slcExecution.getAttributes().get( + SlcAntConstants.EXECATTR_ANT_TARGETS); List targets = new Vector(); - StringTokenizer stTargets = new StringTokenizer(targetList,","); - while(stTargets.hasMoreTokens()){ - targets.add(stTargets.nextToken()); + if (targetList != null) { + StringTokenizer stTargets = new StringTokenizer(targetList, ","); + while (stTargets.hasMoreTokens()) { + targets.add(stTargets.nextToken()); + } } - - Project project = new Project(); - + return targets; + } + + protected ConfigurableApplicationContext createExecutionContext() { + try { + if (confDir != null && contextLocation == null) { + contextLocation = confDir + .createRelative("applicationContext.xml"); + } + + GenericApplicationContext ctx = new GenericApplicationContext( + slcRuntime.getRuntimeContext()); + if (contextLocation != null && contextLocation.exists()) { + XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( + ctx); + xmlReader.loadBeanDefinitions(contextLocation); + } + return ctx; + } catch (Exception e) { + throw new SlcAntException( + "Cannot create SLC execution application context.", e); + } + } + + 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()); + project.init(); + addCustomTaskAndTypes(project); + } + + /** Loads the SLC specific Ant tasks. */ + protected void addCustomTaskAndTypes(Project project) { + Properties taskdefs = getDefs(project, + SlcAntConstants.SLC_TASKDEFS_RESOURCE_PATH); + for (Object o : taskdefs.keySet()) { + String name = o.toString(); + try { + project.addTaskDefinition(name, Class.forName(taskdefs + .getProperty(name))); + } catch (ClassNotFoundException e) { + log.error("Unknown class for task " + name, e); + } + } + Properties typedefs = getDefs(project, + SlcAntConstants.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 SlcAntException("Cannot load task definitions", e); + } + return defs; + } + + protected void initStructure(Project project, Resource script) { + // Init structure registry + try { + StructureRegistry registry = new TreeSRegistry(); + project.addReference(SlcAntConstants.REF_STRUCTURE_REGISTRY, + registry); + + String scriptPath = script.getURL().getPath(); + if (rootDir != null) { + scriptPath = scriptPath.substring(rootDir.getURL().getPath() + .length()); + log.debug("rootDirPath=" + rootDir.getURL().getPath()); + } + log.debug("scriptPath=" + scriptPath); + + List dirNames = new Vector(); + StringTokenizer st = new StringTokenizer(scriptPath, "/"); + TreeSPath currPath = null; + while (st.hasMoreTokens()) { + String name = st.nextToken(); + if (currPath == null) { + currPath = TreeSPath.createRootPath(name); + } else { + currPath = currPath.createChild(name); + } + registry.register(currPath, new SimpleSElement(name)); + } + TreeSPath projectPath = currPath + .createChild(project.getName() != null + && !project.getName().equals("") ? project + .getName() : "project"); + String projectDesc = project.getDescription() != null + && !project.getDescription().equals("") ? project + .getDescription() : projectPath.getName(); + registry.register(projectPath, new SimpleSElement(projectDesc)); + project.addReference(SlcAntConstants.REF_PROJECT_PATH, currPath); + + if (log.isDebugEnabled()) + log.debug("Project path: " + projectPath); + } catch (IOException e) { + throw new SlcAntException("Cannot inititalize execution structure", + e); + } + + /* + * File rootDir = new File(project + * .getUserProperty(SlcAntConstants.ROOT_DIR_PROPERTY)) + * .getAbsoluteFile(); File baseDir = + * project.getBaseDir().getAbsoluteFile(); List dirs = new Vector(); + * File currentDir = baseDir; do { dirs.add(currentDir); currentDir = + * currentDir.getParentFile(); if (log.isTraceEnabled()) log.trace("List " + + * currentDir); } while (!currentDir.equals(rootDir.getParentFile())); // + * first path is root dir (because of previous algorithm) TreeSPath + * currPath = TreeSPath.createRootPath(rootDir.getName()); for (int i = + * dirs.size() - 1; i >= 0; i--) { File dir = dirs.get(i); // retrieves + * description for this path final String description; if (i == 0) {// + * project itself description = project.getDescription() != null && + * !project.getDescription().equals("") ? project .getDescription() : + * project.getName(); } else { description = dir.getName(); if + * (log.isTraceEnabled()) log.trace("Dir desc " + i + "/" + dirs.size() + ": " + + * description); } SimpleSElement element = new + * SimpleSElement(description); // creates and register path if + * (!dir.equals(rootDir)) {// already set currPath = + * currPath.createChild(dir.getName()); } registry.register(currPath, + * element); } project.addReference(SlcAntConstants.REF_PROJECT_PATH, + * currPath); + */ } + + protected void parseProject(Project project, Resource script) { + try { + 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 SlcAntException("Could not parse project for script " + + script, 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 SlcAntException("SLC Ant execution failed", exception); + } finally { + p.fireBuildFinished(exception); + } + } + + public void setSlcRuntime(SlcRuntime slcRuntime) { + this.slcRuntime = slcRuntime; + } + + 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(Resource workDir) { + this.workDir = workDir; + } + } diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java index d92a5f892..61b78cc7c 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java @@ -108,12 +108,6 @@ public class SlcAntConfig { // SLC ROOT PROPERTIES /** Property for the root file (SLC root property file). */ public final static String ROOT_FILE_PROPERTY = "slc.rootFile"; - /** 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"; /** * Comma-separated list of property file names to load from the conf dir and * add to project user properties @@ -194,30 +188,30 @@ public class SlcAntConfig { final File workDir; // Root dir final File rootDir = slcRootFile.getParentFile(); - all.setProperty(ROOT_DIR_PROPERTY, fileUrlPrefix + all.setProperty(SlcAntConstants.ROOT_DIR_PROPERTY, fileUrlPrefix + rootDir.getCanonicalPath()); // Conf dir - if (all.getProperty(CONF_DIR_PROPERTY) == null) { - confDir = new File(rootProps.getProperty(CONF_DIR_PROPERTY, + if (all.getProperty(SlcAntConstants.CONF_DIR_PROPERTY) == null) { + confDir = new File(rootProps.getProperty(SlcAntConstants.CONF_DIR_PROPERTY, rootDir.getAbsolutePath() + "/../conf")) .getCanonicalFile(); - all.setProperty(CONF_DIR_PROPERTY, fileUrlPrefix + all.setProperty(SlcAntConstants.CONF_DIR_PROPERTY, fileUrlPrefix + confDir.getAbsolutePath()); } else { - confDir = new File(all.getProperty(CONF_DIR_PROPERTY)) + confDir = new File(all.getProperty(SlcAntConstants.CONF_DIR_PROPERTY)) .getCanonicalFile(); } // Work dir - if (all.getProperty(WORK_DIR_PROPERTY) == null) { - workDir = new File(rootProps.getProperty(WORK_DIR_PROPERTY, + if (all.getProperty(SlcAntConstants.WORK_DIR_PROPERTY) == null) { + workDir = new File(rootProps.getProperty(SlcAntConstants.WORK_DIR_PROPERTY, rootDir.getAbsolutePath() + "/../work")) .getCanonicalFile(); - all.setProperty(WORK_DIR_PROPERTY, fileUrlPrefix + all.setProperty(SlcAntConstants.WORK_DIR_PROPERTY, fileUrlPrefix + workDir.getAbsolutePath()); } else { - workDir = new File(all.getProperty(WORK_DIR_PROPERTY)) + workDir = new File(all.getProperty(SlcAntConstants.WORK_DIR_PROPERTY)) .getCanonicalFile(); } diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java index c76dac60b..2a8405e35 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java @@ -24,5 +24,11 @@ public interface SlcAntConstants { public final static String EXECATTR_ANT_FILE = "ant.file"; public final static String EXECATTR_ANT_TARGETS = "ant.targets"; + /** 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"; } diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java index 420f48dd6..dcede31b3 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java @@ -185,7 +185,7 @@ public class SlcExecutionBuildListener extends AppenderSkeleton implements // avoid StackOverflow if notification calls Log4j itself. return; } - + // FIXME: make it more generic if (event.getLoggerName().equals( WebServiceSlcExecutionNotifier.class.getName())) { diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java index e9275ad87..227148189 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java @@ -107,7 +107,7 @@ public class SlcProjectHelper extends ProjectHelper2 { StructureRegistry registry = (StructureRegistry) project .getReference(SlcAntConstants.REF_STRUCTURE_REGISTRY); File rootDir = new File(project - .getUserProperty(SlcAntConfig.ROOT_DIR_PROPERTY)) + .getUserProperty(SlcAntConstants.ROOT_DIR_PROPERTY)) .getAbsoluteFile(); File baseDir = project.getBaseDir().getAbsoluteFile(); List dirs = new Vector(); diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java index c19cdd4a2..c49fcc74f 100644 --- a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java @@ -1,11 +1,15 @@ package org.argeo.slc.ant; +import java.io.File; import java.net.URL; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.runtime.SimpleSlcRuntime; import org.argeo.slc.unit.AbstractSpringTestCase; +import org.springframework.core.io.FileSystemResource; public class SlcAntTest extends AbstractSpringTestCase { private Log log = LogFactory.getLog(getClass()); @@ -16,9 +20,21 @@ public class SlcAntTest extends AbstractSpringTestCase { URL url = getClass().getResource("/org/argeo/slc/ant/build.xml"); log.info("Run Ant file from URL: " + url); - AntRunner antRunner = new AntRunner(getContext(), url, "test"); - antRunner.run(); + // AntRunner antRunner = new AntRunner(getContext(), url, "test"); + // antRunner.run(); + + AntSlcApplication slcApp = new AntSlcApplication(); + slcApp.setSlcRuntime(new SimpleSlcRuntime(getContext())); + slcApp.setRootDir(new FileSystemResource(new File("src/test/resources") + .getAbsolutePath() + + File.separator)); + + SlcExecution slcExecution = new SlcExecution(); + slcExecution.getAttributes().put(SlcAntConstants.EXECATTR_ANT_FILE, + url.toString()); + + slcApp.execute(slcExecution, null, null); } } diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml index 84ea6980d..35de7be94 100644 --- a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml @@ -3,16 +3,21 @@ - + - - - - - + + + + + + + + + + -- 2.39.5