1 package org
.argeo
.slc
.ant
;
4 import java
.io
.FileInputStream
;
5 import java
.io
.IOException
;
7 import java
.util
.Properties
;
8 import java
.util
.StringTokenizer
;
10 import org
.springframework
.util
.Log4jConfigurer
;
12 import org
.apache
.commons
.logging
.Log
;
13 import org
.apache
.commons
.logging
.LogFactory
;
14 import org
.apache
.tools
.ant
.Project
;
18 * Manager and initializer of the properties required by SLC Ant.
22 * All properties described here will get a value one way or another (see below
23 * for details)/ Each property will be accessible via Ant or Spring properties.
27 * The property <i>slc.rootFile</i> is set based on the location of the SLC
28 * root property file found in the directory structure of a called Ant file. The
29 * default name of this file is <b>slcRoot.properties</b> (can be set by
30 * {@link #setSlcRootFileName(String)}). <br>
31 * This property provides the absolute path to the unique SLC root property file
32 * which marks the root of an Ant SLC tree structure.
36 * The property <i>slc.rootDir</i> is inferred from <i>slc.rootFile</i> and
37 * provides a convenient shortcut to the root directory of the Ant files
38 * directory structure.
42 * A few directory and file related properties can be set in the SLC root
43 * property file (if they are not explicitly set their default values will be
46 * <table border="1" cellspacing="0">
49 * <th>Description</th>
53 * <td><i>slc.confDir</i></td>
54 * <td>Directory where to find the various configuration files of a given SLC
56 * <td>${slc.rootDir}/../conf</td>
59 * <td><i>slc.workDir</i></td>
60 * <td>Directory where data can be retrieved or generated: build outputs, test
61 * inputs/outputs, test results, etc. The underlying directory structure is
62 * specified by the specific SLC application.</td>
63 * <td>${slc.rootDir}/../work</td>
66 * <td><i>slc.propertyFileNames</i></td>
67 * <td>Comma-separated list of the files names of the property files to load
68 * from the conf directory. Having various files allows to separate between SLC
69 * framework properties and properties specific to a given application built on
70 * top of SLC. All will be available across Ant and Spring.</td>
71 * <td>slc.properties</td>
73 * </table> <b>Note:</b> Only the properties above can be set in the SLC root
74 * properties file. All other properties should be defined in the registered
79 * Any property can be defined in the conf files defined in the SLC root
80 * properties file (see above). SLC expects some which will have defaults but
81 * can be overriden there. By convention they should be defined in the
82 * <b>slc.properties</b> file, while application specific properties should be
83 * defined in other conf files. This allows for a clean spearation between SLC
84 * and the applications built on top of it:
86 * <table border="1" cellspacing="0">
89 * <th>Description</th>
93 * <td><i>slc.applicationContext</i></td>
94 * <td>Path to the root Spring application context file used by SLC Ant.</td>
95 * <td>${slc.confDir}/applicationContext.xml</td>
98 * <td><i>slc.defaultTestRun</i></td>
99 * <td>Name of the {@link WritableTestRun} Spring bean that the
100 * <code>slc.test</code> task will use by default. This can be overridden when
101 * calling the task from Ant.</td>
102 * <td>defaultTestRun</td>
107 public class SlcAntConfig
{
108 // SLC ROOT PROPERTIES
109 /** Property for the root file (SLC root property file). */
110 public final static String ROOT_FILE_PROPERTY
= "slc.rootFile";
111 /** Property for the root dir (SLC root property file). */
112 public final static String ROOT_DIR_PROPERTY
= "slc.rootDir";
113 /** Property for the conf dir (SLC root property file). */
114 public final static String CONF_DIR_PROPERTY
= "slc.confDir";
115 /** Property for the work dir (SLC root property file). */
116 public final static String WORK_DIR_PROPERTY
= "slc.workDir";
118 * Comma-separated list of property file names to load from the conf dir and
119 * add to project user properties
121 public final static String PROPERTY_FILE_NAMES_PROPERTY
= "slc.propertyFileNames";
123 // SLC CONF PROPERTIES
124 /** Path to the root Spring application context */
125 public static String APPLICATION_CONTEXT_PROPERTY
= "slc.applicationContext";
126 /** Name of the Spring bean used by default */
127 public static String DEFAULT_TEST_RUN_PROPERTY
= "slc.defaultTestRun";
129 // SLC LOCAL PROPERTIES
130 /** Property for the dir label (SLC local property file). */
131 public static String DIR_LABEL_PROPERTY
= "slc.dirLabel";
133 private String slcRootFileName
= "slcRoot.properties";
134 private String slcLocalFileName
= "slcLocal.properties";
137 * Retrieves or infers all properties and set them as project user
138 * properties. All these properties will be set as project properties <b>if
139 * they had not been set as project properties before</b> (like by
140 * overriding through the standard Ant mechanisms).
143 * the Ant <code>Project</code> being run.
144 * @return whether the project could be initialized for SLC usage (e.g.
145 * presence of an SLC root file)
147 public boolean initProject(Project project
) {
148 File projectBaseDir
= project
.getBaseDir();
149 File slcRootFile
= findSlcRootFile(projectBaseDir
);
150 if (slcRootFile
== null) {
154 // pass the project properties through the System properties
155 System
.getProperties().putAll((Map
<?
, ?
>) project
.getUserProperties());
156 Properties all
= new Properties();
157 all
.putAll(System
.getProperties());
158 prepareAllProperties(slcRootFile
, all
);
160 Log log
= LogFactory
.getLog(this.getClass());
161 for (Object o
: all
.keySet()) {
162 String key
= o
.toString();
163 // System.out.println(key+"="+all.getProperty(key));
164 if (project
.getUserProperty(key
) == null) {// not already set
165 // if (log.isDebugEnabled())
166 // log.debug(key + "=" + all.getProperty(key));
167 project
.setUserProperty(key
, all
.getProperty(key
));
174 * Retrieves or infers all required properties.
177 * the location of the SLC root file
179 * @return the prepared properties. Note that it also contains the System
180 * and Ant properties which had previously been set.
182 public void prepareAllProperties(File slcRootFile
, Properties all
) {
184 final String fileUrlPrefix
= "";
186 all
.put(ROOT_FILE_PROPERTY
, slcRootFile
.getCanonicalPath());
187 // Remove basedir property in order to avoid conflict with Maven
188 if (all
.containsKey("basedir"))
189 all
.remove("basedir");
191 Properties rootProps
= loadFile(slcRootFile
.getCanonicalPath());
196 final File rootDir
= slcRootFile
.getParentFile();
197 all
.setProperty(ROOT_DIR_PROPERTY
, fileUrlPrefix
198 + rootDir
.getCanonicalPath());
201 if (all
.getProperty(CONF_DIR_PROPERTY
) == null) {
202 confDir
= new File(rootProps
.getProperty(CONF_DIR_PROPERTY
,
203 rootDir
.getAbsolutePath() + "/../conf"))
205 all
.setProperty(CONF_DIR_PROPERTY
, fileUrlPrefix
206 + confDir
.getAbsolutePath());
208 confDir
= new File(all
.getProperty(CONF_DIR_PROPERTY
))
213 if (all
.getProperty(WORK_DIR_PROPERTY
) == null) {
214 workDir
= new File(rootProps
.getProperty(WORK_DIR_PROPERTY
,
215 rootDir
.getAbsolutePath() + "/../work"))
217 all
.setProperty(WORK_DIR_PROPERTY
, fileUrlPrefix
218 + workDir
.getAbsolutePath());
220 workDir
= new File(all
.getProperty(WORK_DIR_PROPERTY
))
224 // Properties from the conf dir files
225 Properties properties
= new Properties();
226 StringTokenizer st
= new StringTokenizer(rootProps
.getProperty(
227 PROPERTY_FILE_NAMES_PROPERTY
, "slc.properties"), ",");
228 while (st
.hasMoreTokens()) {
229 String fileName
= st
.nextToken();
230 properties
.putAll(loadFile(confDir
.getAbsolutePath()
231 + File
.separator
+ fileName
));
234 for (Object o
: properties
.keySet()) {
235 String key
= o
.toString();
236 if (all
.getProperty(key
) == null) {// not already set
237 all
.setProperty(key
, properties
.getProperty(key
));
241 // Default application context
242 if (all
.getProperty(APPLICATION_CONTEXT_PROPERTY
) == null) {
243 all
.setProperty(APPLICATION_CONTEXT_PROPERTY
, confDir
245 + "/applicationContext.xml");
248 if (all
.getProperty(DEFAULT_TEST_RUN_PROPERTY
) == null) {
249 all
.setProperty(DEFAULT_TEST_RUN_PROPERTY
,
254 if (all
.getProperty("log4j.configuration") == null) {
255 System
.setProperty("log4j.configuration", confDir
257 + File
.separator
+ "log4j.properties");
258 // TODO: fix dependency to log4j
259 Log4jConfigurer
.initLogging(confDir
.getCanonicalPath()
260 + File
.separator
+ "log4j.properties");
262 } catch (Exception e
) {
263 throw new SlcAntException("Unexpected exception while configuring",
268 /** Loads the content of a file as <code>Properties</code>. */
269 private Properties
loadFile(String path
) {
270 Properties p
= new Properties();
272 FileInputStream in
= new FileInputStream(path
);
275 } catch (IOException e
) {
276 throw new SlcAntException("Cannot read SLC root file", e
);
282 * Looks for a file named {@link #getSlcLocalFileName()} in the directory,
283 * loads it as properties file and return the value of the property
284 * {@link #DIR_LABEL_PROPERTY}.
286 public String
getDescriptionForDir(File dir
) {
287 String description
= dir
.getName();
288 File slcLocal
= new File(dir
.getPath() + File
.separator
289 + getSlcLocalFileName());
290 if (slcLocal
.exists()) {
291 Properties properties
= loadFile(slcLocal
.getAbsolutePath());
292 description
= properties
.getProperty(
293 SlcAntConfig
.DIR_LABEL_PROPERTY
, description
);
299 * Recursively scans directories downwards until it find a file names as
300 * defined by {@link #getSlcRootFileName()}.
302 public File
findSlcRootFile(File dir
) {
303 for (File file
: dir
.listFiles()) {
304 if (!file
.isDirectory()
305 && file
.getName().equals(getSlcRootFileName())) {
310 File parentDir
= dir
.getParentFile();
311 if (parentDir
== null) {
312 return null;// stop condition: not found
314 return findSlcRootFile(parentDir
);
319 * Gets the file name of the file marking the root directory, default being
320 * <i>slcRoot.properties</i>.
322 public String
getSlcRootFileName() {
323 return slcRootFileName
;
326 /** Sets the file name of the file marking the root directory. */
327 public void setSlcRootFileName(String slcRootFileName
) {
328 this.slcRootFileName
= slcRootFileName
;
332 * Gets the file name of the file containing directory specific properties,
333 * default being <i>slcLocal.properties</i>.
335 public String
getSlcLocalFileName() {
336 return slcLocalFileName
;
339 /** Sets the file name of the file containing directory specific properties. */
340 public void setSlcLocalFileName(String slcLocalFileName
) {
341 this.slcLocalFileName
= slcLocalFileName
;