View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *  http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.any23.vocab;
    19
    20  import org.apache.any23.rdf.RDFUtils;
    21  import org.apache.any23.util.DiscoveryUtils;
    22  import org.apache.any23.util.StringUtils;
    23  import org.eclipse.rdf4j.model.IRI;
    24  import org.eclipse.rdf4j.model.vocabulary.RDF;
    25  import org.eclipse.rdf4j.model.vocabulary.RDFS;
    26  import org.eclipse.rdf4j.rio.RDFFormat;
    27  import org.eclipse.rdf4j.rio.RDFHandlerException;
    28  import org.eclipse.rdf4j.rio.RDFWriter;
    29  import org.eclipse.rdf4j.rio.Rio;
    30
    31  import java.io.ByteArrayOutputStream;
    32  import java.io.PrintStream;
    33  import java.io.UnsupportedEncodingException;
    34  import java.lang.reflect.Constructor;
    35  import java.util.List;
    36  import java.util.Map;
    37
    38  /**
    39   * This class provides a set of methods for generating <a href="http://www.w3.org/TR/rdf-schema/">RDF Schema</a>.
    40   *
    41   * @author Michele Mostarda (mostarda@fbk.eu)
    42   */
    43  public class RDFSchemaUtils {
    44
    45      private static final String RDF_XML_SEPARATOR = StringUtils.multiply('=', 100);
    46
    47      private RDFSchemaUtils() {
    48      }
    49
    50      /**
    51       * Serializes a vocabulary composed of the given <code>namespace</code>, <code>resources</code> and
    52       * <code>properties</code>.
    53       *
    54       * @param namespace
    55       *            vocabulary namespace.
    56       * @param classes
    57       *            list of classes.
    58       * @param properties
    59       *            list of properties.
    60       * @param comments
    61       *            map of resource comments.
    62       * @param writer
    63       *            writer to print out the RDF Schema triples.
    64       *
    65       * @throws RDFHandlerException
    66       *             if there is an error handling the RDF
    67       */
    68      public static void serializeVocabulary(IRI namespace, IRI[] classes, IRI[] properties, Map<IRI, String> comments,
    69              RDFWriter writer) {
    70          writer.startRDF();
    71          for (IRI clazz : classes) {
    72              writer.handleStatement(RDFUtils.quad(clazz, RDF.TYPE, RDFS.CLASS, namespace));
    73              writer.handleStatement(RDFUtils.quad(clazz, RDFS.MEMBER, namespace, namespace));
    74              final String comment = comments.get(clazz);
    75              if (comment != null)
    76                  writer.handleStatement(RDFUtils.quad(clazz, RDFS.COMMENT, RDFUtils.literal(comment), namespace));
    77          }
    78          for (IRI property : properties) {
    79              writer.handleStatement(RDFUtils.quad(property, RDF.TYPE, RDF.PROPERTY, namespace));
    80              writer.handleStatement(RDFUtils.quad(property, RDFS.MEMBER, namespace, namespace));
    81              final String comment = comments.get(property);
    82              if (comment != null)
    83                  writer.handleStatement(RDFUtils.quad(property, RDFS.COMMENT, RDFUtils.literal(comment), namespace));
    84          }
    85          writer.endRDF();
    86      }
    87
    88      /**
    89       * Serializes the given <code>vocabulary</code> to triples over the given <code>writer</code>.
    90       *
    91       * @param vocabulary
    92       *            vocabulary to be serialized.
    93       * @param writer
    94       *            output writer.
    95       *
    96       * @throws RDFHandlerException
    97       *             if there is an error handling the RDF
    98       */
    99      public static void serializeVocabulary(Vocabulary vocabulary, RDFWriter writer) {
    100         serializeVocabulary(vocabulary.getNamespace(), vocabulary.getClasses(), vocabulary.getProperties(),
    101                 vocabulary.getComments(), writer);
    102     }
    103
    104     /**
    105      * Serializes the given <code>vocabulary</code> to <i>NQuads</i> over the given output stream.
    106      *
    107      * @param vocabulary
    108      *            vocabulary to be serialized.
    109      * @param format
    110      *            output format for vocabulary.
    111      * @param willFollowAnother
    112      *            if <code>true</code> another vocab will be printed in the same stream.
    113      * @param ps
    114      *            output stream.
    115      *
    116      * @throws RDFHandlerException
    117      *             if there is an error handling the RDF
    118      */
    119     public static void serializeVocabulary(Vocabulary vocabulary, RDFFormat format, boolean willFollowAnother,
    120             PrintStream ps) {
    121         final RDFWriter rdfWriter;
    122         if (format == RDFFormat.RDFXML) {
    123             rdfWriter = Rio.createWriter(RDFFormat.RDFXML, ps);
    124             if (willFollowAnother)
    125                 ps.print("\n");
    126             ps.print(RDF_XML_SEPARATOR);
    127             ps.print("\n");
    128         } else {
    129             rdfWriter = Rio.createWriter(format, ps);
    130         }
    131         serializeVocabulary(vocabulary, rdfWriter);
    132     }
    133
    134     /**
    135      * Serialized the given <code>vocabulary</code> to <i>NQuads</i> and return them as string.
    136      *
    137      * @param vocabulary
    138      *            vocabulary to be serialized.
    139      * @param format
    140      *            output format for vocabulary.
    141      *
    142      * @return string contained serialization.
    143      *
    144      * @throws RDFHandlerException
    145      *             if there is an error handling the RDF
    146      */
    147     public static String serializeVocabulary(Vocabulary vocabulary, RDFFormat format) {
    148         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    149         PrintStream ps;
    150         try {
    151             ps = new PrintStream(baos, true, "UTF-8");
    152         } catch (UnsupportedEncodingException e1) {
    153             throw new RuntimeException("UTF-8 encoding error when serializing the vocabulary to NQuads.", e1);
    154         }
    155         serializeVocabulary(vocabulary, format, false, ps);
    156         ps.close();
    157         try {
    158             return baos.toString("UTF-8");
    159         } catch (UnsupportedEncodingException e) {
    160             throw new RuntimeException("Error writing ByteArrayOutputStream to String with \"UTF-8\" encoding!");
    161         }
    162     }
    163
    164     /**
    165      * Serializes all the vocabularies to <i>NQuads</i> over the given output stream.
    166      *
    167      * @param format
    168      *            output format for vocabularies.
    169      * @param ps
    170      *            output print stream.
    171      */
    172     public static void serializeVocabularies(RDFFormat format, PrintStream ps) {
    173         final Class<Vocabulary> vocabularyClass = Vocabulary.class;
    174         @SuppressWarnings("rawtypes")
    175         final List<Class> vocabularies = DiscoveryUtils.getClassesInPackage(vocabularyClass.getPackage().getName(),
    176                 vocabularyClass);
    177         int currentIndex = 0;
    178         for (Class<?> vocabClazz : vocabularies) {
    179             final Vocabulary instance;
    180             try {
    181                 final Constructor<?> constructor = vocabClazz.getDeclaredConstructor();
    182                 constructor.trySetAccessible();
    183                 instance = (Vocabulary) constructor.newInstance();
    184             } catch (Exception e) {
    185                 throw new RuntimeException("Error while instantiating vocabulary class " + vocabClazz, e);
    186             }
    187             try {
    188                 serializeVocabulary(instance, format, currentIndex < vocabularies.size() - 2, ps);
    189             } catch (RDFHandlerException rdfhe) {
    190                 throw new RuntimeException("Error while serializing vocabulary.", rdfhe);
    191             }
    192         }
    193     }
    194
    195 }