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