Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2007 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *    Authors: Chad Berkley
6
 *
7
 *   '$Author: berkley $'
8
 *     '$Date: 2007-04-12 10:23:54 -0700 (Thu, 12 Apr 2007) $'
9
 * '$Revision: 3227 $'
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 */
25

    
26
package edu.ucsb.nceas.metacat;
27

    
28
import java.io.*;
29
import java.util.*;
30

    
31
import org.w3c.dom.*;
32
import org.apache.xpath.*;
33

    
34
import org.apache.log4j.Logger;
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

    
49
/**
50
 * this class implements a metacat resultset and can be serialized to xml
51
 * for printing to the servlet output stream.
52
 */
53
public class MetacatResultSet extends DefaultHandler
54
{    
55
  private Logger log = Logger.getLogger(MetacatResultSet.class);
56
  private Vector results = new Vector();
57
  private Result currentResult = null;
58
  private String currentElementName = "";
59
  Attributes atts = null;
60
  
61
  /**
62
   * constructor that can process a dom.  WARNING: this is very slow.
63
   */
64
  public MetacatResultSet(Document d)
65
    throws Exception
66
  {
67
    log.warn("#####################processing resultset...");
68
    NodeList nl = XPathAPI.selectNodeList(d, "//document");
69
    for(int i=0; i<nl.getLength(); i++)
70
    { //get each of the document nodes
71
      Node docNode = nl.item(i);
72
      Node docidNode = XPathAPI.selectSingleNode(docNode, "./docid");
73
      log.warn("processing " + docidNode.getFirstChild().getNodeValue());
74
      Node docnameNode = XPathAPI.selectSingleNode(docNode, "./docname");
75
      Node doctypeNode = XPathAPI.selectSingleNode(docNode, "./doctype");
76
      Node createdateNode = XPathAPI.selectSingleNode(docNode, "./createdate");
77
      Node updatedateNode = XPathAPI.selectSingleNode(docNode, "./updatedate");
78
      //process the returnfields
79
      NodeList returnfieldNL = XPathAPI.selectNodeList(docNode, "./param");
80
      Hashtable returnfieldHash = new Hashtable();
81
      for(int j=0; j<returnfieldNL.getLength(); j++)
82
      {
83
        Node returnfieldNode = returnfieldNL.item(j);
84
        Node nameNode = XPathAPI.selectSingleNode(returnfieldNode, "@name");
85
        String value = returnfieldNode.getFirstChild().getNodeValue();
86
        String name = nameNode.getNodeValue();
87
        returnfieldHash.put(name, value);
88
      }
89
      
90
      Result r = new Result(docidNode.getFirstChild().getNodeValue(),
91
                            docnameNode.getFirstChild().getNodeValue(),
92
                            doctypeNode.getFirstChild().getNodeValue(),
93
                            createdateNode.getFirstChild().getNodeValue(),
94
                            updatedateNode.getFirstChild().getNodeValue(),
95
                            returnfieldHash);
96
      addResult(r);
97
    }
98
  }
99
  
100
  /**
101
   * process a resultset using SAX
102
   */
103
  public MetacatResultSet(String xmlDoc)
104
    throws SAXException, IOException
105
  {
106
    double mrsStart = System.currentTimeMillis() / 1000;
107
    log.warn("###############parsing for paged results.....");
108
    XMLReader parser = null;
109
    String parserName = MetaCatUtil.getOption("saxparser");
110
    parser = XMLReaderFactory.createXMLReader(parserName);
111
    parser.setContentHandler(this);
112
    parser.setErrorHandler(this);
113
    parser.parse(new InputSource(new StringReader(xmlDoc)));
114
    double mrsStop = System.currentTimeMillis() / 1000;
115
    log.warn("##############done parsing for paged results.  total time: " + 
116
      (mrsStop - mrsStart) + " seconds");
117
    
118
  }
119
  
120
  /**
121
   * process the beginning of an element
122
   */
123
  public void startElement(String uri, String localName, String qName, 
124
    Attributes atts) throws SAXException
125
  {
126
    //get the attributes
127
    this.atts = atts;
128
    if(localName.equals("document"))
129
    {
130
      currentResult = new Result();
131
    }
132
    else if(localName.equals("docid") ||
133
            localName.equals("docname") ||
134
            localName.equals("doctype") ||
135
            localName.equals("createdate") ||
136
            localName.equals("updatedate") ||
137
            localName.equals("param"))
138
    { //set the current element name
139
      currentElementName = localName;
140
    }
141
  }
142
  
143
  /**
144
   * process the end of an element
145
   */
146
  public void endElement(String uri, String localName, String qName)
147
    throws SAXException
148
  {
149
    if(localName.equals("document"))
150
    { //if we're closing a document, save the result
151
      addResult(new Result(currentResult));
152
      currentResult = new Result();
153
      currentElementName = "";
154
    }
155
  }
156
  
157
  /**
158
   * process character data
159
   */
160
  public void characters(char[] cbuf, int start, int len) 
161
    throws SAXException
162
  { //get the character data for each node we care about
163
    String s = new String(cbuf, start, len);
164
    if(currentElementName.equals("docid"))
165
    {
166
      currentResult.docid = s;
167
    }
168
    else if(currentElementName.equals("docname"))
169
    {
170
      currentResult.docname = s;
171
    }
172
    else if(currentElementName.equals("doctype"))
173
    {
174
      currentResult.doctype = s;
175
    }
176
    else if(currentElementName.equals("createdate"))
177
    {
178
      currentResult.createDate = s;
179
    }
180
    else if(currentElementName.equals("updatedate"))
181
    {
182
      currentResult.updateDate = s;
183
    }
184
    else if(currentElementName.equals("param"))
185
    { //add the returnfields to the hashtable
186
      for (int i = 0; i < atts.getLength(); i++)
187
      {
188
        String attributeName = atts.getQName(i);
189
        String attributeValue = null;
190
        if(attributeName.equals("name"))
191
        {
192
          attributeValue = atts.getValue(i);
193
        }
194
        currentResult.returnfields.put(attributeValue, s);
195
      }
196
    }
197
  }
198
  
199
  /**
200
   * SAX Handler that receives notification of fatal parsing errors
201
   */
202
  public void fatalError(SAXParseException exception) throws SAXException
203
  {
204
      log.fatal("FATALERROR while parsing/caching resultset: " + 
205
        exception.getMessage());
206
      throw (new SAXException("Fatal error processing/caching resultset.", 
207
        exception));
208
  }
209

    
210
  /**
211
   * SAX Handler that receives notification of recoverable parsing errors
212
   */
213
  public void error(SAXParseException exception) throws SAXException
214
  {
215
      log.error("ERROR while parsing/caching resultset: " + 
216
        exception.getMessage());
217
      throw (new SAXException("Error in processing/caching resultset.", 
218
        exception));
219
  }
220

    
221
  /**
222
   * SAX Handler that receives notification of warnings
223
   */
224
  public void warning(SAXParseException exception) throws SAXException
225
  {
226
      log.warn("WARNING while parsing/caching resultset: " + 
227
        exception.getMessage());
228
      throw (new SAXException("Warning.", exception));
229
  }
230
  
231
  /**
232
   * add a new result to the resultSet
233
   */
234
  public void addResult(Result r)
235
  {
236
    results.addElement(r);
237
  }
238
  
239
  /**
240
   * returns a vector of the results
241
   */
242
  public Vector getResults()
243
  {
244
    return results;
245
  }
246
  
247
  /**
248
   * serialize a selection of the results.  This will print the results from
249
   * start to end-1.  if end is 0, nothing will be printed.
250
   */
251
  public String serializeToXML(int start, int end)
252
  {
253
    StringBuffer sb = new StringBuffer();
254
    if(start > results.size() || end > results.size())
255
    { //make sure we don't go over the edge of the vector
256
      start = results.size() - 10;
257
      end = results.size();
258
    }
259
    
260
    for(int i=start; i<end; i++)
261
    {
262
      Result r = (Result)results.elementAt(i);
263
      sb.append(r.toString());
264
      sb.append("\n");
265
    }
266
    return sb.toString();
267
  }
268
  
269
  /**
270
   * returns an xml representation of this object
271
   */
272
  public String toString()
273
  {
274
    StringBuffer sb = new StringBuffer();
275
    for(int i=0; i<results.size(); i++)
276
    {
277
      Result r = (Result)results.elementAt(i);
278
      sb.append(r.toString());
279
      sb.append("\n");
280
    }
281
    return sb.toString();
282
  }
283
  
284
  
285
  /**
286
   * a class to store one result
287
   */
288
  public class Result
289
  {
290
    protected String docid;
291
    protected String docname;
292
    protected String doctype;
293
    protected String createDate;
294
    protected String updateDate;
295
    protected Hashtable returnfields;
296
    
297
    /**
298
     * copy constructor
299
     */
300
    public Result(Result r)
301
    {
302
      if(r != null)
303
      {
304
        docid = r.docid;
305
        docname = r.docname;
306
        doctype = r.doctype;
307
        createDate = r.createDate;
308
        updateDate = r.updateDate;
309
        returnfields = r.returnfields;
310
      }
311
    }
312
    
313
    /**
314
     * constructor
315
     */
316
    public Result(String docid, String docname, String doctype, 
317
      String createDate, String updateDate, Hashtable returnfields)
318
    {
319
      this.docid = docid;
320
      this.doctype = doctype;
321
      this.createDate = createDate;
322
      this.updateDate = updateDate;
323
      this.returnfields = returnfields;
324
    }
325
    
326
    /**
327
     * default constructor
328
     */
329
    public Result()
330
    {
331
      returnfields = new Hashtable();
332
    }
333
    
334
    /**
335
     * returns serialized version of this result
336
     */
337
    public String toString()
338
    {
339
      StringBuffer sb = new StringBuffer();
340
      sb.append("<document>\n");
341
      sb.append("  <docid>" + docid + "</docid>\n");
342
      sb.append("  <docname>" + docname + "</docname>\n");
343
      sb.append("  <doctype>" + doctype + "</doctype>\n");
344
      sb.append("  <createdate>" + createDate + "</createdate>\n");
345
      sb.append("  <updatedate>" + updateDate + "</updatedate>\n");
346
      
347
      Enumeration keys = returnfields.keys();
348
      while(keys.hasMoreElements())
349
      {
350
        String key = (String)keys.nextElement();
351
        String value = (String)returnfields.get(key);
352
        sb.append("  <param name=\"" + key + "\">" + value + "</param>\n");
353
      }
354
      sb.append("</document>");
355
      return sb.toString();
356
    }
357
  }
358
}
(47-47/66)