Package edu.isi.karma.kr2rml

Source Code of edu.isi.karma.kr2rml.KR2RMLMappingWriter

/*******************************************************************************
* Copyright 2012 University of Southern California
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This code was developed by the Information Integration Group as part
* of the Karma project at the Information Sciences Institute of the
* University of Southern California.  For more information, publications,
* and related projects, please see: http://www.isi.edu/integration
******************************************************************************/

package edu.isi.karma.kr2rml;

import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.openrdf.OpenRDFException;
import org.openrdf.model.BNode;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.turtle.TurtleWriter;
import org.openrdf.sail.memory.MemoryStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.isi.karma.common.HttpMethods;
import edu.isi.karma.kr2rml.formatter.KR2RMLColumnNameFormatter;
import edu.isi.karma.kr2rml.mapping.KR2RMLMapping;
import edu.isi.karma.kr2rml.planning.TriplesMap;
import edu.isi.karma.kr2rml.template.StringTemplateTerm;
import edu.isi.karma.kr2rml.template.TemplateTerm;
import edu.isi.karma.kr2rml.template.TemplateTermSet;
import edu.isi.karma.modeling.Namespaces;
import edu.isi.karma.modeling.Prefixes;
import edu.isi.karma.modeling.Uris;
import edu.isi.karma.rep.RepFactory;
import edu.isi.karma.rep.Worksheet;
import edu.isi.karma.rep.Workspace;
import edu.isi.karma.rep.metadata.WorksheetProperties;
import edu.isi.karma.rep.metadata.WorksheetProperties.Property;

public class KR2RMLMappingWriter {
 
  private Repository myRepository;
 
  // Internal instance variables
  private RepositoryConnection con;
  private ValueFactory f;
  private Map<String, URI> repoURIs;
  private static Logger logger = LoggerFactory
      .getLogger(KR2RMLMappingWriter.class);
 
  public KR2RMLMappingWriter()
      throws RepositoryException {

    initializeTripleStore();
    initializeURIs();
  }

  private Resource addKR2RMLMappingResource(Worksheet worksheet, KR2RMLMapping mapping)
      throws RepositoryException {
    /** Create resource for the mapping as a blank node **/
    Resource mappingRes = f.createBNode();
    con.add(mappingRes, RDF.TYPE, repoURIs.get(Uris.KM_R2RML_MAPPING_URI));
    Value srcNameVal = f.createLiteral(worksheet.getTitle());
    con.add(mappingRes, repoURIs.get(Uris.KM_SOURCE_NAME_URI), srcNameVal);
   
    // Add the timestamp
    con.add(mappingRes, repoURIs.get(Uris.KM_MODEL_PUBLICATION_TIME_URI), f.createLiteral(new Date().getTime()));
    String inputColumns = worksheet.getMetadataContainer().getWorksheetProperties().getPropertyValue(
        Property.inputColumns);
    String outputColumns = worksheet.getMetadataContainer().getWorksheetProperties().getPropertyValue(
        Property.outputColumns);
    String oldHistory = worksheet.getMetadataContainer().getWorksheetProperties().getPropertyValue(
        Property.oldCommandHistory);
    String graphLabel = worksheet.getMetadataContainer().getWorksheetProperties().getPropertyValue(
        Property.graphLabel);
    String baseURI = worksheet.getMetadataContainer().getWorksheetProperties().getPropertyValue(
        Property.baseURI);
    // Add the version
    con.add(mappingRes, repoURIs.get(Uris.KM_MODEL_VERSION_URI), f.createLiteral(KR2RMLVersion.getCurrent().toString()));
    if (inputColumns != null && !inputColumns.trim().isEmpty())
      con.add(mappingRes, repoURIs.get(Uris.KM_HAS_INPUTCOLUMNS), f.createLiteral(inputColumns));
    if (outputColumns != null && !outputColumns.trim().isEmpty())
      con.add(mappingRes, repoURIs.get(Uris.KM_HAS_OUTPUTCOLUMNS), f.createLiteral(outputColumns));
    if (graphLabel != null && !graphLabel.trim().isEmpty())
      con.add(mappingRes, repoURIs.get(Uris.KM_HAS_MODELLABEL), f.createLiteral(graphLabel))
    if (baseURI != null && !baseURI.trim().isEmpty())
      con.add(mappingRes, repoURIs.get(Uris.KM_HAS_BASEURI), f.createLiteral(baseURI));
    if (oldHistory != null && !oldHistory.trim().isEmpty())
      con.add(mappingRes, repoURIs.get(Uris.KM_HAS_OLDHISTORY), f.createLiteral(oldHistory));
    addWorksheetProperties(worksheet, mappingRes);
    addCompleteWorksheetHistory(mapping, mappingRes);
    return mappingRes;
  }

