/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/extractor/SimpleXmlExtractor.java,v 1.7.2.2 2004/11/17 18:01:55 unico Exp $
* $Revision: 1.7.2.2 $
* $Date: 2004/11/17 18:01:55 $
*
* ====================================================================
*
* Copyright 2004 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.slide.extractor;
import org.apache.slide.common.PropertyName;
import org.apache.slide.util.conf.Configurable;
import org.apache.slide.util.conf.Configuration;
import org.apache.slide.util.conf.ConfigurationException;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.Text;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* The SimpleXmlExtractor class
*
*/
public class SimpleXmlExtractor extends AbstractPropertyExtractor implements Configurable {
protected List instructions = new ArrayList();
public SimpleXmlExtractor(String uri, String contentType, String namespace) {
super(uri, contentType, namespace);
}
public Map extract(InputStream content) throws ExtractorException {
Map properties = new HashMap();
try {
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(content);
for (Iterator i = instructions.iterator(); i.hasNext();) {
Instruction instruction = (Instruction) i.next();
XPath xPath = instruction.getxPath();
List nodeList = xPath.selectNodes(document);
Object propertyValue = filter(nodeList, instruction);
if (propertyValue != null) {
properties.put(instruction.getPropertyName(), propertyValue);
}
}
} catch (IOException e) {
throw new ExtractorException("Exception while retrieving content");
} catch (JDOMException e) {
throw new ExtractorException("Exception while parsing content. XML document must be wellformed.");
}
return properties;
}
public void configure(Configuration configuration) throws ConfigurationException {
Enumeration instructions = configuration.getConfigurations("instruction");
while (instructions.hasMoreElements()) {
Configuration instruction = (Configuration) instructions.nextElement();
addInstruction(createInstruction(instruction));
}
}
/**
* Allow subclasses to apply filtering to property values before they are written.
* Returning null signals that the extractor ignors this value.
*
* @param text the Node List identified by the xpath instruction.
* @return the property value to be set, <code>null</codee> if to be ignored.
*/
protected Object filter(List nodeList, Instruction instruction) throws ExtractorException {
if (nodeList.size() > 0) {
if (nodeList.get(0) instanceof Text) {
return ((Text) nodeList.get(0)).getText();
} else if (nodeList.get(0) instanceof Attribute) {
return ((Attribute) nodeList.get(0)).getValue();
} else if (nodeList.get(0) instanceof String) {
return nodeList.get(0);
}
}
return null;
}
protected void addInstruction(Instruction instruction) {
instructions.add(instruction);
}
protected Instruction createInstruction(Configuration instruction) throws ConfigurationException {
try {
String property = instruction.getAttribute("property");
String namespace = instruction.getAttribute("namespace", "DAV:");
XPath xPath = XPath.newInstance(instruction.getAttribute("xpath"));
return new Instruction(xPath, new PropertyName(property, namespace));
} catch (JDOMException e) {
throw new ConfigurationException("Could not create xPath from given attribute", instruction);
}
}
protected static class Instruction {
private XPath xPath;
private PropertyName propertyName;
public Instruction(XPath xPath, PropertyName property) {
this.xPath = xPath;
this.propertyName = property;
}
public XPath getxPath() {
return xPath;
}
public PropertyName getPropertyName() {
return propertyName;
}
}
}