/** * Sorts in the order nulls>BNodes>URIs>Literals * * <p>This is due to the fact that nulls are only applicable to contexts, and according to the * OpenRDF documentation, the type of the null cannot be sufficiently distinguished from any other * Value to make an intelligent comparison to other Values * * <p>http://www.openrdf.org/doc/sesame2/api/org/openrdf/OpenRDFUtil.html#verifyContextNotNull(org. * openrdf.model.Resource...) * * <p>BNodes are sorted according to the lexical compare of their identifiers, which provides a * way to sort statements with the same BNodes in the same positions, near each other * * <p>BNode sorting is not specified across sessions */ @Override public int compare(final Value first, final Value second) { if (first == null) { if (second == null) { return ValueComparator.EQUALS; } else { return ValueComparator.BEFORE; } } else if (second == null) { // always sort null Values before others, so if the second is null, but the first // wasn't, sort the first after the second return ValueComparator.AFTER; } if (first == second || first.equals(second)) { return ValueComparator.EQUALS; } if (first instanceof BNode) { if (second instanceof BNode) { // if both are BNodes, sort based on the lexical value of the internal ID // Although this sorting is not guaranteed to be consistent across sessions, // it provides a consistent sorting of statements in every case // so that statements with the same BNode are sorted near each other return ((BNode) first).getID().compareTo(((BNode) second).getID()); } else { return ValueComparator.BEFORE; } } else if (second instanceof BNode) { // sort BNodes before other things, and first was not a BNode return ValueComparator.AFTER; } else if (first instanceof URI) { if (second instanceof URI) { return ((URI) first).stringValue().compareTo(((URI) second).stringValue()); } else { return ValueComparator.BEFORE; } } else if (second instanceof URI) { // sort URIs before Literals return ValueComparator.AFTER; } // they must both be Literal's, so sort based on the lexical value of the Literal else { return first.stringValue().compareTo(second.stringValue()); } }
private void storeStatement(Resource subj, URI pred, Value obj, Resource... contexts) throws SailException { if (subj.equals(currentTrx)) { subj = getTrx(); } if (obj.equals(currentTrx)) { obj = getTrx(); } if (contexts != null && contexts.length == 1) { if (currentTrx.equals(contexts[0])) { contexts[0] = getTrx(); } } else if (contexts != null) { for (int i = 0; i < contexts.length; i++) { if (currentTrx.equals(contexts[i])) { contexts[i] = getTrx(); } } } if (contexts == null || contexts.length == 0 || contexts.length == 1 && contexts[0] == null) { addRevision(subj); super.addStatement(subj, pred, obj, getTrx()); } else if (contexts.length == 1) { if (contexts[0].equals(trx)) { addRevision(subj); } super.addStatement(subj, pred, obj, contexts); Resource ctx = contexts[0]; if (isURI(ctx) && !ctx.equals(trx) && modified.add(ctx)) { addMetadata(currentTrx, MODIFIED, ctx, currentTrx); } } else { for (Resource ctx : contexts) { if (ctx == null || ctx.equals(trx)) { addRevision(subj); break; } } super.addStatement(subj, pred, obj, contexts); for (Resource ctx : contexts) { if (isURI(ctx) && !ctx.equals(trx) && modified.add(ctx)) { addMetadata(currentTrx, MODIFIED, ctx, currentTrx); } } } }
@Override public synchronized void addStatement(Resource subj, URI pred, Value obj, Resource... contexts) throws SailException { flushArchive(); if (subj.equals(currentTrx) || obj.equals(currentTrx) && !Audit.REVISION.equals(pred)) { if (contexts == null) { addMetadata(subj, pred, obj, null); } else if (contexts.length == 1) { addMetadata(subj, pred, obj, contexts[0]); } else { for (Resource ctx : contexts) { addMetadata(subj, pred, obj, ctx); } } } else { storeStatement(subj, pred, obj, contexts); } }
private static boolean statementsMatch( Statement st1, Statement st2, Map<BNode, BNode> bNodeMapping) { URI pred1 = st1.getPredicate(); URI pred2 = st2.getPredicate(); if (!pred1.equals(pred2)) { // predicates don't match return false; } Resource subj1 = st1.getSubject(); Resource subj2 = st2.getSubject(); if (!(subj1 instanceof BNode)) { if (!subj1.equals(subj2)) { // subjects are not bNodes and don't match return false; } } else { // subj1 instanceof BNode BNode mappedBNode = bNodeMapping.get(subj1); if (mappedBNode != null) { // bNode 'subj1' was already mapped to some other bNode if (!subj2.equals(mappedBNode)) { // 'subj1' and 'subj2' do not match return false; } } else { // 'subj1' was not yet mapped. we need to check if 'subj2' is a // possible mapping candidate if (bNodeMapping.containsValue(subj2)) { // 'subj2' is already mapped to some other value. return false; } } } Value obj1 = st1.getObject(); Value obj2 = st2.getObject(); if (!(obj1 instanceof BNode)) { if (!obj1.equals(obj2)) { // objects are not bNodes and don't match return false; } } else { // obj1 instanceof BNode BNode mappedBNode = bNodeMapping.get(obj1); if (mappedBNode != null) { // bNode 'obj1' was already mapped to some other bNode if (!obj2.equals(mappedBNode)) { // 'obj1' and 'obj2' do not match return false; } } else { // 'obj1' was not yet mapped. we need to check if 'obj2' is a // possible mapping candidate if (bNodeMapping.containsValue(obj2)) { // 'obj2' is already mapped to some other value. return false; } } } return true; }
/** Copied from org.openrdf.query.QueryResultUtil */ private static boolean bindingSetsMatch(final BindingSet bs1, final BindingSet bs2) { if (bs1.size() != bs2.size()) { return false; } for (Binding binding1 : bs1) { Value value1 = binding1.getValue(); Value value2 = bs2.getValue(binding1.getName()); if ((value1 instanceof BNode) && (value2 instanceof BNode)) { // BNode mappedBNode = bNodeMapping.get(value1); // // if (mappedBNode != null) { // // bNode 'value1' was already mapped to some other bNode // if (!value2.equals(mappedBNode)) { // // 'value1' and 'value2' do not match // return false; // } // } else { // // 'value1' was not yet mapped, we need to check if 'value2' // // is a // // possible mapping candidate // if (bNodeMapping.containsValue(value2)) { // // 'value2' is already mapped to some other value. // return false; // } // } return value1.equals(value2); } else { // values are not (both) bNodes if ((value1 instanceof Literal) && (value2 instanceof Literal)) { // do literal value-based comparison for supported datatypes Literal leftLit = (Literal) value1; Literal rightLit = (Literal) value2; URI dt1 = leftLit.getDatatype(); URI dt2 = rightLit.getDatatype(); if ((dt1 != null) && (dt2 != null) && dt1.equals(dt2) && XMLDatatypeUtil.isValidValue(leftLit.getLabel(), dt1) && XMLDatatypeUtil.isValidValue(rightLit.getLabel(), dt2)) { Integer compareResult = null; if (dt1.equals(XMLSchema.DOUBLE)) { compareResult = Double.compare(leftLit.doubleValue(), rightLit.doubleValue()); } else if (dt1.equals(XMLSchema.FLOAT)) { compareResult = Float.compare(leftLit.floatValue(), rightLit.floatValue()); } else if (dt1.equals(XMLSchema.DECIMAL)) { compareResult = leftLit.decimalValue().compareTo(rightLit.decimalValue()); } else if (XMLDatatypeUtil.isIntegerDatatype(dt1)) { compareResult = leftLit.integerValue().compareTo(rightLit.integerValue()); } else if (dt1.equals(XMLSchema.BOOLEAN)) { Boolean leftBool = Boolean.valueOf(leftLit.booleanValue()); Boolean rightBool = Boolean.valueOf(rightLit.booleanValue()); compareResult = leftBool.compareTo(rightBool); } else if (XMLDatatypeUtil.isCalendarDatatype(dt1)) { XMLGregorianCalendar left = leftLit.calendarValue(); XMLGregorianCalendar right = rightLit.calendarValue(); compareResult = left.compare(right); } if (compareResult != null) { if (compareResult.intValue() != 0) { return false; } } else if (!value1.equals(value2)) { return false; } } else if (!value1.equals(value2)) { return false; } } else if (!value1.equals(value2)) { return false; } } } return true; }