  private void initializeTripleStore() throws RepositoryException {
    /** Initialize an in-memory sesame triple store **/
    myRepository = new SailRepository(new MemoryStore());
    myRepository.initialize();
    con = myRepository.getConnection();
    f = myRepository.getValueFactory();
  }
 
  protected void initializeURIs()
  {
    repoURIs = new HashMap<String, URI>();
    for (String uri : Uris.Uris) {
      repoURIs.put(uri, f.createURI(uri));
    }       
   
  }

  public boolean addR2RMLMapping(KR2RMLMapping mapping, Worksheet worksheet, Workspace workspace)
      throws RepositoryException, JSONException {

    try {

      Resource mappingRes = addKR2RMLMappingResource(worksheet, mapping);
      addTripleMaps(mapping, mappingRes, worksheet, workspace);
      addPrefixes(mapping);
     
    } catch (OpenRDFException e) {
      logger.error("Error occured while generating RDF representation of R2RML data " +
          "structures.", e);
    }
    return true;
  }

  public void writeR2RMLMapping(PrintWriter writer)  {
    try {
      con.export(new TurtleWriter(writer));
    } catch (RepositoryException e) {
      logger.error("Error occured while outputing R2RML mapping");
    } catch (RDFHandlerException e) {
      logger.error("Error occured while outputing R2RML mapping");
    }
  }

  private void addPrefixes(KR2RMLMapping mapping) throws RepositoryException {
    for (Prefix p : mapping.getPrefixes())
    {
      con.setNamespace(p.getPrefix(), p.getNamespace());
    }
    con.setNamespace(Prefixes.RR, Namespaces.RR);
    con.setNamespace(Prefixes.KARMA_DEV, Namespaces.KARMA_DEV);
  }

  private void addTripleMaps(KR2RMLMapping mapping, Resource mappingRes, Worksheet worksheet, Workspace workspace)
      throws RepositoryException {
    /** Get the required data structures of R2RML **/

    List<TriplesMap> triplesMapList = mapping.getTriplesMapList();
    /** Add all the triple maps **/
    for (TriplesMap trMap:triplesMapList) {
      addTripleMap(mapping, mappingRes, worksheet, workspace,
          trMap);
    }
  }

  private void addTripleMap(KR2RMLMapping mapping, Resource mappingRes,
      Worksheet worksheet, Workspace workspace, TriplesMap trMap) throws RepositoryException {
    URI trMapUri = f.createURI(Namespaces.KARMA_DEV + trMap.getId());
    addTripleMapMetadata(mapping, mappingRes, worksheet, trMap, trMapUri);
   
    addSubjectMap(mapping, mappingRes, trMap, trMapUri, workspace);
   
    addPredicateObjectMaps(mapping, mappingRes, trMap, trMapUri, workspace, worksheet);
  }

  private void addTripleMapMetadata(KR2RMLMapping mapping, Resource mappingRes, Worksheet worksheet,
      TriplesMap trMap, URI trMapUri) throws RepositoryException {
   
    // Add the triples map type statement
    con.add(trMapUri, RDF.TYPE, repoURIs.get(Uris.RR_TRIPLESMAP_CLASS_URI));
    // Associate it with the source mapping URI
    con.add(mappingRes, repoURIs.get(Uris.KM_HAS_TRIPLES_MAP_URI), trMapUri);
    con.add(trMapUri, repoURIs.get(Uris.KM_IS_PART_OF_MAPPING_URI), mappingRes);
   
    addLogicalSource(mapping, worksheet, mappingRes, trMapUri);
  }

  private void addLogicalSource(KR2RMLMapping mapping, Worksheet worksheet, Resource mappingRes, URI trMapUri)
      throws RepositoryException {
    // Add the Logical table information
    BNode logTableBNode = f.createBNode();
   
    con.add(logTableBNode, repoURIs.get(Uris.RR_TABLENAME_URI), f.createLiteral(worksheet.getTitle()));
    con.add(logTableBNode, RDF.TYPE, repoURIs.get(Uris.RR_LOGICAL_TABLE_CLASS_URI));
    con.add(logTableBNode, repoURIs.get(Uris.KM_IS_PART_OF_MAPPING_URI), mappingRes);
    con.add(mappingRes, repoURIs.get(Uris.KM_HAS_LOGICAL_TABLE_URI), logTableBNode);
    con.add(trMapUri, repoURIs.get(Uris.RR_LOGICAL_TABLE_URI), logTableBNode);

  }
 
