📄 ontresourceimpl.java
字号:
* @param lang The language we're searching for, assumed non-null.
* @return The literal value that best matches the given language tag, or null if there are no matches
*/
protected String selectLang( StmtIterator stmts, String lang ) {
String found = null;
while (stmts.hasNext()) {
RDFNode n = stmts.nextStatement().getObject();
if (n instanceof Literal) {
Literal l = (Literal) n;
String lLang = l.getLanguage();
// is this a better match?
if (lang.equalsIgnoreCase( lLang )) {
// exact match
found = l.getString();
break;
}
else if (lLang != null && lLang.length() > 1 && lang.equalsIgnoreCase( lLang.substring( 0, 2 ) )) {
// partial match - want EN, found EN-GB
// keep searching in case there's a better
found = l.getString();
}
else if (found == null && lLang == null) {
// found a string with no (i.e. default) language - keep this unless we've got something better
found = l.getString();
}
}
}
stmts.close();
return found;
}
/** Answer true if the desired lang tag matches the target lang tag */
protected boolean langTagMatch( String desired, String target ) {
return (desired == null) ||
(desired.equalsIgnoreCase( target )) ||
(target.length() > desired.length() && desired.equalsIgnoreCase( target.substring( desired.length() ) ));
}
/** Answer the object of a statement with the given property, .as() the given class */
protected Object objectAs( Property p, String name, Class asClass ) {
checkProfile( p, name );
try {
return getRequiredProperty( p ).getObject().as( asClass );
}
catch (PropertyNotFoundException e) {
return null;
}
}
/** Answer the object of a statement with the given property, .as() an OntResource */
protected OntResource objectAsResource( Property p, String name ) {
return (OntResource) objectAs( p, name, OntResource.class );
}
/** Answer the object of a statement with the given property, .as() an OntProperty */
protected OntProperty objectAsProperty( Property p, String name ) {
return (OntProperty) objectAs( p, name, OntProperty.class );
}
/** Answer the int value of a statement with the given property */
protected int objectAsInt( Property p, String name ) {
checkProfile( p, name );
return getRequiredProperty( p ).getInt();
}
/** Answer an iterator for the given property, whose values are .as() some class */
protected ExtendedIterator listAs( Property p, String name, Class cls ) {
checkProfile( p, name );
return WrappedIterator.create( listProperties( p ) ).mapWith( new ObjectAsMapper( cls ) );
}
/** Add the property value, checking that it is supported in the profile */
protected void addPropertyValue( Property p, String name, RDFNode value ) {
checkProfile( p, name );
addProperty( p, value );
}
/** Set the property value, checking that it is supported in the profile */
protected void setPropertyValue( Property p, String name, RDFNode value ) {
checkProfile( p, name );
removeAll( p );
addProperty( p, value );
}
/** Answer true if the given property is defined in the profile, and has the given value */
protected boolean hasPropertyValue( Property p, String name, RDFNode value ) {
checkProfile( p, name );
return hasProperty( p, value );
}
/** Add the given value to a list which is the value of the given property */
protected void addListPropertyValue( Property p, String name, RDFNode value ) {
checkProfile( p, name );
// get the list value
if (hasProperty( p )) {
RDFNode cur = getRequiredProperty( p ).getObject();
if (!cur.canAs( RDFList.class )) {
throw new OntologyException( "Tried to add a value to a list-valued property " + p +
" but the current value is not a list: " + cur );
}
RDFList values = (RDFList) cur.as( RDFList.class );
// now add our value to the list
if (!values.contains( value )){
RDFList newValues = values.with( value );
// if the previous values was nil, the return value will be a new list
if (newValues != values) {
removeAll( p );
addProperty( p, newValues );
}
}
}
else {
// create a new list to hold the only value we know so far
addProperty( p, ((OntModel) getModel()).createList( new RDFNode[] {value} ) );
}
}
/** Convert this resource to the facet denoted by cls, by adding rdf:type type if necessary */
protected RDFNode convertToType( Resource type, String name, Class cls ) {
checkProfile( type, name );
if (canAs( cls )) {
// don't need to update the model, we already can do the given facet
return as( cls );
}
// we're told that adding this rdf:type will make the as() possible - let's see
addProperty( RDF.type, type );
return as( cls );
}
/**
* <p>Return an iterator of values, respecting the 'direct' modifier</p>
* @param p The property whose values are required
* @param name The short name of the property (for generating error messages)
* @param cls Class object denoting the facet to map the returned values to
* @param orderRel If direct, and we are not using an inference engine, this is the property
* to use to define the maximal lower elements of the partial order
* @param direct If true, only return the direct (adjacent) values
* @param inverse If true, use the inverse of p rather than p
* @return An iterator of nodes that are in relation p to this resource (possibly inverted), which
* have been mapped to the facet denoted by cls.
*/
protected ExtendedIterator listDirectPropertyValues( Property p, String name, Class cls, Property orderRel, boolean direct, boolean inverse ) {
Iterator i = null;
checkProfile( p, name );
Property sc = p;
// check for requesting direct versions of these properties
if (direct) {
sc = getModel().getProperty( ReasonerRegistry.makeDirect( sc.asNode() ).getURI() );
}
// determine the subject and object pairs for the list statements calls
Resource subject = inverse ? null : this;
Resource object = inverse ? this : null;
Map1 mapper = inverse ? (Map1) new SubjectAsMapper( cls ) : (Map1) new ObjectAsMapper( cls );
// are we working on an inference graph?
OntModel m = (OntModel) getGraph();
InfGraph ig = null;
if (m.getGraph() instanceof InfGraph) {
ig = (InfGraph) m.getGraph();
}
// can we go direct to the graph?
if (!direct || ((ig != null) && ig.getReasoner().supportsProperty( sc ))) {
// either not direct, or the direct sc property is supported
// ensure we have an extended iterator of statements this rdfs:subClassOf _x
// NB we only want the subjects or objects of the statements
i = getModel().listStatements( subject, sc, object ).mapWith( mapper );
}
else {
i = computeDirectValues( p, orderRel, inverse, subject, object, mapper );
}
return UniqueExtendedIterator.create( i );
}
/**
* <p>In the absence of a reasoner that can compute direct (adjacent) property values,
* we must perform the calculation of the direct values computationally here.</p>
* @param p
* @param orderRel
* @param inverse
* @param subject
* @param object
* @param mapper
* @return
*/
private Iterator computeDirectValues( Property p, Property orderRel, boolean inverse, Resource subject, Resource object, Map1 mapper ) {
// graph does not support direct directly
ExtendedIterator j = getModel().listStatements( subject, p, object )
.mapWith( mapper );
// collect a list of the candidates
List s = new ArrayList();
for( ; j.hasNext(); ) {
s.add( j.next() );
}
// we need to keep this node out of the iterator for now, else it will spoil the maximal
// generator compression (since all the (e.g.) sub-classes will be sub-classes of this node
// and so will be excluded from the maximal lower elements calculation)
ResourceUtils.removeEquiv( s, orderRel, this );
boolean withheld = s.remove( this );
// we now compress the list by reducing all equivalent values to a single representative
// first partition the list by equivalence under orderRel
List partition = ResourceUtils.partition( s, orderRel );
Map equivSets = new HashMap();
// then reduce each part of the partition to a singleton, but remember the others
s.clear();
for (Iterator i = partition.iterator(); i.hasNext(); ) {
List part = (List) i.next();
// if this is a singleton we just add it to the compressed candidates
if (part.size() == 1) {
s.add( part.get(0) );
}
else {
// we select a single representative
Resource r = (Resource) part.remove( 0 );
// remember the other equivalent values
equivSets.put( r, part );
s.add( r );
}
}
// now s1 contains a reduced set of nodes, in which any fully-connected sub-graph under
// orderRel has been reduced to a single representative
// generate the short list as the maximal bound under the given partial order
s = ResourceUtils.maximalLowerElements( s, orderRel, inverse );
// create a list of these values lower elements, plus their equivalents (if any)
List s2 = new ArrayList();
for (Iterator i = s.iterator(); i.hasNext(); ) {
Resource r = (Resource) i.next();
s2.add( r );
if (equivSets.containsKey( r )) {
s2.addAll( (List) equivSets.get( r ) );
}
}
// put myself back if needed
if (withheld) {
s2.add( this );
}
return s2.iterator();
}
/** Remove a specified property-value pair, if it exists */
protected void removePropertyValue( Property prop, String name, RDFNode value ) {
checkProfile( prop, name );
getModel().remove( this, prop, value );
}
/** Answer the given node presenting the OntResource facet if it can */
private static RDFNode asOntResource( RDFNode n ) {
return n.isResource() ? n.as( OntResource.class ) : n;
}
//==============================================================================
// Inner class definitions
//==============================================================================
/** Implementation of Map1 that performs as( Class ) for a given class */
protected static class AsMapper
implements Map1
{
private Class m_as;
public AsMapper( Class as ) { m_as = as; }
public Object map1( Object x ) { return (x instanceof Resource) ? ((Resource) x).as( m_as ) : x; }
}
/** Implementation of Map1 that performs as( Class ) for a given class, on the subject of a statement */
protected static class SubjectAsMapper
implements Map1
{
private Class m_as;
public SubjectAsMapper( Class as ) { m_as = as; }
public Object map1( Object x ) {
if (x instanceof Statement) {
RDFNode subj = ((Statement) x).getSubject();
return (m_as == null) ? subj : subj.as( m_as );
}
else {
return x;
}
}
}
/** Implementation of Map1 that extracts the subject of a statement */
protected static class SubjectMapper
implements M
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -