001: /*************************************************************************
002: * *
003: * EJBCA: The OpenSource Certificate Authority *
004: * *
005: * This software is free software; you can redistribute it and/or *
006: * modify it under the terms of the GNU Lesser General Public *
007: * License as published by the Free Software Foundation; either *
008: * version 2.1 of the License, or any later version. *
009: * *
010: * See terms of license at gnu.org. *
011: * *
012: *************************************************************************/package org.ejbca.util.query;
013:
014: import java.util.Date;
015: import java.util.Iterator;
016: import java.util.Vector;
017:
018: import org.apache.log4j.Logger;
019: import org.ejbca.util.StringTools;
020:
021: /**
022: * A class used to produce advanced querys from the log and user data tables. It's main function is
023: * getQueryString which returns a string which should be placed in the 'WHERE' clause of a SQL
024: * statement.
025: *
026: * @author tomselleck
027: * @version $Id: Query.java,v 1.5 2007/02/02 09:36:28 anatom Exp $
028: */
029: public class Query implements java.io.Serializable {
030:
031: private static final long serialVersionUID = -1L;
032:
033: private static Logger log = Logger.getLogger(Query.class);
034: // Public Constants.
035: public static final int TYPE_LOGQUERY = 0;
036: public static final int TYPE_USERQUERY = 1;
037: public static final int TYPE_APPROVALQUERY = 2;
038: public static final int CONNECTOR_AND = 0;
039: public static final int CONNECTOR_OR = 1;
040: public static final int CONNECTOR_ANDNOT = 2;
041: public static final int CONNECTOR_ORNOT = 3;
042:
043: // Public methods.
044:
045: /**
046: * Creates a new instance of Query
047: *
048: * @param type is the typ of query to produce. Should be one of the 'TYPE' constants of this
049: * class.
050: */
051: public Query(int type) {
052: matches = new Vector();
053: connectors = new Vector();
054: this .type = type;
055: }
056:
057: /**
058: * Adds a time restraint to the query. Both parameter cannot be null This method should only be
059: * used in ra user queries.
060: *
061: * @param startdate gives the start date of the query or null if it no startdate.
062: * @param enddate gives the end date of the query or null if it no startdate.
063: */
064: public void add(Date startdate, Date enddate) {
065: matches.addElement(new TimeMatch(type, startdate, enddate));
066: }
067:
068: /**
069: * Adds a time restraint to the query. Both start and enddate parameters cannot be null This
070: * method should only be used in ra user queries.
071: *
072: * @param matchwith should indicate which field to match with, on of the TimeMatch.MATCH_WITH
073: * constants.
074: * @param startdate gives the start date of the query or null if it no startdate.
075: * @param enddate gives the end date of the query or null if it no startdate.
076: */
077: public void add(int matchwith, Date startdate, Date enddate) {
078: matches.addElement(new TimeMatch(type, matchwith, startdate,
079: enddate));
080: }
081:
082: /**
083: * Adds a time restraint and a connector to the query. Both parameter cannot be null. This
084: * method should only be used in log queries.
085: *
086: * @param startdate gives the start date of the query or null if it no startdate.
087: * @param enddate gives the end date of the query or null if it no startdate.
088: * @param connector should be one of the 'CONNECTOR' constants.
089: */
090: public void add(Date startdate, Date enddate, int connector) {
091: matches.addElement(new TimeMatch(type, startdate, enddate));
092: connectors.addElement(new Integer(connector));
093: }
094:
095: /**
096: * Adds a time restraint and a connector to the query. Both start and enddate parameters cannot
097: * be null. This method should only be used in ra user queries.
098: *
099: * @param matchwith should indicate which field to match with, on of the TimeMatch.MATCH_WITH
100: * constants.
101: * @param startdate gives the start date of the query or null if it no startdate.
102: * @param enddate gives the end date of the query or null if it no startdate.
103: * @param connector should be one of the 'CONNECTOR' constants.
104: */
105: public void add(int matchwith, Date startdate, Date enddate,
106: int connector) {
107: matches.addElement(new TimeMatch(type, matchwith, startdate,
108: enddate));
109: connectors.addElement(new Integer(connector));
110: }
111:
112: /**
113: * Adds a match ot type UserMatch or LogMatch to the query.
114: *
115: * @param matchwith should be one of the the UserMatch.MATCH_WITH or LogMatch.MATCH_WITH
116: * connstants depending on query type.
117: * @param matchtype should be one of BasicMatch.MATCH_TYPE constants.
118: * @param matchvalue should be a string representation to match against.
119: *
120: * @throws NumberFormatException if there is an illegal character in matchvalue string.
121: */
122: public void add(int matchwith, int matchtype, String matchvalue)
123: throws NumberFormatException {
124: switch (this .type) {
125: case TYPE_LOGQUERY:
126: matches.addElement(new LogMatch(matchwith, matchtype,
127: matchvalue));
128: break;
129: case TYPE_USERQUERY:
130: matches.addElement(new UserMatch(matchwith, matchtype,
131: matchvalue));
132: break;
133: case TYPE_APPROVALQUERY:
134: matches.addElement(new ApprovalMatch(matchwith, matchtype,
135: matchvalue));
136: break;
137: }
138: if (StringTools.hasSqlStripChars(matchvalue)) {
139: hasIllegalSqlChars = true;
140: }
141: }
142:
143: /**
144: * Adds a match ot type UserMatch or LogMatch ant a connector to the query.
145: *
146: * @param matchwith should be one of the the UserMatch.MATCH_WITH or LogMatch.MATCH_WITH
147: * connstants depending on query type.
148: * @param matchtype should be one of BasicMatch.MATCH_TYPE constants.
149: * @param matchvalue should be a string representation to match against.
150: * @param connector should be one of the 'CONNECTOR' constants.
151: *
152: * @throws NumberFormatException if there is an illegal character in matchvalue string.
153: */
154: public void add(int matchwith, int matchtype, String matchvalue,
155: int connector) throws NumberFormatException {
156: add(matchwith, matchtype, matchvalue);
157: connectors.addElement(new Integer(connector));
158:
159: }
160:
161: /**
162: * Adds a connector to the query.
163: *
164: * @param connector should be one of the 'CONNECTOR' constants.
165: *
166: * @throws NumberFormatException if there is an illegal character in matchvalue string.
167: */
168: public void add(int connector) {
169: connectors.addElement(new Integer(connector));
170: }
171:
172: /**
173: * Gives the string to be used in the 'WHERE' clause int the SQL-statement.
174: *
175: * @return the string to be used in the 'WHERE'-clause.
176: */
177: public String getQueryString() {
178: String returnval = "";
179:
180: for (int i = 0; i < (matches.size() - 1); i++) {
181: returnval += ((BasicMatch) matches.elementAt(i))
182: .getQueryString();
183: returnval += CONNECTOR_SQL_NAMES[((Integer) connectors
184: .elementAt(i)).intValue()];
185: }
186:
187: returnval += ((BasicMatch) matches
188: .elementAt(matches.size() - 1)).getQueryString();
189:
190: return returnval;
191: }
192:
193: /**
194: * Checks if the present query is legal by checking if every match is legal and that the number
195: * of connectors is one less than matches.
196: *
197: * @return true if the query is legal, false otherwise
198: */
199: public boolean isLegalQuery() {
200: boolean returnval = true;
201: Iterator i = matches.iterator();
202:
203: while (i.hasNext()) {
204: BasicMatch match = (BasicMatch) i.next();
205: returnval = returnval && match.isLegalQuery();
206: if (!returnval) {
207: log
208: .error("Query is illegal: "
209: + match.getQueryString());
210: }
211: }
212:
213: returnval = returnval
214: && ((matches.size() - 1) == connectors.size());
215:
216: returnval = returnval && (matches.size() > 0);
217:
218: return returnval;
219: }
220:
221: /**
222: * Checks if the present query contains illegal SQL string charcters as set by add(String) methods.
223: * The add(String) methods checks against StringTools.hasStripChars.
224: *
225: * @return true if the query is legal, false otherwise
226: * @see org.ejbca.util.StringTools#hasStripChars
227: */
228: public boolean hasIllegalSqlChars() {
229: log.debug("hasIllegalSqlChars: " + hasIllegalSqlChars);
230: return hasIllegalSqlChars;
231: }
232:
233: // Private Constants.
234: static final String[] CONNECTOR_SQL_NAMES = { " AND ", " OR ",
235: " AND NOT ", " OR NOT " };
236:
237: // Private fields.
238: private Vector matches = null; // Should only contain BasicMatch objects.
239: private Vector connectors = null; // Should only containg CONNECTOR constants.
240: protected int type = 0;
241: private boolean hasIllegalSqlChars = false;
242: }
|