package fr.inria.diversify.diversification; import fr.inria.diversify.codeFragment.CodeFragment; import fr.inria.diversify.codeFragment.Statement; import fr.inria.diversify.util.Log; import sun.reflect.generics.reflectiveObjects.NotImplementedException; import java.io.*; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; /** * The input configuration class encapsulates all the data and asociated behavior we obtain from the input properties * given by the user. * <p> * The InputConfiguration makes other objects life easier by not only being a data holder but also by implementing * behaviors related from this data as the building of new CodeFragments given the CodeFragmentClass property * <p> * Created by marcel on 8/06/14. */ public class InputConfiguration { //GENERATOR VERSIONS public static final String GEN_VERSION_1_0_0 = "1.0.0"; public static final String LATEST_GENERATOR_VERSION = GEN_VERSION_1_0_0; /** * Internal properties */ protected Properties prop; /** * resulting input program from the input configuration */ private InputProgram inputProgram; /* * Output path to all operations resulting in output */ //private String outputPath; /** * Errors raised during validation */ private List<String> errors; private String rootPath; public InputConfiguration() { prop = new Properties(); setDefaultProperties(); setCodeFragmentClass(); errors = new ArrayList<>(); rootPath = prop.getProperty("root.path"); } public InputConfiguration(InputStream stream) throws IOException { prop = new Properties(); setDefaultProperties(); prop.load(stream); setCodeFragmentClass(); errors = new ArrayList<>(); rootPath = prop.getProperty("root.path"); } public InputConfiguration(String file) throws IOException { this(new FileInputStream(file)); if (rootPath == null || rootPath.equals("")) rootPath = System.getProperty("user.dir"); } /** * Return the internal properties * * @return Proprties instance */ public Properties getProperties() { return prop; } /** * Gets the specific value of a property * * @param key Key to the value * @return A string with the value */ public String getProperty(String key) { return getProperties().getProperty(key); } /** * Gets the specific value of a property * * @param key Key to the value * @param defaultValue Default value to set * @return A string with the value */ public String getProperty(String key, String defaultValue) { return getProperties().getProperty(key, defaultValue); } /** * The input program we are sosieficating. */ public InputProgram getInputProgram() { return inputProgram; } /** * The input program we are sosieficating. */ public void setInputProgram(InputProgram inputProgram) { this.inputProgram = inputProgram; } /** * Gets the project path. The project path is the parent directory where all files concerning a project are. * * @return String with the path */ public String getProjectPath() { return getAbsolutePath(getProperty("project")); } /** * Returns the full path of the production (source) code of a project. * * @return String with the path */ public String getRelativeSourceCodeDir() { return prop.getProperty("src"); } /** * Returns the full path of the test (source) code of a project. * * @return String with the path */ public String getRelativeTestSourceCodeDir() { return prop.getProperty("testSrc", "src/test/java"); } /** * Returns the path of the previously found transformations * * @return */ public String getPreviousTransformationPath() { String s = prop.getProperty("transformation.directory", ""); return getAbsolutePath(s); } /** * Returns the path of the built classes * * @return String with the path */ public String getClassesDir() { return prop.getProperty("classes"); } /** * Get coverage dir of a project * * @return */ public String getCoverageDir() { String s = prop.getProperty("jacoco") == null ? prop.getProperty("coverage", "") : prop.getProperty("jacoco"); return getAbsolutePath(s); } /** * Returns the results path * <p> * NOTE: Possible duplicate of getOutputDirectory * * @return */ public String getResultPath() { return prop.getProperty("result", prop.getProperty("outputDirectory", "")); } /** * If some path is given as relative path, this root will be used to resolve it */ public String getRootPath() { return rootPath; } /** * Errors found during the validation * * @return A collection of messages of errors found during the validation */ public Collection<String> getValidationErrors() { return errors; } /** * Returns a new code fragment given the processing level set by the user in the input properties * <p> * Defaults to statement in case of any error * * @return */ public CodeFragment getNewCodeFragment() { CodeFragment result; try { Class cl = Class.forName(getProperties().getProperty("CodeFragmentClass")); result = (CodeFragment) cl.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { result = new Statement(); Log.warn("Unable to create the code fragment requested, resolved to Statement level", e); e.printStackTrace(); } return result; } protected void setCodeFragmentClass() { if (getProperties().getProperty("processor").equals("fr.inria.diversify.codeFragmentProcessor.StatementProcessor")) getProperties().setProperty("CodeFragmentClass", "fr.inria.diversify.codeFragment.Statement"); if (getProperties().getProperty("processor").equals("fr.inria.diversify.codeFragmentProcessor.ExpressionProcessor")) getProperties().setProperty("CodeFragmentClass", "fr.inria.diversify.codeFragment.Expression"); if (getProperties().getProperty("processor").equals("fr.inria.diversify.codeFragmentProcessor.BlockProcessor")) getProperties().setProperty("CodeFragmentClass", "fr.inria.diversify.codeFragment.Block"); } protected void setDefaultProperties() { prop.setProperty("src", "src/main/java"); prop.setProperty("testSrc", "src/test/java"); prop.setProperty("classes", "target/classes"); prop.setProperty("clojure", "false"); prop.setProperty("javaVersion", "5"); prop.setProperty("transformation.type", "all"); prop.setProperty("transformation.size", "1"); prop.setProperty("stat", "false"); prop.setProperty("sosie", "false"); //Indicates if the Diversify must report early prop.setProperty("early.report", "0"); //tempory directory prop.setProperty("tmpDir", "tmpDir"); //directory for output (ex sosie) prop.setProperty("outputDirectory", "output"); //directory for output result (ex sosie) prop.setProperty("result", "output_diversify"); prop.setProperty("sosieOnMultiProject", "false"); prop.setProperty("timeOut", "-1"); prop.setProperty("logLevel", "2"); prop.setProperty("gitRepository", "null"); prop.setProperty("processor", "fr.inria.diversify.codeFragmentProcessor.StatementProcessor"); prop.setProperty("transplant.point.search.strategy", "fr.inria.diversify.transformation.executeQuery.searchStrategy.SimpleRandomStrategy"); prop.setProperty("transplant.search.strategy", "fr.inria.diversify.transformation.executeQuery.searchStrategy.SimpleRandomStrategy"); prop.setProperty("syncroRange", "0"); prop.setProperty("newPomFile", ""); prop.setProperty("transformation.level", "statement"); prop.setProperty("builder", "maven"); } protected String getAbsolutePath(String path) { Path p = Paths.get(path); if ( new File(path).exists() || p.isAbsolute() ) return path; if (rootPath != null && !rootPath.equals("")) p = Paths.get(rootPath + "/" + path); else p = Paths.get(path); return p.normalize().toString().replace(File.separator, "/"); } private void addError(String error) { errors.add(error); } private void checkPath(String desc, String path, boolean mustExist) { if (path == null) { if (mustExist) addError(desc + " at " + path + " does not exists"); } else if (!new File(path).exists() && (mustExist || !path.equals(""))) addError(desc + " at " + path + " does not exists"); } /** * Checks that the configuration is valid */ public boolean validate() { checkPath("Project path", getProjectPath(), true); checkPath("Source path", getProjectPath() + "/"+ getResultPath() , true); checkPath("Previous transformation path", getPreviousTransformationPath(), false); checkPath("Coverage dir", getCoverageDir(), false); checkPath("Root dir", getRootPath(), false); checkPath("Temp directory", getTempDir(), false); return errors.size() == 0; } /** * Gets the temporary directory for all operations * @return */ public String getTempDir() { return getAbsolutePath(getProperty("tmpDir")); } }