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