package net.jxta.impl.xindice.core.indexer; /* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xindice" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999-2001, The dbXML * Group, L.L.C., http://www.dbxmlgroup.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ import net.jxta.impl.xindice.core.data.Value; import java.util.Arrays; /** * IndexQuery represents the most primitive form of index querying. * Instances of this object should be created by QueryResolvers and * cached in Query instances. */ public class IndexQuery { // No Operator public static final int ANY = 0; // Any And All Matches // Singleton Operators public static final int EQ = 1; // Equal To public static final int NEQ = -1; // Not Equal To public static final int GT = 2; // Greater Than public static final int LEQ = -2; // Less Than Or Equal To public static final int LT = 3; // Less Than public static final int GEQ = -3; // Greater Than Or Equal To // Range Operators public static final int BW = 4; // Between (Inclusive) public static final int NBW = -4; // Not Between (Inclusive) public static final int BWX = 5; // Between (Exclusive) public static final int NBWX = -5; // Not Between (Exclusive) // Set Operators public static final int IN = 6; // In The Set public static final int NIN = -6; // Not In The Set // Other operators public static final int SW = 7; // Starts-with public static final int NSW = -7; // Not Starts-with public static final int EW = 8; // Ends-with public static final int NEW = -8; // Not Ends-with protected int op; protected Value[] vals; public IndexQuery() { op = ANY; } public IndexQuery(int op, Value[] vals) { this.op = op; this.vals = vals; } public IndexQuery(Value[] vals) { this(IN, vals); } public IndexQuery(int op, Value val1) { this.op = op; if (op == SW || op == NSW) { byte[] b = new byte[val1.getLength() + 1]; System.arraycopy(val1.getData(), 0, b, 0, b.length - 1); b[b.length - 1] = 127; // TODO: Must fix this Value val2 = new Value(b); vals = new Value[] { val1, val2 }; } else { vals = new Value[] { val1 }; } } public IndexQuery(Value val1) { this(EQ, val1); } public IndexQuery(int op, Value val1, Value val2) { this.op = op; vals = new Value[] { val1, val2 }; } public IndexQuery(Value val1, Value val2) { this(IN, val1, val2); } public IndexQuery(int op, String val1) { this(op, new Value(val1)); } public IndexQuery(String val1) { this(new Value(val1)); } public IndexQuery(int op, String val1, String val2) { this(op, new Value(val1), new Value(val2)); } public IndexQuery(String val1, String val2) { this(new Value(val1), new Value(val2)); } /** * getOperator returns the operator associated with this query. * * @return The operator */ public int getOperator() { return op; } /** * getValue returns one of the Values associated with this query. * * @param index The Value index * @return The request Value */ public final Value getValue(int index) { return vals[index]; } /** * getValues returns the Values associated with this query. * * @return The Value set */ public Value[] getValues() { return vals; } /** * getLength returns the length of the Value set associated with * this query. * * @return The Value set length */ public final int getLength() { return vals.length; } /** * testValue tests the specified value for validity against this * IndexQuery. The helper classes in org.apache.xindice.core.indexer.helpers * should be used for optimized performance. * * @param value The Value to compare * @return Whether or not the value matches */ public boolean testValue(Value value) { switch (op) { // No Comparison (Any) case ANY: return true; // Singleton Comparisons case EQ: return value.equals(vals[0]); case NEQ: return !value.equals(vals[0]); case GT: return value.compareTo(vals[0]) > 0; case LEQ: return value.compareTo(vals[0]) <= 0; case LT: return value.compareTo(vals[0]) < 0; case GEQ: return value.compareTo(vals[0]) >= 0; // Range Comparisons case BW: return value.compareTo(vals[0]) >= 0 && value.compareTo(vals[1]) <= 0; case NBW: return value.compareTo(vals[0]) <= 0 || value.compareTo(vals[1]) >= 0; case BWX: return value.compareTo(vals[0]) > 0 && value.compareTo(vals[1]) < 0; case NBWX: return value.compareTo(vals[0]) < 0 || value.compareTo(vals[1]) > 0; // Set Comparisons case IN: case NIN: return Arrays.binarySearch(vals, value) >= 0 ? op == IN : op == NIN; // Other comparisons case SW: case NSW: return value.startsWith(vals[0]) ? op == SW : op == NSW; case EW: case NEW: return value.endsWith(vals[0]) ? op == EW : op == NEW; } return false; } /** * testValue tests the specified value for validity against this * IndexQuery. The helper classes in org.apache.xindice.core.indexer.helpers * should be used for optimized performance. * * @param value The Value to compare * @return Whether or not the value matches */ public final boolean testValue(String value) { return testValue(new Value(value)); } }