001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.commons.rdf.api; 019 020import java.util.Objects; 021import java.util.Optional; 022 023/** 024 * A Quad is a statement in a 025 * <a href= "http://www.w3.org/TR/rdf11-concepts/#section-dataset" >RDF-1.1 026 * Dataset</a>, as defined by <a href= 027 * "https://www.w3.org/TR/2014/NOTE-rdf11-datasets-20140225/#quad-semantics" 028 * >RDF-1.1 Concepts and Abstract Syntax</a>, a W3C Working Group Note published 029 * on 25 February 2014. 030 * <p> 031 * A <code>Quad</code> object in Commons RDF is considered 032 * <strong>immutable</strong>, that is, over its life time it will have 033 * consistent behaviour for its {@link #equals(Object)}, and the instances 034 * returned from {@link #getGraphName()}, {@link #getSubject()}, 035 * {@link #getPredicate()}, {@link #getObject()} and {@link #asTriple()} will 036 * have consistent {@link Object#equals(Object)} behaviour. 037 * <p> 038 * Note that <code>Quad</code> methods are not required to return object 039 * identical (<code>==</code>) instances as long as they are equivalent 040 * according to {@link Object#equals(Object)}. Specialisations of 041 * <code>Quad</code> may provide additional methods that are documented to be 042 * mutable. 043 * <p> 044 * <code>Quad</code> methods are <strong>thread-safe</strong>, however 045 * specialisations may provide additional methods that are documented to not be 046 * thread-safe. 047 * <p> 048 * <code>Quad</code>s can be safely used in hashing collections like 049 * {@link java.util.HashSet} and {@link java.util.HashMap}. 050 * <p> 051 * Any <code>Quad</code> can be used interchangeably across Commons RDF 052 * implementations. 053 * 054 * @since 0.3.0-incubating 055 * @see Dataset 056 * @see RDF#createQuad(BlankNodeOrIRI,BlankNodeOrIRI,IRI,RDFTerm) 057 * @see <a href="http://www.w3.org/TR/2014/NOTE-rdf11-datasets-20140225/">RDF 058 * 1.1: On Semantics of RDF Datasets</a> 059 * @see <a href="http://www.w3.org/TR/rdf11-concepts/#section-dataset"> </a> 060 */ 061public interface Quad extends QuadLike<BlankNodeOrIRI> { 062 063 /** 064 * The graph name (graph label) of this quad, if present. 065 * 066 * If {@link Optional#isPresent()}, then the {@link Optional#get()} is 067 * either a {@link BlankNode} or an {@link IRI}, indicating the 068 * <a href="https://www.w3.org/TR/rdf11-concepts/#dfn-named-graph">graph 069 * name</a> of this Quad. If the graph name is not present, e.g. the value 070 * is {@link Optional#empty()}, it indicates that this Quad is in the 071 * <a href="https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph">default 072 * graph</a>. 073 * 074 * @return If {@link Optional#isPresent()}, the graph name 075 * {@link BlankNodeOrIRI} of this quad, otherwise 076 * {@link Optional#empty()}, indicating the default graph. 077 * 078 * @see <a href="https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset">RDF- 079 * 1.1 Dataset</a> 080 */ 081 @Override 082 Optional<BlankNodeOrIRI> getGraphName(); 083 084 /** 085 * The subject of this quad, which may be either a {@link BlankNode} or an 086 * {@link IRI}, which are represented in Commons RDF by the interface 087 * {@link BlankNodeOrIRI}. 088 * 089 * @return The subject {@link BlankNodeOrIRI} of this quad. 090 * @see <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-subject">RDF-1.1 091 * Triple subject</a> 092 */ 093 @Override 094 BlankNodeOrIRI getSubject(); 095 096 /** 097 * The predicate {@link IRI} of this quad. 098 * 099 * @return The predicate {@link IRI} of this quad. 100 * @see <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-predicate">RDF-1.1 101 * Triple predicate</a> 102 */ 103 @Override 104 IRI getPredicate(); 105 106 /** 107 * The object of this quad, which may be either a {@link BlankNode}, an 108 * {@link IRI}, or a {@link Literal}, which are represented in Commons RDF 109 * by the interface {@link RDFTerm}. 110 * 111 * @return The object {@link RDFTerm} of this quad. 112 * @see <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-object">RDF-1.1 113 * Triple object</a> 114 */ 115 @Override 116 RDFTerm getObject(); 117 118 /** 119 * Adapt this Quad to a Triple. 120 * <p> 121 * The returned {@link Triple} will have equivalent values returned from the 122 * methods {@link TripleLike#getSubject()}, 123 * {@link TripleLike#getPredicate()} and {@link TripleLike#getObject()}. 124 * <p> 125 * The returned {@link Triple} MUST NOT be {@link #equals(Object)} to this 126 * {@link Quad}, even if this quad has a default graph 127 * {@link #getGraphName()} value of {@link Optional#empty()}, but MUST 128 * follow the {@link Triple#equals(Object)} semantics. This means that the 129 * following MUST be true: 130 * 131 * <pre> 132 * Quad q1, q2; 133 * if (q1.equals(q2)) { 134 * assert (q1.asTriple().equals(q2.asTriple())); 135 * } else if (q1.asTriple().equals(q2.asTriple())) { 136 * assert (q1.getSubject().equals(q2.getSubject())); 137 * assert (q1.getPredicate().equals(q2.getPredicate())); 138 * assert (q1.getObject().equals(q2.getObject())); 139 * assert (!q1.getGraphName().equals(q2.getGraphName())); 140 * } 141 * </pre> 142 * 143 * The <code>default</code> implementation of this method return a proxy 144 * {@link Triple} instance that keeps a reference to this {@link Quad} to 145 * call the underlying {@link TripleLike} methods, but supplies a 146 * {@link Triple} compatible implementation of {@link Triple#equals(Object)} 147 * and {@link Triple#hashCode()}. Implementations may override this method, 148 * e.g. for a more efficient solution. 149 * 150 * @return A {@link Triple} that contains the same {@link TripleLike} 151 * properties as this Quad. 152 */ 153 default Triple asTriple() { 154 return new Triple() { 155 @Override 156 public BlankNodeOrIRI getSubject() { 157 return Quad.this.getSubject(); 158 } 159 160 @Override 161 public IRI getPredicate() { 162 return Quad.this.getPredicate(); 163 } 164 165 @Override 166 public RDFTerm getObject() { 167 return Quad.this.getObject(); 168 } 169 170 @Override 171 public boolean equals(final Object obj) { 172 if (obj == this) { 173 return true; 174 } 175 if (!(obj instanceof Triple)) { 176 return false; 177 } 178 final Triple other = (Triple) obj; 179 return Objects.equals(getSubject(), other.getSubject()) 180 && Objects.equals(getPredicate(), other.getPredicate()) 181 && Objects.equals(getObject(), other.getObject()); 182 } 183 184 @Override 185 public int hashCode() { 186 return Objects.hash(getSubject(), getPredicate(), getObject()); 187 } 188 }; 189 } 190 191 /** 192 * Check it this Quad is equal to another Quad. 193 * <p> 194 * Two Quads are equal if and only if their {@link #getGraphName()}, 195 * {@link #getSubject()}, {@link #getPredicate()} and {@link #getObject()} 196 * are equal. 197 * </p> 198 * <p> 199 * Implementations MUST also override {@link #hashCode()} so that two equal 200 * Quads produce the same hash code. 201 * </p> 202 * <p> 203 * Note that a {@link Quad} MUST NOT be equal to a {@link Triple}, even if 204 * this Quad's {@link #getGraphName()} is {@link Optional#empty()}. To test 205 * triple-like equivalence, callers can use: 206 * </p> 207 * 208 * <pre> 209 * Quad q1; 210 * Triple t2; 211 * q1.asTriple().equals(t2)); 212 * </pre> 213 * 214 * @param other 215 * Another object 216 * @return true if other is a Quad and is equal to this 217 * @see Object#equals(Object) 218 */ 219 @Override 220 boolean equals(Object other); 221 222 /** 223 * Calculate a hash code for this Quad. 224 * <p> 225 * The returned hash code MUST be equal to the result of 226 * {@link Objects#hash(Object...)} with the arguments {@link #getSubject()}, 227 * {@link #getPredicate()}, {@link #getObject()}, {@link #getGraphName()}. 228 * <p> 229 * This method MUST be implemented in conjunction with 230 * {@link #equals(Object)} so that two equal {@link Quad}s produce the same 231 * hash code. 232 * 233 * @return a hash code value for this Quad. 234 * @see Object#hashCode() 235 * @see Objects#hash(Object...) 236 */ 237 @Override 238 int hashCode(); 239 240}