package gov.nih.nci.cagrid.common; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * PropertiesPreservingComments * Properties which maintains comment lines, blank lines, and ordering when stored * * @author David Ervin * * @created Jun 15, 2007 11:28:40 AM * @version $Id: PropertiesPreservingComments.java,v 1.2 2007-06-18 14:20:46 dervin Exp $ */ public class PropertiesPreservingComments { private Map<String, Integer> propertyIndices = null; private List<String> lines = null; public PropertiesPreservingComments() { propertyIndices = new HashMap<String, Integer>(); lines = new ArrayList<String>(); } public void load(File file) throws IOException { FileInputStream fis = new FileInputStream(file); load(fis); fis.close(); } public void load(InputStream stream) throws IOException { StringBuffer rawProps = Utils.inputStreamToStringBuffer(stream); BufferedReader reader = new BufferedReader(new StringReader(rawProps.toString())); String line = null; while ((line = reader.readLine()) != null) { if (!"\n".equals(line)) { line = line + "\n"; } lines.add(line); if (!line.startsWith("#")) { String key = getPropertyKeyFromLine(line); if (key != null) { propertyIndices.put(key, Integer.valueOf(lines.size() - 1)); } } } } public void store(OutputStream stream) { store(stream, null); } public void store(OutputStream stream, String comments) { PrintWriter writer = new PrintWriter(stream); if (comments != null) { writer.println("#" + comments); } for (String line : lines) { writer.print(line); } writer.flush(); } public String getProperty(String key) { return getProperty(key, null); } public String getProperty(String key, String defaultValue) { Integer lineIndex = propertyIndices.get(key); if (lineIndex == null) { return defaultValue; } String line = lines.get(lineIndex.intValue()); return getPropertyValueFromLine(line); } public Object setProperty(String key, String value) { String line = key + "=" + value + "\n"; String oldValue = null; // see if the property exists Integer lineIndex = propertyIndices.get(key); if (lineIndex != null) { oldValue = getProperty(key); lines.set(lineIndex.intValue(), line); } else { lines.add(line); propertyIndices.put(key, Integer.valueOf(lines.size() - 1)); } return oldValue; } public Object remove(Object key) { Object oldValue = getProperty((String) key); Integer lineIndex = propertyIndices.remove(key); if (lineIndex != null) { lines.remove(lineIndex.intValue()); } return oldValue; } /** * Comments out the property. * * @param key * The key of the property to comment out * @return * True if the property existed and was commented out, false otherwise */ public boolean commentOutProperty(String key) { boolean commented = false; if (propertyIndices.containsKey(key)) { Integer lineNum = propertyIndices.remove(key); String line = "#" + lines.get(lineNum.intValue()); lines.set(lineNum.intValue(), line); commented = true; } return commented; } /** * Uncomments a property * * @param key * The key of the property to uncomment * @return * True if the property existed and was uncommented */ public boolean uncommentProperty(String key) throws IllegalStateException { // since the key is no longer in the properties index, we have to search for it int lineNum = 0; int foundIndex = -1; for (; lineNum < lines.size(); lineNum++) { String line = lines.get(lineNum); String uncommentedLine = trimLeadingHashes(line); String lineKey = getPropertyKeyFromLine(uncommentedLine); boolean found = lineKey != null && lineKey.equals(key); if (found) { if (foundIndex != -1) { throw new IllegalStateException("A property with key " + key + " was found multiple times!"); } else { foundIndex = lineNum; } } } if (foundIndex != -1) { lines.set(foundIndex, trimLeadingHashes(lines.get(foundIndex))); propertyIndices.put(key, Integer.valueOf(foundIndex)); } return foundIndex != -1; } private String getPropertyKeyFromLine(String line) { int split = line.indexOf('='); return split != -1 ? line.substring(0, split) : null; } private String getPropertyValueFromLine(String line) { int split = line.indexOf('='); if (line.length() > split) { return line.substring(split + 1, line.length() - 1); } return ""; } private String trimLeadingHashes(String line) { int i = 0; for (; i < line.length(); i++) { if (line.charAt(i) != '#') { break; } } return line.substring(i); } }