package org.neo4j.meta.input.rdfs; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import org.neo4j.meta.model.RdfUtil; import org.ontoware.aifbcommons.collection.ClosableIterator; import org.ontoware.rdf2go.RDF2Go; import org.ontoware.rdf2go.model.Model; import org.ontoware.rdf2go.model.Statement; import org.ontoware.rdf2go.model.node.BlankNode; import org.ontoware.rdf2go.model.node.DatatypeLiteral; import org.ontoware.rdf2go.model.node.Literal; import org.ontoware.rdf2go.model.node.Node; import org.ontoware.rdf2go.model.node.Resource; import org.ontoware.rdf2go.model.node.Variable; import org.ontoware.rdf2go.model.node.impl.URIImpl; import org.ontoware.rdf2go.vocabulary.OWL; import org.ontoware.rdf2go.vocabulary.RDF; /** * Some fine helper methods for RDF models. */ abstract class RdfHelper { static String local( String uri ) { int index = uri.lastIndexOf( '#' ); return index == -1 ? uri : uri.substring( index + 1 ); } static String resourceUri( Node node ) { return node.asURI().asJavaURI().toString(); } static String resourceType( Model model, Resource resource ) { Node[] nodes = subNodes( model, resource, RDF.type.toString() ); return nodes.length == 0 ? null : resourceUri( nodes[ 0 ] ); } static String literalDatatype( Model model, Literal literal ) { if ( literal instanceof DatatypeLiteral ) { return literal.asDatatypeLiteral().getDatatype().toString(); } return RdfUtil.NS_XML_SCHEMA + "string"; } static Node[] subNodes( Model model, Resource resource, String predicate ) { ClosableIterator<? extends Statement> itr = model.findStatements( resource, new URIImpl( predicate ), Variable.ANY ); try { ArrayList<Node> result = new ArrayList<Node>(); while ( itr.hasNext() ) { result.add( itr.next().getObject() ); } return result.toArray( new Node[ result.size() ] ); } finally { itr.close(); } } static Node subNode( Model model, Resource resource, String predicate ) { Node[] nodes = subNodes( model, resource, predicate ); if ( nodes.length > 1 ) { throw new RuntimeException( "More than one " + predicate + " for " + resourceUri( resource ) ); } return nodes.length == 0 ? null : nodes[ 0 ]; } static boolean resourceIsType( Model model, Resource resource, String type ) { for ( Node typeNode : subNodes( model, resource, RDF.type.toString() ) ) { if ( smartMatch( resourceUri( typeNode ), type ) ) { return true; } } return false; } static boolean smartMatch( String type1, String type2 ) { if ( type1.equals( type2 ) ) { return true; } if ( isW3Uri( type1 ) && isW3Uri( type2 ) && RdfHelper.local( type1 ).equals( RdfHelper.local( type2 ) ) ) { return true; } return false; } static boolean smartMatchThese( String uri, String... matchWith ) { for ( String match : matchWith ) { if ( smartMatch( uri, match ) ) { return true; } } return false; } static boolean isW3Uri( String uriString ) { try { URI uri = new URI( uriString ); if ( uri.getHost().contains( "www.w3.org" ) ) { return true; } return false; } catch ( URISyntaxException e ) { throw new RuntimeException( e ); } } static String tryGetLiteral( Model model, Resource resource, String predicate ) { Node node = subNode( model, resource, predicate ); if ( node == null ) { return null; } return node instanceof Literal ? ( ( Literal ) node ).getValue() : null; } static Collection<Node> getClassOrUnionOfClasses( Model model, Resource theClassOrUnion ) { Collection<Node> result = null; if ( RdfHelper.resourceIsType( model, theClassOrUnion, OWL.Class.toString() ) && theClassOrUnion instanceof BlankNode ) { // TODO Also support intersectionOf and complementOf result = new ArrayList<Node>(); for ( Node classNode : RdfHelper.subNodes( model, theClassOrUnion, OWL.unionOf.toString() ) ) { result = parseCollection( model, classNode.asResource() ); } } else { result = Arrays.asList( ( Node ) theClassOrUnion ); } return result; } static Node getFirstInCollection( Model model, Resource resource ) { return subNode( model, resource, RDF.first.toString() ); } static Collection<Node> parseCollection( Model model, Resource resourceWhichIsACollection ) { ArrayList<Node> collection = new ArrayList<Node>(); collectFromCollection( model, resourceWhichIsACollection, collection ); return collection; } static void collectFromCollection( Model model, Resource resourceWhichIsACollection, Collection<Node> collection ) { Node firstNode = getFirstInCollection( model, resourceWhichIsACollection ); if ( firstNode != null ) { collection.add( firstNode ); Node restNode = subNode( model, resourceWhichIsACollection, RDF.rest.toString() ); if ( restNode != null && !resourceIsType( model, restNode.asResource(), RDF.nil.toString() ) ) { collectFromCollection( model, restNode.asResource(), collection ); } } } static void printStatementsAbout( Model model, Node node ) { ClosableIterator<? extends Statement> itr = model.findStatements( Variable.ANY, Variable.ANY, node ); printStatements( itr ); if ( node instanceof Resource ) { itr = model.findStatements( node.asResource(), Variable.ANY, Variable.ANY ); printStatements( itr ); } } static void printStatements( ClosableIterator<? extends Statement> itr ) { try { while ( itr.hasNext() ) { printStatement( itr.next() ); } } finally { itr.close(); } } static void printStatement( Statement statement ) { System.out.println( statement.getSubject() + ":" + statement.getPredicate() + ":" + statement.getObject() ); } static Collection<Object> nodesToLiterals( Collection<Node> nodes, String datatype ) { ArrayList<Object> list = new ArrayList<Object>(); for ( Node node : nodes ) { try { String type = datatype != null ? datatype : node.asDatatypeLiteral().getDatatype().toString(); list.add( RdfUtil.getRealValue( type, ( ( Literal ) node ).getValue() ) ); } catch ( ParseException e ) { throw new RuntimeException( e ); } } return list; } static void safeClose( Closeable closeable ) { if ( closeable != null ) { try { closeable.close(); } catch ( IOException e ) { // Yep } } } static Model readModel( File file ) throws IOException { FileInputStream in = null; try { in = new FileInputStream( file ); return readModel( in ); } finally { RdfHelper.safeClose( in ); } } static Model readModel( InputStream stream ) throws IOException { Model model = RDF2Go.getModelFactory().createModel(); model.open(); model.readFrom( stream ); return model; } }