Package org.apache.clerezza.rdf.schemagen

Source Code of org.apache.clerezza.rdf.schemagen.SchemaGen$RDF

/*
* 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.clerezza.rdf.schemagen;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.clerezza.rdf.core.BNode;
import org.apache.clerezza.rdf.core.Graph;
import org.apache.clerezza.rdf.core.Literal;
import org.apache.clerezza.rdf.core.MGraph;
import org.apache.clerezza.rdf.core.NonLiteral;
import org.apache.clerezza.rdf.core.Resource;
import org.apache.clerezza.rdf.core.Triple;
import org.apache.clerezza.rdf.core.UriRef;
import org.apache.clerezza.rdf.core.impl.SimpleMGraph;
import org.apache.clerezza.rdf.core.serializedform.Parser;
import org.wymiwyg.commons.util.arguments.AnnotatedInterfaceArguments;
import org.wymiwyg.commons.util.arguments.ArgumentHandler;
import org.wymiwyg.commons.util.arguments.InvalidArgumentsException;

/**
* Generates the source code of a java-class with constants for an ontology
* described in RDF
*
* @author reto
*/
public class SchemaGen {

  public static void main(String... args) throws Exception {
    SchemaGenArguments arguments;
    try {
      arguments = new ArgumentHandler(args).getInstance(SchemaGenArguments.class);
    } catch (InvalidArgumentsException e) {
      System.out.println(e.getMessage());
      System.out.print("Usage: SchemaGen ");
      System.out.println(AnnotatedInterfaceArguments.getArgumentsSyntax(SchemaGenArguments.class));
      PrintWriter out = new PrintWriter(System.out, true);
      AnnotatedInterfaceArguments.printArgumentDescriptions(
          SchemaGenArguments.class, out);
      out.flush();
      return;
    }

    SchemaGen schemaGen = new SchemaGen(arguments);
    PrintWriter out = new PrintWriter(System.out);
    schemaGen.writeClass(out);
    out.flush();
  }
  private final Graph schemaGraph;
  private final String className;
  private final String namespace;

  /**
   * Creates an instance doing the transformation as specified by the
   * arguments.
   * @param arguments  specification of the transformation
   * @throws IOException  If an IO error occurs.
   */
  public SchemaGen(SchemaGenArguments arguments)
      throws IOException, URISyntaxException {
    Parser parser = Parser.getInstance();
    InputStream serializedGraph = arguments.getSchemaUrl().openStream();
    schemaGraph = parser.parse(serializedGraph,
        arguments.getFormatIdentifier());
    className = arguments.getClassName();

    if (arguments.getNamespace() == null) {
      namespace = getOntologyUri();
    } else {
      namespace = arguments.getNamespace();
    }
  }

  private String getOntologyUri() {
    Iterator<Triple> ontologyTriples = schemaGraph.filter(null, RDF.type, OWL.Ontology);
    String result;
    if(ontologyTriples.hasNext()) {
      result = ((UriRef) ontologyTriples.next().getSubject()).getUnicodeString();
    } else {
      throw new RuntimeException("No OWL Ontology found!");
    }
    if(ontologyTriples.hasNext()) {
      throw new RuntimeException("More than one OWL Ontology found!");
    }
    return result;
  }

