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