/**
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nutch.admin.configuration;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.hadoop.conf.Configuration;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XpathUtil {
public static void saveConfiguration(Map parameterMap,
Configuration configuration, OutputStream outputStream)
throws ParserConfigurationException, TransformerException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document document = factory.newDocumentBuilder().newDocument();
Element configurationElement = document.createElement("configuration");
Node node = document.appendChild(configurationElement);
Set set = parameterMap.keySet();
TreeSet treeSet = new TreeSet(set);
treeSet.remove("action");
treeSet.remove("config");
for (Iterator iter = treeSet.iterator(); iter.hasNext();) {
// e.g. key=http.agent.name
String key = (String) iter.next();
// e.g. strings=Nutch
String[] strings = (String[]) parameterMap.get(key);
String valueFromMap = strings[0];
int index = key.indexOf(" ");
if (index > -1) {
key = key.substring(index + 1);
}
//
configuration.set(key, valueFromMap);
Element property = document.createElement("property");
Element name = document.createElement("name");
name.appendChild(document.createTextNode(key));
Element value = document.createElement("value");
value.appendChild(document.createTextNode(valueFromMap));
Element description = document.createElement("description");
Node propertyNode = node.appendChild(property);
propertyNode.appendChild(name);
propertyNode.appendChild(value);
propertyNode.appendChild(description);
}
save(document, outputStream);
}
public static void saveConfiguration(Document document,
Node newNode, OutputStream outputStream)
throws TransformerException, IOException {
boolean duplicate = checkDuplicateNodes(document, newNode);
if (!duplicate) {
Node node = document.importNode(newNode, true);
Node firstChild = document.getDocumentElement();
firstChild.appendChild(node);
}
save(document, outputStream);
}
private static void save(Document document, OutputStream outputStream)
throws TransformerFactoryConfigurationError,
TransformerConfigurationException, TransformerException, IOException {
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(outputStream);
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.setOutputProperty("indent", "yes");
transformer.transform(source, result);
outputStream.close();
}
/**
* @param document
* @param newNode
* @return true if an property with the same name exists in the document
* @throws TransformerException
*/
private static boolean checkDuplicateNodes(final Document document,
final Node newNode)
throws TransformerException {
boolean bit = false;
Element element = document.getDocumentElement();
Node newProperty = XPathAPI.selectSingleNode(newNode, "name");
NodeList list = XPathAPI.selectNodeList(element, "//name");
for (int i = 0; i < list.getLength(); i++) {
Node actualProperty = list.item(i);
if (newProperty.getFirstChild().getNodeValue().equals(
actualProperty.getFirstChild().getNodeValue())) {
bit = true;
}
}
return bit;
}
}