  /**
   * Writes the generated source code of a java class to the specified
   * print writer.
   * @param out  The print writer to write the transformation to.
   * @throws IllegalArgumentException  If out is <code>null</code>.
   */
  public void writeClass(PrintWriter out) {
    if (out == null) {
      throw new IllegalArgumentException("Invalid out: out");
    }
    out.print("// Generated by ");
    out.println(getClass().getName());
    String packageName = getPackageName();
    if (packageName != null) {
      out.print("package ");
      out.print(packageName);
      out.println(';');
    }
    out.println();
    out.println("import org.apache.clerezza.rdf.core.UriRef;");
    out.println();
    out.print("public class ");
    out.print(getSimpleName());
    out.println(" {");

    SortedSet<OntologyResource> ontClasses = new TreeSet<OntologyResource>();
    ontClasses.addAll(getResourcesOfType(RDFS.Class));
    ontClasses.addAll(getResourcesOfType(RDFS.Datatype));
    ontClasses.addAll(getResourcesOfType(OWL.Class));



    if (ontClasses.size() > 0) {
      out.println("\t// Classes");
      printResources(ontClasses.iterator(), out);
    }
    SortedSet<OntologyResource> ontProperties = new TreeSet<OntologyResource>();
    //some ontologies defining things that are both classes
    //and properties, like image in RSS 1.0 - so we remove those
    ontProperties.addAll(getResourcesOfType(RDF.Property,ontClasses));
    ontProperties.addAll(getResourcesOfType( OWL.ObjectProperty,ontClasses));
    ontProperties.addAll(getResourcesOfType(OWL.DatatypeProperty,ontClasses));

    if (ontProperties.size() > 0) {
      out.println();
      out.println("\t// Properties");
      printResources(ontProperties.iterator(), out);
    }

    //create a set of classes and properties. Everything else should be instances
    ontClasses.addAll(ontProperties);
    Collection<OntologyResource> instances = getResourcesOfType(null, ontClasses);

    if (instances.size() > 0) {
      out.println();
      out.println("\t// Properties");
      printResources(instances.iterator(), out);
    }

    out.println("}");
  }

  private void printResources(Iterator<OntologyResource> iterator,
      PrintWriter out) {
    while (iterator.hasNext()) {
      OntologyResource ontologyResource = iterator.next();
      String description = ontologyResource.getDescription();
      if (description != null) {
        out.println();
        out.println("\t/**");
        out.print("\t * ");
        out.println(description);
        out.println("\t */");
      }
      out.print("\tpublic static final UriRef ");
      out.print(ontologyResource.getLocalName());
      out.print(" = new UriRef(\"");
      out.print(ontologyResource.getUriString());
      out.println("\");");
    }

  }

  private Collection<OntologyResource> getResourcesOfType(UriRef type) {
     return getResourcesOfType(type, null);
  }

  /**
   *
   * @param type the type of the class, or null for all things that are declared to be of a type
   * @param ignore a set things to ignore
   * @return
   */
  private Collection<OntologyResource> getResourcesOfType(UriRef type, Collection<OntologyResource> ignore) {
    Set<OntologyResource> result = new HashSet<OntologyResource>();
    Iterator<Triple> classStatemente = schemaGraph.filter(null, RDF.type,
        type);
    while (classStatemente.hasNext()) {
      Triple triple = classStatemente.next();
      NonLiteral classResource = triple.getSubject();
      if (classResource instanceof BNode) {
        if (type !=null) System.err.println("Ignoring anonymous resource of type " + type.getUnicodeString());
        else System.err.println("Ignoring anonymous resource");
        for (Triple contextTriple : getNodeContext(classResource, schemaGraph)) {
          System.err.println(contextTriple);
        }
        continue;
      }

      // Test if the given resource belongs to the ontology
      final UriRef classUri = (UriRef) classResource;
      final String strClassUri = classUri.getUnicodeString();
      if (strClassUri.startsWith(namespace)) {
        // The remaining part of the class URI must not contain
        // a slash '/' or a hash '#' character. Otherwise we assume
        // that is belongs to another ontology.
        final int offset = namespace.length();
        int idxSlash = strClassUri.indexOf('/', offset);
        int idxHash = strClassUri.indexOf('#', offset);

        // Note that we generously ignore the first character of the
        // remaining part that may be a '/' or a '#' because the
        // namespace may not end with such a character.
        if (idxSlash <= offset && idxHash <= offset) {
          OntologyResource ontologyResource =
              new OntologyResource(classUri, schemaGraph);
          if (ignore ==null || !ignore.contains(ontologyResource))
            result.add(ontologyResource);
        }
      }
    }
    return result;
  }

