]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java
Change default separator
[gpl/argeo-slc.git] / org.argeo.slc / src / main / java / org / argeo / slc / ant / SlcProjectHelper.java
1 package org.argeo.slc.ant;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Properties;
9 import java.util.Vector;
10
11 import org.springframework.context.support.AbstractApplicationContext;
12 import org.springframework.context.support.FileSystemXmlApplicationContext;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.apache.tools.ant.BuildException;
17 import org.apache.tools.ant.Project;
18 import org.apache.tools.ant.helper.ProjectHelperImpl;
19
20 import org.argeo.slc.core.structure.DefaultSRegistry;
21 import org.argeo.slc.core.structure.SimpleSElement;
22 import org.argeo.slc.core.structure.StructureRegistry;
23 import org.argeo.slc.core.structure.tree.TreeSPath;
24
25 /**
26 * Custom implementation of an Ant <code>ProjectHelper</code> binding a Spring
27 * application context and a structure registry with the Ant project.
28 */
29 public class SlcProjectHelper extends ProjectHelperImpl {
30 private static Log log;
31
32 /** The Ant reference to the Spring application context used. */
33 public static String REF_ROOT_CONTEXT = "slcApplicationContext";
34 /** The Ant reference to the SLC structure registry used. */
35 public static String REF_STRUCTURE_REGISTRY = "slcStructureRegistry";
36 /** The Ant reference to the <code>TreePath</code> of the current project */
37 private static String REF_PROJECT_PATH = "slcProjectPath";
38 /**
39 * Resource path to the property file listing the SLC specific Ant tasks:
40 * /org/argeo/slc/ant/taskdefs.properties
41 */
42 private static String SLC_TASKDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/taskdefs.properties";
43
44 @Override
45 public void parse(Project project, Object source) throws BuildException {
46
47 // initialize config
48 SlcAntConfig slcAntConfig = new SlcAntConfig();
49
50 if(!slcAntConfig.initProject(project)){
51 // not SLC compatible, do normal Ant
52 super.parse(project, source);
53 return;
54 }
55
56 if (log == null) {
57 // log4j is initialized only now
58 log = LogFactory.getLog(SlcProjectHelper.class);
59 }
60 log.debug("SLC properties are set, starting initialization..");
61
62 // init Spring application context
63 initSpringContext(project);
64
65 // init structure registry
66 DefaultSRegistry registry = new DefaultSRegistry();
67 project.addReference(REF_STRUCTURE_REGISTRY, registry);
68
69 // call the underlying implementation to do the actual work
70 super.parse(project, source);
71
72 // create structure root
73 registerProjectAndParents(project, slcAntConfig);
74
75 addSlcTasks(project);
76
77 }
78
79 /** Creates the tree-based structure for this project. */
80 private void registerProjectAndParents(Project project,
81 SlcAntConfig slcAntConfig) {
82 StructureRegistry registry = (StructureRegistry) project
83 .getReference(REF_STRUCTURE_REGISTRY);
84 File rootDir = new File(project
85 .getUserProperty(SlcAntConfig.ROOT_DIR_PROPERTY))
86 .getAbsoluteFile();
87 File baseDir = project.getBaseDir().getAbsoluteFile();
88
89 List<File> dirs = new Vector<File>();
90 File currentDir = baseDir;
91 do {
92 dirs.add(currentDir);
93 currentDir = currentDir.getParentFile();
94 if (log.isTraceEnabled())
95 log.trace("List " + currentDir);
96 } while (!currentDir.equals(rootDir.getParentFile()));
97
98 // first path is root dir (because of previous algorithm)
99 TreeSPath currPath = TreeSPath.createRootPath(rootDir.getName());
100 for (int i = dirs.size() - 1; i >= 0; i--) {
101 File dir = dirs.get(i);
102
103 // retrieves description for this path
104 final String description;
105 if (i == 0) {// project itself
106 description = project.getDescription() != null ? project
107 .getDescription() : "";
108 } else {
109 description = slcAntConfig.getDescriptionForDir(dir);
110 }
111 SimpleSElement element = new SimpleSElement(description);
112
113 // creates and register path
114 if (!dir.equals(rootDir)) {// already set
115 currPath = currPath.createChild(dir.getName());
116 }
117 registry.register(currPath, element);
118 }
119 project.addReference(REF_PROJECT_PATH, currPath);
120 }
121
122 /** Gets the path of a project (root). */
123 public static TreeSPath getProjectPath(Project project) {
124 return (TreeSPath) project.getReference(REF_PROJECT_PATH);
125 }
126
127 /** Initializes the Spring application context. */
128 private void initSpringContext(Project project) {
129 System.getProperties().putAll((Map<?, ?>) project.getProperties());
130 String acPath = project
131 .getUserProperty(SlcAntConfig.APPLICATION_CONTEXT_PROPERTY);
132 AbstractApplicationContext context = new FileSystemXmlApplicationContext(
133 acPath);
134 context.registerShutdownHook();
135 project.addReference(REF_ROOT_CONTEXT, context);
136 }
137
138 /** Loads the SLC specific Ant tasks. */
139 private void addSlcTasks(Project project) {
140 Properties taskdefs = new Properties();
141 try {
142 InputStream in = project.getClass().getResourceAsStream(
143 SLC_TASKDEFS_RESOURCE_PATH);
144 taskdefs.load(in);
145 in.close();
146 } catch (IOException e) {
147 throw new SlcAntException("Cannot load task definitions", e);
148 }
149
150 for (Object o : taskdefs.keySet()) {
151 String name = o.toString();
152 try {
153 project.addTaskDefinition(name, Class.forName(taskdefs
154 .getProperty(name)));
155 } catch (ClassNotFoundException e) {
156 log.error("Unknown class for task " + name, e);
157 }
158 }
159 }
160 }