  private void addSubjectMap(KR2RMLMapping mapping,
      Resource mappingRes, TriplesMap trMap,
      URI trMapUri, Workspace workspace) throws RepositoryException {
   
    KR2RMLColumnNameFormatter columnNameFormatter = mapping.getColumnNameFormatter();
    RepFactory factory = workspace.getFactory();
    // Add the subject map statements
    SubjectMap sjMap = trMap.getSubject();
    BNode sjBlankNode = f.createBNode();
    con.add(trMapUri, repoURIs.get(Uris.RR_SUBJECTMAP_URI), sjBlankNode);
    con.add(mappingRes, repoURIs.get(Uris.KM_HAS_SUBJECT_MAP_URI), sjBlankNode);
    con.add(sjBlankNode, repoURIs.get(Uris.KM_IS_PART_OF_MAPPING_URI), mappingRes);
    // Add the subject map type statement
    con.add(sjBlankNode, RDF.TYPE, repoURIs.get(Uris.RR_SUBJECTMAP_CLASS_URI));
   
    // Add the node id for the subject
    Value nodeIdVal = f.createLiteral(sjMap.getId());
    con.add(sjBlankNode, repoURIs.get(Uris.KM_NODE_ID_URI), nodeIdVal);
   
    // Add the type for subject maps
    List<TemplateTermSet> rdfsTypes = sjMap.getRdfsType();
    for (TemplateTermSet typeTermSet:rdfsTypes) {
      if (typeTermSet.isSingleUriString()) {
        URI sjTypeUri = f.createURI(typeTermSet.getR2rmlTemplateString(factory, columnNameFormatter));
        con.add(sjBlankNode, repoURIs.get(Uris.RR_CLASS_URI), sjTypeUri);
      } else {
        if (typeTermSet.isSingleColumnTerm()) {
          BNode typeBlankNode = f.createBNode();
          String colRepr  = typeTermSet.getR2rmlTemplateString(factory, columnNameFormatter);
          con.add(typeBlankNode, repoURIs.get(Uris.RR_TEMPLATE_URI), f.createLiteral(colRepr));
          con.add(sjBlankNode, repoURIs.get(Uris.RR_CLASS_URI), typeBlankNode);
        }
      }
    }
   
    // Check if the subject map is a blank node
    if (sjMap.isBlankNode()) {
      con.add(sjBlankNode, repoURIs.get(Uris.RR_TERM_TYPE_URI), repoURIs.get(Uris.RR_BLANK_NODE_URI));
     
      // Add the prefix name for the blank node
      String prefix = mapping.getAuxInfo().getBlankNodesUriPrefixMap().get(sjMap.getId());
      Value prefixVal = f.createLiteral(prefix);
      con.add(sjBlankNode, repoURIs.get(Uris.KM_BLANK_NODE_PREFIX_URI), prefixVal);
    }
    else
    {
      // Print out the template for anything that isn't a blank node
      Value templVal = f.createLiteral(sjMap.getTemplate()
          .getR2rmlTemplateString(factory, columnNameFormatter));
      con.add(sjBlankNode, repoURIs.get(Uris.RR_TEMPLATE_URI), templVal);
    }
   
    // Mark as Steiner tree root node if required
    if (sjMap.isSteinerTreeRootNode()) {
      con.add(sjBlankNode, RDF.TYPE, repoURIs.get(Uris.KM_STEINER_TREE_ROOT_NODE));
    }
  }


  private void addPredicateObjectMaps(
      KR2RMLMapping mapping, Resource mappingRes, TriplesMap trMap,
      URI trMapUri, Workspace workspace, Worksheet worksheet) throws RepositoryException {

    // Add the predicate object maps
    for (PredicateObjectMap pom:trMap.getPredicateObjectMaps()) {
      addPredicateObjectMap(mapping, mappingRes, trMapUri, workspace, pom, worksheet);
    }
  }

  private void addPredicateObjectMap(KR2RMLMapping mapping, Resource mappingRes, URI trMapUri,
      Workspace workspace, PredicateObjectMap pom, Worksheet worksheet)
      throws RepositoryException {
    KR2RMLColumnNameFormatter columnNameFormatter = mapping.getColumnNameFormatter();
    RepFactory factory = workspace.getFactory();
    URI pomUri = f.createURI(Namespaces.KARMA_DEV + pom.getId());
    //BNode pomBlankNode = f.createBNode();
   
    boolean usablePredicate = addPredicate(pom, columnNameFormatter, factory, pomUri);
    if(!usablePredicate)
    {
      return;
    }
   
    addObject(mappingRes, pom, columnNameFormatter, factory, pomUri, worksheet);
    con.add(trMapUri, repoURIs.get(Uris.RR_PRED_OBJ_MAP_URI), pomUri);
    // Add the predicate object map type statement
    con.add(pomUri, RDF.TYPE, repoURIs.get(Uris.RR_PREDICATEOBJECTMAP_CLASS_URI));
    con.add(pomUri, repoURIs.get(Uris.KM_IS_PART_OF_MAPPING_URI), mappingRes);
    con.add(mappingRes, repoURIs.get(Uris.KM_HAS_PREDICATE_OBJECT_MAP_URI), pomUri);
   
  }
 
  private boolean addPredicate(PredicateObjectMap pom,
      KR2RMLColumnNameFormatter columnNameFormatter, RepFactory factory,
      URI pomUri) throws RepositoryException {
    // Add the predicate
    TemplateTermSet predTermSet = pom.getPredicate().getTemplate();
    if (predTermSet.isSingleUriString()) {
      URI predValUri = f.createURI(predTermSet
          .getR2rmlTemplateString(factory, columnNameFormatter));
     
      // Skip the class instance special meta property
      if (predValUri.stringValue().equals(Uris.CLASS_INSTANCE_LINK_URI))
        return false;
     
      con.add(pomUri, repoURIs.get(Uris.RR_PREDICATE_URI), predValUri);
    } else {
      Value predValLiteratl = f.createLiteral(predTermSet.
          getR2rmlTemplateString(factory, columnNameFormatter));
      con.add(pomUri, repoURIs.get(Uris.RR_PREDICATE_URI), predValLiteratl);
    }
    return true;
  }

  private void addObject(Resource mappingRes, PredicateObjectMap pom,
      KR2RMLColumnNameFormatter columnNameFormatter, RepFactory factory,
      URI pomUri, Worksheet worksheet) throws RepositoryException {
    // Add the object: Could be RefObjectMap or simple object with column values
    if (pom.getObject().hasRefObjectMap()) {
      RefObjectMap rfMap = pom.getObject().getRefObjectMap();
      URI rfUri = f.createURI(Namespaces.KARMA_DEV + rfMap.getId());
      con.add(rfUri, RDF.TYPE, repoURIs.get(Uris.RR_REF_OBJECT_MAP_CLASS_URI));
      con.add(rfUri, RDF.TYPE, repoURIs.get(Uris.RR_OBJECTMAP_CLASS_URI));
     
      TriplesMap prMap = rfMap.getParentTriplesMap();
      URI prMapUri = f.createURI(Namespaces.KARMA_DEV + prMap.getId());
      con.add(rfUri, repoURIs.get(Uris.RR_PARENT_TRIPLE_MAP_URI), prMapUri);
      con.add(rfUri, repoURIs.get(Uris.KM_IS_PART_OF_MAPPING_URI), mappingRes);
      con.add(mappingRes, repoURIs.get(Uris.KM_HAS_OBJECT_MAP_URI), rfUri);
      // Add the RefObjectMap as the object map of current POMap
      con.add(pomUri, repoURIs.get(Uris.RR_OBJECTMAP_URI), rfUri);
    } else {
      TemplateTermSet objTermSet = pom.getObject().getTemplate();
      TemplateTermSet rdfLiteralTypeTermSet = pom.getObject().getRdfLiteralType();
       
      if (objTermSet.isSingleColumnTerm()) {
        BNode cnBnode = f.createBNode();
        Value cnVal = f.createLiteral(objTermSet.
            getColumnNameR2RMLRepresentation(factory, columnNameFormatter));
       
        con.add(cnBnode, repoURIs.get(Uris.RR_COLUMN_URI), cnVal);
        con.add(cnBnode, RDF.TYPE, repoURIs.get(Uris.RR_OBJECTMAP_CLASS_URI));
        if (rdfLiteralTypeTermSet != null && rdfLiteralTypeTermSet.isSingleUriString()) {
          String rdfLiteralTypeString = rdfLiteralTypeTermSet.
              getR2rmlTemplateString(factory);
          if(!rdfLiteralTypeString.isEmpty())
          {
            Value cnRdfLiteralType = f.createLiteral(rdfLiteralTypeString);
            con.add(cnBnode, repoURIs.get(Uris.RR_DATATYPE_URI), cnRdfLiteralType);
          }

        }
        con.add(cnBnode, repoURIs.get(Uris.KM_IS_PART_OF_MAPPING_URI), mappingRes);
        con.add(mappingRes, repoURIs.get(Uris.KM_HAS_OBJECT_MAP_URI), cnBnode);
       
        // Add the link b/w blank node and object map
        con.add(pomUri, repoURIs.get(Uris.RR_OBJECTMAP_URI), cnBnode);
      }
      else if(!objTermSet.isEmpty())
      {
        BNode cnBnode = f.createBNode();
        // Print out the template for anything that isn't a blank node
        boolean isUri = false;
       
        for (TemplateTerm term:objTermSet.getAllTerms()) {
          if (term instanceof StringTemplateTerm) {
            if(((StringTemplateTerm)term).hasFullUri())
              isUri = true;
          }
        }
           
        String value = objTermSet
            .getR2rmlTemplateString(factory, columnNameFormatter);
        Value templVal;
        if(isUri) {
          try {
            templVal = f.createURI(value);
          }catch(IllegalArgumentException e) {
            String baseURI = worksheet.getMetadataContainer().getWorksheetProperties().getPropertyValue(
                Property.baseURI);
            templVal = f.createURI(baseURI + value);
          }
        } else {
          templVal = f.createLiteral(value);
        }
        con.add(cnBnode, repoURIs.get(Uris.RR_CONSTANT), templVal);
        if (rdfLiteralTypeTermSet != null && rdfLiteralTypeTermSet.isSingleUriString()) {
          String rdfLiteralTypeString = rdfLiteralTypeTermSet.
              getR2rmlTemplateString(factory);
          if(!rdfLiteralTypeString.isEmpty())
          {
            Value cnRdfLiteralType = f.createLiteral(rdfLiteralTypeString);
            con.add(cnBnode, repoURIs.get(Uris.RR_DATATYPE_URI), cnRdfLiteralType);
          }

        }
        //con.add(cnBnode, repoURIs.get(Uris.RR_TERM_TYPE_URI), repoURIs.get(Uris.RR_LITERAL_URI));
        con.add(cnBnode, RDF.TYPE, repoURIs.get(Uris.RR_OBJECTMAP_CLASS_URI));
        con.add(cnBnode, repoURIs.get(Uris.KM_IS_PART_OF_MAPPING_URI), mappingRes);
        con.add(mappingRes, repoURIs.get(Uris.KM_HAS_OBJECT_MAP_URI), cnBnode);
       
        //Add the link b/w blank node and object map
        con.add(pomUri, repoURIs.get(Uris.RR_OBJECTMAP_URI), cnBnode);
       
      }
    }
  }


  public void close() throws RepositoryException {
    con.close();
    myRepository.shutDown();
  }

  public void addCompleteWorksheetHistory(KR2RMLMapping mapping, Resource mappingRes)
      throws RepositoryException {
    URI hasWorksheetHistoryUri = f.createURI(Uris.KM_HAS_WORKSHEET_HISTORY_URI);
   
      Value historyLiteral = f.createLiteral(mapping.getWorksheetHistory().toString(4));
      con.add(mappingRes, hasWorksheetHistoryUri, historyLiteral);
   
  }

  public void addWorksheetProperties(Worksheet worksheet, Resource mappingRes) throws RepositoryException {
    WorksheetProperties props = worksheet.getMetadataContainer().getWorksheetProperties();
    if (props == null) {
      return;
    }
   
    // Service options (if present)
    if (props.hasServiceProperties()) {
      if (props.getPropertyValue(Property.serviceUrl) == null) {
        return;
      }
     
      // Request method triple
      URI reqMethodUri = f.createURI(Uris.KM_SERVICE_REQ_METHOD_URI);
      Value method = f.createLiteral(props.getPropertyValue(Property.serviceRequestMethod));
      con.add(mappingRes, reqMethodUri, method);
     
      // Service Url triple
      URI serUrlUri = f.createURI(Uris.KM_SERVICE_URL_URI);
      Value servUrl = f.createLiteral(props.getPropertyValue(Property.serviceUrl));
      con.add(mappingRes, serUrlUri, servUrl);
     
      if (props.getPropertyValue(Property.serviceRequestMethod).equals(HttpMethods.POST.name())) {
        // POST method related option triple
        URI postMethodUri = f.createURI(Uris.KM_SERVICE_POST_METHOD_TYPE_URI);
        Value methodUrl = f.createLiteral(props.getPropertyValue(Property.serviceDataPostMethod));
        con.add(mappingRes, postMethodUri, methodUrl);
      }
    }
  }
}
TOP

Related Classes of edu.isi.karma.kr2rml.KR2RMLMappingWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.