1 package org
.argeo
.slc
.ant
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
8 import java
.util
.Properties
;
9 import java
.util
.Vector
;
11 import org
.springframework
.context
.support
.AbstractApplicationContext
;
12 import org
.springframework
.context
.support
.FileSystemXmlApplicationContext
;
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
.ProjectHelper2
;
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
;
26 * Custom implementation of an Ant <code>ProjectHelper</code> binding a Spring
27 * application context and a structure registry with the Ant project.
29 public class SlcProjectHelper
extends ProjectHelper2
{
30 private static Log log
;
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";
39 * Resource path to the property file listing the SLC specific Ant tasks:
40 * /org/argeo/slc/ant/taskdefs.properties
42 private static String SLC_TASKDEFS_RESOURCE_PATH
= "/org/argeo/slc/ant/taskdefs.properties";
43 private static String SLC_TYPEDEFS_RESOURCE_PATH
= "/org/argeo/slc/ant/typedefs.properties";
45 protected SlcAntConfig slcAntConfig
= null;
48 public void parse(Project project
, Object source
) throws BuildException
{
50 if (source
instanceof File
) {
51 File sourceFile
= (File
) source
;
52 // Reset basedir property, in order to avoid base dir override when
54 project
.setProperty("basedir", sourceFile
.getParentFile()
58 if (slcAntConfig
!= null) {
59 // Config already initialized (probably import), only parse
60 super.parse(project
, source
);
65 slcAntConfig
= new SlcAntConfig();
67 if (!slcAntConfig
.initProject(project
)) {
68 // not SLC compatible, do normal Ant
69 super.parse(project
, source
);
74 // log4j is initialized only now
75 log
= LogFactory
.getLog(SlcProjectHelper
.class);
78 if (log
.isDebugEnabled())
79 log
.debug("SLC properties are set, starting initialization for "
80 + source
+ " (projectHelper=" + this + ")");
82 beforeParsing(project
);
84 // Calls the underlying implementation to do the actual work
85 super.parse(project
, source
);
87 afterParsing(project
);
91 * Performs operations after config initialization and before Ant file
92 * parsing. Performed only once when the main project file is parsed. Should
93 * be called by overriding methods.
95 protected void beforeParsing(Project project
) {
96 // Init Spring application context
97 initSpringContext(project
);
99 // Init structure registry
100 DefaultSRegistry registry
= new DefaultSRegistry();
101 project
.addReference(REF_STRUCTURE_REGISTRY
, registry
);
105 * Performs operations after parsing of the main file. Called only once (not
108 protected void afterParsing(Project project
) {
109 // Creates structure root
110 registerProjectAndParents(project
, slcAntConfig
);
111 addCustomTaskAndTypes(project
);
114 /** Creates the tree-based structure for this project. */
115 private void registerProjectAndParents(Project project
,
116 SlcAntConfig slcAntConfig
) {
117 StructureRegistry
<TreeSPath
> registry
= (StructureRegistry
<TreeSPath
>) project
118 .getReference(REF_STRUCTURE_REGISTRY
);
119 File rootDir
= new File(project
120 .getUserProperty(SlcAntConfig
.ROOT_DIR_PROPERTY
))
122 File baseDir
= project
.getBaseDir().getAbsoluteFile();
123 List
<File
> dirs
= new Vector
<File
>();
124 File currentDir
= baseDir
;
126 dirs
.add(currentDir
);
127 currentDir
= currentDir
.getParentFile();
128 if (log
.isTraceEnabled())
129 log
.trace("List " + currentDir
);
130 } while (!currentDir
.equals(rootDir
.getParentFile()));
132 // first path is root dir (because of previous algorithm)
133 TreeSPath currPath
= TreeSPath
.createRootPath(rootDir
.getName());
134 for (int i
= dirs
.size() - 1; i
>= 0; i
--) {
135 File dir
= dirs
.get(i
);
137 // retrieves description for this path
138 final String description
;
139 if (i
== 0) {// project itself
140 description
= project
.getDescription() != null
141 && !project
.getDescription().equals("") ? project
142 .getDescription() : project
.getName() != null ? project
143 .getName() : slcAntConfig
.getDescriptionForDir(dir
);
145 description
= slcAntConfig
.getDescriptionForDir(dir
);
146 if (log
.isTraceEnabled())
147 log
.trace("Dir desc " + i
+ "/" + dirs
.size() + ": "
150 SimpleSElement element
= new SimpleSElement(description
);
152 // creates and register path
153 if (!dir
.equals(rootDir
)) {// already set
154 currPath
= currPath
.createChild(dir
.getName());
156 registry
.register(currPath
, element
);
158 project
.addReference(REF_PROJECT_PATH
, currPath
);
161 /** Gets the path of a project (root). */
162 public static TreeSPath
getProjectPath(Project project
) {
163 return (TreeSPath
) project
.getReference(REF_PROJECT_PATH
);
166 /** Initializes the Spring application context. */
167 private void initSpringContext(Project project
) {
168 System
.getProperties().putAll((Map
<?
, ?
>) project
.getProperties());
169 String acPath
= project
170 .getUserProperty(SlcAntConfig
.APPLICATION_CONTEXT_PROPERTY
);
171 if (log
.isDebugEnabled())
172 log
.debug("Loading Spring application context from " + acPath
);
173 // FIXME: workaround to the removal of leading '/' by Spring
175 AbstractApplicationContext context
= new FileSystemXmlApplicationContext(
177 context
.registerShutdownHook();
178 project
.addReference(REF_ROOT_CONTEXT
, context
);
181 /** Loads the SLC specific Ant tasks. */
182 private void addCustomTaskAndTypes(Project project
) {
183 Properties taskdefs
= getDefs(project
, SLC_TASKDEFS_RESOURCE_PATH
);
184 for (Object o
: taskdefs
.keySet()) {
185 String name
= o
.toString();
187 project
.addTaskDefinition(name
, Class
.forName(taskdefs
188 .getProperty(name
)));
189 } catch (ClassNotFoundException e
) {
190 log
.error("Unknown class for task " + name
, e
);
193 Properties typedefs
= getDefs(project
, SLC_TYPEDEFS_RESOURCE_PATH
);
194 for (Object o
: typedefs
.keySet()) {
195 String name
= o
.toString();
197 project
.addDataTypeDefinition(name
, Class
.forName(typedefs
198 .getProperty(name
)));
199 } catch (ClassNotFoundException e
) {
200 log
.error("Unknown class for type " + name
, e
);
205 private Properties
getDefs(Project project
, String path
) {
206 Properties defs
= new Properties();
208 InputStream in
= project
.getClass().getResourceAsStream(path
);
211 } catch (IOException e
) {
212 throw new SlcAntException("Cannot load task definitions", e
);