package il.co.topq.refactor.model; import il.co.topq.refactor.exception.ScenarioXmlParseException; import il.co.topq.refactor.exception.UnmodifiableFileException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; import java.util.UUID; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; import jsystem.extensions.sourcecontrol.SourceControlI; /** * Represents a JSystem Project Properties file * * @author Itai Agmon */ public class ScenarioPropertiesFile extends JSystemFile { private Properties properties; private FileInputStream fis; private final String scenariosFolder; public ScenarioPropertiesFile(File propertiesFile) { super(propertiesFile); scenariosFolder = file.getAbsolutePath().split("scenarios")[0].replaceAll("/", File.separator); } public String getAbsolutePath() { return file.getAbsolutePath(); } /** * * Replace a parameter name of a test with a new one * * NOTE: Usually retrieve the uuid of a specific test from the xml pair file * and then it will be possible to rename a specific parameter * * @param testUUID * - the test uuid which parameter need to be changed * @param oldName * - the old parameter name * @param newName * - the new name for the parameter * @return - true if the properties file was change, false otherwise * @throws IOException * - In case while loading the file an exception has occurred * @throws il.co.topq.refactor.exception.UnmodifiableFileException * - If the file is in a read only mode this exception is thrown */ public boolean replacePropertyName(UUID testUUID, String oldName, String newName) throws IOException, UnmodifiableFileException { init(); Properties newProperties = new Properties(); Iterator<Map.Entry<Object, Object>> it = properties.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Object, Object> entry = it.next(); //We ask here if the property line ends with the parameter name so we wont accept a subset of this parameter name if (((String) entry.getKey()).endsWith(testUUID + "." + oldName)) { log.fine("Found property " + ((String) entry.getKey()) + " in file " + file.getName()); it.remove(); newProperties.put(((String) entry.getKey()).replace(oldName, newName), entry.getValue()); // if (!oldName.equals("timeoutInSec")) { // } } } if (newProperties.size() > 0) { properties.putAll(newProperties); return true; } return false; } private void init() throws IOException { if (properties == null) { properties = new Properties(); fis = new FileInputStream(file); properties.load(fis); } } public void close() throws IOException { if (properties != null) { if (fis != null) { fis.close(); } properties = null; } } public Set<? extends String> getTestParameters(UUID testUUID) throws IOException { init(); Set<String> testParameters = new HashSet<String>(); Iterator<Map.Entry<Object, Object>> it = properties.entrySet().iterator(); Pattern pattern = Pattern.compile(testUUID + "\\." + "([\\w]+)$"); while (it.hasNext()) { Map.Entry<Object, Object> entry = it.next(); Matcher matcher = pattern.matcher(((String) entry.getKey())); if (matcher.find()) { testParameters.add(matcher.group(1)); } } return testParameters; } public void rename(String newName) throws IOException, UnmodifiableFileException { close(); File newPropFile = new File(scenariosFolder + newName + ".properties"); if (newPropFile.exists()) { log.severe("Scenario properites file with the same name is already exists: " + newPropFile.getAbsolutePath()); throw new IOException("Scenario properties file with the same name is already exists: " + newPropFile.getAbsolutePath()); } if (!file.renameTo(newPropFile)) { throw new UnmodifiableFileException(file); } file = newPropFile; } public void rename(String newName, SourceControlI sourceControlHandler) throws ScenarioXmlParseException, IOException, UnmodifiableFileException { if (null == sourceControlHandler) { rename(newName); return; } try { //We have to close because we don't want to lock the file. close(); File newPropertiesFile = new File(scenariosFolder + newName + ".properties"); if (newPropertiesFile.exists()) { log.severe("Scenario properties file with the same name is already exists: " + newPropertiesFile.getAbsolutePath()); throw new IOException("Scenario XML file with the same name is already exists: " + newPropertiesFile.getAbsolutePath()); } sourceControlHandler.moveFile(file, newPropertiesFile); file = newPropertiesFile; } catch (Exception e) { log.log(Level.SEVERE, "Excpetion was caught during renaming of file", e); throw new ScenarioXmlParseException(); } } public void save() throws IOException { log.finer("Saving file " + this); init(); FileOutputStream fos = null; try { if (!file.exists()) { file.createNewFile(); } fos = new FileOutputStream(file); properties.store(fos, ""); } catch (Exception e) { log.log(Level.WARNING, "Failed to save properties file " + file.getAbsolutePath(), e); throw new IOException("Failed to save properties file " + file.getAbsolutePath()); } finally { if (fos != null) { fos.close(); } } close(); } /** * * @return The content of the properties file. Not included the scenario * attributes. * @throws IOException */ public Map<String, String> getContent() throws IOException { init(); Map<String, String> content = new TreeMap<String, String>(); for (Object key : properties.keySet()) { if (((String) key).startsWith("jsystem.")) { continue; } content.put((String) key, (String) properties.getProperty((String) key)); } return content; } public void put(String prop, String newBean) throws IOException { init(); log.fine("Putting in file key:" + prop + " with value: " + newBean); properties.put(prop, newBean); } }