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-03 13:17:34 -0700 (Tue, 03 Apr 2007) $'
9
 * '$Revision: 3222 $'
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
    XMLReader parser = null;
107
    String parserName = MetaCatUtil.getOption("saxparser");
108
    parser = XMLReaderFactory.createXMLReader(parserName);
109
    parser.setContentHandler(this);
110
    parser.setErrorHandler(this);
111
    parser.parse(new InputSource(new StringReader(xmlDoc)));
112
  }
113
  
114
  /**
115
   * process the beginning of an element
116
   */
117
  public void startElement(String uri, String localName, String qName, 
118
    Attributes atts) throws SAXException
119
  {
120
    //get the attributes
121
    this.atts = atts;
122
    if(localName.equals("document"))
123
    {
124
      currentResult = new Result();
125
    }
126
    else if(localName.equals("docid") ||
127
            localName.equals("docname") ||
128
            localName.equals("doctype") ||
129
            localName.equals("createdate") ||
130
            localName.equals("updatedate") ||
131
            localName.equals("param"))
132
    { //set the current element name
133
      currentElementName = localName;
134
    }
135
  }
136
  
137
  /**
138
   * process the end of an element
139
   */
140
  public void endElement(String uri, String localName, String qName)
141
    throws SAXException
142
  {
143
    if(localName.equals("document"))
144
    { //if we're closing a document, save the result
145
      addResult(new Result(currentResult));
146
      currentResult = new Result();
147
      currentElementName = "";
148
    }
149
  }
150
  
151
  /**
152
   * process character data
153
   */
154
  public void characters(char[] cbuf, int start, int len) 
155
    throws SAXException
156
  { //get the character data for each node we care about
157
    String s = new String(cbuf, start, len);
158
    if(currentElementName.equals("docid"))
159
    {
160
      currentResult.docid = s;
161
    }
162
    else if(currentElementName.equals("docname"))
163
    {
164
      currentResult.docname = s;
165
    }
166
    else if(currentElementName.equals("doctype"))
167
    {
168
      currentResult.doctype = s;
169
    }
170
    else if(currentElementName.equals("createdate"))
171
    {
172
      currentResult.createDate = s;
173
    }
174
    else if(currentElementName.equals("updatedate"))
175
    {
176
      currentResult.updateDate = s;
177
    }
178
    else if(currentElementName.equals("param"))
179
    { //add the returnfields to the hashtable
180
      for (int i = 0; i < atts.getLength(); i++)
181
      {
182
        String attributeName = atts.getQName(i);
183
        String attributeValue = null;
184
        if(attributeName.equals("name"))
185
        {
186
          attributeValue = atts.getValue(i);
187
        }
188
        currentResult.returnfields.put(attributeValue, s);
189
      }
190
    }
191
  }
192
  
193
  /**
194
   * SAX Handler that receives notification of fatal parsing errors
195
   */
196
  public void fatalError(SAXParseException exception) throws SAXException
197
  {
198
      log.fatal("FATALERROR while parsing/caching resultset: " + 
199
        exception.getMessage());
200
      throw (new SAXException("Fatal error processing/caching resultset.", 
201
        exception));
202
  }
203

    
204
  /**
205
   * SAX Handler that receives notification of recoverable parsing errors
206
   */
207
  public void error(SAXParseException exception) throws SAXException
208
  {
209
      log.error("ERROR while parsing/caching resultset: " + 
210
        exception.getMessage());
211
      throw (new SAXException("Error in processing/caching resultset.", 
212
        exception));
213
  }
214

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