|
@@ -27,6 +27,7 @@ import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStream;
|
|
import java.io.OutputStream;
|
|
|
|
+import java.io.OutputStreamWriter;
|
|
import java.io.Reader;
|
|
import java.io.Reader;
|
|
import java.io.Writer;
|
|
import java.io.Writer;
|
|
import java.net.URL;
|
|
import java.net.URL;
|
|
@@ -53,6 +54,7 @@ import javax.xml.parsers.DocumentBuilder;
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import javax.xml.transform.Transformer;
|
|
import javax.xml.transform.Transformer;
|
|
|
|
+import javax.xml.transform.TransformerException;
|
|
import javax.xml.transform.TransformerFactory;
|
|
import javax.xml.transform.TransformerFactory;
|
|
import javax.xml.transform.dom.DOMSource;
|
|
import javax.xml.transform.dom.DOMSource;
|
|
import javax.xml.transform.stream.StreamResult;
|
|
import javax.xml.transform.stream.StreamResult;
|
|
@@ -68,6 +70,7 @@ import org.apache.hadoop.util.ReflectionUtils;
|
|
import org.apache.hadoop.util.StringUtils;
|
|
import org.apache.hadoop.util.StringUtils;
|
|
import org.codehaus.jackson.JsonFactory;
|
|
import org.codehaus.jackson.JsonFactory;
|
|
import org.codehaus.jackson.JsonGenerator;
|
|
import org.codehaus.jackson.JsonGenerator;
|
|
|
|
+import org.w3c.dom.Comment;
|
|
import org.w3c.dom.DOMException;
|
|
import org.w3c.dom.DOMException;
|
|
import org.w3c.dom.Document;
|
|
import org.w3c.dom.Document;
|
|
import org.w3c.dom.Element;
|
|
import org.w3c.dom.Element;
|
|
@@ -153,6 +156,12 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
*/
|
|
*/
|
|
private ArrayList<Object> resources = new ArrayList<Object>();
|
|
private ArrayList<Object> resources = new ArrayList<Object>();
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * The value reported as the setting resource when a key is set
|
|
|
|
+ * by code rather than a file resource.
|
|
|
|
+ */
|
|
|
|
+ static final String UNKNOWN_RESOURCE = "Unknown";
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* List of configuration parameters marked <b>final</b>.
|
|
* List of configuration parameters marked <b>final</b>.
|
|
*/
|
|
*/
|
|
@@ -175,13 +184,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
|
|
|
|
private static final Map<ClassLoader, Map<String, Class<?>>>
|
|
private static final Map<ClassLoader, Map<String, Class<?>>>
|
|
CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, Class<?>>>();
|
|
CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, Class<?>>>();
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Flag to indicate if the storage of resource which updates a key needs
|
|
|
|
- * to be stored for each key
|
|
|
|
- */
|
|
|
|
- private boolean storeResource;
|
|
|
|
-
|
|
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Stores the mapping of key to the resource which modifies or loads
|
|
* Stores the mapping of key to the resource which modifies or loads
|
|
* the key most recently
|
|
* the key most recently
|
|
@@ -385,26 +388,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
*/
|
|
*/
|
|
public Configuration(boolean loadDefaults) {
|
|
public Configuration(boolean loadDefaults) {
|
|
this.loadDefaults = loadDefaults;
|
|
this.loadDefaults = loadDefaults;
|
|
|
|
+ updatingResource = new HashMap<String, String>();
|
|
synchronized(Configuration.class) {
|
|
synchronized(Configuration.class) {
|
|
REGISTRY.put(this, null);
|
|
REGISTRY.put(this, null);
|
|
}
|
|
}
|
|
- this.storeResource = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * A new configuration with the same settings and additional facility for
|
|
|
|
- * storage of resource to each key which loads or updates
|
|
|
|
- * the key most recently
|
|
|
|
- * @param other the configuration from which to clone settings
|
|
|
|
- * @param storeResource flag to indicate if the storage of resource to
|
|
|
|
- * each key is to be stored
|
|
|
|
- */
|
|
|
|
- private Configuration(Configuration other, boolean storeResource) {
|
|
|
|
- this(other);
|
|
|
|
- this.storeResource = storeResource;
|
|
|
|
- if (storeResource) {
|
|
|
|
- updatingResource = new HashMap<String, String>();
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -423,6 +410,8 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
if (other.overlay!=null) {
|
|
if (other.overlay!=null) {
|
|
this.overlay = (Properties)other.overlay.clone();
|
|
this.overlay = (Properties)other.overlay.clone();
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ this.updatingResource = new HashMap<String, String>(other.updatingResource);
|
|
}
|
|
}
|
|
|
|
|
|
this.finalParameters = new HashSet<String>(other.finalParameters);
|
|
this.finalParameters = new HashSet<String>(other.finalParameters);
|
|
@@ -604,6 +593,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
if (!isDeprecated(name)) {
|
|
if (!isDeprecated(name)) {
|
|
getOverlay().setProperty(name, value);
|
|
getOverlay().setProperty(name, value);
|
|
getProps().setProperty(name, value);
|
|
getProps().setProperty(name, value);
|
|
|
|
+ updatingResource.put(name, UNKNOWN_RESOURCE);
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
DeprecatedKeyInfo keyInfo = deprecatedKeyMap.get(name);
|
|
DeprecatedKeyInfo keyInfo = deprecatedKeyMap.get(name);
|
|
@@ -1352,10 +1342,8 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
loadResources(properties, resources, quietmode);
|
|
loadResources(properties, resources, quietmode);
|
|
if (overlay!= null) {
|
|
if (overlay!= null) {
|
|
properties.putAll(overlay);
|
|
properties.putAll(overlay);
|
|
- if (storeResource) {
|
|
|
|
- for (Map.Entry<Object,Object> item: overlay.entrySet()) {
|
|
|
|
- updatingResource.put((String) item.getKey(), "Unknown");
|
|
|
|
- }
|
|
|
|
|
|
+ for (Map.Entry<Object,Object> item: overlay.entrySet()) {
|
|
|
|
+ updatingResource.put((String) item.getKey(), UNKNOWN_RESOURCE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1438,9 +1426,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
if (finalParameters.contains(oldKey)) {
|
|
if (finalParameters.contains(oldKey)) {
|
|
finalParameters.remove(oldKey);
|
|
finalParameters.remove(oldKey);
|
|
}
|
|
}
|
|
- if (storeResource) {
|
|
|
|
- updatingResource.remove(oldKey);
|
|
|
|
- }
|
|
|
|
|
|
+ updatingResource.remove(oldKey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1464,9 +1450,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
properties.setProperty(key, value);
|
|
properties.setProperty(key, value);
|
|
- if (storeResource) {
|
|
|
|
- updatingResource.put(key, updatingResource.get(attr));
|
|
|
|
- }
|
|
|
|
|
|
+ updatingResource.put(key, updatingResource.get(attr));
|
|
if (finalParameter) {
|
|
if (finalParameter) {
|
|
finalParameters.add(key);
|
|
finalParameters.add(key);
|
|
}
|
|
}
|
|
@@ -1581,9 +1565,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
if (value != null) {
|
|
if (value != null) {
|
|
if (!finalParameters.contains(attr)) {
|
|
if (!finalParameters.contains(attr)) {
|
|
properties.setProperty(attr, value);
|
|
properties.setProperty(attr, value);
|
|
- if (storeResource) {
|
|
|
|
- updatingResource.put(attr, name.toString());
|
|
|
|
- }
|
|
|
|
|
|
+ updatingResource.put(attr, name.toString());
|
|
} else {
|
|
} else {
|
|
LOG.warn(name+":a attempt to override final parameter: "+attr
|
|
LOG.warn(name+":a attempt to override final parameter: "+attr
|
|
+"; Ignoring.");
|
|
+"; Ignoring.");
|
|
@@ -1611,12 +1593,22 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Write out the non-default properties in this configuration to the give
|
|
|
|
|
|
+ * Write out the non-default properties in this configuration to the given
|
|
* {@link OutputStream}.
|
|
* {@link OutputStream}.
|
|
*
|
|
*
|
|
* @param out the output stream to write to.
|
|
* @param out the output stream to write to.
|
|
*/
|
|
*/
|
|
public void writeXml(OutputStream out) throws IOException {
|
|
public void writeXml(OutputStream out) throws IOException {
|
|
|
|
+ writeXml(new OutputStreamWriter(out));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Write out the non-default properties in this configuration to the given
|
|
|
|
+ * {@link Writer}.
|
|
|
|
+ *
|
|
|
|
+ * @param out the writer to write to.
|
|
|
|
+ */
|
|
|
|
+ public synchronized void writeXml(Writer out) throws IOException {
|
|
Properties properties = getProps();
|
|
Properties properties = getProps();
|
|
try {
|
|
try {
|
|
Document doc =
|
|
Document doc =
|
|
@@ -1635,7 +1627,12 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
}
|
|
}
|
|
Element propNode = doc.createElement("property");
|
|
Element propNode = doc.createElement("property");
|
|
conf.appendChild(propNode);
|
|
conf.appendChild(propNode);
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ if (updatingResource != null) {
|
|
|
|
+ Comment commentNode = doc.createComment(
|
|
|
|
+ "Loaded from " + updatingResource.get(name));
|
|
|
|
+ propNode.appendChild(commentNode);
|
|
|
|
+ }
|
|
Element nameNode = doc.createElement("name");
|
|
Element nameNode = doc.createElement("name");
|
|
nameNode.appendChild(doc.createTextNode(name));
|
|
nameNode.appendChild(doc.createTextNode(name));
|
|
propNode.appendChild(nameNode);
|
|
propNode.appendChild(nameNode);
|
|
@@ -1652,8 +1649,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
TransformerFactory transFactory = TransformerFactory.newInstance();
|
|
TransformerFactory transFactory = TransformerFactory.newInstance();
|
|
Transformer transformer = transFactory.newTransformer();
|
|
Transformer transformer = transFactory.newTransformer();
|
|
transformer.transform(source, result);
|
|
transformer.transform(source, result);
|
|
- } catch (Exception e) {
|
|
|
|
- throw new RuntimeException(e);
|
|
|
|
|
|
+ } catch (TransformerException te) {
|
|
|
|
+ throw new IOException(te);
|
|
|
|
+ } catch (ParserConfigurationException pe) {
|
|
|
|
+ throw new IOException(pe);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1668,26 +1667,26 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
* @param out the Writer to write to
|
|
* @param out the Writer to write to
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
- public static void dumpConfiguration(Configuration conf,
|
|
|
|
|
|
+ public static void dumpConfiguration(Configuration config,
|
|
Writer out) throws IOException {
|
|
Writer out) throws IOException {
|
|
- Configuration config = new Configuration(conf,true);
|
|
|
|
- config.reloadConfiguration();
|
|
|
|
JsonFactory dumpFactory = new JsonFactory();
|
|
JsonFactory dumpFactory = new JsonFactory();
|
|
JsonGenerator dumpGenerator = dumpFactory.createJsonGenerator(out);
|
|
JsonGenerator dumpGenerator = dumpFactory.createJsonGenerator(out);
|
|
dumpGenerator.writeStartObject();
|
|
dumpGenerator.writeStartObject();
|
|
dumpGenerator.writeFieldName("properties");
|
|
dumpGenerator.writeFieldName("properties");
|
|
dumpGenerator.writeStartArray();
|
|
dumpGenerator.writeStartArray();
|
|
dumpGenerator.flush();
|
|
dumpGenerator.flush();
|
|
- for (Map.Entry<Object,Object> item: config.getProps().entrySet()) {
|
|
|
|
- dumpGenerator.writeStartObject();
|
|
|
|
- dumpGenerator.writeStringField("key", (String) item.getKey());
|
|
|
|
- dumpGenerator.writeStringField("value",
|
|
|
|
- config.get((String) item.getKey()));
|
|
|
|
- dumpGenerator.writeBooleanField("isFinal",
|
|
|
|
- config.finalParameters.contains(item.getKey()));
|
|
|
|
- dumpGenerator.writeStringField("resource",
|
|
|
|
- config.updatingResource.get(item.getKey()));
|
|
|
|
- dumpGenerator.writeEndObject();
|
|
|
|
|
|
+ synchronized (config) {
|
|
|
|
+ for (Map.Entry<Object,Object> item: config.getProps().entrySet()) {
|
|
|
|
+ dumpGenerator.writeStartObject();
|
|
|
|
+ dumpGenerator.writeStringField("key", (String) item.getKey());
|
|
|
|
+ dumpGenerator.writeStringField("value",
|
|
|
|
+ config.get((String) item.getKey()));
|
|
|
|
+ dumpGenerator.writeBooleanField("isFinal",
|
|
|
|
+ config.finalParameters.contains(item.getKey()));
|
|
|
|
+ dumpGenerator.writeStringField("resource",
|
|
|
|
+ config.updatingResource.get(item.getKey()));
|
|
|
|
+ dumpGenerator.writeEndObject();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
dumpGenerator.writeEndArray();
|
|
dumpGenerator.writeEndArray();
|
|
dumpGenerator.writeEndObject();
|
|
dumpGenerator.writeEndObject();
|