001: /**
002: * $Id: JPimABSearchTerm.java,v 1.2 2003/06/16 15:10:56 byork Exp $
003: * Copyright 2002 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and iPlanet
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.ssoadapter.ab.pim;
014:
015: import java.lang.reflect.Method;
016:
017: import com.sun.addressbook.ABSearchTerm;
018: import com.sun.addressbook.ABStoreException;
019:
020: import com.aligo.pim.PimFilterOperandType;
021: import com.aligo.pim.interfaces.PimAddressEntryItemFilter;
022: import com.aligo.pim.exceptions.PimException;
023:
024: /**
025: * Address Book SearchTerm does the recursive computation of the search
026: * filter from a combination of search terms. It implements the compute
027: * command of the ABSearchTerm.
028: * The search terms can be nested in a tree structure and combined with
029: * an 'and' or an 'or' e.g. "ln=doe & (fn=john | fn=joe)"
030: *
031: */
032: public class JPimABSearchTerm extends ABSearchTerm implements
033: JPimABConstants {
034: //
035: // Will have a non-null value only in the outer-most searchTerm
036: //
037: private PimAddressEntryItemFilter pimAEItemFilter = null;
038:
039: //
040: // Operand for Grouping in Aligo Filters. (0-100 reserved for ABSearchTerm)
041: //
042: private static final int OPEN = 101;
043: private static final int CLOSE = 102;
044:
045: /**
046: * Initializes the search term object. This constructor indicates this
047: * search term is an end node and does not contain recursive search terms.
048: *
049: * @param name Name of the attribute to search on.
050: * @param value Value of the attribute to search.
051: * @param exact Boolean indicating whether search is 'exact'(true) or
052: * 'contains'(false).
053: */
054: public JPimABSearchTerm(String name, String value, boolean exact) {
055: super (name, value, exact);
056: }
057:
058: /**
059: * Initializes the search term object. This constructor is used for the
060: * unary operator NOT on the ABSearchTerm. Usage of this constructor
061: * means that ABSearchTerm is recursive and is not the end node, and
062: * it will contain terms, op and not name, value.
063: *
064: * @param The recursive ABSearchTerm.
065: * @param Operator binding the recursive searchTerms. The value can only
066: * be NOT.
067: */
068: public JPimABSearchTerm(ABSearchTerm term, int op)
069: throws ABStoreException {
070: super (term, op);
071: }
072:
073: /**
074: * Initializes the search term object. This constructor is used for the
075: * binary operators like AND and OR on the ABSearchTerms array. Usage of
076: * this constructor means that ABSearchTerm is recursive and is not the
077: * end node, and it will contain terms, op and not name, value.
078: *
079: * @param The recursive ABSearchTerm array.
080: * @param Operator binding the recursive searchTerms. The values can be
081: * AND or OR.
082: */
083: public JPimABSearchTerm(ABSearchTerm[] terms, int op)
084: throws ABStoreException {
085: super (terms, op);
086: }
087:
088: //
089: // Store the JABAPI Entry & Aligo ContactItem names
090: //
091: private SchemaElements schemaElements = new SchemaElements();
092:
093: public void setAddressEntryItemFilter(
094: PimAddressEntryItemFilter filter) {
095: pimAEItemFilter = filter;
096: }
097:
098: /**
099: * computes the search filter by looking at all the searchTerms
100: *
101: * @return The computed search Filter object.
102: */
103: public Object compute() throws ABStoreException {
104: if (pimAEItemFilter == null) {
105: throw new ABStoreException(
106: "PimAddressEntryItemFilter == null");
107: }
108:
109: StringBuffer dbgStr = new StringBuffer(); // for debug
110:
111: addToFilter(pimAEItemFilter, dbgStr);
112:
113: System.out.println("Filter equivalent = " + dbgStr);
114:
115: return pimAEItemFilter;
116: }
117:
118: /**
119: * called recursively
120: */
121:
122: private void addToFilter(PimAddressEntryItemFilter pimFilter,
123: StringBuffer dbgStr) throws ABStoreException {
124: ABSearchTerm[] searchTerms = getTerms();
125:
126: if (searchTerms != null) {
127: int num_elements = searchTerms.length;
128: setOperandOnFilter(pimFilter, OPEN, dbgStr); // begin Grouping
129:
130: for (int i = 0; i < num_elements; i++) {
131: JPimABSearchTerm searchTerm = (JPimABSearchTerm) searchTerms[i];
132:
133: searchTerm.addToFilter(pimFilter, dbgStr); // recurse
134:
135: //
136: // setoperand (for every element before the last element) OR
137: // (for unary operators (NOT), which have only 1 searchTerm)
138: //
139: if (i < (num_elements - 1) || (num_elements == 1)) {
140: setOperandOnFilter(pimFilter, getOp(), dbgStr);
141: }
142: }
143:
144: setOperandOnFilter(pimFilter, CLOSE, dbgStr); // end Grouping
145: }
146:
147: setInFilter(pimFilter, dbgStr); // leaf node
148: return;
149: }
150:
151: /**
152: * Map operation to PimFilterOperandType
153: */
154: private void setOperandOnFilter(
155: PimAddressEntryItemFilter pimFilter, int operation,
156: StringBuffer dbgStr) throws ABStoreException {
157: if (operation != NO_OP) {
158: PimFilterOperandType opType = null;
159: switch (operation) {
160: case OR:
161: dbgStr.append("|");
162: opType = PimFilterOperandType.OR;
163: break;
164: case AND:
165: dbgStr.append("&");
166: opType = PimFilterOperandType.AND;
167: break;
168: case OPEN:
169: dbgStr.append("(");
170: opType = PimFilterOperandType.OPEN;
171: break;
172: case CLOSE:
173: dbgStr.append(")");
174: opType = PimFilterOperandType.CLOSE;
175: break;
176: case NOT: // Aligo doesn't have NOT
177: dbgStr.append("{NOT}");
178: default:
179: throw new ABStoreException("Operand not supported: "
180: + operation);
181: }
182:
183: try {
184: pimFilter.setOperand(opType);
185: } catch (PimException pe) {
186: pe.printStackTrace();
187: throw new ABStoreException("Could not setOperand: "
188: + pe);
189: }
190: }
191: }
192:
193: private void setInFilter(PimAddressEntryItemFilter pimFilter,
194: StringBuffer dbgStr) throws ABStoreException {
195: String name = getName();
196: String value = getValue();
197:
198: if (name == null || value == null) {
199: //
200: // The outermost ABSearchTerm will only be a container for the
201: // array, in which case name is null. So we dont do anything here.
202: //
203: return;
204: }
205:
206: //
207: // exact ignored for now: no equivalent in Aligo
208: //
209: boolean exact = isExact();
210:
211: String[] params = { value };
212: Class filterClass = pimFilter.getClass();
213:
214: if (name.equalsIgnoreCase(ANY)) {
215: //
216: // dont set any filters for "*"
217: //
218: if ((value != null) && (!value.equals("*"))) {
219: Object[] allPropNames = schemaElements
220: .getAEFilterPropertyNames();
221:
222: if (allPropNames == null)
223: return;
224:
225: int count = allPropNames.length;
226: setOperandOnFilter(pimFilter, OPEN, dbgStr); // Begin Grouping
227:
228: for (int i = 0; i < count; i++) {
229: setInFilter(pimFilter, filterClass,
230: (String) allPropNames[i], params, dbgStr);
231:
232: //
233: // for every element before the last element - set operand
234: //
235: if (i < (count - 1)) {
236: setOperandOnFilter(pimFilter, OR, dbgStr);
237: }
238: }
239:
240: setOperandOnFilter(pimFilter, CLOSE, dbgStr); // END Grouping
241: }
242: } else {
243: setInFilter(pimFilter, filterClass, name, params, dbgStr);
244: }
245:
246: return;
247: }
248:
249: /**
250: * @param pimFilter The PimAddressEntryItemFilter.
251: * @param filterClass The PimAddressEntryItemFilter Class. Since this method
252: * can be called in a loop, passing in the Class helps improve perf.
253: * @param propName The name of a bean property in the JABAPIs Entry object
254: * @param dbgStr The debug String to represent the filter being added
255: */
256: private void setInFilter(PimAddressEntryItemFilter pimFilter,
257: Class filterClass, String propName, Object[] values,
258: StringBuffer dbgStr) throws ABStoreException {
259: dbgStr.append(propName + "=" + values[0]);
260:
261: //
262: // Get the PimElementName coresponding to JABAPIs Entry property
263: //
264: String pimElementName = schemaElements
265: .getPimElementName(propName);
266:
267: if (pimElementName == null) {
268: return; // no equivalent in Alligo
269: }
270:
271: String setterMethodName = SET + pimElementName;
272: try {
273: //
274: // set in Filter
275: //
276: Method setterMethod = filterClass.getMethod(
277: setterMethodName, beanParams);
278: setterMethod.invoke(pimFilter, values); // set
279: } catch (Exception e) {
280: throw new ABStoreException(
281: "Could not get/set in PimAddressEntryItemFilter:"
282: + setterMethodName + " :: " + e);
283: }
284:
285: return;
286: }
287:
288: }
|