1 |
1 |
/**
|
2 |
2 |
* '$RCSfile$'
|
3 |
|
* Purpose: A Class that searches a relational DB for elements and
|
4 |
|
* attributes that have free text matches a query string,
|
5 |
|
* or structured query matches to a path specified node in the
|
6 |
|
* XML hierarchy. It returns a result set consisting of the
|
7 |
|
* document ID for each document that satisfies the query
|
8 |
|
* Copyright: 2000 Regents of the University of California and the
|
|
3 |
* Copyright: 2007 Regents of the University of California and the
|
9 |
4 |
* National Center for Ecological Analysis and Synthesis
|
10 |
|
* Authors: Matt Jones
|
|
5 |
* Authors: Chad Berkley
|
11 |
6 |
*
|
12 |
7 |
* '$Author$'
|
13 |
8 |
* '$Date$'
|
... | ... | |
38 |
33 |
|
39 |
34 |
import org.apache.log4j.Logger;
|
40 |
35 |
|
|
36 |
import org.apache.log4j.Logger;
|
|
37 |
import org.xml.sax.Attributes;
|
|
38 |
import org.xml.sax.SAXException;
|
|
39 |
import org.xml.sax.SAXParseException;
|
|
40 |
import org.xml.sax.ext.DeclHandler;
|
|
41 |
import org.xml.sax.ext.LexicalHandler;
|
|
42 |
import org.xml.sax.helpers.DefaultHandler;
|
|
43 |
import org.xml.sax.XMLReader;
|
|
44 |
import org.xml.sax.helpers.XMLReaderFactory;
|
|
45 |
import org.xml.sax.ContentHandler;
|
|
46 |
import org.xml.sax.ErrorHandler;
|
|
47 |
import org.xml.sax.InputSource;
|
|
48 |
|
41 |
49 |
/**
|
42 |
50 |
* this class implements a metacat resultset and can be serialized to xml
|
43 |
51 |
* for printing to the servlet output stream.
|
44 |
52 |
*/
|
45 |
|
public class MetacatResultSet
|
|
53 |
public class MetacatResultSet extends DefaultHandler
|
46 |
54 |
{
|
|
55 |
public static final String VALIDATIONFEATURE = "http://xml.org/sax/features/validation";
|
|
56 |
public static final String SCHEMAVALIDATIONFEATURE = "http://apache.org/xml/features/validation/schema";
|
|
57 |
public static final String NAMESPACEFEATURE = "http://xml.org/sax/features/namespaces";
|
|
58 |
public static final String NAMESPACEPREFIXESFEATURE = "http://xml.org/sax/features/namespace-prefixes";
|
|
59 |
public static final String RESOLVEDTDFEATURE = "http://apache.org/sax/features/load-dtd-grammar";
|
|
60 |
public static final String LOADDTDFEATURE = "http://apache.org/sax/features/load-external-dtd";
|
|
61 |
public static final String DOCTYPEDECLFEATURE = "http://apache.org/sax/features/disallow-doctype-decl";
|
|
62 |
public static final String DECLARATIONHANDLERPROPERTY = "http://xml.org/sax/properties/declaration-handler";
|
|
63 |
public static final String LEXICALPROPERTY = "http://xml.org/sax/properties/lexical-handler";
|
|
64 |
|
47 |
65 |
private Logger log = Logger.getLogger(MetacatResultSet.class);
|
48 |
66 |
private Vector results = new Vector();
|
|
67 |
private Result currentResult = null;
|
|
68 |
private String currentElementName = "";
|
|
69 |
Attributes atts = null;
|
49 |
70 |
|
50 |
71 |
/**
|
51 |
72 |
* default constructor
|
... | ... | |
56 |
77 |
}
|
57 |
78 |
|
58 |
79 |
/**
|
59 |
|
* constructor that can process a dom. this is very slow.
|
|
80 |
* constructor that can process a dom. WARNING: this is very slow.
|
60 |
81 |
*/
|
61 |
82 |
public MetacatResultSet(Document d)
|
62 |
83 |
throws Exception
|
... | ... | |
95 |
116 |
}
|
96 |
117 |
|
97 |
118 |
/**
|
|
119 |
* process a resultset using SAX
|
|
120 |
*/
|
|
121 |
public MetacatResultSet(String xmlDoc)
|
|
122 |
throws SAXException, IOException
|
|
123 |
{
|
|
124 |
XMLReader parser = null;
|
|
125 |
String parserName = MetaCatUtil.getOption("saxparser");
|
|
126 |
parser = XMLReaderFactory.createXMLReader(parserName);
|
|
127 |
parser.setContentHandler(this);
|
|
128 |
parser.setErrorHandler(this);
|
|
129 |
parser.parse(new InputSource(new StringReader(xmlDoc)));
|
|
130 |
}
|
|
131 |
|
|
132 |
/**
|
|
133 |
* process the beginning of an element
|
|
134 |
*/
|
|
135 |
public void startElement(String uri, String localName, String qName,
|
|
136 |
Attributes atts) throws SAXException
|
|
137 |
{
|
|
138 |
//get the attributes
|
|
139 |
this.atts = atts;
|
|
140 |
if(localName.equals("document"))
|
|
141 |
{
|
|
142 |
currentResult = new Result();
|
|
143 |
}
|
|
144 |
else if(localName.equals("docid") ||
|
|
145 |
localName.equals("docname") ||
|
|
146 |
localName.equals("doctype") ||
|
|
147 |
localName.equals("createdate") ||
|
|
148 |
localName.equals("updatedate") ||
|
|
149 |
localName.equals("param"))
|
|
150 |
{ //set the current element name
|
|
151 |
currentElementName = localName;
|
|
152 |
}
|
|
153 |
}
|
|
154 |
|
|
155 |
/**
|
|
156 |
* process the end of an element
|
|
157 |
*/
|
|
158 |
public void endElement(String uri, String localName, String qName)
|
|
159 |
throws SAXException
|
|
160 |
{
|
|
161 |
if(localName.equals("document"))
|
|
162 |
{ //if we're closing a document, save the result
|
|
163 |
addResult(new Result(currentResult));
|
|
164 |
currentResult = new Result();
|
|
165 |
currentElementName = "";
|
|
166 |
}
|
|
167 |
}
|
|
168 |
|
|
169 |
/**
|
|
170 |
* process character data
|
|
171 |
*/
|
|
172 |
public void characters(char[] cbuf, int start, int len)
|
|
173 |
throws SAXException
|
|
174 |
{ //get the character data for each node we care about
|
|
175 |
String s = new String(cbuf, start, len);
|
|
176 |
if(currentElementName.equals("docid"))
|
|
177 |
{
|
|
178 |
currentResult.docid = s;
|
|
179 |
}
|
|
180 |
else if(currentElementName.equals("docname"))
|
|
181 |
{
|
|
182 |
currentResult.docname = s;
|
|
183 |
}
|
|
184 |
else if(currentElementName.equals("doctype"))
|
|
185 |
{
|
|
186 |
currentResult.doctype = s;
|
|
187 |
}
|
|
188 |
else if(currentElementName.equals("createdate"))
|
|
189 |
{
|
|
190 |
currentResult.createDate = s;
|
|
191 |
}
|
|
192 |
else if(currentElementName.equals("updatedate"))
|
|
193 |
{
|
|
194 |
currentResult.updateDate = s;
|
|
195 |
}
|
|
196 |
else if(currentElementName.equals("param"))
|
|
197 |
{ //add the returnfields to the hashtable
|
|
198 |
for (int i = 0; i < atts.getLength(); i++)
|
|
199 |
{
|
|
200 |
String attributeName = atts.getQName(i);
|
|
201 |
String attributeValue = null;
|
|
202 |
if(attributeName.equals("name"))
|
|
203 |
{
|
|
204 |
attributeValue = atts.getValue(i);
|
|
205 |
}
|
|
206 |
currentResult.returnfields.put(attributeValue, s);
|
|
207 |
}
|
|
208 |
}
|
|
209 |
}
|
|
210 |
|
|
211 |
/**
|
|
212 |
* SAX Handler that receives notification of fatal parsing errors
|
|
213 |
*/
|
|
214 |
public void fatalError(SAXParseException exception) throws SAXException
|
|
215 |
{
|
|
216 |
log.fatal("FATALERROR: " + exception.getMessage());
|
|
217 |
throw (new SAXException("Fatal error processing/caching resultset.", exception));
|
|
218 |
}
|
|
219 |
|
|
220 |
/**
|
|
221 |
* SAX Handler that receives notification of recoverable parsing errors
|
|
222 |
*/
|
|
223 |
public void error(SAXParseException exception) throws SAXException
|
|
224 |
{
|
|
225 |
log.error("ERROR: " + exception.getMessage());
|
|
226 |
throw (new SAXException("Error in processing/caching resultset.", exception));
|
|
227 |
}
|
|
228 |
|
|
229 |
/**
|
|
230 |
* SAX Handler that receives notification of warnings
|
|
231 |
*/
|
|
232 |
public void warning(SAXParseException exception) throws SAXException
|
|
233 |
{
|
|
234 |
log.warn("WARNING while parsing/caching resultset: " + exception.getMessage());
|
|
235 |
throw (new SAXException("Warning.", exception));
|
|
236 |
}
|
|
237 |
|
|
238 |
/**
|
98 |
239 |
* add a new result to the resultSet
|
99 |
240 |
*/
|
100 |
241 |
public void addResult(Result r)
|
... | ... | |
153 |
294 |
*/
|
154 |
295 |
public class Result
|
155 |
296 |
{
|
156 |
|
private String docid;
|
157 |
|
private String docname;
|
158 |
|
private String doctype;
|
159 |
|
private String createDate;
|
160 |
|
private String updateDate;
|
161 |
|
private Hashtable returnfields;
|
|
297 |
protected String docid;
|
|
298 |
protected String docname;
|
|
299 |
protected String doctype;
|
|
300 |
protected String createDate;
|
|
301 |
protected String updateDate;
|
|
302 |
protected Hashtable returnfields;
|
162 |
303 |
|
163 |
304 |
/**
|
|
305 |
* copy constructor
|
|
306 |
*/
|
|
307 |
public Result(Result r)
|
|
308 |
{
|
|
309 |
if(r != null)
|
|
310 |
{
|
|
311 |
docid = r.docid;
|
|
312 |
docname = r.docname;
|
|
313 |
doctype = r.doctype;
|
|
314 |
createDate = r.createDate;
|
|
315 |
updateDate = r.updateDate;
|
|
316 |
returnfields = r.returnfields;
|
|
317 |
}
|
|
318 |
}
|
|
319 |
|
|
320 |
/**
|
164 |
321 |
* constructor
|
165 |
322 |
*/
|
166 |
323 |
public Result(String docid, String docname, String doctype,
|
... | ... | |
174 |
331 |
}
|
175 |
332 |
|
176 |
333 |
/**
|
|
334 |
* default constructor
|
|
335 |
*/
|
|
336 |
public Result()
|
|
337 |
{
|
|
338 |
returnfields = new Hashtable();
|
|
339 |
}
|
|
340 |
|
|
341 |
/**
|
177 |
342 |
* returns serialized version of this result
|
178 |
343 |
*/
|
179 |
344 |
public String toString()
|
paging now works well. sped up the caching by using SAX instead of DOM parsing. it seems fast. need some other people to test for me though. the two params needed are 'pagesize' and 'pagestart'. I haven't updated any of the web interfaces to use this, so if you want to try it, you'll have to type in the url the old fashioned way