/* * QueryItem.java * * Created on July 5, 2001, 3:25 PM */ package context.arch.discoverer.query; import java.util.ArrayList; import java.util.Collection; import java.util.List; import context.arch.comm.DataObject; import context.arch.comm.DataObjects; import context.arch.discoverer.ComponentDescription; import context.arch.discoverer.component.AbstractElement; import context.arch.discoverer.component.dataModel.AbstractDataModel; import context.arch.discoverer.component.dataModel.IndexTable; import context.arch.discoverer.query.comparison.AbstractComparison; /** * * @param <C1> * @param <C2> * @author Agathe * @author Brian Y. Lim */ public final class RuleQueryItem<C1,C2> extends AbstractQueryItem<C1,C2> { private static final long serialVersionUID = -6384542390323950065L; public static final String QUERY_ITEM = "queryItem"; /** The type of comparison : equal, greater, lower, different... */ private AbstractComparison<C1,C2> comparison; /** The object that specifies the type of description element and the value * wanted * i.e. : type = id * value = PersonNamePresence */ private AbstractElement<?,C1,C2> elementToMatch; /** * Creates a RuleQueryItem */ private RuleQueryItem(AbstractElement<?,C1,C2> element, AbstractComparison<C1,C2> comparison) { this.elementToMatch = element; this.comparison = comparison; // System.out.println("QueryItem this.hashCode(): " + this.hashCode()); // System.out.println("QueryItem comparison: " + comparison); // System.out.println("QueryItem elementToMatch: " + elementToMatch); } /** * Creates a RuleQueryItem with {@link Equal} as the comparator. * @param element */ private RuleQueryItem(AbstractElement<?,C1,C2> element) { this(element, element.getDefaultComparison()); } /** * Convenience method to instantiate without knowing the generics parameters beforehand. * @param <C1> * @param <C2> * @param element * @return */ public static <C1,C2> RuleQueryItem<C1,C2> instance(AbstractElement<?,C1,C2> element, AbstractComparison<C1,C2> comparison) { return new RuleQueryItem<C1,C2>(element, comparison); } public static <C1,C2> RuleQueryItem<C1,C2> instance(AbstractElement<?,C1,C2> element) { return new RuleQueryItem<C1,C2>(element); } /** * Searches for ComponentDescription in the dataModel that satisfies this RuleQueryItem. * Seems to be mainly called by {@link DiscovererMediator#rawSearch(AbstractQueryItem<)} * * TODO: should this method actually be in AbstractDataModel? * @see DiscovererMediator * @param dataModel AbstractDataModel passed from DiscovererMediator * @return */ @SuppressWarnings("unchecked") @Override public Collection<ComponentDescription> search(AbstractDataModel dataModel) { Collection<ComponentDescription> selectedComponents = new ArrayList<ComponentDescription>(); IndexTable<?> indexTable = dataModel.getIndexTable(elementToMatch.getElementName()); // System.out.println("QueryItem.process dataModel: " + dataModel); // System.out.println("QueryItem.process elementToMatch: " + elementToMatch); // System.out.println("QueryItem.process elementToMatch.getElementName(): " + elementToMatch.getElementName()); // System.out.println("QueryItem.process table: " + table); if (indexTable == null) { System.err.println("indexTable == null; elementToMatch.getElementName() = " + elementToMatch.getElementName()); return selectedComponents; // empty } C2 toMatch = elementToMatch.getValue(); for (Object elementAsKey : indexTable.keySet()) { // System.out.print("elementAsKey("+elementAsKey.getClass().getSimpleName()+") = " + elementAsKey + ", toMatch("+toMatch.getClass().getSimpleName()+") = " + toMatch); // System.out.print(": " + comparison); // System.out.println(" = " + comparison.compare((C1)elementAsKey, toMatch)); if (comparison.compare((C1)elementAsKey, toMatch)) { List<ComponentDescription> components = indexTable.get(elementAsKey); selectedComponents.addAll(components); } } return selectedComponents; } @Override public Boolean match(ComponentDescription component) { Boolean result = false; // if (comparison == null) { // System.out.println("QueryItem elementToMatch: " + elementToMatch); // System.out.println("QueryItem component: " + component); // System.out.println("QueryItem comparison: " + comparison); // } result = elementToMatch.processQueryItem(component, comparison); return result; } public String toString(){ return "QueryItem: " + elementToMatch + " " + comparison; } public static AbstractQueryItem<?,?> fromDataObject(DataObject data) { String c1 = data.getDataObject(AbstractComparison.ABSTRACT_COMPARISON_C1).getValue(); String c2 = data.getDataObject(AbstractComparison.ABSTRACT_COMPARISON_C2).getValue(); try { return fromDataObject(data, Class.forName(c1), Class.forName(c2)); } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } } /** * TODO: is this only used for subscription, and not for polling enactor rules? */ @SuppressWarnings("unchecked") protected static <C1,C2> AbstractQueryItem<C1,C2> fromDataObject(DataObject data, Class<C1> c1, Class<C2> c2) { // AbstractDescriptionElement DataObject doAbsDes = data.getDataObject(AbstractElement.ABSTRACT_DESCRIPTION_ELEMENT); AbstractElement<?,C1,C2> abDes = (AbstractElement<?,C1,C2>) AbstractElement.fromDataObject(doAbsDes); // AbstractComparison AbstractComparison<C1,C2> comp = AbstractComparison.fromDataObject(data, c1,c2); return new RuleQueryItem<C1,C2>(abDes, comp); } /** * */ @Override public DataObject toDataObject() { DataObject absEl = elementToMatch.toDataObject(); DataObject comp = comparison.toDataObject(); DataObjects v = new DataObjects(); v.add (absEl); v.add (comp); DataObject doj = new DataObject(QUERY_ITEM, v); // new RuntimeException("doj = " + doj).printStackTrace(); return doj; } public AbstractElement<?,C1,C2> getElementToMatch() { return elementToMatch; } public AbstractComparison<C1,C2> getComparison() { return comparison; } }//class end