1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.xmlhammer.gui.xpath;
23
24 import java.io.IOException;
25 import java.net.URI;
26 import java.util.ArrayList;
27
28 import javax.xml.namespace.QName;
29 import javax.xml.parsers.DocumentBuilder;
30 import javax.xml.parsers.DocumentBuilderFactory;
31 import javax.xml.parsers.ParserConfigurationException;
32 import javax.xml.xpath.XPathConstants;
33 import javax.xml.xpath.XPathExpression;
34 import javax.xml.xpath.XPathExpressionException;
35 import javax.xml.xpath.XPathFactoryConfigurationException;
36
37 import org.apache.log4j.Logger;
38 import org.bounce.util.URIUtils;
39 import org.w3c.dom.Attr;
40 import org.w3c.dom.Comment;
41 import org.w3c.dom.Document;
42 import org.w3c.dom.Element;
43 import org.w3c.dom.Node;
44 import org.w3c.dom.NodeList;
45 import org.w3c.dom.ProcessingInstruction;
46 import org.w3c.dom.Text;
47 import org.xml.sax.InputSource;
48 import org.xml.sax.SAXException;
49 import org.xml.sax.SAXParseException;
50 import org.xmlhammer.DefaultErrorHandler;
51 import org.xmlhammer.Module;
52 import org.xmlhammer.ResultModel;
53 import org.xmlhammer.DefaultErrorHandler.Error;
54 import org.xmlhammer.DefaultErrorHandler.Fatal;
55 import org.xmlhammer.DefaultErrorHandler.Problem;
56 import org.xmlhammer.DefaultErrorHandler.Warning;
57 import org.xmlhammer.gui.status.StatusModel;
58 import org.xmlhammer.model.preferences.Preferences;
59 import org.xmlhammer.model.project.Project;
60
61 /***
62 * Put comment...
63 *
64 * @version $Revision$, $Date$
65 * @author Edwin Dankert <edankert@gmail.com>
66 */
67 public class XPathSearchModule extends Module {
68 private XPathExpression expression = null;
69 private DocumentBuilder builder = null;
70
71 public XPathSearchModule(Preferences preferences, Project project, Logger logger, boolean logSettings) throws XPathExpressionException, ParserConfigurationException, SAXException {
72 super(preferences, project, logger, logSettings);
73
74
75 try {
76 logSettings("\t[xpath-expression] "+project.getXPath().getExpression());
77 this.expression = getXPath().compile(project.getXPath().getExpression());
78 } catch (XPathExpressionException e) {
79 Throwable cause = e;
80
81 while (cause.getCause() != null) {
82 cause = cause.getCause();
83 }
84
85 logError(cause);
86
87 throw e;
88 }
89
90 DocumentBuilderFactory factory = getDocumentBuilderFactory();
91 builder = factory.newDocumentBuilder();
92 }
93
94 /***
95 * Sets-up an XPath Factory, creates an XPath and compiles the XPath Expression.
96 *
97 * @param preferences the global preferences.
98 * @param project the project specific properties;
99 * @throws XPathFactoryConfigurationException
100 * @throws XPathExpressionException
101 * @throws SAXException
102 * @throws ParserConfigurationException
103 */
104 public XPathSearchModule(Preferences preferences, Project project, Logger logger) throws XPathExpressionException, ParserConfigurationException, SAXException {
105 this(preferences, project, logger, true);
106 }
107
108 /***
109 * Execute the XPath expression.
110 * @throws XPathExpressionException
111 * @throws IOException
112 * @throws SAXException
113 */
114 @Override
115 public void execute(StatusModel status, ResultModel result, URI uri) throws XPathExpressionException {
116
117 if ( uri != null) {
118
119
120
121 getLogger().info( "xpath-search: "+URIUtils.toString(uri));
122
123 InputSource in = new InputSource( uri.toString());
124
125 DefaultErrorHandler errorHandler = new DefaultErrorHandler(null);
126 builder.setErrorHandler(errorHandler);
127 builder.setEntityResolver(getCatalogResolver());
128
129 Document document = null;
130
131 try {
132 document = builder.parse( in);
133
134 } catch ( SAXException e) {
135 if ( e instanceof SAXParseException) {
136 try {
137 errorHandler.fatalError( (SAXParseException)e);
138 } catch ( Exception x) {}
139 }
140 } catch ( IOException e) {
141 errorHandler.fatalError(e);
142 }
143
144 if ( errorHandler.getProblems().size() > 0) {
145 ArrayList<Problem> list = errorHandler.getProblems();
146
147 for ( Problem problem : list) {
148 if ( problem instanceof Warning) {
149 logWarning(uri, (SAXParseException)problem.getException());
150
151 if (result != null) {
152 result.addWarning( uri, (SAXParseException)problem.getException());
153 }
154 } else if ( problem instanceof Error) {
155 logError(uri, (SAXParseException)problem.getException());
156
157 if (result != null) {
158 result.addError( uri, (SAXParseException)problem.getException());
159 }
160 } else if ( problem instanceof Fatal) {
161 logFatal(uri, problem.getException());
162
163 if (result != null) {
164 Exception exception = problem.getException();
165 if ( exception instanceof IOException) {
166 result.addFatal( uri, (IOException)problem.getException());
167 } else {
168 result.addFatal( uri, (SAXParseException)problem.getException());
169 }
170 }
171 }
172 }
173 } else {
174
175 QName returnType = null;
176
177 String type = getProject().getXPath().getReturnType();
178
179 if ( "BOOLEAN".equals( type)) {
180 returnType = XPathConstants.BOOLEAN;
181 } else if ( "NODE".equals( type)) {
182 returnType = XPathConstants.NODE;
183 } else if ( "NUMBER".equals( type)) {
184 returnType = XPathConstants.NUMBER;
185 } else if ( "STRING".equals( type)) {
186 returnType = XPathConstants.STRING;
187 } else {
188 returnType = XPathConstants.NODESET;
189 }
190
191
192 Object node = expression.evaluate( document, returnType);
193
194 ArrayList<Object> list = null;
195
196 if (node instanceof NodeList && returnType == XPathConstants.NODESET) {
197 list = new ArrayList<Object>( ((NodeList)node).getLength());
198
199 for (int i = 0; i < ((NodeList)node).getLength(); i++) {
200 list.add( ((NodeList)node).item( i));
201 }
202 } else if (node instanceof ArrayList) {
203 list = new ArrayList<Object>();
204
205 for ( Object n : (ArrayList)node) {
206 list.add( n);
207 }
208 } else if (node instanceof String || node instanceof Number || node instanceof Boolean || node instanceof Node) {
209 list = new ArrayList<Object>();
210 list.add( node);
211 } else if (node != null) {
212 getLogger().error("Unknown result type:\n"+node.getClass());
213 }
214
215 if (list != null) {
216 for ( int i = 0; i < list.size(); i++) {
217 Object object = list.get( i);
218
219 if (result != null && object != null) {
220 result.addValue( uri, object);
221 }
222
223
224 if ( object instanceof Element) {
225 getLogger().info( "\t[element] "+((Element)object).getTagName());
226 } else if ( object instanceof Attr) {
227 getLogger().info( "\t[attribute] "+((Attr)object).getName()+"=\""+((Attr)object).getNodeValue()+"\"");
228 } else if ( object instanceof Text) {
229 getLogger().info( "\t[text] "+((Text)object).getNodeValue());
230 } else if ( object instanceof Comment) {
231 getLogger().info( "\t[comment] "+((Node)object).getNodeValue());
232 } else if ( object instanceof ProcessingInstruction) {
233 getLogger().info( "\t[processing-instruction] "+((Node)object).getNodeValue());
234 } else if ( object instanceof Boolean) {
235 getLogger().info( "\t[boolean] "+object.toString());
236 } else if ( object instanceof String) {
237 getLogger().info( "\t[string] "+(String)object);
238 } else if ( object instanceof Number) {
239 getLogger().info( "\t[number] "+((Number)object).toString());
240 } else if (object != null) {
241 getLogger().error( "Unknown node:\n"+object.getClass());
242 }
243 }
244 }
245 }
246 }
247 }
248 }