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