]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java
1a69c493bf7509eac155dfbc3d4e4e10ab15f8da
[gpl/argeo-slc.git] / org.argeo.slc.agent / src / main / java / org / argeo / slc / ant / AntSlcApplication.java
1 package org.argeo.slc.ant;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Properties;
10 import java.util.StringTokenizer;
11 import java.util.Vector;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.apache.tools.ant.BuildException;
16 import org.apache.tools.ant.Project;
17 import org.apache.tools.ant.ProjectHelper;
18 import org.apache.tools.ant.helper.ProjectHelper2;
19 import org.apache.tools.ant.listener.CommonsLoggingListener;
20 import org.argeo.slc.core.SlcException;
21 import org.argeo.slc.core.process.SlcExecution;
22 import org.argeo.slc.core.structure.DefaultSRegistry;
23 import org.argeo.slc.core.structure.SimpleSElement;
24 import org.argeo.slc.core.structure.StructureRegistry;
25 import org.argeo.slc.core.structure.tree.TreeSPath;
26 import org.argeo.slc.core.structure.tree.TreeSRegistry;
27 import org.argeo.slc.runtime.SlcExecutionContext;
28 import org.argeo.slc.runtime.SlcRuntime;
29 import org.springframework.beans.factory.BeanDefinitionStoreException;
30 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
31 import org.springframework.context.ApplicationContext;
32 import org.springframework.context.ConfigurableApplicationContext;
33 import org.springframework.context.support.GenericApplicationContext;
34 import org.springframework.core.io.FileSystemResource;
35 import org.springframework.core.io.Resource;
36
37 public class AntSlcApplication {
38 private final static Log log = LogFactory.getLog(AntSlcApplication.class);
39
40 private SlcRuntime slcRuntime;
41
42 private Resource contextLocation;
43 private ConfigurableApplicationContext context;
44
45 private Resource rootDir;
46 private Resource confDir;
47 private File workDir;
48
49 public void init() {
50 try {
51 try {
52 if (rootDir != null)
53 System.setProperty(SlcAntConstants.ROOT_DIR_PROPERTY,
54 rootDir.getURL().toString());
55 if (confDir != null)
56 System.setProperty(SlcAntConstants.CONF_DIR_PROPERTY,
57 confDir.getURL().toString());
58 } catch (IOException e) {
59 throw new SlcAntException("Cannot interpret dir as URL.", e);
60 }
61 if (workDir != null)
62 System.setProperty(SlcAntConstants.WORK_DIR_PROPERTY, workDir
63 .toString());
64
65 if (confDir != null && contextLocation == null) {
66 contextLocation = confDir
67 .createRelative("applicationContext.xml");
68 }
69
70 GenericApplicationContext ctx = new GenericApplicationContext(
71 slcRuntime.getRuntimeContext());
72 if (contextLocation != null && contextLocation.exists()) {
73 XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(
74 ctx);
75 xmlReader.loadBeanDefinitions(contextLocation);
76 }
77 ctx.refresh();
78 context = ctx;
79 } catch (Exception e) {
80 throw new SlcAntException(
81 "Cannot create SLC app application context.", e);
82 }
83
84 }
85
86 public SlcExecutionContext execute(SlcExecution slcExecution,
87 Properties properties, Map<String, Object> references) {
88 log.info("### Start SLC execution " + slcExecution.getUuid() + " ###");
89 if (log.isDebugEnabled()) {
90 log.debug("rootDir=" + rootDir);
91 log.debug("confDir=" + confDir);
92 log.debug("workDir=" + workDir);
93 }
94
95 // Ant coordinates
96 Resource script = findAntScript(slcExecution);
97 List<String> targets = findAntTargets(slcExecution);
98
99 ConfigurableApplicationContext ctx = createExecutionContext(properties);
100
101 Project project = new Project();
102 AntExecutionContext executionContext = new AntExecutionContext(project);
103 project.addReference(SlcAntConstants.REF_ROOT_CONTEXT, ctx);
104 project.addReference(SlcAntConstants.REF_SLC_EXECUTION, slcExecution);
105 initProject(project, properties, references);
106 parseProject(project, script);
107
108 initStructure(project, script);
109 runProject(project, targets);
110
111 ctx.close();
112
113 return executionContext;
114 }
115
116 protected Resource findAntScript(SlcExecution slcExecution) {
117 String scriptStr = slcExecution.getAttributes().get(
118 SlcAntConstants.EXECATTR_ANT_FILE);
119 if (scriptStr == null)
120 throw new SlcAntException("No Ant script provided");
121
122 try {
123 if (log.isTraceEnabled())
124 log.trace("scriptStr=" + scriptStr);
125 Resource script = null;
126
127 if (rootDir != null) {
128 script = rootDir.createRelative(scriptStr);
129 if (log.isTraceEnabled())
130 log.trace("script(relative)=" + script);
131 if (script.exists())
132 return script;
133 }
134
135 script = slcRuntime.getRuntimeContext().getResource(scriptStr);
136 if (log.isTraceEnabled())
137 log.trace("script(absolute)=" + script);
138 if (script.exists())
139 return script;
140
141 script = new FileSystemResource(scriptStr);
142 if (log.isTraceEnabled())
143 log.trace("script(fs)=" + script);
144 if (script.exists())
145 return script;
146
147 } catch (Exception e) {
148 throw new SlcAntException("Cannot find Ant script " + scriptStr, e);
149 }
150
151 throw new SlcAntException("Cannot find Ant script " + scriptStr);
152 }
153
154 protected List<String> findAntTargets(SlcExecution slcExecution) {
155 String targetList = slcExecution.getAttributes().get(
156 SlcAntConstants.EXECATTR_ANT_TARGETS);
157 List<String> targets = new Vector<String>();
158 if (targetList != null) {
159 StringTokenizer stTargets = new StringTokenizer(targetList, ",");
160 while (stTargets.hasMoreTokens()) {
161 targets.add(stTargets.nextToken());
162 }
163 }
164 return targets;
165 }
166
167 protected ConfigurableApplicationContext createExecutionContext(
168 Properties userProperties) {
169 // Set user properties as system properties so that Spring can access
170 // them
171 for (Object key : userProperties.keySet()) {
172 System.setProperty(key.toString(), userProperties.getProperty(key
173 .toString()));
174 }
175
176 if (System.getProperty(SlcAntConstants.DEFAULT_TEST_RUN_PROPERTY) == null) {
177 System.setProperty(SlcAntConstants.DEFAULT_TEST_RUN_PROPERTY,
178 "defaultTestRun");
179 }
180
181 try {
182 GenericApplicationContext ctx = new GenericApplicationContext(
183 context);
184 ctx.refresh();
185 return ctx;
186 } catch (Exception e) {
187 throw new SlcAntException(
188 "Cannot create SLC execution application context.", e);
189 }
190 }
191
192 protected void initProject(Project project, Properties properties,
193 Map<String, Object> references) {
194 if (properties != null) {
195 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
196 project.setUserProperty(entry.getKey().toString(), entry
197 .getValue().toString());
198 }
199 }
200
201 if (references != null) {
202 for (Map.Entry<String, Object> entry : references.entrySet()) {
203 project.addReference(entry.getKey(), entry.getValue());
204 }
205 }
206
207 project.addBuildListener(new CommonsLoggingListener());
208 project.init();
209 addCustomTaskAndTypes(project);
210 }
211
212 /** Loads the SLC specific Ant tasks. */
213 protected void addCustomTaskAndTypes(Project project) {
214 Properties taskdefs = getDefs(project,
215 SlcAntConstants.SLC_TASKDEFS_RESOURCE_PATH);
216 for (Object o : taskdefs.keySet()) {
217 String name = o.toString();
218 try {
219 project.addTaskDefinition(name, Class.forName(taskdefs
220 .getProperty(name)));
221 } catch (ClassNotFoundException e) {
222 log.error("Unknown class for task " + name, e);
223 }
224 }
225 Properties typedefs = getDefs(project,
226 SlcAntConstants.SLC_TYPEDEFS_RESOURCE_PATH);
227 for (Object o : typedefs.keySet()) {
228 String name = o.toString();
229 try {
230 project.addDataTypeDefinition(name, Class.forName(typedefs
231 .getProperty(name)));
232 } catch (ClassNotFoundException e) {
233 log.error("Unknown class for type " + name, e);
234 }
235 }
236 }
237
238 private Properties getDefs(Project project, String path) {
239 Properties defs = new Properties();
240 try {
241 InputStream in = project.getClass().getResourceAsStream(path);
242 defs.load(in);
243 in.close();
244 } catch (IOException e) {
245 throw new SlcAntException("Cannot load task definitions", e);
246 }
247 return defs;
248 }
249
250 protected void initStructure(Project project, Resource script) {
251 // Init structure registry
252 try {
253 StructureRegistry<TreeSPath> registry = new TreeSRegistry();
254 project.addReference(SlcAntConstants.REF_STRUCTURE_REGISTRY,
255 registry);
256
257 String scriptPath = script.getURL().getPath();
258 if (rootDir != null) {
259 scriptPath = scriptPath.substring(rootDir.getURL().getPath()
260 .length());
261 log.debug("rootDirPath=" + rootDir.getURL().getPath());
262 }
263 log.debug("scriptPath=" + scriptPath);
264
265 StringTokenizer st = new StringTokenizer(scriptPath, "/");
266 TreeSPath currPath = null;
267 while (st.hasMoreTokens()) {
268 String name = st.nextToken();
269 if (currPath == null) {
270 currPath = TreeSPath.createRootPath(name);
271 } else {
272 currPath = currPath.createChild(name);
273 }
274 registry.register(currPath, new SimpleSElement(name));
275 }
276 TreeSPath projectPath = currPath
277 .createChild(project.getName() != null
278 && !project.getName().equals("") ? project
279 .getName() : "project");
280 String projectDesc = project.getDescription() != null
281 && !project.getDescription().equals("") ? project
282 .getDescription() : projectPath.getName();
283 registry.register(projectPath, new SimpleSElement(projectDesc));
284 project.addReference(SlcAntConstants.REF_PROJECT_PATH, currPath);
285
286 if (log.isDebugEnabled())
287 log.debug("Project path: " + projectPath);
288 } catch (IOException e) {
289 throw new SlcAntException("Cannot inititalize execution structure",
290 e);
291 }
292 }
293
294 protected void parseProject(Project project, Resource script) {
295 try {
296 File baseDir = null;
297 try {
298 File scriptFile = script.getFile();
299 baseDir = scriptFile.getParentFile();
300 } catch (IOException e) {// resource is not a file
301 baseDir = new File(System.getProperty("user.dir"));
302 }
303 project.setBaseDir(baseDir);
304 // Reset basedir property, in order to avoid base dir override when
305 // running in Maven
306 project.setProperty("basedir", baseDir.getAbsolutePath());
307
308 ProjectHelper2 projectHelper = new ProjectHelper2();
309 project.addReference(ProjectHelper.PROJECTHELPER_REFERENCE,
310 projectHelper);
311 projectHelper.parse(project, script.getURL());
312 } catch (Exception e) {
313 throw new SlcAntException("Could not parse project for script "
314 + script, e);
315 }
316
317 }
318
319 protected void runProject(Project p, List<String> targets) {
320 p.fireBuildStarted();
321 Throwable exception = null;
322 try {
323 if (targets.size() == 0) {// no target defined
324 p.executeTarget(p.getDefaultTarget());
325 } else {
326 p.executeTargets(new Vector<String>(targets));
327 }
328 } catch (Throwable e) {
329 exception = e;
330 throw new SlcAntException("SLC Ant execution failed", exception);
331 } finally {
332 p.fireBuildFinished(exception);
333 }
334 }
335
336 public void setSlcRuntime(SlcRuntime slcRuntime) {
337 this.slcRuntime = slcRuntime;
338 }
339
340 public void setContextLocation(Resource contextLocation) {
341 this.contextLocation = contextLocation;
342 }
343
344 public void setRootDir(Resource rootDir) {
345 this.rootDir = rootDir;
346 }
347
348 public void setConfDir(Resource confDir) {
349 this.confDir = confDir;
350 }
351
352 public void setWorkDir(File workDir) {
353 this.workDir = workDir;
354 }
355
356 }