package org.argeo.slc.ant;\r
\r
-import org.springframework.context.ApplicationContext;\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Properties;\r
+import java.util.Vector;\r
+\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.tools.ant.BuildException;\r
import org.apache.tools.ant.Project;\r
import org.apache.tools.ant.helper.ProjectHelperImpl;\r
\r
+import org.argeo.slc.core.UnsupportedException;\r
import org.argeo.slc.core.structure.DefaultSRegistry;\r
-import org.argeo.slc.core.structure.tree.TreeSElement;\r
+import org.argeo.slc.core.structure.SimpleSElement;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
import org.argeo.slc.core.structure.tree.TreeSPath;\r
\r
+/**\r
+ * 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 static String PROP_APPLICATION_CONTEXT = "org.argeo.slc.slcRootContext";\r
- //public static String PROP_REGISTRY_MODE = "org.argeo.slc.slcRegistryMode";\r
+ private static Log log;\r
+\r
+ /** The Ant reference to the Spring application context used. */\r
public static String REF_ROOT_CONTEXT = "slcApplicationContext";\r
+ /** 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
+ /**\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
\r
@Override\r
public void parse(Project project, Object source) throws BuildException {\r
- stdOut("Entered SLC project helper");\r
+ if (!(source instanceof File)) {\r
+ throw new UnsupportedException("Ant file", source);\r
+ }\r
+ File sourceFile = (File)source;\r
+\r
+ // initialize config\r
+ SlcAntConfig slcAntConfig = new SlcAntConfig();\r
+\r
+ System.out.println("Base dir prop2: " + project.getProperty("basedir"));\r
+ // In order to avoid base dire override when running in Maven\r
+ project.setProperty("basedir", sourceFile.getParentFile().getAbsolutePath());\r
+ if (!slcAntConfig.initProject(project)) {\r
+ // not SLC compatible, do normal Ant\r
+ super.parse(project, source);\r
+ return;\r
+ }\r
+\r
+ if (log == null) {\r
+ // log4j is initialized only now\r
+ log = LogFactory.getLog(SlcProjectHelper.class);\r
+ }\r
+ log.debug("SLC properties are set, starting initialization..");\r
+ log.debug("Base dir1: " + project.getBaseDir().getAbsoluteFile());\r
+ log.debug("Base dir prop1: " + project.getProperty("basedir"));\r
\r
// init Spring application context\r
- String acPath = System.getProperty(PROP_APPLICATION_CONTEXT,\r
- "applicationContext.xml");\r
- ApplicationContext context = new FileSystemXmlApplicationContext(acPath);\r
- project.addReference(REF_ROOT_CONTEXT, context);\r
+ initSpringContext(project);\r
+ log.debug("Base dir2: " + project.getBaseDir().getAbsoluteFile());\r
\r
- // init structure register if it does not exist\r
+ // init structure registry\r
DefaultSRegistry registry = new DefaultSRegistry();\r
- project.addReference(REF_STRUCTURE_REGISTRY, registry);\r
+ project.addReference(REF_STRUCTURE_REGISTRY, registry);\r
\r
- // call the underlying implementation to do the actual work\r
- super.parse(project, source);\r
+ log.debug("Base dir prop2: " + project.getProperty("basedir"));\r
+ // in order to prevent pb w/ basedir setting:\r
+ source = ((File) source).getAbsoluteFile();\r
+ // call the underlying implementation to do the actual work\r
+ super.parse(project, source);\r
+\r
+ log.debug("Base dir3: " + project.getBaseDir().getAbsoluteFile());\r
+ // create structure root\r
+ registerProjectAndParents(project, slcAntConfig);\r
+\r
+ addSlcTasks(project);\r
\r
- String projectDescription = project.getDescription() != null ? project\r
- .getDescription()\r
- : "Root";\r
- TreeSElement element = TreeSElement.createRootElelment(\r
- getProjectPathName(project), projectDescription);\r
- registry.register(element);\r
}\r
\r
- private static void stdOut(Object o) {\r
- System.out.println(o);\r
+ /** Creates the tree-based structure for this project. */\r
+ private void registerProjectAndParents(Project project,\r
+ SlcAntConfig slcAntConfig) {\r
+ StructureRegistry registry = (StructureRegistry) project\r
+ .getReference(REF_STRUCTURE_REGISTRY);\r
+ File rootDir = new File(project\r
+ .getUserProperty(SlcAntConfig.ROOT_DIR_PROPERTY))\r
+ .getAbsoluteFile();\r
+ File baseDir = project.getBaseDir().getAbsoluteFile();\r
+ List<File> dirs = new Vector<File>();\r
+ File currentDir = baseDir;\r
+ do {\r
+ dirs.add(currentDir);\r
+ currentDir = currentDir.getParentFile();\r
+ if (log.isTraceEnabled())\r
+ log.trace("List " + currentDir);\r
+ } while (!currentDir.equals(rootDir.getParentFile()));\r
+\r
+ // first path is root dir (because of previous algorithm)\r
+ TreeSPath currPath = TreeSPath.createRootPath(rootDir.getName());\r
+ for (int i = dirs.size() - 1; i >= 0; i--) {\r
+ File dir = dirs.get(i);\r
+\r
+ // 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
+ } else {\r
+ description = slcAntConfig.getDescriptionForDir(dir);\r
+ }\r
+ SimpleSElement element = new SimpleSElement(description);\r
+\r
+ // creates and register path\r
+ if (!dir.equals(rootDir)) {// already set\r
+ currPath = currPath.createChild(dir.getName());\r
+ }\r
+ registry.register(currPath, element);\r
+ }\r
+ project.addReference(REF_PROJECT_PATH, currPath);\r
}\r
\r
+ /** Gets the path of a project (root). */\r
public static TreeSPath getProjectPath(Project project) {\r
- return TreeSPath.createChild(null, getProjectPathName(project));\r
+ return (TreeSPath) project.getReference(REF_PROJECT_PATH);\r
}\r
\r
- private static String getProjectPathName(Project project) {\r
- String projectName = project.getName() != null ? project.getName()\r
- : "project";\r
- return projectName;\r
+ /** Initializes the Spring application context. */\r
+ private void initSpringContext(Project project) {\r
+ System.getProperties().putAll((Map<?, ?>) project.getProperties());\r
+ String acPath = project\r
+ .getUserProperty(SlcAntConfig.APPLICATION_CONTEXT_PROPERTY);\r
+ AbstractApplicationContext context = new FileSystemXmlApplicationContext(\r
+ acPath);\r
+ context.registerShutdownHook();\r
+ project.addReference(REF_ROOT_CONTEXT, context);\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
+ for (Object o : taskdefs.keySet()) {\r
+ String name = o.toString();\r
+ try {\r
+ project.addTaskDefinition(name, Class.forName(taskdefs\r
+ .getProperty(name)));\r
+ } catch (ClassNotFoundException e) {\r
+ log.error("Unknown class for task " + name, e);\r
+ }\r
+ }\r
}\r
}\r