Project

General

Profile

1
/**
2
 *      Name: QuerySpecification.java
3
 *   Purpose: A Class that represents a structured query, and can be 
4
 *            constructed from an XML serialization
5
 * Copyright: 2000 Regents of the University of California and the
6
 *            National Center for Ecological Analysis and Synthesis
7
 *   Authors: Matt Jones
8
 *
9
 *   Version: '$Id: QuerySpecification.java 159 2000-06-15 01:55:28Z jones $'
10
 */
11

    
12
package edu.ucsb.nceas.metacat;
13

    
14
import java.io.*;
15
import java.util.Stack;
16
import java.util.Vector;
17
import java.util.Enumeration;
18

    
19
import org.xml.sax.AttributeList;
20
import org.xml.sax.InputSource;
21
import org.xml.sax.HandlerBase;
22
import org.xml.sax.Parser;
23
import org.xml.sax.SAXException;
24
import org.xml.sax.SAXParseException;
25
import org.xml.sax.helpers.ParserFactory;
26
//import oracle.xml.parser.v2.SAXParser;
27

    
28

    
29

    
30
/** 
31
 * A Class that represents a structuredd query,and can be constructed from an
32
 * XML serialization
33
 */
34
public class QuerySpecification extends HandlerBase {
35
 
36
  /** Default parser name. */
37
  private static final String
38
      DEFAULT_PARSER = "org.apache.xerces.parsers.SAXParser";
39
      //DEFAULT_PARSER = "oracle.xml.parser.v2.SAXParser";
40

    
41
  // Query data structures
42
  private String meta_file_id;
43
  private String querytitle;
44
  private QueryGroup query = null;
45

    
46
  private Stack elementStack;
47
  private Stack queryStack;
48
  private String currentValue;
49
  private String currentPathexpr;
50

    
51
  /**
52
   * construct an instance of the QuerySpecification class 
53
   *
54
   * @param queryspec the XML representation of the query as a Reader
55
   */
56
  public QuerySpecification( Reader queryspec ) throws IOException {
57
    super();
58

    
59
    // Initialize the stack
60
    elementStack = new Stack();
61
    queryStack   = new Stack();
62

    
63
    // Initialize the parser and read the queryspec
64
    Parser parser = initializeParser();
65
    try {
66
      parser.parse(new InputSource(queryspec));
67
    } catch (SAXException e) {
68
      System.out.println("error parsing data");
69
      System.out.println(e.getMessage());
70
    }
71
  }
72

    
73
  /**
74
   * construct an instance of the QuerySpecification class 
75
   *
76
   * @param queryspec the XML representation of the query as a String
77
   */
78
  public QuerySpecification( String queryspec ) throws IOException {
79

    
80
    this(new StringReader(queryspec));
81
  }
82

    
83
  /** Main routine for testing */
84
  static public void main(String[] args) {
85

    
86
     if (args.length < 1) {
87
       System.err.println("Wrong number of arguments!!!");
88
       System.err.println("USAGE: java QuerySpecification <xmlfile>");
89
       return;
90
     } else {
91
       String xmlfile  = args[0];
92
        
93
       try {
94
         FileReader xml = new FileReader(new File(xmlfile));
95
         QuerySpecification qspec = new QuerySpecification(xml);
96
         System.out.println(qspec);
97
       } catch (IOException e) {
98
         System.err.println(e.getMessage());
99
       }
100
         
101
     }
102
  }
103

    
104
  private Parser initializeParser() {
105
    Parser parser = null;
106
    //
107
    // Set up the SAX document handlers for parsing
108
    //
109
    try {
110

    
111
      // Get an instance of the parser
112
      parser = ParserFactory.makeParser(DEFAULT_PARSER);
113

    
114
      // Set the DocumentHandler to this instance
115
      parser.setDocumentHandler(this);
116

    
117
      // Set the other Handler to the defHandler
118
      parser.setErrorHandler(this);
119

    
120
    } catch (Exception e) {
121
       System.err.println(e.toString());
122
    }
123

    
124
    return parser;
125
  }
126

    
127
  public void startElement (String name, AttributeList atts) 
128
         throws SAXException {
129

    
130
    BasicNode currentNode = new BasicNode(name);
131
    // add attributes to BasicNode here
132
    if (atts != null) {
133
      int len = atts.getLength();
134
      for (int i = 0; i < len; i++) {
135
        currentNode.setAttribute(atts.getName(i), atts.getValue(i));
136
      }
137
    }
138

    
139
    elementStack.push(currentNode); 
140
    if (currentNode.getTagName().equals("querygroup")) {
141
      QueryGroup currentGroup = new QueryGroup(
142
                                currentNode.getAttribute("booleantype"));
143
      if (query == null) {
144
        query = currentGroup;
145
      } else {
146
        QueryGroup parentGroup = (QueryGroup)queryStack.peek();
147
        parentGroup.addChild(currentGroup);
148
      }
149
      queryStack.push(currentGroup);
150
    }
151
  }
152

    
153
  public void endElement (String name) throws SAXException {
154
    BasicNode leaving = (BasicNode)elementStack.pop(); 
155
    if (leaving.getTagName().equals("queryterm")) {
156
      boolean isCaseSensitive = (new Boolean(
157
              leaving.getAttribute("casesensitive"))).booleanValue();
158
      QueryTerm currentTerm = null;
159
      if (currentPathexpr == null) {
160
        currentTerm = new QueryTerm(isCaseSensitive,
161
                      leaving.getAttribute("searchmode"),currentValue);
162
      } else {
163
        currentTerm = new QueryTerm(isCaseSensitive,
164
                      leaving.getAttribute("searchmode"),currentValue,
165
                      currentPathexpr);
166
      }
167
      QueryGroup currentGroup = (QueryGroup)queryStack.peek();
168
      currentGroup.addChild(currentTerm);
169
      currentValue = null;
170
      currentPathexpr = null;
171
    } else if (leaving.getTagName().equals("querygroup")) {
172
      QueryGroup leavingGroup = (QueryGroup)queryStack.pop();
173
    }
174
  }
175

    
176
  public void characters(char ch[], int start, int length) {
177

    
178
    String inputString = new String(ch, start, length);
179
    BasicNode currentNode = (BasicNode)elementStack.peek(); 
180
    String currentTag = currentNode.getTagName();
181
    if (currentTag.equals("meta_file_id")) {
182
      meta_file_id = inputString;
183
    } else if (currentTag.equals("querytitle")) {
184
      querytitle = inputString;
185
    } else if (currentTag.equals("value")) {
186
      currentValue = inputString;
187
    } else if (currentTag.equals("pathexpr")) {
188
      currentPathexpr = inputString;
189
    }
190
  }
191

    
192
  public String toString() {
193
    return "meta_file_id=" + meta_file_id + "\n" + 
194
           "querytitle=" + querytitle + "\n" + query;
195
  }
196

    
197
  /** a utility class that represents a group of terms in a query */
198
  private class QueryGroup {
199
    private String booleantype = null; // indicates how query terms are combined
200
    private Vector children = null;    // the list of query terms and groups
201

    
202
    public QueryGroup(String booleantype) {
203
      this.booleantype = booleantype;
204
      children = new Vector();
205
    }
206

    
207
    public void addChild(QueryGroup qgroup) {
208
      children.add((Object)qgroup); 
209
    }
210

    
211
    public void addChild(QueryTerm qterm) {
212
      children.add((Object)qterm); 
213
    }
214

    
215
    public Enumeration getChildren() {
216
      return children.elements();
217
    }
218
   
219
    public String toString() {
220
      StringBuffer self = new StringBuffer();
221

    
222
      self.append("  (Query group booleantype=" + booleantype + "\n");
223
      Enumeration en= getChildren();
224
      while (en.hasMoreElements()) {
225
        Object qobject = en.nextElement();
226
        self.append(qobject);
227
      }
228
      self.append("  )\n");
229
      return self.toString();
230
    }
231
  }
232

    
233
  /** a utility class that represents a single term in a query */
234
  private class QueryTerm {
235
    private boolean casesensitive = false;
236
    private String searchmode = null;
237
    private String value = null;
238
    private String pathexpr = null;
239

    
240
    public QueryTerm(boolean casesensitive, String searchmode, 
241
                     String value) {
242
      this.casesensitive = casesensitive;
243
      this.searchmode = searchmode;
244
      this.value = value;
245
    }
246

    
247
    public QueryTerm(boolean casesensitive, String searchmode, 
248
                     String value, String pathexpr) {
249
      this(casesensitive, searchmode, value);
250
      this.pathexpr = pathexpr;
251
    }
252

    
253
    public boolean isCaseSensitive() {
254
      return casesensitive;
255
    }
256

    
257
    public String getSearchMode() {
258
      return searchmode;
259
    }
260
 
261
    public String getValue() {
262
      return value;
263
    }
264

    
265
    public String getPathExpression() {
266
      return pathexpr;
267
    }
268

    
269
    public String toString() {
270
      StringBuffer self = new StringBuffer();
271

    
272
      self.append("    Query Term iscasesensitive=" + casesensitive + "\n");
273
      self.append("               searchmode=" + searchmode + "\n");
274
      self.append("               value=" + value + "\n");
275
      if (pathexpr != null) {
276
        self.append("               pathexpr=" + pathexpr + "\n");
277
      }
278

    
279
      return self.toString();
280
    }
281
  }
282
}
(18-18/20)