X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.core%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fant%2FSlcProjectHelper.java;h=001ead97bd28db91d77d5bbea186bcde54aa4675;hb=fb1f473a0fa4f3b11ebbf7a676983ea946fbdac0;hp=b7d7365725cdb3bb6780cbb5bf47cc855f5048cf;hpb=ad39dc06e6fcc81a50caf5c617f93f83b6cc698a;p=gpl%2Fargeo-slc.git diff --git a/org.argeo.slc.core/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java b/org.argeo.slc.core/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java index b7d736572..001ead97b 100644 --- a/org.argeo.slc.core/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java +++ b/org.argeo.slc.core/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java @@ -3,21 +3,29 @@ 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.List; import java.util.Map; import java.util.Properties; +import java.util.UUID; import java.util.Vector; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.context.ApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.log4j.LogManager; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.BuildListener; import org.apache.tools.ant.Project; -import org.apache.tools.ant.helper.ProjectHelperImpl; +import org.apache.tools.ant.helper.ProjectHelper2; -import org.argeo.slc.core.UnsupportedException; +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.process.SlcExecutionNotifier; import org.argeo.slc.core.structure.DefaultSRegistry; import org.argeo.slc.core.structure.SimpleSElement; import org.argeo.slc.core.structure.StructureRegistry; @@ -27,7 +35,7 @@ import org.argeo.slc.core.structure.tree.TreeSPath; * Custom implementation of an Ant ProjectHelper binding a Spring * application context and a structure registry with the Ant project. */ -public class SlcProjectHelper extends ProjectHelperImpl { +public class SlcProjectHelper extends ProjectHelper2 { private static Log log; /** The Ant reference to the Spring application context used. */ @@ -35,27 +43,36 @@ public class SlcProjectHelper extends ProjectHelperImpl { /** The Ant reference to the SLC structure registry used. */ public static String REF_STRUCTURE_REGISTRY = "slcStructureRegistry"; /** The Ant reference to the TreePath of the current project */ - private static String REF_PROJECT_PATH = "slcProjectPath"; + public static String REF_PROJECT_PATH = "slcProjectPath"; /** * Resource path to the property file listing the SLC specific Ant tasks: * /org/argeo/slc/ant/taskdefs.properties */ private static String SLC_TASKDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/taskdefs.properties"; + private static String SLC_TYPEDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/typedefs.properties"; + + protected SlcAntConfig slcAntConfig = null; @Override public void parse(Project project, Object source) throws BuildException { - if (!(source instanceof File)) { - throw new UnsupportedException("Ant file", source); + + if (source instanceof File) { + File sourceFile = (File) source; + // Reset basedir property, in order to avoid base dir override when + // running in Maven + project.setProperty("basedir", sourceFile.getParentFile() + .getAbsolutePath()); } - File sourceFile = (File) source; - // initialize config - SlcAntConfig slcAntConfig = new SlcAntConfig(); + if (slcAntConfig != null) { + // Config already initialized (probably import), only parse + super.parse(project, source); + return; + } + + // Initialize config + slcAntConfig = new SlcAntConfig(); - // Reset basedir property, in order to avoid base dir override when - // running in Maven - project.setProperty("basedir", sourceFile.getParentFile() - .getAbsolutePath()); if (!slcAntConfig.initProject(project)) { // not SLC compatible, do normal Ant super.parse(project, source); @@ -66,29 +83,47 @@ public class SlcProjectHelper extends ProjectHelperImpl { // log4j is initialized only now log = LogFactory.getLog(SlcProjectHelper.class); } - log.debug("SLC properties are set, starting initialization.."); - // init Spring application context - initSpringContext(project); + if (log.isDebugEnabled()) + log.debug("SLC properties are set, starting initialization for " + + source + " (projectHelper=" + this + ")"); - // init structure registry - DefaultSRegistry registry = new DefaultSRegistry(); - project.addReference(REF_STRUCTURE_REGISTRY, registry); + beforeParsing(project); - // call the underlying implementation to do the actual work + // Calls the underlying implementation to do the actual work super.parse(project, source); - // create structure root - registerProjectAndParents(project, slcAntConfig); + afterParsing(project); + } + + /** + * Performs operations after config initialization and before Ant file + * parsing. Performed only once when the main project file is parsed. Should + * be called by overriding methods. + */ + protected void beforeParsing(Project project) { + // Init Spring application context + initSpringContext(project); - addSlcTasks(project); + // Init structure registry + DefaultSRegistry registry = new DefaultSRegistry(); + project.addReference(REF_STRUCTURE_REGISTRY, registry); + } + /** + * Performs operations after parsing of the main file. Called only once (not + * for imports). + */ + protected void afterParsing(Project project) { + // Creates structure root + registerProjectAndParents(project, slcAntConfig); + addCustomTaskAndTypes(project); } /** Creates the tree-based structure for this project. */ private void registerProjectAndParents(Project project, SlcAntConfig slcAntConfig) { - StructureRegistry registry = (StructureRegistry) project + StructureRegistry registry = (StructureRegistry) project .getReference(REF_STRUCTURE_REGISTRY); File rootDir = new File(project .getUserProperty(SlcAntConfig.ROOT_DIR_PROPERTY)) @@ -111,10 +146,15 @@ public class SlcProjectHelper extends ProjectHelperImpl { // retrieves description for this path final String description; if (i == 0) {// project itself - description = project.getDescription() != null ? project - .getDescription() : "[no desc]"; + description = project.getDescription() != null + && !project.getDescription().equals("") ? project + .getDescription() : project.getName() != null ? project + .getName() : slcAntConfig.getDescriptionForDir(dir); } else { description = slcAntConfig.getDescriptionForDir(dir); + if (log.isTraceEnabled()) + log.trace("Dir desc " + i + "/" + dirs.size() + ": " + + description); } SimpleSElement element = new SimpleSElement(description); @@ -128,10 +168,9 @@ public class SlcProjectHelper extends ProjectHelperImpl { } /** Gets the path of a project (root). */ - public static TreeSPath getProjectPath(Project project) { - return (TreeSPath) project.getReference(REF_PROJECT_PATH); - } - + // private static TreeSPath getProjectPath(Project project) { + // return (TreeSPath) project.getReference(REF_PROJECT_PATH); + // } /** Initializes the Spring application context. */ private void initSpringContext(Project project) { System.getProperties().putAll((Map) project.getProperties()); @@ -142,23 +181,22 @@ public class SlcProjectHelper extends ProjectHelperImpl { // FIXME: workaround to the removal of leading '/' by Spring // use URL instead? AbstractApplicationContext context = new FileSystemXmlApplicationContext( - '/'+acPath); + '/' + acPath); context.registerShutdownHook(); project.addReference(REF_ROOT_CONTEXT, context); + + createAndRegisterSlcExecution(project); + // Add build listeners declared in Spring context + // Map listeners = context.getBeansOfType( + // BuildListener.class, false, true); + // for (BuildListener listener : listeners.values()) { + // project.addBuildListener(listener); + // } } /** Loads the SLC specific Ant tasks. */ - private void addSlcTasks(Project project) { - Properties taskdefs = new Properties(); - try { - InputStream in = project.getClass().getResourceAsStream( - SLC_TASKDEFS_RESOURCE_PATH); - taskdefs.load(in); - in.close(); - } catch (IOException e) { - throw new SlcAntException("Cannot load task definitions", e); - } - + protected static void addCustomTaskAndTypes(Project project) { + Properties taskdefs = getDefs(project, SLC_TASKDEFS_RESOURCE_PATH); for (Object o : taskdefs.keySet()) { String name = o.toString(); try { @@ -168,5 +206,61 @@ public class SlcProjectHelper extends ProjectHelperImpl { log.error("Unknown class for task " + name, e); } } + Properties typedefs = getDefs(project, 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 static 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 static void createAndRegisterSlcExecution(Project project) { + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + try { + slcExecution.setHost(InetAddress.getLocalHost().getHostName()); + } catch (UnknownHostException e) { + slcExecution.setHost(SlcExecution.UNKOWN_HOST); + } + + if (project.getReference(SlcProjectHelper.REF_ROOT_CONTEXT) != null) { + slcExecution.setType(SlcExecutionBuildListener.SLC_ANT_TYPE); + } else { + slcExecution.setType(SlcExecutionBuildListener.ANT_TYPE); + } + + slcExecution.setUser(System.getProperty("user.name")); + slcExecution.setStatus(SlcExecution.STATUS_RUNNING); + slcExecution.getAttributes().put("ant.file", + project.getProperty("ant.file")); + + project.addReference(SlcExecutionBuildListener.REF_SLC_EXECUTION, + slcExecution); + + // Add build listeners declared in Spring context + Map listeners = ((ListableBeanFactory) project + .getReference(REF_ROOT_CONTEXT)).getBeansOfType( + ProjectRelatedBuildListener.class, false, true); + for (ProjectRelatedBuildListener listener : listeners.values()) { + listener.init(project); + project.addBuildListener(listener); + } + } }