001: /*
002: * Copyright 2006 Hippo Webworks.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package nl.hippo.slide.extractor;
017:
018: import java.text.DateFormat;
019: import java.text.SimpleDateFormat;
020: import java.util.Date;
021: import java.util.Enumeration;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: import org.apache.slide.common.Domain;
028: import org.apache.slide.common.PropertyName;
029: import org.apache.slide.extractor.ExtractorException;
030: import org.apache.slide.util.conf.Configuration;
031: import org.apache.slide.util.conf.ConfigurationException;
032: import org.apache.slide.util.logger.Logger;
033: import org.jdom.Attribute;
034: import org.jdom.Element;
035: import org.jdom.JDOMException;
036: import org.jdom.Text;
037: import org.jdom.output.XMLOutputter;
038: import org.jdom.xpath.XPath;
039:
040: /**
041: * HippoXmlPropertyExtractor
042: */
043: public class HippoXmlPropertyExtractor extends HippoSimpleXmlExtractor {
044: protected static final String EMPTY = "";
045: private static final String LOG_CHANNEL = HippoXmlPropertyExtractor.class
046: .getName();
047:
048: public HippoXmlPropertyExtractor(String uri, String contentType,
049: String namespace) {
050: super (uri, contentType, namespace);
051: }
052:
053: protected Object filter(List nodeList, Instruction instruction)
054: throws ExtractorException {
055: return filter(nodeList, instruction, "result");
056: }
057:
058: protected Object filter(List nodeList, Instruction instruction,
059: String elName) throws ExtractorException {
060: if (nodeList.size() > 0) {
061: StringBuffer buf = new StringBuffer();
062: XMLOutputter out = new XMLOutputter();
063:
064: boolean surroundXML = nodeList.size() > 1
065: || instruction instanceof MultipleXPathInstruction;
066:
067: for (int i = 0; i < nodeList.size(); i++) {
068: Object o = nodeList.get(i);
069:
070: if (surroundXML)
071: buf.append("<" + elName + ">");
072:
073: // hack to prevent recursing
074: if (instruction instanceof MultipleXPathInstruction
075: && (elName.equals("result"))) {
076: Map xpaths = ((MultipleXPathInstruction) instruction)
077: .getSubXPaths();
078: Iterator it = xpaths.keySet().iterator();
079: while (it.hasNext()) {
080: String name = (String) it.next();
081: XPath xpath = (XPath) xpaths.get(name);
082: try {
083: List nodes = xpath.selectNodes(o);
084: buf
085: .append(filter(nodes, instruction,
086: name));
087: } catch (JDOMException e) {
088: ExtractorException tobethrown = new ExtractorException(
089: "HippoXmlPropertyExtractor: Exception while parsing content. XML document must be wellformed.");
090: tobethrown.initCause(e);
091: throw tobethrown;
092: }
093: }
094: } else {
095: String obj = null;
096: if (o instanceof Element) {
097: Element node = (Element) o;
098: obj = out.outputString(node);
099: } else if (o instanceof Text) {
100: obj = ((Text) o).getText();
101: } else if (o instanceof Attribute) {
102: obj = ((Attribute) o).getValue();
103: } else if (o instanceof String) {
104: obj = (String) o;
105: } else {
106: obj = o.toString();
107: }
108:
109: if (instruction instanceof DateInstruction) {
110: try {
111: DateFormat inf = ((DateInstruction) instruction)
112: .getInputFormat();
113: DateFormat outf = ((DateInstruction) instruction)
114: .getOutputFormat();
115: Date date = inf.parse(obj);
116: obj = outf.format(date);
117: } catch (Exception e) {
118: if (Domain.isEnabled(Logger.INFO)) {
119: Domain.log(
120: "HippoXmlPropertyExtractor: Could not extract date: "
121: + e.getMessage(),
122: LOG_CHANNEL, Logger.INFO);
123: }
124: }
125: }
126: buf.append(obj);
127: }
128:
129: if (surroundXML)
130: buf.append("</" + elName + ">");
131: }
132: return buf.toString();
133: }
134: return EMPTY;
135: }
136:
137: protected Instruction createInstruction(Configuration instruction)
138: throws ConfigurationException {
139:
140: if (instruction.getAttribute("type", "").equals("multiple")) {
141: Enumeration subpaths = instruction.getConfigurations("sub");
142: try {
143: String property = instruction.getAttribute("property");
144: String namespace = instruction.getAttribute(
145: "namespace", "DAV:");
146: XPath xPath = XPath.newInstance(instruction
147: .getAttribute("xpath"));
148:
149: Map subs = new HashMap();
150: while (subpaths.hasMoreElements()) {
151: Configuration sub = (Configuration) subpaths
152: .nextElement();
153: subs.put(sub.getAttribute("name"), XPath
154: .newInstance(sub.getAttribute("xpath")));
155: }
156:
157: return new MultipleXPathInstruction(xPath,
158: new PropertyName(property, namespace), subs);
159: } catch (JDOMException e) {
160: throw new ConfigurationException(
161: "Could not create xPath from given attribute: "
162: + e.toString(), instruction);
163: }
164: } else if (instruction.getAttribute("type", "").equals("date")) {
165: try {
166: String property = instruction.getAttribute("property");
167: String namespace = instruction.getAttribute(
168: "namespace", "DAV:");
169: XPath xPath = XPath.newInstance(instruction
170: .getAttribute("xpath"));
171: String inputFormat = instruction
172: .getAttribute("inputFormat");
173: String outputFormat = instruction
174: .getAttribute("outputFormat");
175: return new DateInstruction(xPath, new PropertyName(
176: property, namespace), inputFormat, outputFormat);
177: } catch (JDOMException e) {
178: throw new ConfigurationException(
179: "Could not create xPath from given attribute: "
180: + e.toString(), instruction);
181: }
182: } else {
183: return super .createInstruction(instruction);
184: }
185: }
186:
187: protected static class MultipleXPathInstruction extends Instruction {
188:
189: private Map subXPaths = null;
190:
191: public MultipleXPathInstruction(XPath xpath, PropertyName prop,
192: Map subxpaths) {
193: super (xpath, prop);
194: this .subXPaths = subxpaths;
195: }
196:
197: public Map getSubXPaths() {
198: return subXPaths;
199: }
200: }
201:
202: protected static class DateInstruction extends Instruction {
203:
204: private final String m_inputFormat;
205: private final String m_outputFormat;
206:
207: public DateInstruction(XPath xPath, PropertyName propertyName,
208: String inputFormat, String outputFormat) {
209: super (xPath, propertyName);
210: m_inputFormat = inputFormat;
211: m_outputFormat = outputFormat;
212: }
213:
214: public DateFormat getInputFormat() {
215: return new SimpleDateFormat(m_inputFormat);
216: }
217:
218: public DateFormat getOutputFormat() {
219: return new SimpleDateFormat(m_outputFormat);
220: }
221: }
222: }
|