  private Graph getNodeContext(NonLiteral resource, Graph graph) {
    final HashSet<BNode> dontExpand = new HashSet<BNode>();
    if (resource instanceof BNode) {
      dontExpand.add((BNode) resource);
    }
    return getContextOf(resource, dontExpand, graph).getGraph();

  }

  private MGraph getContextOf(NonLiteral node, Set<BNode> dontExpand,
      Graph graph) {
    MGraph result = new SimpleMGraph();
    Iterator<Triple> forwardProperties = graph.filter(node, null, null);
    while (forwardProperties.hasNext()) {
      Triple triple = forwardProperties.next();
      result.add(triple);
      Resource object = triple.getObject();
      if (object instanceof BNode) {
        BNode bNodeObject = (BNode) object;
        if (!dontExpand.contains(bNodeObject)) {
          dontExpand.add(bNodeObject);
          result.addAll(getContextOf(bNodeObject, dontExpand, graph));
        }
      }
    }
    Iterator<Triple> backwardProperties = graph.filter(null, null, node);
    while (backwardProperties.hasNext()) {
      Triple triple = backwardProperties.next();
      result.add(triple);
      NonLiteral subject = triple.getSubject();
      if (subject instanceof BNode) {
        BNode bNodeSubject = (BNode) subject;
        if (!dontExpand.contains(bNodeSubject)) {
          dontExpand.add(bNodeSubject);
          result.addAll(getContextOf(bNodeSubject, dontExpand, graph));
        }
      }
    }
    return result;
  }

  private String getSimpleName() {
    int lastDotPos = className.lastIndexOf('.');
    if (lastDotPos == -1) {
      return className;
    }
    return className.substring(lastDotPos + 1);
  }

  private String getPackageName() {
    int lastDotPos = className.lastIndexOf('.');
    if (lastDotPos == -1) {
      return null;
    }
    return className.substring(0, lastDotPos);
  }

