package org.argeo.slc.cli; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.ant.AntSlcApplication; import org.argeo.slc.ant.SlcAntConstants; import org.argeo.slc.ant.SlcAntException; import org.argeo.slc.core.SlcException; import org.argeo.slc.core.process.SlcExecution; import org.argeo.slc.runtime.SimpleSlcRuntime; import org.argeo.slc.runtime.SlcExecutionContext; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.Resource; public class DefaultSlcRuntime extends SimpleSlcRuntime implements BeanFactoryAware { private final static Log log = LogFactory.getLog(DefaultSlcRuntime.class); public final static String SLC_ROOT_FILE_NAME = "slcRoot.properties"; public SlcExecutionContext executeScript(Resource script, Properties properties, Map references) { if (runtimeContext == null) runtimeContext = new GenericApplicationContext(); SlcExecution slcExecution = new SlcExecution(); slcExecution.setUuid(UUID.randomUUID().toString()); try { slcExecution.setHost(InetAddress.getLocalHost().getHostName()); } catch (UnknownHostException e) { slcExecution.setHost(SlcExecution.UNKOWN_HOST); } slcExecution.setType(SlcAntConstants.EXECTYPE_SLC_ANT); slcExecution.setUser(System.getProperty("user.name")); slcExecution.setStatus(SlcExecution.STATUS_RUNNING); slcExecution.getAttributes().put(SlcAntConstants.EXECATTR_ANT_FILE, script.toString()); AntSlcApplication application = new AntSlcApplication(); prepareApplication(slcExecution, application, script); return application.execute(slcExecution, properties, references); } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { runtimeContext = (ApplicationContext) beanFactory; } protected void prepareApplication(SlcExecution slcExecution, AntSlcApplication application, Resource script) { try { final String fileUrlPrefix = ""; Resource slcRootFile = findSlcRootFile(script); // Remove basedir property in order to avoid conflict with Maven // if (all.containsKey("basedir")) // all.remove("basedir"); InputStream inRootFile = slcRootFile.getInputStream(); Properties rootProps = loadFile(inRootFile); Resource confDir = null; File workDir = null; // Root dir final Resource rootDir = getParentOfFile(slcRootFile); // Conf dir String confDirStr = rootProps .getProperty(SlcAntConstants.CONF_DIR_PROPERTY); if (confDirStr != null) confDir = runtimeContext.getResource(confDirStr); if (confDir == null || !confDir.exists()) { confDir = rootDir.createRelative("../conf"); } // Work dir String workDirStr = rootProps .getProperty(SlcAntConstants.WORK_DIR_PROPERTY); if (workDirStr != null) { workDir = new File(workDirStr); } if (workDir == null || !workDir.exists()) { try { File rootDirAsFile = rootDir.getFile(); workDir = new File(rootDirAsFile.getParent() + File.separator + "work").getCanonicalFile(); } catch (IOException e) { workDir = new File(System.getProperty("java.io.tmpdir") + File.separator + "slcExecutions" + File.separator + slcExecution.getUuid()).getCanonicalFile(); log.debug("Root dir is not a file: " + e.getMessage() + ", creating work dir in temp: " + workDir); } } application.setConfDir(confDir); application.setRootDir(rootDir); application.setWorkDir(workDir); application.setSlcRuntime(this); } catch (IOException e) { throw new SlcException( "Could not prepare SLC application for SLC execution " + slcExecution.getUuid() + " and script " + script, e); } // 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)); // } // } // } /** * Recursively scans directories downwards until it find a file name as * defined by {@link #SLC_ROOT_FILE_NAME}. */ protected Resource findSlcRootFile(Resource currDir) { if (log.isDebugEnabled()) log.debug("Look for SLC root file in " + currDir); try { Resource slcRootFile = currDir.createRelative(SLC_ROOT_FILE_NAME); if (slcRootFile.exists()) { return slcRootFile; } else { String currPath = currDir.getURL().getPath(); if (currPath.equals("/") || currPath.equals("")) { return null; } else { return findSlcRootFile(getParentOfDir(currDir)); } // int indx = currPath.lastIndexOf('/',currPath.length()-1); } } catch (IOException e) { throw new SlcException("Problem when looking in SLC root file in " + currDir, e); } // for (File file : dir.listFiles()) { // if (!file.isDirectory() // && file.getName().equals(SLC_ROOT_FILE_NAME)) { // return file; // } // } // // File parentDir = dir.getParentFile(); // if (parentDir == null) { // return null;// stop condition: not found // } else { // return findSlcRootFile(parentDir); // } } /** Loads the content of a file as Properties. */ private Properties loadFile(InputStream in) { Properties p = new Properties(); try { p.load(in); } catch (IOException e) { throw new SlcAntException("Cannot read SLC root file", e); } return p; } private Resource getParentOfDir(Resource dir) { try { return dir.createRelative(".."); } catch (IOException e) { throw new SlcException("Cannot get parent for resource " + dir, e); } } private Resource getParentOfFile(Resource file) { try { return file.createRelative("."); } catch (IOException e) { throw new SlcException("Cannot get parent for resource " + file, e); } } }