blob: 59ff551d0d3354041a838981e78fe35d5d7f5538 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.enhanced;
import org.apache.jena.graph.* ;
import org.apache.jena.rdf.model.* ;
/**
* <p>
* A specialisation of Polymorphic that models an extended node in a an extended graph. An extended node
* wraps a normal node, and adds additional convenience access or user affordances, though the state
* remains in the graph itself.
* </p>
*/
public class EnhNode extends Polymorphic<RDFNode> implements FrontsNode
{
/** The graph node that this enhanced node is wrapping */
final protected Node node;
/** The enhanced graph containing this node */
final protected EnhGraph enhGraph;
public EnhNode( Node n, EnhGraph g ) {
super();
node=n;
enhGraph = g;
}
// External interface
/**
* Answer the graph node that this enhanced node wraps
* @return A plain node
*/
@Override
public Node asNode() {
return node;
}
/**
* Answer the graph containing this node
* @return An enhanced graph
*/
public EnhGraph getGraph() {
return enhGraph;
}
/**
An enhanced node is Anon[ymous] iff its underlying node is Blank.
*/
public final boolean isAnon() {
return node.isBlank();
}
/**
An enhanced node is Literal iff its underlying node is too.
*/
public final boolean isLiteral() {
return node.isLiteral();
}
/**
An enhanced node is a URI resource iff its underlying node is too.
*/
public final boolean isURIResource() {
return node.isURI();
}
/**
An enhanced node is a statement resource iff its underlying node is a triple term (RDF-star).
*/
public final boolean isStmtResource() {
return node.isNodeTriple();
}
/**
An enhanced node is a resource if it's node is a URI node, a blank node or a triple term.
*/
public final boolean isResource() {
return node.isURI() || node.isBlank() || node.isNodeTriple();
}
/**
* Answer a facet of this node, where that facet is denoted by the
* given type.
*
* @param t A type denoting the desired facet of the underlying node
* @return An enhanced nodet that corresponds to t; this may be <i>this</i>
* Java object, or a different object.
*/
public <X extends RDFNode> X viewAs( Class<X> t ) {
return asInternal( t );
}
/** allow subclasses to implement RDFNode &amp; its subinterface */
public <T extends RDFNode> T as( Class<T> t )
{ return asInternal( t ); }
/**
API-level method for polymorphic testing
*/
public <X extends RDFNode> boolean canAs( Class<X> t )
{ return canSupport( t ); }
/**
* The hash code of an enhanced node is defined to be the same as the underlying node.
* @return The hashcode as an int
*/
@Override final public int hashCode() {
return node.hashCode();
}
/**
* An enhanced node is equal to another enhanced node n iff the underlying
* nodes are equal. We generalise to allow the other object to be any class
* implementing asNode, because we allow other implemementations of
* Resource than EnhNodes, at least in principle.
* This is deemed to be a complete and correct interpretation of enhanced node
* equality, which is why this method has been marked final.
*
* @param o An object to test for equality with this node
* @return True if o is equal to this node.
*/
@Override final public boolean equals( Object o )
{ return o instanceof FrontsNode && node.equals(((FrontsNode) o).asNode()); }
@Override public boolean isValid()
{ return true; }
/**
Answer an new enhanced node object that presents <i>this</i> in a way
which satisfies type <code>t</code>. The new object is linked into this
object's sibling ring. If the node cannot be converted, throw an
UnsupportedPolymorphismException.
*/
@Override protected <X extends RDFNode> X convertTo( Class<X> t )
{
EnhGraph eg = getGraph();
if (eg == null) throw new UnsupportedPolymorphismException( this, false, t );
Implementation imp = getPersonality().getImplementation( t );
if (imp == null) throw new UnsupportedPolymorphismException( this, true, t );
EnhNode result = imp.wrap( asNode(), eg );
this.addView( result );
return t.cast( result );
}
/**
answer true iff this enhanced node can support the class <code>t</code>,
ie it is already a value <code>t</code> or it can be reimplemented
as a <code>t</code> via the graph's personality's implementation.
If this node has no graph, answer false.
*/
@Override protected <X extends RDFNode> boolean canSupport( Class<X> t )
{
if (alreadyHasView( t )) return true;
if (getGraph() == null) return false;
Implementation imp = getPersonality().getImplementation( t );
return imp == null ? false : imp.canWrap( asNode(), getGraph() );
}
/**
* Answer the personality object bound to this enhanced node, which we obtain from
* the associated enhanced graph.
*
* @return The personality object
*/
@Override protected Personality<RDFNode> getPersonality() {
return getGraph().getPersonality();
}
}