/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source: /cvsroot/slrp/glitter/com.ibm.adtech.glitter/src/com/ibm/adtech/glitter/rdf/Triple.java,v $ * Created by: Lee Feigenbaum (<a href="mailto:feigenbl@us.ibm.com">feigenbl@us.ibm.com</a>) * Created on: 10/23/06 * Revision: $Id: Triple.java 164 2007-07-31 14:11:09Z mroy $ * * Contributors: IBM Corporation - initial API and implementation * Cambridge Semantics Incorporated - Fork to Anzo *******************************************************************************/ package org.openanzo.rdf; import org.apache.commons.lang.builder.CompareToBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.openanzo.glitter.query.PatternSolution; import org.openanzo.glitter.query.PatternSolutionImpl; /** * A {@link Statement} is either a {@link TriplePattern} or a quad without any variables. * * @author lee <lee@cambridgesemantics.com> * */ public class Statement extends TriplePattern implements Comparable<Statement> { private static final long serialVersionUID = -8405680742581917240L; private final Value namedGraphUri; private int hashCode = -1; /** * Construct a triple from three {@link Value}s. * * @param subject * @param predicate * @param object */ public Statement(Resource subject, URI predicate, Value object) { super(subject, predicate, object); this.namedGraphUri = null; } /** * Create a statement quad * * @param subject * @param predicate * @param object * @param namedGraphUri */ public Statement(Resource subject, URI predicate, Value object, URI namedGraphUri) { super(subject, predicate, object); this.namedGraphUri = namedGraphUri; } @Override public Resource getSubject() { return (Resource) subject; } @Override public URI getPredicate() { return (URI) predicate; } @Override public Value getObject() { return (Value) object; } /** * Get namedgraphURI of statement * * @return namedGraphUri */ public URI getNamedGraphUri() { return (URI) namedGraphUri; } /** * Determines whether this triple entails the given {@link TriplePattern}, and if so, what bindings are necessary to make that so. (This is effectively * subgraph matching.) entails it * * @param other * The {@link TriplePattern} that may contain {@link Bindable}s to be bound in defining the entailment relationship. * @return A {@link PatternSolution} that, when applied to <tt>other</tt> results in this {@link Statement}. If this triple does not entail <tt>other</tt>, * then <tt>null</tt> is returned. */ public PatternSolution entails(TriplePattern other) { PatternSolutionImpl sol = new PatternSolutionImpl(); TriplePatternComponent otherS = other.getSubject(), otherP = other.getPredicate(), otherO = other.getObject(); TriplePatternComponent[][] pairs = new TriplePatternComponent[][] { new TriplePatternComponent[] { this.subject, otherS }, new TriplePatternComponent[] { this.predicate, otherP }, new TriplePatternComponent[] { this.object, otherO } }; for (int i = 0; i < pairs.length; i++) { Value us = (Value) pairs[i][0]; TriplePatternComponent them = pairs[i][1]; // if we're a bindable object, then we need to bind us as long // as we're not already bound to something else if (them instanceof Bindable) { Value existing = sol.getBinding((Bindable) them); if (existing != null && !existing.equals(us)) return null; sol.setBinding((Bindable) them, us); } else if (!(them.equals(us))) { // a non-bindable object only entails itself return null; } } return sol; } @Override public boolean equals(Object other) { if (!(other instanceof Statement)) return false; if (hashCode() == other.hashCode()) { Statement otherStmt = (Statement) other; if (this.namedGraphUri != null && otherStmt.namedGraphUri != null) { if (!this.namedGraphUri.equals(otherStmt.namedGraphUri)) return false; } return super.equals(other); } else { return false; } } public int compareTo(Statement o) { CompareToBuilder builder = new CompareToBuilder(); builder.append(getNamedGraphUri() != null ? getNamedGraphUri() : null, o.getNamedGraphUri() != null ? o.getNamedGraphUri() : null); builder.append(getSubject(), o.getSubject()); builder.append(getPredicate(), o.getPredicate()); builder.append(getObject(), o.getObject()); return builder.toComparison(); } @Override public int hashCode() { if (hashCode == -1) { if (namedGraphUri == null) hashCode = super.hashCode(); else { HashCodeBuilder builder = new HashCodeBuilder(); builder.append(this.subject); builder.append(this.predicate); builder.append(this.object); builder.append(this.namedGraphUri); hashCode = builder.toHashCode(); } } return hashCode; } @Override public String toString() { String str = toPatternString(this.subject) + " " + toPatternString(this.predicate) + " " + toPatternString(this.object) + " " + toPatternString(this.namedGraphUri); return str; } }