📄 compareto.java
字号:
/* Sesame - Storage and Querying architecture for RDF and RDF Schema * Copyright (C) 2001-2005 Aduna * * Contact: * Aduna * Prinses Julianaplein 14 b * 3817 CS Amersfoort * The Netherlands * tel. +33 (0)33 465 99 87 * fax. +33 (0)33 465 99 87 * * http://aduna.biz/ * http://www.openrdf.org/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package org.openrdf.sesame.query.rql.model;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import org.openrdf.model.Literal;import org.openrdf.model.Resource;import org.openrdf.model.Value;import org.openrdf.sesame.query.QueryEvaluationException;import org.openrdf.sesame.sail.RdfSchemaSource;import org.openrdf.sesame.sail.StatementIterator;import org.openrdf.sesame.sail.ValueIterator;/** * Comparison operators on various types of operands. */public class CompareTo implements BooleanQuery { /*-------------------------------------------+ | Constants | +-------------------------------------------*/ /** Lower Than * */ public static final int LT = 0; /** Lower or Equal * */ public static final int LE = 1; /** EQual * */ public static final int EQ = 2; /** Larger or Equal * */ public static final int GE = 3; /** Larger Than * */ public static final int GT = 4; /** Not Equal * */ public static final int NE = 5; /*-------------------------------------------+ | Variables | +-------------------------------------------*/ protected ResourceQuery _arg1; protected ResourceQuery _arg2; protected int _operator; protected RdfSchemaSource _rss; /*-------------------------------------------+ | Constructors | +-------------------------------------------*/ public CompareTo(ResourceQuery arg1, int op, ResourceQuery arg2) { _arg1 = arg1; _arg2 = arg2; if (op < LT || op > NE) { throw new RuntimeException("Illegal operator: " + op); } _operator = op; } /*-------------------------------------------+ | Methods | +-------------------------------------------*/ public ResourceQuery getArg1() { return _arg1; } public ResourceQuery getArg2() { return _arg2; } public int getOperator() { return _operator; } /** * Determines what the boolean value of the comparison operator is. Possible * comparisons are <, <=, =, >, >=, !=. When incompatible * datatypes are compared, all comparisons (except !=) evaluate to * <code>false</code>. * * @throws QueryEvaluationException * is thrown when the comparison is between a set and a single * element, or when a variable has no assigned value. * @param rss * the repository abstraction layer on which the query needs to be * evaluated. * @return <code>true</code> when the selected comparison operator * evaluates to <code>true</code>,<code>false</code> otherwise. */ public boolean isTrue(RdfSchemaSource rss) throws QueryEvaluationException { boolean result = false; _rss = rss; ValueIterator iter1, iter2; // First check whether both arguments are initialized iter1 = _arg1.getResources(_rss); if (iter1 == null) { throw new QueryEvaluationException(_arg1.toString() + " has no assigned value. "); } else if (!iter1.hasNext()) { return false; } iter2 = _arg2.getResources(_rss); if (iter2 == null) { iter1.close(); throw new QueryEvaluationException(_arg2.toString() + " has no assigned value. "); } else if (!iter2.hasNext()) { return false; } // Then Check what we're comparing (sets, elements, ...) // Cannot compare a set and a single element: if (_arg1.returnsSet() != _arg2.returnsSet()) { iter1.close(); iter2.close(); throw new QueryEvaluationException( "Cannot compare a set with a single element: " + this.toString()); } if (_arg1.returnsSet()) { // set comparison result = _compareSets(iter1, iter2); iter1.close(); iter2.close(); } else { // Element comparison Value val1 = iter1.next(); Value val2 = iter2.next(); iter1.close(); iter2.close(); result = _compareElements(val1, val2); } return result; } /*----------------------------------------+ | Methods for comparing elements | +----------------------------------------*/ protected boolean _compareElements(Value val1, Value val2) { boolean result = false; if (val1 instanceof Intersection || val2 instanceof Intersection) { result = _compareIntersections(val1, val2); } else if (_arg1 instanceof ClassQuery && _arg2 instanceof ClassQuery) { result = _compareClasses((Resource)val1, (Resource)val2); } else if (_arg1 instanceof PropertyQuery && _arg2 instanceof PropertyQuery) { result = _compareProperties((Resource)val1, (Resource)val2); } else if (_arg1 instanceof RealConstant || _arg2 instanceof RealConstant) { try { result = _compareReals((Literal)val1, (Literal)val2); } catch (QueryEvaluationException ignore) { // incompatible type comparison. simply ignore and return // false. } } else if (_arg1 instanceof IntegerConstant || _arg2 instanceof IntegerConstant) { try { result = _compareIntegers((Literal)val1, (Literal)val2); } catch (QueryEvaluationException ignore) { // incompatible type comparison. simply ignore and return // false. } } else if (val1 instanceof Literal && val2 instanceof Literal) { result = _compareLiterals((Literal)val1, (Literal)val2); } else if (val1 instanceof Resource && val2 instanceof Resource) { result = _compareUris((Resource)val1, (Resource)val2); } // else return false return result; } protected boolean _compareClasses(Resource class1, Resource class2) { switch (_operator) { case LT: return _rss.isSubClassOf(class1, class2); case LE: return class1.equals(class2) || _rss.isSubClassOf(class1, class2); case EQ: return class1.equals(class2); case GE: return class1.equals(class2) || _rss.isSubClassOf(class2, class1); case GT: return _rss.isSubClassOf(class2, class1); case NE: return !class1.equals(class2); } return false; } protected boolean _compareProperties(Resource prop1, Resource prop2) { switch (_operator) { case LT: return _rss.isSubPropertyOf(prop1, prop2); case LE: return prop1.equals(prop2) || _rss.isSubPropertyOf(prop1, prop2); case EQ: return prop1.equals(prop2); case GE: return prop1.equals(prop2) || _rss.isSubPropertyOf(prop2, prop1); case GT: return _rss.isSubPropertyOf(prop2, prop1); case NE: return !prop1.equals(prop2); } return false; } protected boolean _compareReals(Literal arg1, Literal arg2) throws QueryEvaluationException { try { float floatVal1 = Float.parseFloat(arg1.getLabel()); float floatVal2 = Float.parseFloat(arg2.getLabel()); switch (_operator) { case LT: return floatVal1 < floatVal2; case LE: return floatVal1 <= floatVal2; case EQ: return floatVal1 == floatVal2; case GE: return floatVal1 >= floatVal2; case GT: return floatVal1 > floatVal2; case NE: return floatVal1 != floatVal2; } } catch (NumberFormatException nfe) { throw new QueryEvaluationException("argument not a float"); } return false; } protected boolean _compareIntegers(Literal arg1, Literal arg2) throws QueryEvaluationException { try { int intVal1 = Integer.parseInt(arg1.getLabel()); int intVal2 = Integer.parseInt(arg2.getLabel()); switch (_operator) { case LT: return intVal1 < intVal2; case LE: return intVal1 <= intVal2; case EQ: return intVal1 == intVal2; case GE: return intVal1 >= intVal2; case GT: return intVal1 > intVal2; case NE: return intVal1 != intVal2; } } catch (NumberFormatException nfe) { throw new QueryEvaluationException("argument not an integer"); } return false; } protected boolean _compareLiterals(Literal lit1, Literal lit2) { try { // try coercing both arguments to integer return _compareIntegers(lit1, lit2); } catch (QueryEvaluationException notAnInteger) { try { // try coercing both arguments to floating point numbers return _compareReals(lit1, lit2); } catch (QueryEvaluationException notAReal) { // coercing to numbers failed, do lexical comparison switch (_operator) { case LT: return lit1.compareTo(lit2) < 0; case LE: return lit1.compareTo(lit2) <= 0; case EQ: return lit1.compareTo(lit2) == 0; case GE: return lit1.compareTo(lit2) >= 0; case GT: return lit1.compareTo(lit2) > 0; case NE: return lit1.compareTo(lit2) != 0; } } } return false; } protected boolean _compareUris(Resource uri1, Resource uri2) { switch (_operator) { case EQ: return uri1.equals(uri2); case NE: return !uri1.equals(uri2); } return false; } /*----------------------------------------+ | Methods for comparing sets | +----------------------------------------*/ protected boolean _compareSets(ValueIterator iter1, ValueIterator iter2) throws QueryEvaluationException { // first read all values and add them to a set Set set1 = new HashSet(); while (iter1.hasNext()) { set1.add(iter1.next()); } Set set2 = new HashSet(); while (iter2.hasNext()) { set2.add(iter2.next()); } // Then compare these sets switch (_operator) { case LT: return set1.size() < set2.size() && set2.containsAll(set1); case LE: return set2.containsAll(set1); case EQ: return set1.equals(set2); case GE: return set1.containsAll(set2); case GT: return set1.size() > set2.size() && set1.containsAll(set2); case NE: return !set1.equals(set2); } return false; } protected boolean _compareIntersections(Value val1, Value val2) { Set set1, set2; if (val1 instanceof Intersection) { set1 = ((Intersection)val1).getMembers(); } else { set1 = new HashSet(); set1.add(val1); } if (val2 instanceof Intersection) { set2 = ((Intersection)val2).getMembers(); } else { set2 = new HashSet(); set2.add(val2); } switch (_operator) { case LT: return _intersectionLowerThan(set1, set2); case LE: return _intersectionLowerEqualThan(set1, set2); case EQ: return _intersectionEqualTo(set1, set2); case GE: return _intersectionGreaterEqualThan(set1, set2); case GT: return _intersectionGreaterThan(set1, set2); case NE: return !_intersectionEqualTo(set1, set2); } return false; } protected boolean _intersectionEqualTo(Set set1, Set set2) { return set1.equals(set2); } protected boolean _intersectionLowerEqualThan(Set set1, Set set2) { // if set2 is a subset of (or equal to) set1, then set1 is more // (or equally) constrained and therefore a larger (or equal) // domain/range. if (set1.containsAll(set2)) { return true; } // we need to check all classes that are in set2 but not in set1; // possibly set1 contains subclasses of these classes. Set difference = new HashSet(set2); difference.removeAll(set1); Resource classResource, subClass; StatementIterator subClassIter; boolean subClassInSet; Iterator diffIter = difference.iterator(); // for each class in the difference, a subclass has to be present // in set1. while (diffIter.hasNext()) { subClassInSet = false; classResource = (Resource)diffIter.next(); subClassIter = _rss.getSubClassOf(null, classResource); // while we have not found a subclass of this class in set1, // we keep on checking. while (!subClassInSet && subClassIter.hasNext()) { subClass = subClassIter.next().getSubject(); if (set1.contains(subClass)) { subClassInSet = true; } } subClassIter.close(); if (!subClassInSet) { // there is a class in set2 that has no subclass in set1. return false; } } // all classes in set2 are also in set1, or a subclass of them is // in set1. return true; } protected boolean _intersectionLowerThan(Set set1, Set set2) { return ((!_intersectionEqualTo(set1, set2)) && _intersectionLowerEqualThan( set1, set2)); } protected boolean _intersectionGreaterEqualThan(Set set1, Set set2) { return _intersectionLowerEqualThan(set2, set1); } protected boolean _intersectionGreaterThan(Set set1, Set set2) { return _intersectionLowerThan(set2, set1); } public String getQuery() { return this.toString(); } public String toString() { String op = null; switch (_operator) { case LT: op = " < "; break; case LE: op = " <= "; break; case EQ: op = " = "; break; case GE: op = " >= "; break; case GT: op = " > "; break; case NE: op = " != "; break; } return _arg1.toString() + op + _arg2.toString(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -