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.lang.reflect.Constructor;
34  import java.util.List;
35  import java.util.Map;
36  
37  /**
38   * This class provides a set of methods for generating
39   * <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       * Serializes a vocabulary composed of the given <code>namespace</code>,
51       * <code>resources</code> and <code>properties</code>.
52       *
53       * @param namespace vocabulary namespace.
54       * @param classes list of classes.
55       * @param properties list of properties.
56       * @param comments map of resource comments.
57       * @param writer writer to print out the RDF Schema triples.
58       * @throws RDFHandlerException if there is an error handling the RDF
59       */
60      public static void serializeVocabulary(
61              IRI namespace,
62              IRI[] classes,
63              IRI[] properties,
64              Map<IRI,String> comments,
65              RDFWriter writer
66      ) {
67          writer.startRDF();
68          for (IRI clazz : classes) {
69              writer.handleStatement(RDFUtils.quad(clazz, RDF.TYPE, RDFS.CLASS, namespace));
70              writer.handleStatement(RDFUtils.quad(clazz, RDFS.MEMBER, namespace, namespace));
71              final String comment = comments.get(clazz);
72              if (comment != null)
73                  writer.handleStatement(RDFUtils.quad(clazz, RDFS.COMMENT, RDFUtils.literal(comment), namespace));
74          }
75          for (IRI property : properties) {
76              writer.handleStatement(RDFUtils.quad(property, RDF.TYPE, RDF.PROPERTY, namespace));
77              writer.handleStatement(RDFUtils.quad(property, RDFS.MEMBER, namespace, namespace));
78              final String comment = comments.get(property);
79              if (comment != null)
80                  writer.handleStatement(RDFUtils.quad(property, RDFS.COMMENT, RDFUtils.literal(comment), namespace));
81          }
82          writer.endRDF();
83      }
84  
85      /**
86       * Serializes the given <code>vocabulary</code> to triples over the given <code>writer</code>.
87       *
88       * @param vocabulary vocabulary to be serialized.
89       * @param writer output writer.
90       * @throws RDFHandlerException if there is an error handling the RDF
91       */
92      public static void serializeVocabulary(Vocabulary vocabulary, RDFWriter writer) {
93          serializeVocabulary(
94                  vocabulary.getNamespace(),
95                  vocabulary.getClasses(),
96                  vocabulary.getProperties(),
97                  vocabulary.getComments(),
98                  writer
99          );
100     }
101 
102     /**
103      * Serializes the given <code>vocabulary</code> to <i>NQuads</i> over the given output stream.
104      *
105      * @param vocabulary vocabulary to be serialized.
106      * @param format output format for vocabulary.
107      * @param willFollowAnother if <code>true</code> another vocab will be printed in the same stream.
108      * @param ps output stream.
109      * @throws RDFHandlerException if there is an error handling the RDF
110      */
111     public static void serializeVocabulary(
112             Vocabulary vocabulary,
113             RDFFormat format,
114             boolean willFollowAnother,
115             PrintStream ps) {
116         final RDFWriter rdfWriter;
117         if (format == RDFFormat.RDFXML) {
118             rdfWriter = Rio.createWriter(RDFFormat.RDFXML, ps);
119             if (willFollowAnother)
120                 ps.print("\n");
121                 ps.print(RDF_XML_SEPARATOR);
122                 ps.print("\n");
123         } else {
124             rdfWriter = Rio.createWriter(format, ps);
125         }
126         serializeVocabulary(vocabulary, rdfWriter);
127     }
128 
129     /**
130      * Serialized the given <code>vocabulary</code> to <i>NQuads</i> and return them as string.
131      *
132      * @param vocabulary vocabulary to be serialized.
133      * @param format output format for vocabulary.
134      * @return string contained serialization.
135      * @throws RDFHandlerException if there is an error handling the RDF
136      */
137     public static String serializeVocabulary(Vocabulary vocabulary, RDFFormat format) {
138         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
139         final PrintStream ps = new PrintStream(baos);
140         serializeVocabulary(vocabulary, format, false, ps);
141         ps.close();
142         return baos.toString();
143     }
144 
145     /**
146      * Serializes all the vocabularies to <i>NQuads</i> over the given output stream.
147      *
148      * @param format output format for vocabularies.
149      * @param ps output print stream.
150      */
151     public static void serializeVocabularies(RDFFormat format, PrintStream ps) {
152         final Class<Vocabulary> vocabularyClass = Vocabulary.class;
153         @SuppressWarnings("rawtypes")
154         final List<Class> vocabularies = DiscoveryUtils.getClassesInPackage(
155                 vocabularyClass.getPackage().getName(),
156                 vocabularyClass
157         );
158         int currentIndex = 0;
159         for (Class<?> vocabClazz : vocabularies) {
160             final Vocabulary instance;
161             try {
162                 final Constructor<?> constructor = vocabClazz.getDeclaredConstructor();
163                 constructor.setAccessible(true);
164                 instance = (Vocabulary) constructor.newInstance();
165             } catch (Exception e) {
166                 throw new RuntimeException("Error while instantiating vocabulary class " + vocabClazz, e);
167             }
168             try {
169                 serializeVocabulary(instance, format, currentIndex < vocabularies.size() - 2, ps);
170             } catch (RDFHandlerException rdfhe) {
171                 throw new RuntimeException("Error while serializing vocabulary.", rdfhe);
172             }
173         }
174     }
175 
176 }