  private static class OntologyResource implements
      Comparable<OntologyResource> {

    final Graph graph;
    final UriRef uri;

    static final List<String> reservedWords = Arrays.asList(
        "abstract", "assert", "boolean", "break", "byte", "case",
        "catch", "char", "class", "const", "continue", "default",
        "do", "double", "else", "enum", "extends", "false", "final",
        "finally", "float", "for", "goto", "if", "implements",
        "import", "instanceof", "int", "interface", "long", "native",
        "new", "null", "package", "private", "protected", "public",
        "return", "short", "static", "strictfp", "super", "switch",
        "synchronized", "this", "throw", "throws", "transient",
        "true", "try", "void", "volatile", "while");

    OntologyResource(UriRef uri, Graph graph) {
      this.uri = uri;
      this.graph = graph;
    }

    String getLocalName() {
      String uriValue = uri.getUnicodeString();
      int hashPos = uriValue.lastIndexOf('#');
      int slashPos = uriValue.lastIndexOf('/');
      int delimiter = hashPos > slashPos ? hashPos : slashPos;
      String val = uriValue.substring(delimiter + 1);
      if (val.length()==0) return "THIS_ONTOLOGY";
      //replace bad characters...
      val = val.replace('-', '_').replace('.','_');
      return reservedWords.contains(val) ? val + "_" : val;
    }

    String getUriString() {
      return uri.getUnicodeString();
    }

    String getDescription() {
      StringBuffer result = new StringBuffer();
      Iterator<Triple> titleStatements = graph.filter(
          uri, DCTERMS.title, null);
      while (titleStatements.hasNext()) {
        Resource object = titleStatements.next().getObject();
        if (object instanceof Literal) {
          result.append("title: ");
          result.append (((Literal) object).getLexicalForm());
          result.append("\n");
        }
      }
      Iterator<Triple> descriptionStatements = graph.filter(
          uri, DCTERMS.description, null);
      while (descriptionStatements.hasNext()) {
        Resource object = descriptionStatements.next().getObject();
        if (object instanceof Literal) {
          result.append("description: ");
          result.append (((Literal) object).getLexicalForm());
          result.append("\n");
        }
      }
      Iterator<Triple> skosDefStatements = graph.filter(
          uri, SKOS.definition, null);
      while (skosDefStatements.hasNext()) {
        Resource object = skosDefStatements.next().getObject();
        if (object instanceof Literal) {
          result.append("definition: ");
          result.append (((Literal) object).getLexicalForm());
          result.append("\n");
        }
      }
      Iterator<Triple> rdfsCommentStatements = graph.filter(
          uri, RDFS.comment, null);
      while (rdfsCommentStatements.hasNext()) {
        Resource object = rdfsCommentStatements.next().getObject();
        if (object instanceof Literal) {
          result.append("comment: ");
          result.append(((Literal) object).getLexicalForm());
          result.append("\n");
        }
      }
      Iterator<Triple> skosNoteStatements = graph.filter(
          uri, SKOS.note, null);
      while (skosNoteStatements.hasNext()) {
        Resource object = skosNoteStatements.next().getObject();
        if (object instanceof Literal) {
          result.append("note: ");
          result.append (((Literal) object).getLexicalForm());
          result.append("\n");
        }
      }
      Iterator<Triple> skosExampleStatements = graph.filter(
          uri, SKOS.example, null);
      while (skosExampleStatements.hasNext()) {
        Resource object = skosExampleStatements.next().getObject();
        if (object instanceof Literal) {
          result.append("example: ");
          result.append (((Literal) object).getLexicalForm());
          result.append("\n");
        } else if (object instanceof UriRef) {
          result.append("see <a href="+((UriRef)object).getUnicodeString()+">example</a>");
          result.append("\n");
        }
      }
      return result.toString();
    }

    @Override
    public int hashCode() {
      return getUriString().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == null) {
        return false;
      } else if (obj == this) {
        return true;
      } else if (OntologyResource.class.equals(obj.getClass())) {
        final OntologyResource other = (OntologyResource) obj;
        return getUriString().equals(other.getUriString());
      }
      return false;
    }

    @Override
    public int compareTo(OntologyResource o) {
      return getUriString().compareTo(o.getUriString());
    }
  }

  /*
   * Ontology vocabs are re-defined here and not imported to avoid a maven dependency loop
   */

  /** OWL Ontology. */
  private static class OWL {


    private static final String NS = "http://www.w3.org/2002/07/owl#";
    private static final UriRef Class =
        new UriRef(NS + "Class");
    public static final Resource Ontology = new UriRef(NS + "Ontology");
    private static final UriRef DatatypeProperty =
        new UriRef(NS + "DatatypeProperty");
    private static final UriRef ObjectProperty =
        new UriRef(NS + "ObjectProperty");
  }

  /** RDFS Ontology. */
  private static class RDFS {

    private static final String NS =
        "http://www.w3.org/2000/01/rdf-schema#";
    private static final UriRef Class = new UriRef(NS + "Class");
    private static final UriRef Datatype = new UriRef(NS + "Datatype");
    private static final UriRef comment = new UriRef(NS + "comment");
  }

  /** RDF Ontology. */
  private static class RDF {

    private static final String NS =
        "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
    private static final UriRef Property = new UriRef(NS + "Property");
    private static final UriRef type = new UriRef(NS + "type");
  }

  private static class SKOS {
    static final UriRef definition = new UriRef("http://www.w3.org/2008/05/skos#definition");
    static final UriRef note = new UriRef("http://www.w3.org/2004/02/skos/core#note");
    static final UriRef example = new UriRef("http://www.w3.org/2004/02/skos/core#example");
  }

  private static class DCTERMS {
    public static final UriRef title = new UriRef("http://purl.org/dc/terms/title");
    public static final UriRef description = new UriRef("http://purl.org/dc/terms/description");

  }
}
TOP

Related Classes of org.apache.clerezza.rdf.schemagen.SchemaGen$RDF

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
y>