001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.jena;
014
015import java.util.*;
016
017import org.apache.juneau.*;
018import org.apache.juneau.parser.*;
019import org.apache.juneau.xml.*;
020
021/**
022 * Parses RDF into POJOs.
023 *
024 * <h5 class='topic'>Behavior-specific subclasses</h5>
025 *
026 * The following direct subclasses are provided for language-specific parsers:
027 * <ul class='spaced-list'>
028 *    <li>
029 *       {@link RdfXmlParser} - RDF/XML and RDF/XML-ABBREV.
030 *    <li>
031 *       {@link NTripleParser} - N-TRIPLE.
032 *    <li>
033 *       {@link TurtleParser} - TURTLE.
034 *    <li>
035 *       {@link N3Parser} - N3.
036 * </ul>
037 *
038 * <h5 class='section'>See Also:</h5>
039 * <ul>
040 *    <li class='link'>{@doc juneau-marshall-rdf}
041 * </ul>
042 */
043public class RdfParser extends ReaderParser implements RdfCommon {
044
045   private static final Namespace
046      DEFAULT_JUNEAU_NS = Namespace.create("j", "http://www.apache.org/juneau/"),
047      DEFAULT_JUNEAUBP_NS = Namespace.create("jp", "http://www.apache.org/juneaubp/");
048
049   //-------------------------------------------------------------------------------------------------------------------
050   // Configurable properties
051   //-------------------------------------------------------------------------------------------------------------------
052
053   private static final String PREFIX = "RdfParser.";
054
055   /**
056    * Configuration property:  Trim whitespace from text elements.
057    *
058    * <h5 class='section'>Property:</h5>
059    * <ul>
060    *    <li><b>Name:</b>  <js>"RdfParser.trimWhitespace.b"</js>
061    *    <li><b>Data type:</b>  <code>Boolean</code>
062    *    <li><b>Default:</b>  <jk>false</jk>
063    *    <li><b>Session property:</b>  <jk>false</jk>
064    *    <li><b>Methods:</b>
065    *       <ul>
066    *          <li class='jm'>{@link RdfParserBuilder#trimWhitespace(boolean)}
067    *          <li class='jm'>{@link RdfParserBuilder#trimWhitespace()}
068    *       </ul>
069    * </ul>
070    *
071    * <h5 class='section'>Description:</h5>
072    * <p>
073    * If <jk>true</jk>, whitespace in text elements will be automatically trimmed.
074    *
075    * <h5 class='section'>Example:</h5>
076    * <p class='bcode w800'>
077    *    <jc>// Create an RDF parser that trims whitespace.</jc>
078    *    ReaderParser p = RdfParser
079    *       .<jsm>create</jsm>()
080    *       .xml()
081    *       .trimWhitespace()
082    *       .build();
083    *
084    *    <jc>// Same, but use property.</jc>
085    *    ReaderParser p = RdfParser
086    *       .<jsm>create</jsm>()
087    *       .xml()
088    *       .set(<jsf>RDF_trimWhitespace</jsf>, <jk>true</jk>)
089    *       .build();
090    * </p>
091    */
092   public static final String RDF_trimWhitespace = PREFIX + "trimWhitespace.b";
093
094   //-------------------------------------------------------------------------------------------------------------------
095   // Instance
096   //-------------------------------------------------------------------------------------------------------------------
097
098   private final boolean trimWhitespace, looseCollections;
099   private final String rdfLanguage;
100   private final Namespace juneauNs, juneauBpNs;
101   private final RdfCollectionFormat collectionFormat;
102
103   final Map<String,Object> jenaSettings = new HashMap<>();
104
105   /**
106    * Constructor.
107    *
108    * @param ps The property store containing all the settings for this object.
109    * @param consumes The list of media types that this parser consumes (e.g. <js>"application/json"</js>).
110    */
111   public RdfParser(PropertyStore ps, String...consumes) {
112      super(ps, consumes);
113      trimWhitespace = getBooleanProperty(RDF_trimWhitespace, false);
114      looseCollections = getBooleanProperty(RDF_looseCollections, false);
115      rdfLanguage = getStringProperty(RDF_language, "RDF/XML-ABBREV");
116      juneauNs = getInstanceProperty(RDF_juneauNs, Namespace.class, DEFAULT_JUNEAU_NS);
117      juneauBpNs = getInstanceProperty(RDF_juneauBpNs, Namespace.class, DEFAULT_JUNEAUBP_NS);
118      collectionFormat = getProperty(RDF_collectionFormat, RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
119   }
120
121   /**
122    * Constructor.
123    *
124    * @param ps The property store containing all the settings for this object.
125    */
126   public RdfParser(PropertyStore ps) {
127      this(ps, "text/xml+rdf");
128   }
129
130   @Override /* Context */
131   public RdfParserBuilder builder() {
132      return new RdfParserBuilder(getPropertyStore());
133   }
134
135   /**
136    * Instantiates a new clean-slate {@link RdfParserBuilder} object.
137    *
138    * <p>
139    * This is equivalent to simply calling <code><jk>new</jk> RdfParserBuilder()</code>.
140    *
141    * <p>
142    * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies
143    * the settings of the object called on.
144    *
145    * @return A new {@link RdfParserBuilder} object.
146    */
147   public static RdfParserBuilder create() {
148      return new RdfParserBuilder();
149   }
150
151   @Override /* Parser */
152   public ReaderParserSession createSession(ParserSessionArgs args) {
153      return new RdfParserSession(this, args);
154   }
155
156   //-----------------------------------------------------------------------------------------------------------------
157   // Properties
158   //-----------------------------------------------------------------------------------------------------------------
159
160   /**
161    * Configuration property:  Trim whitespace from text elements.
162    *
163    * @see #RDF_trimWhitespace
164    * @return
165    *    <jk>true</jk> if whitespace in text elements will be automatically trimmed.
166    */
167   protected final boolean isTrimWhitespace() {
168      return trimWhitespace;
169   }
170
171   /**
172    * Configuration property:  Collections should be serialized and parsed as loose collections.
173    *
174    * @see #RDF_looseCollections
175    * @return
176    *    <jk>true</jk> if collections of resources are handled as loose collections of resources in RDF instead of
177    *    resources that are children of an RDF collection (e.g. Sequence, Bag).
178    */
179   protected final boolean isLooseCollections() {
180      return looseCollections;
181   }
182
183   /**
184    * Configuration property:  RDF language.
185    *
186    * @see #RDF_language
187    * @return
188    *    The RDF language to use.
189    */
190   protected final String getRdfLanguage() {
191      return rdfLanguage;
192   }
193
194   /**
195    * Configuration property:  XML namespace for Juneau properties.
196    *
197    * @see #RDF_juneauNs
198    * @return
199    *    XML namespace for Juneau properties.
200    */
201   protected final Namespace getJuneauNs() {
202      return juneauNs;
203   }
204
205   /**
206    * Configuration property:  Default XML namespace for bean properties.
207    *
208    * @see #RDF_juneauBpNs
209    * @return
210    *    Default XML namespace for bean properties.
211    */
212   protected final Namespace getJuneauBpNs() {
213      return juneauBpNs;
214   }
215
216   /**
217    * Configuration property:  RDF format for representing collections and arrays.
218    *
219    * @see #RDF_collectionFormat
220    * @return
221    *    RDF format for representing collections and arrays.
222    */
223   protected final RdfCollectionFormat getCollectionFormat() {
224      return collectionFormat;
225   }
226
227   @Override /* Context */
228   public ObjectMap asMap() {
229      return super.asMap()
230         .append("RdfParser", new ObjectMap()
231            .append("trimWhitespace", trimWhitespace)
232            .append("looseCollections", looseCollections)
233            .append("rdfLanguage", rdfLanguage)
234            .append("juneauNs", juneauNs)
235            .append("juneauBpNs", juneauBpNs)
236            .append("collectionFormat", collectionFormat)
237         );
238   }
239
240   /**
241    * @deprecated Use {@link RdfXmlParser#DEFAULT}
242    */
243   @Deprecated
244   public static final RdfParser DEFAULT_XML = new RdfXmlParser(PropertyStore.DEFAULT);
245
246   /**
247    * @deprecated Use {@link TurtleParser#DEFAULT}
248    */
249   @Deprecated
250   public static final RdfParser DEFAULT_TURTLE = new TurtleParser(PropertyStore.DEFAULT);
251
252   /**
253    * @deprecated Use {@link NTripleParser#DEFAULT}
254    */
255   @Deprecated
256   public static final RdfParser DEFAULT_NTRIPLE = new NTripleParser(PropertyStore.DEFAULT);
257
258   /**
259    * @deprecated Use {@link N3Parser#DEFAULT}
260    */
261   @Deprecated
262   public static final RdfParser DEFAULT_N3 = new N3Parser(PropertyStore.DEFAULT);
263
264   /**
265    * @deprecated Use {@link RdfXmlParser}
266    */
267   @Deprecated
268   @SuppressWarnings("javadoc")
269   public static class Xml extends RdfXmlParser {
270      public Xml(PropertyStore ps) {
271         super(ps);
272      }
273   }
274
275   /**
276    * @deprecated Use {@link NTripleParser}
277    */
278   @Deprecated
279   @SuppressWarnings("javadoc")
280   public static class NTriple extends NTripleParser {
281      public NTriple(PropertyStore ps) {
282         super(ps);
283      }
284   }
285
286   /**
287    * @deprecated Use {@link TurtleParser}
288    */
289   @Deprecated
290   @SuppressWarnings("javadoc")
291   public static class Turtle extends TurtleParser {
292      public Turtle(PropertyStore ps) {
293         super(ps);
294      }
295   }
296
297   /**
298    * @deprecated Use {@link N3Parser}
299    */
300   @Deprecated
301   @SuppressWarnings("javadoc")
302   public static class N3 extends N3Parser {
303      public N3(PropertyStore ps) {
304         super(ps);
305      }
306   }
307}