X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.agent%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fant%2FSlcAntConfig.java;fp=org.argeo.slc.agent%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fant%2FSlcAntConfig.java;h=9b2824886aca8503e3cc6dba6e73186729691772;hb=a7b136d40c14e4559faa5c34dc2b4dd2170ac2d4;hp=0000000000000000000000000000000000000000;hpb=956079f214e8b52944d1b5fe4576a9a7587ebb6e;p=gpl%2Fargeo-slc.git diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java new file mode 100644 index 000000000..9b2824886 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java @@ -0,0 +1,344 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.springframework.util.Log4jConfigurer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.Project; + +/** + *

+ * Manager and initializer of the properties required by SLC Ant. + *

+ * + *

+ * All properties described here will get a value one way or another (see below + * for details)/ Each property will be accessible via Ant or Spring properties. + *

+ * + *

+ * The property slc.rootFile is set based on the location of the SLC + * root property file found in the directory structure of a called Ant file. The + * default name of this file is slcRoot.properties (can be set by + * {@link #setSlcRootFileName(String)}).
+ * This property provides the absolute path to the unique SLC root property file + * which marks the root of an Ant SLC tree structure. + *

+ * + *

+ * The property slc.rootDir is inferred from slc.rootFile and + * provides a convenient shortcut to the root directory of the Ant files + * directory structure. + *

+ * + *

+ * A few directory and file related properties can be set in the SLC root + * property file (if they are not explicitly set their default values will be + * used): + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
PropertyDescriptionDefault
slc.confDirDirectory where to find the various configuration files of a given SLC + * Ant deployment${slc.rootDir}/../conf
slc.workDirDirectory where data can be retrieved or generated: build outputs, test + * inputs/outputs, test results, etc. The underlying directory structure is + * specified by the specific SLC application.${slc.rootDir}/../work
slc.propertyFileNamesComma-separated list of the files names of the property files to load + * from the conf directory. Having various files allows to separate between SLC + * framework properties and properties specific to a given application built on + * top of SLC. All will be available across Ant and Spring.slc.properties
Note: Only the properties above can be set in the SLC root + * properties file. All other properties should be defined in the registered + * conf files. + *

+ * + *

+ * Any property can be defined in the conf files defined in the SLC root + * properties file (see above). SLC expects some which will have defaults but + * can be overriden there. By convention they should be defined in the + * slc.properties file, while application specific properties should be + * defined in other conf files. This allows for a clean spearation between SLC + * and the applications built on top of it: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
PropertyDescriptionDefault
slc.applicationContextPath to the root Spring application context file used by SLC Ant.${slc.confDir}/applicationContext.xml
slc.defaultTestRunName of the {@link WritableTestRun} Spring bean that the + * slc.test task will use by default. This can be overridden when + * calling the task from Ant.defaultTestRun
+ *

+ */ +public class SlcAntConfig { + // SLC ROOT PROPERTIES + /** Property for the root file (SLC root property file). */ + public final static String ROOT_FILE_PROPERTY = "slc.rootFile"; + /** Property for the root dir (SLC root property file). */ + public final static String ROOT_DIR_PROPERTY = "slc.rootDir"; + /** Property for the conf dir (SLC root property file). */ + public final static String CONF_DIR_PROPERTY = "slc.confDir"; + /** Property for the work dir (SLC root property file). */ + public final static String WORK_DIR_PROPERTY = "slc.workDir"; + /** + * Comma-separated list of property file names to load from the conf dir and + * add to project user properties + */ + public final static String PROPERTY_FILE_NAMES_PROPERTY = "slc.propertyFileNames"; + + // SLC CONF PROPERTIES + /** Path to the root Spring application context */ + public static String APPLICATION_CONTEXT_PROPERTY = "slc.applicationContext"; + /** Name of the Spring bean used by default */ + public static String DEFAULT_TEST_RUN_PROPERTY = "slc.defaultTestRun"; + + // SLC LOCAL PROPERTIES + /** Property for the dir label (SLC local property file). */ + public static String DIR_LABEL_PROPERTY = "slc.dirLabel"; + + private String slcRootFileName = "slcRoot.properties"; + private String slcLocalFileName = "slcLocal.properties"; + + /** + * Retrieves or infers all properties and set them as project user + * properties. All these properties will be set as project properties if + * they had not been set as project properties before (like by + * overriding through the standard Ant mechanisms). + * + * @param project + * the Ant Project being run. + * @return whether the project could be initialized for SLC usage (e.g. + * presence of an SLC root file) + */ + public boolean initProject(Project project) { + File projectBaseDir = project.getBaseDir(); + File slcRootFile = findSlcRootFile(projectBaseDir); + if (slcRootFile == null) { + return false; + } + + // pass the project properties through the System properties + System.getProperties().putAll((Map) project.getUserProperties()); + Properties all = new Properties(); + all.putAll(System.getProperties()); + prepareAllProperties(slcRootFile, all); + + Log log = LogFactory.getLog(this.getClass()); + for (Object o : all.keySet()) { + String key = o.toString(); + // System.out.println(key+"="+all.getProperty(key)); + if (project.getUserProperty(key) == null) {// not already set + // if (log.isDebugEnabled()) + // log.debug(key + "=" + all.getProperty(key)); + project.setUserProperty(key, all.getProperty(key)); + } + } + return true; + } + + /** + * Retrieves or infers all required properties. + * + * @param slcRootFile + * the location of the SLC root file + * + * @return the prepared properties. Note that it also contains the System + * and Ant properties which had previously been set. + */ + public void prepareAllProperties(File slcRootFile, Properties all) { + try { + final String fileUrlPrefix = ""; + + all.put(ROOT_FILE_PROPERTY, slcRootFile.getCanonicalPath()); + // Remove basedir property in order to avoid conflict with Maven + if (all.containsKey("basedir")) + all.remove("basedir"); + + Properties rootProps = loadFile(slcRootFile.getCanonicalPath()); + + final File confDir; + final File workDir; + // Root dir + final File rootDir = slcRootFile.getParentFile(); + all.setProperty(ROOT_DIR_PROPERTY, fileUrlPrefix + + rootDir.getCanonicalPath()); + + // Conf dir + if (all.getProperty(CONF_DIR_PROPERTY) == null) { + confDir = new File(rootProps.getProperty(CONF_DIR_PROPERTY, + rootDir.getAbsolutePath() + "/../conf")) + .getCanonicalFile(); + all.setProperty(CONF_DIR_PROPERTY, fileUrlPrefix + + confDir.getAbsolutePath()); + } else { + confDir = new File(all.getProperty(CONF_DIR_PROPERTY)) + .getCanonicalFile(); + } + + // Work dir + if (all.getProperty(WORK_DIR_PROPERTY) == null) { + workDir = new File(rootProps.getProperty(WORK_DIR_PROPERTY, + rootDir.getAbsolutePath() + "/../work")) + .getCanonicalFile(); + all.setProperty(WORK_DIR_PROPERTY, fileUrlPrefix + + workDir.getAbsolutePath()); + } else { + workDir = new File(all.getProperty(WORK_DIR_PROPERTY)) + .getCanonicalFile(); + } + + // Properties from the conf dir files + Properties properties = new Properties(); + StringTokenizer st = new StringTokenizer(rootProps.getProperty( + PROPERTY_FILE_NAMES_PROPERTY, "slc.properties"), ","); + while (st.hasMoreTokens()) { + String fileName = st.nextToken(); + properties.putAll(loadFile(confDir.getAbsolutePath() + + File.separator + fileName)); + } + + for (Object o : properties.keySet()) { + String key = o.toString(); + if (all.getProperty(key) == null) {// not already set + all.setProperty(key, properties.getProperty(key)); + } + } + + // Default application context + if (all.getProperty(APPLICATION_CONTEXT_PROPERTY) == null) { + all.setProperty(APPLICATION_CONTEXT_PROPERTY, confDir + .getAbsolutePath() + + "/applicationContext.xml"); + } + // Default test run + if (all.getProperty(DEFAULT_TEST_RUN_PROPERTY) == null) { + all.setProperty(DEFAULT_TEST_RUN_PROPERTY, + "defaultTestRun"); + } + + // Default log4j + if (all.getProperty("log4j.configuration") == null) { + System.setProperty("log4j.configuration", confDir + .getCanonicalPath() + + File.separator + "log4j.properties"); + // TODO: fix dependency to log4j + Log4jConfigurer.initLogging(confDir.getCanonicalPath() + + File.separator + "log4j.properties"); + } + } catch (Exception e) { + throw new SlcAntException("Unexpected exception while configuring", + e); + } + } + + /** Loads the content of a file as Properties. */ + private Properties loadFile(String path) { + Properties p = new Properties(); + try { + FileInputStream in = new FileInputStream(path); + p.load(in); + in.close(); + } catch (IOException e) { + throw new SlcAntException("Cannot read SLC root file", e); + } + return p; + } + + /** + * Looks for a file named {@link #getSlcLocalFileName()} in the directory, + * loads it as properties file and return the value of the property + * {@link #DIR_LABEL_PROPERTY}. + */ + public String getDescriptionForDir(File dir) { + String description = dir.getName(); + File slcLocal = new File(dir.getPath() + File.separator + + getSlcLocalFileName()); + if (slcLocal.exists()) { + Properties properties = loadFile(slcLocal.getAbsolutePath()); + description = properties.getProperty( + SlcAntConfig.DIR_LABEL_PROPERTY, description); + } + return description; + } + + /** + * Recursively scans directories downwards until it find a file names as + * defined by {@link #getSlcRootFileName()}. + */ + public File findSlcRootFile(File dir) { + for (File file : dir.listFiles()) { + if (!file.isDirectory() + && file.getName().equals(getSlcRootFileName())) { + return file; + } + } + + File parentDir = dir.getParentFile(); + if (parentDir == null) { + return null;// stop condition: not found + } else { + return findSlcRootFile(parentDir); + } + } + + /** + * Gets the file name of the file marking the root directory, default being + * slcRoot.properties. + */ + public String getSlcRootFileName() { + return slcRootFileName; + } + + /** Sets the file name of the file marking the root directory. */ + public void setSlcRootFileName(String slcRootFileName) { + this.slcRootFileName = slcRootFileName; + } + + /** + * Gets the file name of the file containing directory specific properties, + * default being slcLocal.properties. + */ + public String getSlcLocalFileName() { + return slcLocalFileName; + } + + /** Sets the file name of the file containing directory specific properties. */ + public void setSlcLocalFileName(String slcLocalFileName) { + this.slcLocalFileName = slcLocalFileName; + } + +}