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