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.rdf;
19  
20  import java.math.BigDecimal;
21  import java.math.BigInteger;
22  import java.util.Date;
23  
24  import org.apache.any23.extractor.IssueReport;
25  import org.apache.commons.lang3.StringUtils;
26  import org.eclipse.rdf4j.model.BNode;
27  import org.eclipse.rdf4j.model.Literal;
28  import org.eclipse.rdf4j.model.Resource;
29  import org.eclipse.rdf4j.model.Statement;
30  import org.eclipse.rdf4j.model.IRI;
31  import org.eclipse.rdf4j.model.Value;
32  import org.eclipse.rdf4j.model.ValueFactory;
33  import org.eclipse.rdf4j.model.vocabulary.RDF;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  import javax.xml.datatype.XMLGregorianCalendar;
38  
39  /**
40   * Any23 specialization of the {@link org.eclipse.rdf4j.model.ValueFactory}. It provides a wrapper to instantiate RDF
41   * objects.
42   */
43  // TODO: Merge with RDFUtils.java
44  public class Any23ValueFactoryWrapper implements ValueFactory {
45  
46      private static final Logger logger = LoggerFactory.getLogger(Any23ValueFactoryWrapper.class);
47  
48      private final ValueFactory wrappedFactory;
49  
50      private IssueReport issueReport;
51  
52      private String defaultLiteralLanguage;
53  
54      /**
55       * Constructor with error reporter.
56       *
57       * @param factory
58       *            the wrapped value factory, cannot be <code>null</code>.
59       * @param er
60       *            the error reporter.
61       * @param defaultLitLanguage
62       *            the default literal language.
63       */
64      public Any23ValueFactoryWrapper(final ValueFactory factory, IssueReport er, String defaultLitLanguage) {
65          if (factory == null) {
66              throw new NullPointerException("factory cannot be null.");
67          }
68          wrappedFactory = factory;
69          issueReport = er;
70          defaultLiteralLanguage = defaultLitLanguage;
71      }
72  
73      public Any23ValueFactoryWrapper(final ValueFactory vFactory, IssueReport er) {
74          this(vFactory, er, null);
75      }
76  
77      public Any23ValueFactoryWrapper(final ValueFactory vFactory) {
78          this(vFactory, null, null);
79      }
80  
81      public IssueReport getIssueReport() {
82          return issueReport;
83      }
84  
85      public void setIssueReport(IssueReport er) {
86          issueReport = er;
87      }
88  
89      public String getDefaultLiteralLanguage() {
90          return defaultLiteralLanguage;
91      }
92  
93      @Override
94      public BNode createBNode() {
95          return wrappedFactory.createBNode();
96      }
97  
98      @Override
99      public BNode createBNode(String id) {
100         if (id == null)
101             return null;
102         return wrappedFactory.createBNode(id);
103     }
104 
105     @Override
106     public Literal createLiteral(String content) {
107         if (content == null)
108             return null;
109         if (defaultLiteralLanguage == null) {
110             return wrappedFactory.createLiteral(content);
111         } else {
112             return wrappedFactory.createLiteral(content, defaultLiteralLanguage);
113         }
114     }
115 
116     @Override
117     public Literal createLiteral(boolean b) {
118         return wrappedFactory.createLiteral(b);
119     }
120 
121     @Override
122     public Literal createLiteral(byte b) {
123         return wrappedFactory.createLiteral(b);
124     }
125 
126     @Override
127     public Literal createLiteral(short i) {
128         return wrappedFactory.createLiteral(i);
129     }
130 
131     @Override
132     public Literal createLiteral(int i) {
133         return wrappedFactory.createLiteral(i);
134     }
135 
136     @Override
137     public Literal createLiteral(long l) {
138         return wrappedFactory.createLiteral(l);
139     }
140 
141     @Override
142     public Literal createLiteral(float v) {
143         return wrappedFactory.createLiteral(v);
144     }
145 
146     @Override
147     public Literal createLiteral(double v) {
148         return wrappedFactory.createLiteral(v);
149     }
150 
151     @Override
152     public Literal createLiteral(BigDecimal v) {
153         return wrappedFactory.createLiteral(v);
154     }
155 
156     @Override
157     public Literal createLiteral(BigInteger v) {
158         return wrappedFactory.createLiteral(v);
159     }
160 
161     @Override
162     public Literal createLiteral(XMLGregorianCalendar calendar) {
163         return wrappedFactory.createLiteral(calendar);
164     }
165 
166     @Override
167     public Literal createLiteral(String label, String language) {
168         if (StringUtils.isBlank(language))
169             return createLiteral(label);
170         if (label == null)
171             return null;
172         return wrappedFactory.createLiteral(label, language);
173     }
174 
175     @Override
176     public Literal createLiteral(String pref, IRI value) {
177         if (RDF.LANGSTRING.equals(value))
178             return createLiteral(pref);
179         if (pref == null)
180             return null;
181         return wrappedFactory.createLiteral(pref, value);
182     }
183 
184     @Override
185     public Literal createLiteral(Date date) {
186         return wrappedFactory.createLiteral(date);
187     }
188 
189     @Override
190     public Statement createStatement(Resource sub, IRI pre, Value obj) {
191         if (sub == null || pre == null || obj == null) {
192             return null;
193         }
194         return wrappedFactory.createStatement(sub, pre, obj);
195     }
196 
197     @Override
198     public Statement createStatement(Resource sub, IRI pre, Value obj, Resource context) {
199         if (sub == null || pre == null || obj == null)
200             return null;
201         return wrappedFactory.createStatement(sub, pre, obj, context);
202     }
203 
204     /**
205      * @param uriStr
206      *            input string to create URI from.
207      * 
208      * @return a valid sesame IRI or null if any exception occurred
209      */
210     @Override
211     public IRI createIRI(String uriStr) {
212         if (uriStr == null)
213             return null;
214         try {
215             return wrappedFactory.createIRI(RDFUtils.fixIRIWithException(uriStr));
216         } catch (Exception e) {
217             reportError(e);
218             return null;
219         }
220     }
221 
222     /**
223      * @return a valid sesame IRI or null if any exception occurred
224      */
225     @Override
226     public IRI createIRI(String namespace, String localName) {
227         if (namespace == null || localName == null)
228             return null;
229         return wrappedFactory.createIRI(RDFUtils.fixIRIWithException(namespace), localName);
230     }
231 
232     /**
233      * Fixes typical errors in IRIs, and resolves relative IRIs against a base IRI.
234      *
235      * @param uri
236      *            A IRI, relative or absolute, can have typical syntax errors
237      * @param baseIRI
238      *            A base IRI to use for resolving relative IRIs
239      * 
240      * @return An absolute IRI, sytnactically valid, or null if not fixable
241      */
242     public IRI resolveIRI(String uri, java.net.URI baseIRI) {
243         try {
244             return wrappedFactory.createIRI(baseIRI.resolve(RDFUtils.fixIRIWithException(uri)).toString());
245         } catch (IllegalArgumentException iae) {
246             reportError(iae);
247             return null;
248         }
249     }
250 
251     /**
252      * @param iri
253      *            IRI to fix
254      * 
255      * @return a valid sesame IRI or null if any exception occurred
256      */
257     public IRI fixIRI(String iri) {
258         try {
259             return wrappedFactory.createIRI(RDFUtils.fixIRIWithException(iri));
260         } catch (Exception e) {
261             reportError(e);
262             return null;
263         }
264     }
265 
266     /**
267      * Helper method to conditionally add a schema to a URI unless it's there, or null if link is empty.
268      * 
269      * @param link
270      *            string representation of the URI
271      * @param defaultSchema
272      *            schema to add the URI
273      * 
274      * @return a valid sesame IRI or null if any exception occurred
275      */
276     public IRI fixLink(String link, String defaultSchema) {
277         if (link == null)
278             return null;
279         link = fixWhiteSpace(link);
280         if ("".equals(link))
281             return null;
282         if (defaultSchema != null && !link.startsWith(defaultSchema + ":")) {
283             link = defaultSchema + ":" + link;
284         }
285         return fixIRI(link);
286     }
287 
288     public String fixWhiteSpace(String name) {
289         return name.replaceAll("\\s+", " ").trim();
290     }
291 
292     /**
293      * Reports an error in the most appropriate way.
294      * 
295      * @param e
296      *            error to be reported.
297      */
298     private void reportError(Exception e) {
299         if (issueReport == null) {
300             logger.warn(e.getMessage());
301         } else {
302             issueReport.notifyIssue(IssueReport.IssueLevel.WARNING, e.getMessage(), -1, -1);
303         }
304     }
305 
306 }