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.extractor.rdf;
    19
    20  import java.util.Map.Entry;
    21  import java.util.UUID;
    22
    23  import org.apache.any23.extractor.ExtractionResult;
    24  import org.eclipse.rdf4j.model.IRI;
    25  import org.eclipse.rdf4j.model.Resource;
    26  import org.eclipse.rdf4j.model.Value;
    27  import org.eclipse.rdf4j.model.ValueFactory;
    28  import com.github.jsonldjava.core.JsonLdConsts;
    29  import com.github.jsonldjava.core.JsonLdTripleCallback;
    30  import com.github.jsonldjava.core.RDFDataset;
    31
    32  /**
    33   * @author Hans Brende (hansbrende@apache.org)
    34   */
    35  class JSONLDJavaSink implements JsonLdTripleCallback {
    36
    37      private static final String BNODE_PREFIX = JsonLdConsts.BLANK_NODE_PREFIX;
    38
    39      private final ExtractionResult handler;
    40      private final ValueFactory valueFactory;
    41      private final String bNodeUniquifier;
    42
    43      JSONLDJavaSink(ExtractionResult handler, ValueFactory valueFactory) {
    44          this.handler = handler;
    45          this.valueFactory = valueFactory;
    46          this.bNodeUniquifier = "n" + UUID.randomUUID().toString().replace("-", "") + "x";
    47      }
    48
    49      private Resource createResource(RDFDataset.Node resource) {
    50          String value = resource == null ? null : resource.getValue();
    51          if (value != null && value.startsWith(BNODE_PREFIX)) {
    52              String bNodeId = value.substring(BNODE_PREFIX.length());
    53
    54              if (bNodeId.length() < 32) { // not globally unique; will collide with other blank node ids
    55                  if (bNodeId.isEmpty()) {
    56                      bNodeId = Integer.toHexString(System.identityHashCode(resource));
    57                  }
    58                  bNodeId = bNodeUniquifier + bNodeId;
    59              }
    60
    61              return valueFactory.createBNode(bNodeId);
    62          }
    63          return valueFactory.createIRI(value);
    64      }
    65
    66      private void writeQuad(RDFDataset.Node sNode, RDFDataset.Node pNode, Value o, String graphName) {
    67          if (graphName != null && graphName.startsWith(BNODE_PREFIX)) {
    68              // TODO support blank node graph names in Any23
    69              return;
    70          }
    71          Resource s = createResource(sNode);
    72          IRI p = valueFactory.createIRI(pNode == null ? null : pNode.getValue());
    73          if (s == null || p == null || o == null) {
    74              return;
    75          }
    76          if (graphName == null || graphName.isEmpty() || JsonLdConsts.DEFAULT.equalsIgnoreCase(graphName)) {
    77              handler.writeTriple(s, p, o);
    78          } else {
    79              handler.writeTriple(s, p, o, valueFactory.createIRI(graphName));
    80          }
    81      }
    82
    83      @Override
    84      public Object call(final RDFDataset dataset) {
    85          for (Entry<String, String> nextNamespace : dataset.getNamespaces().entrySet()) {
    86              handler.writeNamespace(nextNamespace.getKey(), nextNamespace.getValue());
    87          }
    88          for (String graphName : dataset.keySet()) {
    89              for (RDFDataset.Quad quad : dataset.getQuads(graphName)) {
    90                  RDFDataset.Node s = quad.getSubject();
    91                  RDFDataset.Node p = quad.getPredicate();
    92                  RDFDataset.Node o = quad.getObject();
    93                  if (o == null || !o.isLiteral()) {
    94                      writeQuad(s, p, createResource(o), graphName);
    95                  } else {
    96                      String lang = o.getLanguage();
    97                      String datatype = o.getDatatype();
    98                      String literal = o.getValue();
    99                      if (lang != null && !lang.isEmpty()
    100                             && (datatype == null || datatype.indexOf(':') < 0
    101                                     || JsonLdConsts.RDF_LANGSTRING.equalsIgnoreCase(datatype)
    102                                     || JsonLdConsts.XSD_STRING.equalsIgnoreCase(datatype))) {
    103                         writeQuad(s, p, valueFactory.createLiteral(literal, lang), graphName);
    104                     } else if (datatype != null && !datatype.isEmpty()) {
    105                         writeQuad(s, p, valueFactory.createLiteral(literal, valueFactory.createIRI(datatype)),
    106                                 graphName);
    107                     } else {
    108                         writeQuad(s, p, valueFactory.createLiteral(literal), graphName);
    109                     }
    110                 }
    111             }
    112         }
    113         return null;
    114     }
    115 }