30 |
30 |
|
31 |
31 |
package edu.ucsb.nceas.metacat;
|
32 |
32 |
|
33 |
|
import edu.ucsb.nceas.dbadapter.*;
|
34 |
|
|
35 |
|
import java.io.*;
|
|
33 |
import java.io.File;
|
|
34 |
import java.io.FileReader;
|
|
35 |
import java.io.IOException;
|
|
36 |
import java.io.Reader;
|
|
37 |
import java.io.StringReader;
|
|
38 |
import java.util.Enumeration;
|
36 |
39 |
import java.util.Hashtable;
|
37 |
40 |
import java.util.Stack;
|
38 |
41 |
import java.util.Vector;
|
39 |
|
import java.util.Enumeration;
|
40 |
42 |
|
|
43 |
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
|
|
44 |
|
41 |
45 |
import org.xml.sax.Attributes;
|
42 |
46 |
import org.xml.sax.InputSource;
|
43 |
47 |
import org.xml.sax.SAXException;
|
44 |
|
import org.xml.sax.SAXParseException;
|
45 |
48 |
import org.xml.sax.XMLReader;
|
|
49 |
import org.xml.sax.helpers.DefaultHandler;
|
46 |
50 |
import org.xml.sax.helpers.XMLReaderFactory;
|
47 |
|
import org.xml.sax.helpers.DefaultHandler;
|
48 |
51 |
|
49 |
52 |
/**
|
50 |
|
* A Class that represents a structured query, and can be
|
51 |
|
* constructed from an XML serialization conforming to @see pathquery.dtd.
|
52 |
|
* The printSQL() method can be used to print a SQL serialization of the query.
|
|
53 |
* A Class that represents a structured query, and can be constructed from an
|
|
54 |
* XML serialization conforming to
|
|
55 |
*
|
|
56 |
* @see pathquery.dtd. The printSQL() method can be used to print a SQL
|
|
57 |
* serialization of the query.
|
53 |
58 |
*/
|
54 |
|
public class QuerySpecification extends DefaultHandler {
|
55 |
|
|
56 |
|
/** flag determining whether extended query terms are present */
|
57 |
|
private boolean containsExtendedSQL=false;
|
58 |
|
/** Identifier for this query document */
|
59 |
|
private String meta_file_id;
|
60 |
|
/** Title of this query */
|
61 |
|
private String queryTitle;
|
62 |
|
/** List of document types to be returned using package back tracing */
|
63 |
|
private Vector returnDocList;
|
64 |
|
/** List of document types to be searched */
|
65 |
|
private Vector filterDocList;
|
66 |
|
/** List of fields to be returned in result set */
|
67 |
|
private Vector returnFieldList;
|
68 |
|
/** List of users owning documents to be searched */
|
69 |
|
private Vector ownerList;
|
70 |
|
/** List of sites/scopes used to constrain search */
|
71 |
|
private Vector siteList;
|
72 |
|
/** The root query group that contains the recursive query constraints */
|
73 |
|
private QueryGroup query = null;
|
74 |
|
|
75 |
|
// Query data structures used temporarily during XML parsing
|
76 |
|
private Stack elementStack;
|
77 |
|
private Stack queryStack;
|
78 |
|
private String currentValue;
|
79 |
|
private String currentPathexpr;
|
80 |
|
private String parserName = null;
|
81 |
|
private String accNumberSeparator = null;
|
82 |
|
private static final AbstractDatabase dbAdapter = MetaCatUtil.dbAdapter;
|
83 |
|
|
|
59 |
public class QuerySpecification extends DefaultHandler
|
|
60 |
{
|
84 |
61 |
|
85 |
|
private boolean percentageSearch = false;
|
86 |
|
|
87 |
|
private String userName = null;
|
88 |
|
private static final String PUBLIC = "public";
|
89 |
|
private String [] group = null;
|
|
62 |
/** flag determining whether extended query terms are present */
|
|
63 |
private boolean containsExtendedSQL = false;
|
90 |
64 |
|
91 |
|
public static final String ATTRIBUTESYMBOL = "@";
|
92 |
|
private boolean hasAttributeReturnField = false;
|
93 |
|
private Hashtable attributeReturnList = new Hashtable();
|
94 |
|
private int countAttributeReturnField = 0;
|
95 |
|
/**
|
96 |
|
* construct an instance of the QuerySpecification class
|
97 |
|
*
|
98 |
|
* @param queryspec the XML representation of the query (should conform
|
99 |
|
* to pathquery.dtd) as a Reader
|
100 |
|
* @param parserName the fully qualified name of a Java Class implementing
|
101 |
|
* the org.xml.sax.XMLReader interface
|
102 |
|
*/
|
103 |
|
public QuerySpecification( Reader queryspec, String parserName,
|
104 |
|
String accNumberSeparator ) throws IOException {
|
105 |
|
super();
|
106 |
|
|
107 |
|
// Initialize the class variables
|
108 |
|
returnDocList = new Vector();
|
109 |
|
filterDocList = new Vector();
|
110 |
|
elementStack = new Stack();
|
111 |
|
queryStack = new Stack();
|
112 |
|
returnFieldList = new Vector();
|
113 |
|
ownerList = new Vector();
|
114 |
|
siteList = new Vector();
|
115 |
|
this.parserName = parserName;
|
116 |
|
this.accNumberSeparator = accNumberSeparator;
|
|
65 |
/** Identifier for this query document */
|
|
66 |
private String meta_file_id;
|
117 |
67 |
|
118 |
|
// Initialize the parser and read the queryspec
|
119 |
|
XMLReader parser = initializeParser();
|
120 |
|
if (parser == null) {
|
121 |
|
System.err.println("SAX parser not instantiated properly.");
|
|
68 |
/** Title of this query */
|
|
69 |
private String queryTitle;
|
|
70 |
|
|
71 |
/** List of document types to be returned using package back tracing */
|
|
72 |
private Vector returnDocList;
|
|
73 |
|
|
74 |
/** List of document types to be searched */
|
|
75 |
private Vector filterDocList;
|
|
76 |
|
|
77 |
/** List of fields to be returned in result set */
|
|
78 |
private Vector returnFieldList;
|
|
79 |
|
|
80 |
/** List of users owning documents to be searched */
|
|
81 |
private Vector ownerList;
|
|
82 |
|
|
83 |
/** List of sites/scopes used to constrain search */
|
|
84 |
private Vector siteList;
|
|
85 |
|
|
86 |
/** The root query group that contains the recursive query constraints */
|
|
87 |
private QueryGroup query = null;
|
|
88 |
|
|
89 |
// Query data structures used temporarily during XML parsing
|
|
90 |
private Stack elementStack;
|
|
91 |
|
|
92 |
private Stack queryStack;
|
|
93 |
|
|
94 |
private String currentValue;
|
|
95 |
|
|
96 |
private String currentPathexpr;
|
|
97 |
|
|
98 |
private String parserName = null;
|
|
99 |
|
|
100 |
private String accNumberSeparator = null;
|
|
101 |
|
|
102 |
private static final AbstractDatabase dbAdapter = MetaCatUtil.dbAdapter;
|
|
103 |
|
|
104 |
private boolean percentageSearch = false;
|
|
105 |
|
|
106 |
private String userName = null;
|
|
107 |
|
|
108 |
private static final String PUBLIC = "public";
|
|
109 |
|
|
110 |
private String[] group = null;
|
|
111 |
|
|
112 |
public static final String ATTRIBUTESYMBOL = "@";
|
|
113 |
|
|
114 |
private boolean hasAttributeReturnField = false;
|
|
115 |
|
|
116 |
private Hashtable attributeReturnList = new Hashtable();
|
|
117 |
|
|
118 |
private int countAttributeReturnField = 0;
|
|
119 |
|
|
120 |
/**
|
|
121 |
* construct an instance of the QuerySpecification class
|
|
122 |
*
|
|
123 |
* @param queryspec
|
|
124 |
* the XML representation of the query (should conform to
|
|
125 |
* pathquery.dtd) as a Reader
|
|
126 |
* @param parserName
|
|
127 |
* the fully qualified name of a Java Class implementing the
|
|
128 |
* org.xml.sax.XMLReader interface
|
|
129 |
*/
|
|
130 |
public QuerySpecification(Reader queryspec, String parserName,
|
|
131 |
String accNumberSeparator) throws IOException
|
|
132 |
{
|
|
133 |
super();
|
|
134 |
|
|
135 |
// Initialize the class variables
|
|
136 |
returnDocList = new Vector();
|
|
137 |
filterDocList = new Vector();
|
|
138 |
elementStack = new Stack();
|
|
139 |
queryStack = new Stack();
|
|
140 |
returnFieldList = new Vector();
|
|
141 |
ownerList = new Vector();
|
|
142 |
siteList = new Vector();
|
|
143 |
this.parserName = parserName;
|
|
144 |
this.accNumberSeparator = accNumberSeparator;
|
|
145 |
|
|
146 |
// Initialize the parser and read the queryspec
|
|
147 |
XMLReader parser = initializeParser();
|
|
148 |
if (parser == null) {
|
|
149 |
System.err.println("SAX parser not instantiated properly.");
|
|
150 |
}
|
|
151 |
try {
|
|
152 |
parser.parse(new InputSource(queryspec));
|
|
153 |
} catch (SAXException e) {
|
|
154 |
System.err.println("error parsing data in "
|
|
155 |
+ "QuerySpecification.QuerySpecification");
|
|
156 |
System.err.println(e.getMessage());
|
|
157 |
}
|
122 |
158 |
}
|
123 |
|
try {
|
124 |
|
parser.parse(new InputSource(queryspec));
|
125 |
|
} catch (SAXException e) {
|
126 |
|
System.err.println("error parsing data in " +
|
127 |
|
"QuerySpecification.QuerySpecification");
|
128 |
|
System.err.println(e.getMessage());
|
|
159 |
|
|
160 |
/**
|
|
161 |
* construct an instance of the QuerySpecification class
|
|
162 |
*
|
|
163 |
* @param queryspec
|
|
164 |
* the XML representation of the query (should conform to
|
|
165 |
* pathquery.dtd) as a String
|
|
166 |
* @param parserName
|
|
167 |
* the fully qualified name of a Java Class implementing the
|
|
168 |
* org.xml.sax.Parser interface
|
|
169 |
*/
|
|
170 |
public QuerySpecification(String queryspec, String parserName,
|
|
171 |
String accNumberSeparator) throws IOException
|
|
172 |
{
|
|
173 |
this(new StringReader(queryspec), parserName, accNumberSeparator);
|
129 |
174 |
}
|
130 |
|
}
|
131 |
175 |
|
132 |
|
/**
|
133 |
|
* construct an instance of the QuerySpecification class
|
134 |
|
*
|
135 |
|
* @param queryspec the XML representation of the query (should conform
|
136 |
|
* to pathquery.dtd) as a String
|
137 |
|
* @param parserName the fully qualified name of a Java Class implementing
|
138 |
|
* the org.xml.sax.Parser interface
|
139 |
|
*/
|
140 |
|
public QuerySpecification( String queryspec, String parserName,
|
141 |
|
String accNumberSeparator) throws IOException {
|
142 |
|
this(new StringReader(queryspec), parserName, accNumberSeparator);
|
143 |
|
}
|
144 |
|
|
145 |
|
/**
|
146 |
|
* construct an instance of the QuerySpecification class which don't need
|
147 |
|
* to parser a xml document
|
148 |
|
* @param accNumberSeparator the separator between doc version
|
149 |
|
*/
|
150 |
|
public QuerySpecification(String accNumberSeparator ) throws IOException
|
151 |
|
{
|
152 |
|
// Initialize the class variables
|
153 |
|
returnDocList = new Vector();
|
154 |
|
filterDocList = new Vector();
|
155 |
|
elementStack = new Stack();
|
156 |
|
queryStack = new Stack();
|
157 |
|
returnFieldList = new Vector();
|
158 |
|
ownerList = new Vector();
|
159 |
|
siteList = new Vector();
|
160 |
|
this.accNumberSeparator = accNumberSeparator;
|
161 |
|
}
|
162 |
|
|
163 |
|
|
164 |
|
/**
|
165 |
|
* Method to set user name
|
166 |
|
*
|
167 |
|
* @param myName the user name
|
168 |
|
*/
|
169 |
|
public void setUserName(String myName)
|
170 |
|
{
|
171 |
|
//to lower case
|
172 |
|
if (myName != null)
|
|
176 |
/**
|
|
177 |
* construct an instance of the QuerySpecification class which don't need
|
|
178 |
* to parser a xml document
|
|
179 |
*
|
|
180 |
* @param accNumberSeparator
|
|
181 |
* the separator between doc version
|
|
182 |
*/
|
|
183 |
public QuerySpecification(String accNumberSeparator) throws IOException
|
173 |
184 |
{
|
174 |
|
this.userName = myName.toLowerCase();
|
|
185 |
// Initialize the class variables
|
|
186 |
returnDocList = new Vector();
|
|
187 |
filterDocList = new Vector();
|
|
188 |
elementStack = new Stack();
|
|
189 |
queryStack = new Stack();
|
|
190 |
returnFieldList = new Vector();
|
|
191 |
ownerList = new Vector();
|
|
192 |
siteList = new Vector();
|
|
193 |
this.accNumberSeparator = accNumberSeparator;
|
175 |
194 |
}
|
176 |
|
else
|
|
195 |
|
|
196 |
/**
|
|
197 |
* Method to set user name
|
|
198 |
*
|
|
199 |
* @param myName
|
|
200 |
* the user name
|
|
201 |
*/
|
|
202 |
public void setUserName(String myName)
|
177 |
203 |
{
|
178 |
|
this.userName = myName;
|
|
204 |
//to lower case
|
|
205 |
if (myName != null) {
|
|
206 |
this.userName = myName.toLowerCase();
|
|
207 |
} else {
|
|
208 |
this.userName = myName;
|
|
209 |
}
|
179 |
210 |
}
|
180 |
|
}
|
181 |
|
|
182 |
|
/**
|
183 |
|
* Method to set user group
|
184 |
|
*
|
185 |
|
* @param myGroup the user group
|
186 |
|
*/
|
187 |
|
public void setGroup(String [] myGroup)
|
188 |
|
{
|
189 |
|
this.group = myGroup;
|
190 |
|
}
|
191 |
|
/**
|
192 |
|
* Method to indicate this query is a percentage search
|
193 |
|
*/
|
194 |
|
public boolean isPercentageSearch()
|
195 |
|
{
|
196 |
|
return percentageSearch;
|
197 |
|
}
|
198 |
|
/*
|
199 |
|
* Method to get owner query. If it is owner it has all permission
|
200 |
|
*/
|
201 |
|
private String createOwerQuery()
|
202 |
|
{
|
203 |
|
String ownerQuery = null;
|
204 |
|
ownerQuery = "SELECT docid FROM xml_documents WHERE ";
|
205 |
|
if (userName != null && !userName.equals(""))
|
|
211 |
|
|
212 |
/**
|
|
213 |
* Method to set user group
|
|
214 |
*
|
|
215 |
* @param myGroup
|
|
216 |
* the user group
|
|
217 |
*/
|
|
218 |
public void setGroup(String[] myGroup)
|
206 |
219 |
{
|
207 |
|
ownerQuery = ownerQuery + "lower(user_owner) ='"+ userName +"'";
|
|
220 |
this.group = myGroup;
|
208 |
221 |
}
|
209 |
|
|
210 |
|
MetaCatUtil.debugMessage("OwnerQuery: "+ownerQuery, 30);
|
211 |
|
return ownerQuery;
|
212 |
|
}
|
213 |
|
|
214 |
|
/*
|
215 |
|
* Method to create query for xml_access, this part is to get docid list which
|
216 |
|
* have a allow rule for a given user
|
217 |
|
*/
|
218 |
|
private String createAllowRuleQuery()
|
219 |
|
{
|
220 |
|
String allowQuery = null;
|
221 |
|
String allowString = constructAllowString();
|
222 |
|
allowQuery ="SELECT docid from xml_access WHERE( "+allowString;
|
223 |
|
allowQuery = allowQuery +") AND subtreeid IS NULL";
|
224 |
|
MetaCatUtil.debugMessage("allow query is: "+ allowQuery, 30);
|
225 |
|
return allowQuery;
|
226 |
|
|
227 |
|
|
228 |
|
}
|
229 |
|
|
230 |
|
/* Method to construct a allow rule string */
|
231 |
|
private String constructAllowString()
|
232 |
|
{
|
233 |
|
String allowQuery ="";
|
234 |
|
// add allow rule for user name
|
235 |
|
if (userName != null && !userName.equals(""))
|
|
222 |
|
|
223 |
/**
|
|
224 |
* Method to indicate this query is a percentage search
|
|
225 |
*/
|
|
226 |
public boolean isPercentageSearch()
|
236 |
227 |
{
|
237 |
|
allowQuery = allowQuery +"(lower(principal_name) = '" + userName
|
238 |
|
+"' AND perm_type = 'allow'"
|
239 |
|
+" AND (permission='4' OR permission='7'))";
|
|
228 |
return percentageSearch;
|
240 |
229 |
}
|
241 |
|
// add allow rule for public
|
242 |
|
allowQuery = allowQuery +"OR (lower(principal_name) = '" + PUBLIC
|
243 |
|
+"' AND perm_type = 'allow'"
|
244 |
|
+" AND (permission='4' OR permission='7'))";
|
245 |
|
|
246 |
|
// add allow rule for group
|
247 |
|
if (group != null)
|
|
230 |
|
|
231 |
/*
|
|
232 |
* Method to get owner query. If it is owner it has all permission
|
|
233 |
*/
|
|
234 |
private String createOwerQuery()
|
248 |
235 |
{
|
249 |
|
for (int i = 0; i< group.length; i++)
|
250 |
|
{
|
251 |
|
String groupUint = group[i];
|
252 |
|
if (groupUint != null && !groupUint.equals(""))
|
253 |
|
{
|
254 |
|
groupUint = groupUint.toLowerCase();
|
255 |
|
allowQuery = allowQuery +" OR (lower(principal_name) = '" + groupUint
|
256 |
|
+"' AND perm_type = 'allow'"
|
257 |
|
+" AND (permission='4' OR permission='7'))";
|
258 |
|
}//if
|
259 |
|
}//for
|
260 |
|
}//if
|
261 |
|
MetaCatUtil.debugMessage("allow string is: "+ allowQuery, 40);
|
262 |
|
return allowQuery;
|
263 |
|
}
|
|
236 |
String ownerQuery = null;
|
|
237 |
ownerQuery = "SELECT docid FROM xml_documents WHERE ";
|
|
238 |
if (userName != null && !userName.equals("")) {
|
|
239 |
ownerQuery = ownerQuery + "lower(user_owner) ='" + userName + "'";
|
|
240 |
}
|
264 |
241 |
|
265 |
|
/*
|
266 |
|
* Method to create query for xml_access, this part is to get docid list which
|
267 |
|
* have a deny rule and perm_order is allowFirst for a given user. This means
|
268 |
|
* the user will be denied to read
|
269 |
|
*/
|
270 |
|
private String createDenyRuleQuery()
|
271 |
|
{
|
272 |
|
String denyQuery = null;
|
273 |
|
String denyString = constructDenyString();
|
274 |
|
denyQuery ="SELECT docid from xml_access WHERE( " + denyString;
|
275 |
|
denyQuery = denyQuery + ") AND subtreeid IS NULL ";
|
276 |
|
MetaCatUtil.debugMessage("denyquery is: "+ denyQuery, 30);
|
277 |
|
return denyQuery;
|
278 |
|
|
279 |
|
}
|
280 |
|
/* Construct deny string */
|
281 |
|
private String constructDenyString()
|
282 |
|
{
|
283 |
|
String denyQuery ="";
|
284 |
|
// add deny rule for user name
|
285 |
|
if (userName != null && !userName.equals(""))
|
|
242 |
MetaCatUtil.debugMessage("OwnerQuery: " + ownerQuery, 30);
|
|
243 |
return ownerQuery;
|
|
244 |
}
|
|
245 |
|
|
246 |
/*
|
|
247 |
* Method to create query for xml_access, this part is to get docid list
|
|
248 |
* which have a allow rule for a given user
|
|
249 |
*/
|
|
250 |
private String createAllowRuleQuery()
|
286 |
251 |
{
|
287 |
|
denyQuery = denyQuery +"(lower(principal_name) = '" + userName
|
288 |
|
+"' AND perm_type = 'deny' "
|
289 |
|
+"AND perm_order ='allowFirst'"
|
290 |
|
+" AND (permission='4' OR permission='7'))";
|
|
252 |
String allowQuery = null;
|
|
253 |
String allowString = constructAllowString();
|
|
254 |
allowQuery = "SELECT docid from xml_access WHERE( " + allowString;
|
|
255 |
allowQuery = allowQuery + ") AND subtreeid IS NULL";
|
|
256 |
MetaCatUtil.debugMessage("allow query is: " + allowQuery, 30);
|
|
257 |
return allowQuery;
|
|
258 |
|
291 |
259 |
}
|
292 |
|
// add deny rule for public
|
293 |
|
denyQuery = denyQuery +"OR (lower(principal_name) = '" + PUBLIC
|
294 |
|
+"' AND perm_type = 'deny' "
|
295 |
|
+"AND perm_order ='allowFirst'"
|
296 |
|
+" AND (permission='4' OR permission='7'))";
|
297 |
|
|
298 |
|
// add allow rule for group
|
299 |
|
if (group != null)
|
|
260 |
|
|
261 |
/* Method to construct a allow rule string */
|
|
262 |
private String constructAllowString()
|
300 |
263 |
{
|
301 |
|
for (int i = 0; i< group.length; i++)
|
302 |
|
{
|
303 |
|
String groupUint = group[i];
|
304 |
|
if (groupUint != null && !groupUint.equals(""))
|
305 |
|
{
|
306 |
|
groupUint = groupUint.toLowerCase();
|
307 |
|
denyQuery = denyQuery +" OR (lower(principal_name) = '" + groupUint
|
308 |
|
+"' AND perm_type = 'deny' "
|
309 |
|
+"AND perm_order ='allowFirst'"
|
310 |
|
+" AND (permission='4' OR permission='7'))";
|
|
264 |
String allowQuery = "";
|
|
265 |
// add allow rule for user name
|
|
266 |
if (userName != null && !userName.equals("")) {
|
|
267 |
allowQuery = allowQuery + "(lower(principal_name) = '" + userName
|
|
268 |
+ "' AND perm_type = 'allow'"
|
|
269 |
+ " AND (permission='4' OR permission='7'))";
|
|
270 |
}
|
|
271 |
// add allow rule for public
|
|
272 |
allowQuery = allowQuery + "OR (lower(principal_name) = '" + PUBLIC
|
|
273 |
+ "' AND perm_type = 'allow'"
|
|
274 |
+ " AND (permission='4' OR permission='7'))";
|
|
275 |
|
|
276 |
// add allow rule for group
|
|
277 |
if (group != null) {
|
|
278 |
for (int i = 0; i < group.length; i++) {
|
|
279 |
String groupUint = group[i];
|
|
280 |
if (groupUint != null && !groupUint.equals("")) {
|
|
281 |
groupUint = groupUint.toLowerCase();
|
|
282 |
allowQuery = allowQuery + " OR (lower(principal_name) = '"
|
|
283 |
+ groupUint + "' AND perm_type = 'allow'"
|
|
284 |
+ " AND (permission='4' OR permission='7'))";
|
|
285 |
}//if
|
|
286 |
}//for
|
311 |
287 |
}//if
|
312 |
|
}//for
|
313 |
|
}//if
|
314 |
|
return denyQuery;
|
315 |
|
}
|
316 |
|
|
317 |
|
/**
|
318 |
|
* Method to append a access control query to SQL. So in DBQuery class, we can
|
319 |
|
* get docid from both user specified query and access control query. We don't
|
320 |
|
* need to checking permission after we get the doclist. It will be good to
|
321 |
|
* performance
|
322 |
|
*
|
323 |
|
*/
|
324 |
|
public String getAccessQuery()
|
325 |
|
{
|
326 |
|
String accessQuery = null;
|
327 |
|
String onwer = createOwerQuery();
|
328 |
|
String allow = createAllowRuleQuery();
|
329 |
|
String deny = createDenyRuleQuery();
|
330 |
|
accessQuery = " AND (docid IN("+ onwer + ")";
|
331 |
|
accessQuery = accessQuery + " OR (docid IN (" + allow + ")"
|
332 |
|
+ " AND docid NOT IN ("+ deny + ")))";
|
333 |
|
MetaCatUtil.debugMessage("accessquery is: "+ accessQuery, 30);
|
334 |
|
return accessQuery;
|
335 |
|
}
|
336 |
|
|
337 |
|
/** Main routine for testing */
|
338 |
|
static public void main(String[] args) {
|
|
288 |
MetaCatUtil.debugMessage("allow string is: " + allowQuery, 40);
|
|
289 |
return allowQuery;
|
|
290 |
}
|
339 |
291 |
|
340 |
|
if (args.length < 1) {
|
341 |
|
System.err.println("Wrong number of arguments!!!");
|
342 |
|
System.err.println("USAGE: java QuerySpecification <xmlfile>");
|
343 |
|
return;
|
344 |
|
} else {
|
345 |
|
int i = 0;
|
346 |
|
boolean useXMLIndex = true;
|
347 |
|
if ( args[i].equals( "-noindex" ) ) {
|
348 |
|
useXMLIndex = false;
|
349 |
|
i++;
|
350 |
|
}
|
351 |
|
String xmlfile = args[i];
|
|
292 |
/*
|
|
293 |
* Method to create query for xml_access, this part is to get docid list
|
|
294 |
* which have a deny rule and perm_order is allowFirst for a given user.
|
|
295 |
* This means the user will be denied to read
|
|
296 |
*/
|
|
297 |
private String createDenyRuleQuery()
|
|
298 |
{
|
|
299 |
String denyQuery = null;
|
|
300 |
String denyString = constructDenyString();
|
|
301 |
denyQuery = "SELECT docid from xml_access WHERE( " + denyString;
|
|
302 |
denyQuery = denyQuery + ") AND subtreeid IS NULL ";
|
|
303 |
MetaCatUtil.debugMessage("denyquery is: " + denyQuery, 30);
|
|
304 |
return denyQuery;
|
352 |
305 |
|
353 |
|
try {
|
354 |
|
MetaCatUtil util = new MetaCatUtil();
|
355 |
|
FileReader xml = new FileReader(new File(xmlfile));
|
356 |
|
QuerySpecification qspec =
|
357 |
|
new QuerySpecification(xml, util.getOption("saxparser"),
|
358 |
|
util.getOption("accNumberSeparator"));
|
359 |
|
System.out.println(qspec.printSQL(useXMLIndex));
|
|
306 |
}
|
360 |
307 |
|
361 |
|
} catch (IOException e) {
|
362 |
|
System.err.println(e.getMessage());
|
363 |
|
}
|
364 |
|
|
365 |
|
}
|
366 |
|
}
|
367 |
|
|
368 |
|
/**
|
369 |
|
* Returns true if the parsed query contains and extended xml query
|
370 |
|
* (i.e. there is at least one <returnfield> in the pathquery document)
|
371 |
|
*/
|
372 |
|
public boolean containsExtendedSQL()
|
373 |
|
{
|
374 |
|
if(containsExtendedSQL)
|
|
308 |
/* Construct deny string */
|
|
309 |
private String constructDenyString()
|
375 |
310 |
{
|
376 |
|
return true;
|
|
311 |
String denyQuery = "";
|
|
312 |
// add deny rule for user name
|
|
313 |
if (userName != null && !userName.equals("")) {
|
|
314 |
denyQuery = denyQuery + "(lower(principal_name) = '" + userName
|
|
315 |
+ "' AND perm_type = 'deny' "
|
|
316 |
+ "AND perm_order ='allowFirst'"
|
|
317 |
+ " AND (permission='4' OR permission='7'))";
|
|
318 |
}
|
|
319 |
// add deny rule for public
|
|
320 |
denyQuery = denyQuery + "OR (lower(principal_name) = '" + PUBLIC
|
|
321 |
+ "' AND perm_type = 'deny' " + "AND perm_order ='allowFirst'"
|
|
322 |
+ " AND (permission='4' OR permission='7'))";
|
|
323 |
|
|
324 |
// add allow rule for group
|
|
325 |
if (group != null) {
|
|
326 |
for (int i = 0; i < group.length; i++) {
|
|
327 |
String groupUint = group[i];
|
|
328 |
if (groupUint != null && !groupUint.equals("")) {
|
|
329 |
groupUint = groupUint.toLowerCase();
|
|
330 |
denyQuery = denyQuery + " OR (lower(principal_name) = '"
|
|
331 |
+ groupUint + "' AND perm_type = 'deny' "
|
|
332 |
+ "AND perm_order ='allowFirst'"
|
|
333 |
+ " AND (permission='4' OR permission='7'))";
|
|
334 |
}//if
|
|
335 |
}//for
|
|
336 |
}//if
|
|
337 |
return denyQuery;
|
377 |
338 |
}
|
378 |
|
else
|
|
339 |
|
|
340 |
/**
|
|
341 |
* Method to append a access control query to SQL. So in DBQuery class, we
|
|
342 |
* can get docid from both user specified query and access control query.
|
|
343 |
* We don't need to checking permission after we get the doclist. It will
|
|
344 |
* be good to performance
|
|
345 |
*
|
|
346 |
*/
|
|
347 |
public String getAccessQuery()
|
379 |
348 |
{
|
380 |
|
return false;
|
|
349 |
String accessQuery = null;
|
|
350 |
String onwer = createOwerQuery();
|
|
351 |
String allow = createAllowRuleQuery();
|
|
352 |
String deny = createDenyRuleQuery();
|
|
353 |
accessQuery = " AND (docid IN(" + onwer + ")";
|
|
354 |
accessQuery = accessQuery + " OR (docid IN (" + allow + ")"
|
|
355 |
+ " AND docid NOT IN (" + deny + ")))";
|
|
356 |
MetaCatUtil.debugMessage("accessquery is: " + accessQuery, 30);
|
|
357 |
return accessQuery;
|
381 |
358 |
}
|
382 |
|
}
|
383 |
|
|
384 |
|
/**
|
385 |
|
* A method to get if the query has an attribute return field
|
386 |
|
*/
|
387 |
|
public boolean containAttributeReturnField()
|
388 |
|
{
|
389 |
|
return hasAttributeReturnField;
|
390 |
|
}
|
391 |
|
|
392 |
|
/**
|
393 |
|
* Accessor method to return the identifier of this Query
|
394 |
|
*/
|
395 |
|
public String getIdentifier()
|
396 |
|
{
|
397 |
|
return meta_file_id;
|
398 |
|
}
|
399 |
359 |
|
400 |
|
/**
|
401 |
|
* method to set the identifier of this query
|
402 |
|
*/
|
403 |
|
public void setIdentifier(String id) {
|
404 |
|
this.meta_file_id = id;
|
405 |
|
}
|
|
360 |
/** Main routine for testing */
|
|
361 |
static public void main(String[] args)
|
|
362 |
{
|
406 |
363 |
|
407 |
|
/**
|
408 |
|
* Accessor method to return the title of this Query
|
409 |
|
*/
|
410 |
|
public String getQueryTitle()
|
411 |
|
{
|
412 |
|
return queryTitle;
|
413 |
|
}
|
|
364 |
if (args.length < 1) {
|
|
365 |
System.err.println("Wrong number of arguments!!!");
|
|
366 |
System.err.println("USAGE: java QuerySpecification <xmlfile>");
|
|
367 |
return;
|
|
368 |
} else {
|
|
369 |
int i = 0;
|
|
370 |
boolean useXMLIndex = true;
|
|
371 |
if (args[i].equals("-noindex")) {
|
|
372 |
useXMLIndex = false;
|
|
373 |
i++;
|
|
374 |
}
|
|
375 |
String xmlfile = args[i];
|
414 |
376 |
|
415 |
|
/**
|
416 |
|
* method to set the title of this query
|
417 |
|
*/
|
418 |
|
public void setQueryTitle(String title)
|
419 |
|
{
|
420 |
|
this.queryTitle = title;
|
421 |
|
}
|
|
377 |
try {
|
|
378 |
MetaCatUtil util = new MetaCatUtil();
|
|
379 |
FileReader xml = new FileReader(new File(xmlfile));
|
|
380 |
QuerySpecification qspec = new QuerySpecification(xml, util
|
|
381 |
.getOption("saxparser"), util
|
|
382 |
.getOption("accNumberSeparator"));
|
|
383 |
System.out.println(qspec.printSQL(useXMLIndex));
|
422 |
384 |
|
423 |
|
/**
|
424 |
|
* Accessor method to return a vector of the return document types as
|
425 |
|
* defined in the <returndoctype> tag in the pathquery dtd.
|
426 |
|
*/
|
427 |
|
public Vector getReturnDocList()
|
428 |
|
{
|
429 |
|
return this.returnDocList;
|
430 |
|
}
|
|
385 |
} catch (IOException e) {
|
|
386 |
System.err.println(e.getMessage());
|
|
387 |
}
|
431 |
388 |
|
432 |
|
/**
|
433 |
|
* method to set the list of return docs of this query
|
434 |
|
*/
|
435 |
|
public void setReturnDocList(Vector returnDocList)
|
436 |
|
{
|
437 |
|
this.returnDocList = returnDocList;
|
438 |
|
}
|
|
389 |
}
|
|
390 |
}
|
439 |
391 |
|
440 |
|
/**
|
441 |
|
* Accessor method to return a vector of the filter doc types as
|
442 |
|
* defined in the <filterdoctype> tag in the pathquery dtd.
|
443 |
|
*/
|
444 |
|
public Vector getFilterDocList()
|
445 |
|
{
|
446 |
|
return this.filterDocList;
|
447 |
|
}
|
|
392 |
/**
|
|
393 |
* Returns true if the parsed query contains and extended xml query (i.e.
|
|
394 |
* there is at least one <returnfield> in the pathquery document)
|
|
395 |
*/
|
|
396 |
public boolean containsExtendedSQL()
|
|
397 |
{
|
|
398 |
if (containsExtendedSQL) {
|
|
399 |
return true;
|
|
400 |
} else {
|
|
401 |
return false;
|
|
402 |
}
|
|
403 |
}
|
448 |
404 |
|
449 |
|
/**
|
450 |
|
* method to set the list of filter docs of this query
|
451 |
|
*/
|
452 |
|
public void setFilterDocList(Vector filterDocList)
|
453 |
|
{
|
454 |
|
this.filterDocList = filterDocList;
|
455 |
|
}
|
|
405 |
/**
|
|
406 |
* A method to get if the query has an attribute return field
|
|
407 |
*/
|
|
408 |
public boolean containAttributeReturnField()
|
|
409 |
{
|
|
410 |
return hasAttributeReturnField;
|
|
411 |
}
|
456 |
412 |
|
457 |
|
/**
|
458 |
|
* Accessor method to return a vector of the extended return fields as
|
459 |
|
* defined in the <returnfield> tag in the pathquery dtd.
|
460 |
|
*/
|
461 |
|
public Vector getReturnFieldList()
|
462 |
|
{
|
463 |
|
return this.returnFieldList;
|
464 |
|
}
|
|
413 |
/**
|
|
414 |
* Accessor method to return the identifier of this Query
|
|
415 |
*/
|
|
416 |
public String getIdentifier()
|
|
417 |
{
|
|
418 |
return meta_file_id;
|
|
419 |
}
|
465 |
420 |
|
466 |
|
/**
|
467 |
|
* method to set the list of fields to be returned by this query
|
468 |
|
*/
|
469 |
|
public void setReturnFieldList(Vector returnFieldList)
|
470 |
|
{
|
471 |
|
this.returnFieldList = returnFieldList;
|
472 |
|
}
|
|
421 |
/**
|
|
422 |
* method to set the identifier of this query
|
|
423 |
*/
|
|
424 |
public void setIdentifier(String id)
|
|
425 |
{
|
|
426 |
this.meta_file_id = id;
|
|
427 |
}
|
473 |
428 |
|
474 |
|
/**
|
475 |
|
* Accessor method to return a vector of the owner fields as
|
476 |
|
* defined in the <owner> tag in the pathquery dtd.
|
477 |
|
*/
|
478 |
|
public Vector getOwnerList()
|
479 |
|
{
|
480 |
|
return this.ownerList;
|
481 |
|
}
|
|
429 |
/**
|
|
430 |
* Accessor method to return the title of this Query
|
|
431 |
*/
|
|
432 |
public String getQueryTitle()
|
|
433 |
{
|
|
434 |
return queryTitle;
|
|
435 |
}
|
482 |
436 |
|
483 |
|
/**
|
484 |
|
* method to set the list of owners used to constrain this query
|
485 |
|
*/
|
486 |
|
public void setOwnerList(Vector ownerList)
|
487 |
|
{
|
488 |
|
this.ownerList = ownerList;
|
489 |
|
}
|
|
437 |
/**
|
|
438 |
* method to set the title of this query
|
|
439 |
*/
|
|
440 |
public void setQueryTitle(String title)
|
|
441 |
{
|
|
442 |
this.queryTitle = title;
|
|
443 |
}
|
490 |
444 |
|
491 |
|
/**
|
492 |
|
* Accessor method to return a vector of the site fields as
|
493 |
|
* defined in the <site> tag in the pathquery dtd.
|
494 |
|
*/
|
495 |
|
public Vector getSiteList()
|
496 |
|
{
|
497 |
|
return this.siteList;
|
498 |
|
}
|
|
445 |
/**
|
|
446 |
* Accessor method to return a vector of the return document types as
|
|
447 |
* defined in the <returndoctype> tag in the pathquery dtd.
|
|
448 |
*/
|
|
449 |
public Vector getReturnDocList()
|
|
450 |
{
|
|
451 |
return this.returnDocList;
|
|
452 |
}
|
499 |
453 |
|
500 |
|
/**
|
501 |
|
* method to set the list of sites used to constrain this query
|
502 |
|
*/
|
503 |
|
public void setSiteList(Vector siteList)
|
504 |
|
{
|
505 |
|
this.siteList = siteList;
|
506 |
|
}
|
|
454 |
/**
|
|
455 |
* method to set the list of return docs of this query
|
|
456 |
*/
|
|
457 |
public void setReturnDocList(Vector returnDocList)
|
|
458 |
{
|
|
459 |
this.returnDocList = returnDocList;
|
|
460 |
}
|
507 |
461 |
|
508 |
|
/**
|
509 |
|
* get the QueryGroup used to express query constraints
|
510 |
|
*/
|
511 |
|
public QueryGroup getQueryGroup()
|
512 |
|
{
|
513 |
|
return query;
|
514 |
|
}
|
515 |
|
|
516 |
|
/**
|
517 |
|
* set the querygroup
|
518 |
|
*/
|
519 |
|
public void setQueryGroup(QueryGroup group)
|
520 |
|
{
|
521 |
|
query = group;
|
522 |
|
}
|
523 |
|
|
524 |
|
/**
|
525 |
|
* set if this query sepcification has extendQuery(has return doc type or not)
|
526 |
|
*/
|
527 |
|
public void setContainsExtenedSQL(boolean hasExtenedQuery)
|
528 |
|
{
|
529 |
|
containsExtendedSQL = hasExtenedQuery;
|
530 |
|
}
|
531 |
|
|
532 |
|
/**
|
533 |
|
* Set up the SAX parser for reading the XML serialized query
|
534 |
|
*/
|
535 |
|
private XMLReader initializeParser() {
|
536 |
|
XMLReader parser = null;
|
|
462 |
/**
|
|
463 |
* Accessor method to return a vector of the filter doc types as defined in
|
|
464 |
* the <filterdoctype> tag in the pathquery dtd.
|
|
465 |
*/
|
|
466 |
public Vector getFilterDocList()
|
|
467 |
{
|
|
468 |
return this.filterDocList;
|
|
469 |
}
|
537 |
470 |
|
538 |
|
// Set up the SAX document handlers for parsing
|
539 |
|
try {
|
|
471 |
/**
|
|
472 |
* method to set the list of filter docs of this query
|
|
473 |
*/
|
|
474 |
public void setFilterDocList(Vector filterDocList)
|
|
475 |
{
|
|
476 |
this.filterDocList = filterDocList;
|
|
477 |
}
|
540 |
478 |
|
541 |
|
// Get an instance of the parser
|
542 |
|
parser = XMLReaderFactory.createXMLReader(parserName);
|
|
479 |
/**
|
|
480 |
* Accessor method to return a vector of the extended return fields as
|
|
481 |
* defined in the <returnfield> tag in the pathquery dtd.
|
|
482 |
*/
|
|
483 |
public Vector getReturnFieldList()
|
|
484 |
{
|
|
485 |
return this.returnFieldList;
|
|
486 |
}
|
543 |
487 |
|
544 |
|
// Set the ContentHandler to this instance
|
545 |
|
parser.setContentHandler(this);
|
|
488 |
/**
|
|
489 |
* method to set the list of fields to be returned by this query
|
|
490 |
*/
|
|
491 |
public void setReturnFieldList(Vector returnFieldList)
|
|
492 |
{
|
|
493 |
this.returnFieldList = returnFieldList;
|
|
494 |
}
|
546 |
495 |
|
547 |
|
// Set the error Handler to this instance
|
548 |
|
parser.setErrorHandler(this);
|
|
496 |
/**
|
|
497 |
* Accessor method to return a vector of the owner fields as defined in the
|
|
498 |
* <owner> tag in the pathquery dtd.
|
|
499 |
*/
|
|
500 |
public Vector getOwnerList()
|
|
501 |
{
|
|
502 |
return this.ownerList;
|
|
503 |
}
|
549 |
504 |
|
550 |
|
} catch (Exception e) {
|
551 |
|
System.err.println("Error in QuerySpcecification.initializeParser " +
|
552 |
|
e.toString());
|
|
505 |
/**
|
|
506 |
* method to set the list of owners used to constrain this query
|
|
507 |
*/
|
|
508 |
public void setOwnerList(Vector ownerList)
|
|
509 |
{
|
|
510 |
this.ownerList = ownerList;
|
553 |
511 |
}
|
554 |
512 |
|
555 |
|
return parser;
|
556 |
|
}
|
|
513 |
/**
|
|
514 |
* Accessor method to return a vector of the site fields as defined in the
|
|
515 |
* <site> tag in the pathquery dtd.
|
|
516 |
*/
|
|
517 |
public Vector getSiteList()
|
|
518 |
{
|
|
519 |
return this.siteList;
|
|
520 |
}
|
557 |
521 |
|
558 |
|
/**
|
559 |
|
* callback method used by the SAX Parser when the start tag of an
|
560 |
|
* element is detected. Used in this context to parse and store
|
561 |
|
* the query information in class variables.
|
562 |
|
*/
|
563 |
|
public void startElement (String uri, String localName,
|
564 |
|
String qName, Attributes atts)
|
565 |
|
throws SAXException {
|
566 |
|
BasicNode currentNode = new BasicNode(localName);
|
567 |
|
// add attributes to BasicNode here
|
568 |
|
if (atts != null) {
|
569 |
|
int len = atts.getLength();
|
570 |
|
for (int i = 0; i < len; i++) {
|
571 |
|
currentNode.setAttribute(atts.getLocalName(i), atts.getValue(i));
|
572 |
|
}
|
|
522 |
/**
|
|
523 |
* method to set the list of sites used to constrain this query
|
|
524 |
*/
|
|
525 |
public void setSiteList(Vector siteList)
|
|
526 |
{
|
|
527 |
this.siteList = siteList;
|
573 |
528 |
}
|
574 |
529 |
|
575 |
|
elementStack.push(currentNode);
|
576 |
|
if (currentNode.getTagName().equals("querygroup")) {
|
577 |
|
QueryGroup currentGroup = new QueryGroup(
|
578 |
|
currentNode.getAttribute("operator"));
|
579 |
|
if (query == null) {
|
580 |
|
query = currentGroup;
|
581 |
|
} else {
|
582 |
|
QueryGroup parentGroup = (QueryGroup)queryStack.peek();
|
583 |
|
parentGroup.addChild(currentGroup);
|
584 |
|
}
|
585 |
|
queryStack.push(currentGroup);
|
|
530 |
/**
|
|
531 |
* get the QueryGroup used to express query constraints
|
|
532 |
*/
|
|
533 |
public QueryGroup getQueryGroup()
|
|
534 |
{
|
|
535 |
return query;
|
586 |
536 |
}
|
587 |
|
}
|
588 |
537 |
|
589 |
|
/**
|
590 |
|
* callback method used by the SAX Parser when the end tag of an
|
591 |
|
* element is detected. Used in this context to parse and store
|
592 |
|
* the query information in class variables.
|
593 |
|
*/
|
594 |
|
public void endElement (String uri, String localName,
|
595 |
|
String qName) throws SAXException {
|
596 |
|
BasicNode leaving = (BasicNode)elementStack.pop();
|
597 |
|
if (leaving.getTagName().equals("queryterm")) {
|
598 |
|
boolean isCaseSensitive = (new Boolean(
|
599 |
|
leaving.getAttribute("casesensitive"))).booleanValue();
|
600 |
|
QueryTerm currentTerm = null;
|
601 |
|
if (currentPathexpr == null) {
|
602 |
|
currentTerm = new QueryTerm(isCaseSensitive,
|
603 |
|
leaving.getAttribute("searchmode"),currentValue);
|
604 |
|
} else {
|
605 |
|
currentTerm = new QueryTerm(isCaseSensitive,
|
606 |
|
leaving.getAttribute("searchmode"),currentValue,
|
607 |
|
currentPathexpr);
|
608 |
|
}
|
609 |
|
QueryGroup currentGroup = (QueryGroup)queryStack.peek();
|
610 |
|
currentGroup.addChild(currentTerm);
|
611 |
|
currentValue = null;
|
612 |
|
currentPathexpr = null;
|
613 |
|
} else if (leaving.getTagName().equals("querygroup")) {
|
614 |
|
QueryGroup leavingGroup = (QueryGroup)queryStack.pop();
|
|
538 |
/**
|
|
539 |
* set the querygroup
|
|
540 |
*/
|
|
541 |
public void setQueryGroup(QueryGroup group)
|
|
542 |
{
|
|
543 |
query = group;
|
615 |
544 |
}
|
616 |
|
}
|
617 |
545 |
|
618 |
|
/**
|
619 |
|
* callback method used by the SAX Parser when the text sequences of an
|
620 |
|
* xml stream are detected. Used in this context to parse and store
|
621 |
|
* the query information in class variables.
|
622 |
|
*/
|
623 |
|
public void characters(char ch[], int start, int length) {
|
|
546 |
/**
|
|
547 |
* set if this query sepcification has extendQuery(has return doc type or
|
|
548 |
* not)
|
|
549 |
*/
|
|
550 |
public void setContainsExtenedSQL(boolean hasExtenedQuery)
|
|
551 |
{
|
|
552 |
containsExtendedSQL = hasExtenedQuery;
|
|
553 |
}
|
624 |
554 |
|
625 |
|
String inputString = new String(ch, start, length);
|
626 |
|
BasicNode currentNode = (BasicNode)elementStack.peek();
|
627 |
|
String currentTag = currentNode.getTagName();
|
628 |
|
if (currentTag.equals("meta_file_id")) {
|
629 |
|
meta_file_id = inputString;
|
630 |
|
} else if (currentTag.equals("querytitle")) {
|
631 |
|
queryTitle = inputString;
|
632 |
|
} else if (currentTag.equals("value")) {
|
633 |
|
currentValue = inputString;
|
634 |
|
} else if (currentTag.equals("pathexpr")) {
|
635 |
|
currentPathexpr = inputString;
|
636 |
|
} else if (currentTag.equals("returndoctype")) {
|
637 |
|
returnDocList.add(inputString);
|
638 |
|
} else if (currentTag.equals("filterdoctype")) {
|
639 |
|
filterDocList.add(inputString);
|
640 |
|
} else if (currentTag.equals("returnfield")) {
|
641 |
|
handleReturnField(inputString);
|
642 |
|
} else if (currentTag.equals("filterdoctype")) {
|
643 |
|
filterDocList.add(inputString);
|
644 |
|
} else if (currentTag.equals("owner")) {
|
645 |
|
ownerList.add(inputString);
|
646 |
|
} else if (currentTag.equals("site")) {
|
647 |
|
siteList.add(inputString);
|
|
555 |
/**
|
|
556 |
* Set up the SAX parser for reading the XML serialized query
|
|
557 |
*/
|
|
558 |
private XMLReader initializeParser()
|
|
559 |
{
|
|
560 |
XMLReader parser = null;
|
|
561 |
|
|
562 |
// Set up the SAX document handlers for parsing
|
|
563 |
try {
|
|
564 |
|
|
565 |
// Get an instance of the parser
|
|
566 |
parser = XMLReaderFactory.createXMLReader(parserName);
|
|
567 |
|
|
568 |
// Set the ContentHandler to this instance
|
|
569 |
parser.setContentHandler(this);
|
|
570 |
|
|
571 |
// Set the error Handler to this instance
|
|
572 |
parser.setErrorHandler(this);
|
|
573 |
|
|
574 |
} catch (Exception e) {
|
|
575 |
System.err.println("Error in QuerySpcecification.initializeParser "
|
|
576 |
+ e.toString());
|
|
577 |
}
|
|
578 |
|
|
579 |
return parser;
|
648 |
580 |
}
|
649 |
|
}
|
650 |
|
|
651 |
|
/**
|
652 |
|
* Method to transfer string to return field
|
653 |
|
*/
|
654 |
|
public void handleReturnField(String inputString)
|
655 |
|
{
|
656 |
|
// make sure if return fields has an attribute or not
|
657 |
|
if (inputString.indexOf(ATTRIBUTESYMBOL) ==-1)
|
658 |
|
{
|
659 |
|
// no attribute value will be returned
|
660 |
|
returnFieldList.add(inputString);
|
661 |
|
containsExtendedSQL = true;
|
662 |
|
}
|
663 |
|
else
|
664 |
|
{
|
665 |
|
// has a attribute return field
|
666 |
|
// divied the return filed into two parts, one is path and the
|
667 |
|
// other is attribue name
|
668 |
|
String returnPath = newPathExpressionWithOutAttribute(inputString);
|
669 |
|
String attributeName = getAttributeName(inputString);
|
670 |
|
Vector pathInfo = new Vector();
|
671 |
|
// the vector has the information about return path and attributename
|
672 |
|
pathInfo.addElement(returnPath);
|
673 |
|
pathInfo.addElement(attributeName);
|
674 |
|
// put the vector into a hash table. The reseaon why don't put
|
675 |
|
// return path or attributename as a key is because they are not unique
|
676 |
|
attributeReturnList.put
|
677 |
|
(new Integer(countAttributeReturnField), pathInfo);
|
678 |
|
countAttributeReturnField++;
|
679 |
|
hasAttributeReturnField = true;
|
680 |
|
containsExtendedSQL = true;
|
681 |
|
|
682 |
|
}
|
683 |
|
}
|
684 |
|
/**
|
685 |
|
* create a SQL serialization of the query that this instance represents
|
686 |
|
*/
|
687 |
|
public String printSQL(boolean useXMLIndex) {
|
688 |
|
|
689 |
|
|
690 |
|
StringBuffer self = new StringBuffer();
|
691 |
581 |
|
692 |
|
self.append("SELECT docid,docname,doctype,");
|
693 |
|
self.append("date_created, date_updated, rev ");
|
694 |
|
self.append("FROM xml_documents WHERE docid IN (");
|
|
582 |
/**
|
|
583 |
* callback method used by the SAX Parser when the start tag of an element
|
|
584 |
* is detected. Used in this context to parse and store the query
|
|
585 |
* information in class variables.
|
|
586 |
*/
|
|
587 |
public void startElement(String uri, String localName, String qName,
|
|
588 |
Attributes atts) throws SAXException
|
|
589 |
{
|
|
590 |
BasicNode currentNode = new BasicNode(localName);
|
|
591 |
// add attributes to BasicNode here
|
|
592 |
if (atts != null) {
|
|
593 |
int len = atts.getLength();
|
|
594 |
for (int i = 0; i < len; i++) {
|
|
595 |
currentNode
|
|
596 |
.setAttribute(atts.getLocalName(i), atts.getValue(i));
|
|
597 |
}
|
|
598 |
}
|
695 |
599 |
|
696 |
|
// This determines the documents that meet the query conditions
|
697 |
|
self.append(query.printSQL(useXMLIndex));
|
|
600 |
elementStack.push(currentNode);
|
|
601 |
if (currentNode.getTagName().equals("querygroup")) {
|
|
602 |
QueryGroup currentGroup = new QueryGroup(currentNode
|
|
603 |
.getAttribute("operator"));
|
|
604 |
if (query == null) {
|
|
605 |
query = currentGroup;
|
|
606 |
} else {
|
|
607 |
QueryGroup parentGroup = (QueryGroup) queryStack.peek();
|
|
608 |
parentGroup.addChild(currentGroup);
|
|
609 |
}
|
|
610 |
queryStack.push(currentGroup);
|
|
611 |
}
|
|
612 |
}
|
698 |
613 |
|
699 |
|
self.append(") ");
|
700 |
|
|
701 |
|
// Add SQL to filter for doctypes requested in the query
|
702 |
|
// This is an implicit OR for the list of doctypes. Only doctypes in this
|
703 |
|
// list will be searched if the tag is present
|
704 |
|
if (!filterDocList.isEmpty()) {
|
705 |
|
boolean firstdoctype = true;
|
706 |
|
self.append(" AND (");
|
707 |
|
Enumeration en = filterDocList.elements();
|
708 |
|
while (en.hasMoreElements()) {
|
709 |
|
String currentDoctype = (String)en.nextElement();
|
710 |
|
if (firstdoctype) {
|
711 |
|
firstdoctype = false;
|
712 |
|
self.append(" doctype = '" + currentDoctype + "'");
|
713 |
|
} else {
|
714 |
|
self.append(" OR doctype = '" + currentDoctype + "'");
|
|
614 |
/**
|
|
615 |
* callback method used by the SAX Parser when the end tag of an element is
|
|
616 |
* detected. Used in this context to parse and store the query information
|
Removed the "getdataguide" action as it was always experimental and is no longer used in metacat or morpho.