X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.agent%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fant%2FAntSlcApplication.java;h=37bdff0dce8f93f352dd6dbfaf4e8e5fb1306998;hb=e95a183611a40be7aca3233bb19b89bdc5043338;hp=76865aef57d8fafe032add61fd3f4a0f00d81632;hpb=48d35a213a2b0d792b11b5df276158159105043b;p=gpl%2Fargeo-slc.git 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 76865aef5..37bdff0dc 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,7 +1,6 @@ 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; @@ -10,146 +9,233 @@ 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.tools.ant.BuildException; +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.apache.tools.ant.listener.CommonsLoggingListener; +import org.argeo.slc.core.SlcException; 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.SlcExecutionContext; -import org.argeo.slc.runtime.SlcRuntime; -import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.argeo.slc.logging.Log4jUtils; +import org.argeo.slc.runtime.SlcExecutionOutput; +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.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.io.FileSystemResource; +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 { - private final static Log log = LogFactory.getLog(AntSlcApplication.class); + private final static String DEFAULT_APP_LOG4J_PROPERTIES = "org/argeo/slc/ant/defaultAppLog4j.properties"; - private SlcRuntime slcRuntime; + private final static Log log = LogFactory.getLog(AntSlcApplication.class); private Resource contextLocation; - private ConfigurableApplicationContext context; + private ConfigurableApplicationContext parentContext; private Resource rootDir; private Resource confDir; private File workDir; - public void init() { - try { - if (confDir != null && contextLocation == null) { - contextLocation = confDir - .createRelative("applicationContext.xml"); - } + public void execute(SlcExecution slcExecution, Properties properties, + Map references, + SlcExecutionOutput executionOutput) { - GenericApplicationContext ctx = new GenericApplicationContext( - slcRuntime.getRuntimeContext()); - if (contextLocation != null && contextLocation.exists()) { - XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( - ctx); - xmlReader.loadBeanDefinitions(contextLocation); - } - ctx.refresh(); - context = ctx; - } catch (Exception e) { - throw new SlcAntException( - "Cannot create SLC app application context.", e); - } - - } + // Properties and application logging initialization + initSystemProperties(properties); + Log4jUtils.initLog4j("classpath:" + DEFAULT_APP_LOG4J_PROPERTIES); - public SlcExecutionContext execute(SlcExecution slcExecution, - Properties properties, Map references) { + log.info("\n###\n### Start SLC execution " + slcExecution.getUuid() + + "\n###\n"); if (log.isDebugEnabled()) { - log.debug("### Start SLC execution " + slcExecution.getUuid() - + " ###"); log.debug("rootDir=" + rootDir); log.debug("confDir=" + confDir); log.debug("workDir=" + workDir); } - if (rootDir != null) - properties.put(SlcAntConstants.ROOT_DIR_PROPERTY, rootDir - .toString()); - if (confDir != null) - properties.put(SlcAntConstants.CONF_DIR_PROPERTY, confDir - .toString()); - if (workDir != null) - properties.put(SlcAntConstants.WORK_DIR_PROPERTY, workDir - .toString()); - // Ant coordinates - Resource script = findAntScript(slcExecution); + String scriptRelativePath = findAntScript(slcExecution); List targets = findAntTargets(slcExecution); - ConfigurableApplicationContext ctx = createExecutionContext(properties); + // Spring initialization + ConfigurableApplicationContext ctx = createExecutionContext(slcExecution); + // Ant project initialization Project project = new Project(); AntExecutionContext executionContext = new AntExecutionContext(project); - project.addReference(SlcAntConstants.REF_ROOT_CONTEXT, ctx); - project.addReference(SlcAntConstants.REF_SLC_EXECUTION, slcExecution); - initProject(project, properties, references); - parseProject(project, script); + project.addReference(AntConstants.REF_ROOT_CONTEXT, ctx); + project.addReference(AntConstants.REF_SLC_EXECUTION, slcExecution); - initStructure(project, script); - runProject(project, targets); + try { + initProject(project, properties, references); + parseProject(project, scriptRelativePath); - ctx.close(); + // Execute project + initStructure(project, scriptRelativePath); + runProject(project, targets); - return executionContext; + if (executionOutput != null) + executionOutput.postExecution(executionContext); + } finally { + ctx.close(); + } } - protected Resource findAntScript(SlcExecution slcExecution) { - String scriptStr = slcExecution.getAttributes().get( - SlcAntConstants.EXECATTR_ANT_FILE); - if (scriptStr == null) - throw new SlcAntException("No Ant script provided"); + 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 (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; + 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); + } + } - script = slcRuntime.getRuntimeContext().getResource(scriptStr); - if (log.isTraceEnabled()) - log.trace("script(absolute)=" + script); - if (script.exists()) - return script; - - script = new FileSystemResource(scriptStr); - if (log.isTraceEnabled()) - log.trace("script(fs)=" + script); - if (script.exists()) - return script; + /** + * 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 SlcAntException("Cannot find Ant script " + scriptStr, e); + throw new SlcException( + "Cannot create SLC execution application context.", e); } + } - throw new SlcAntException("Cannot find Ant script " + scriptStr); + 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( - SlcAntConstants.EXECATTR_ANT_TARGETS); + AntConstants.EXECATTR_ANT_TARGETS); List targets = new Vector(); if (targetList != null) { StringTokenizer stTargets = new StringTokenizer(targetList, ","); @@ -160,26 +246,6 @@ public class AntSlcApplication { return targets; } - protected ConfigurableApplicationContext createExecutionContext( - Properties userProperties) { - // Set user properties as system properties so that Spring can access - // them - for (Object key : userProperties.keySet()) { - System.setProperty(key.toString(), userProperties.getProperty(key - .toString())); - } - - try { - GenericApplicationContext ctx = new GenericApplicationContext( - context); - ctx.refresh(); - 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) { @@ -196,6 +262,25 @@ public class AntSlcApplication { } 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); } @@ -203,7 +288,7 @@ public class AntSlcApplication { /** Loads the SLC specific Ant tasks. */ protected void addCustomTaskAndTypes(Project project) { Properties taskdefs = getDefs(project, - SlcAntConstants.SLC_TASKDEFS_RESOURCE_PATH); + AntConstants.SLC_TASKDEFS_RESOURCE_PATH); for (Object o : taskdefs.keySet()) { String name = o.toString(); try { @@ -214,7 +299,7 @@ public class AntSlcApplication { } } Properties typedefs = getDefs(project, - SlcAntConstants.SLC_TYPEDEFS_RESOURCE_PATH); + AntConstants.SLC_TYPEDEFS_RESOURCE_PATH); for (Object o : typedefs.keySet()) { String name = o.toString(); try { @@ -233,58 +318,50 @@ public class AntSlcApplication { defs.load(in); in.close(); } catch (IOException e) { - throw new SlcAntException("Cannot load task definitions", e); + throw new SlcException("Cannot load task definitions", e); } return defs; } - protected void initStructure(Project project, Resource script) { + protected void initStructure(Project project, String scriptRelativePath) { // 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 { + 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)); } - 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); + 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, Resource script) { + protected void parseProject(Project project, String scriptRelativePath) { try { + Resource script = rootDir.createRelative(scriptRelativePath); File baseDir = null; try { File scriptFile = script.getFile(); @@ -302,8 +379,8 @@ public class AntSlcApplication { projectHelper); projectHelper.parse(project, script.getURL()); } catch (Exception e) { - throw new SlcAntException("Could not parse project for script " - + script, e); + throw new SlcException("Could not parse project for script " + + scriptRelativePath, e); } } @@ -319,16 +396,12 @@ public class AntSlcApplication { } } catch (Throwable e) { exception = e; - throw new SlcAntException("SLC Ant execution failed", exception); + throw new SlcException("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; } @@ -345,4 +418,8 @@ public class AntSlcApplication { this.workDir = workDir; } + public void setParentContext(ConfigurableApplicationContext runtimeContext) { + this.parentContext = runtimeContext; + } + }