edu.isi.karma.kr2rml.mapping.WorksheetR2RMLJenaModelParser.java Source code

Java tutorial

Introduction

Here is the source code for edu.isi.karma.kr2rml.mapping.WorksheetR2RMLJenaModelParser.java

Source

/*******************************************************************************
 * 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.mapping;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;

import edu.isi.karma.kr2rml.KR2RMLVersion;
import edu.isi.karma.kr2rml.ObjectMap;
import edu.isi.karma.kr2rml.Predicate;
import edu.isi.karma.kr2rml.PredicateObjectMap;
import edu.isi.karma.kr2rml.Prefix;
import edu.isi.karma.kr2rml.RefObjectMap;
import edu.isi.karma.kr2rml.SubjectMap;
import edu.isi.karma.kr2rml.formatter.KR2RMLColumnNameFormatter;
import edu.isi.karma.kr2rml.formatter.KR2RMLColumnNameFormatterFactory;
import edu.isi.karma.kr2rml.planning.TriplesMap;
import edu.isi.karma.kr2rml.planning.TriplesMapLink;
import edu.isi.karma.kr2rml.template.ColumnTemplateTerm;
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.kr2rml.template.TemplateTermSetBuilder;
import edu.isi.karma.modeling.Uris;
import edu.isi.karma.rep.metadata.WorksheetProperties.SourceTypes;
import edu.isi.karma.webserver.KarmaException;

public class WorksheetR2RMLJenaModelParser {

    private Model model;
    private R2RMLMappingIdentifier id;
    private KR2RMLMapping mapping;
    private static Logger logger = LoggerFactory.getLogger(WorksheetR2RMLJenaModelParser.class);

    public WorksheetR2RMLJenaModelParser(R2RMLMappingIdentifier id) throws JSONException, KarmaException {
        this.id = id;
    }

    public WorksheetR2RMLJenaModelParser(Model model, R2RMLMappingIdentifier id)
            throws JSONException, KarmaException {
        this.id = id;
    }

    public synchronized Model getModel() throws IOException {
        if (this.model == null) {
            loadModel();
        }
        return model;
    }

    public Model getModelFromCache() {
        return model;
    }

    private void loadModel() throws IOException {
        if (model != null) {
            return;
        }
        synchronized (this) {
            if (model == null) {
                this.model = loadSourceModelIntoJenaModel(id);
            }
        }
    }

    public KR2RMLMapping parse() throws IOException, KarmaException, JSONException {
        loadModel();

        if (null != mapping) {
            return mapping;
        }
        synchronized (this) {
            if (null != mapping) {
                return mapping;
            }
            // Capture the main mapping resource that corresponds to the source name
            Resource mappingResource = getMappingResourceFromSourceName();
            if (mappingResource == null) {
                throw new KarmaException("Resource not found in model for the source: " + id.getName());
            }

            Property modelVersionNameProp = model.getProperty(Uris.KM_MODEL_VERSION_URI);
            Statement s = model.getProperty(mappingResource, modelVersionNameProp);

            KR2RMLVersion version;
            try {
                version = new KR2RMLVersion(s.getString());
            } catch (Exception e) {
                version = KR2RMLVersion.unknown;
            }
            KR2RMLMapping kr2rmlMapping = new KR2RMLMapping(id, version);
            Map<String, String> prefixes = model.getNsPrefixMap();
            for (Entry<String, String> prefix : prefixes.entrySet()) {
                Prefix p = new Prefix(prefix.getKey(), prefix.getValue());
                kr2rmlMapping.addPrefix(p);
            }

            SourceTypes sourceType = getSourceType(mappingResource);
            kr2rmlMapping.setColumnNameFormatter(KR2RMLColumnNameFormatterFactory.getFormatter(sourceType));
            // Load any transformations on the worksheet if required
            loadWorksheetHistory(mappingResource, kr2rmlMapping);

            // Generate TriplesMap for each InternalNode in the tree
            List<Resource> subjectResources = createSubjectMaps(mappingResource, kr2rmlMapping);

            // Identify the object property links
            createPredicateObjectMaps(mappingResource, kr2rmlMapping);

            // Calculate the nodes covered by each InternalNode
            calculateColumnNodesCoveredByBlankNodes(kr2rmlMapping, subjectResources);
            createGraphNodeToTriplesNodeMap(kr2rmlMapping);
            return mapping = kr2rmlMapping;
        }
    }

    private void createGraphNodeToTriplesNodeMap(KR2RMLMapping kr2rmlMapping)
            throws FileNotFoundException, UnsupportedEncodingException {

        StmtIterator itr = model.listStatements(null, model.getProperty(Uris.KM_NODE_ID_URI), (RDFNode) null);
        Resource subject;
        Map<String, String> graphNodeIdToTriplesMapIdMap = kr2rmlMapping.getAuxInfo()
                .getGraphNodeIdToTriplesMapIdMap();
        while (itr.hasNext()) {
            Statement subjMapToNodeIdStmt = itr.next();
            String nodeId = subjMapToNodeIdStmt.getObject().toString();
            subject = subjMapToNodeIdStmt.getSubject();
            if (subject != null) {
                StmtIterator itr2 = model.listStatements(null, model.getProperty(Uris.RR_SUBJECTMAP_URI), subject);
                while (itr2.hasNext()) {
                    String triplesMapId = itr2.next().getSubject().toString();
                    graphNodeIdToTriplesMapIdMap.put(nodeId, triplesMapId);
                }

            }
        }
    }

    private SourceTypes getSourceType(Resource mappingResource) {
        Property sourceNameProp = model.getProperty(Uris.KM_SOURCE_TYPE_URI);
        Statement s = model.getProperty(mappingResource, sourceNameProp);
        String sourceType;
        if (s != null) {
            RDFNode node = s.getObject();
            if (node != null && node.isLiteral()) {
                sourceType = node.asLiteral().getString();
                return SourceTypes.valueOf(sourceType);
            }
        }
        return SourceTypes.CSV;

    }

    public static Model loadSourceModelIntoJenaModel(R2RMLMappingIdentifier id) throws IOException {
        // Create an empty Model
        Model model = ModelFactory.createDefaultModel();
        InputStream s;
        if (id.getContent() != null) {
            s = IOUtils.toInputStream(id.getContent());
        } else {
            URL modelURL = id.getLocation();
            logger.info("Load model:" + modelURL.toString());
            s = modelURL.openStream();
        }
        model.read(s, null, "TURTLE");
        return model;
    }

    private Resource getMappingResourceFromSourceName() throws KarmaException {
        Property sourceNameProp = model.getProperty(Uris.KM_SOURCE_NAME_URI);
        RDFNode node = model.createLiteral(id.getName());
        ResIterator res = model.listResourcesWithProperty(sourceNameProp, node);
        List<Resource> resList = res.toList();

        if (resList.size() > 1) {
            throw new KarmaException("More than one resource exists with source name: " + id.getName());
        } else if (resList.size() == 1) {
            return resList.get(0);
        } else {
            //If we didnt find the sourceName in the model, maybe it is a different source with the
            //same schema.
            //Maybe we need to substitute the sourceName in the model with this one
            NodeIterator sourceObjectIter = model.listObjectsOfProperty(sourceNameProp);
            List<RDFNode> sourceObjects = sourceObjectIter.toList();

            if (sourceObjects.size() > 1) {
                throw new KarmaException("More than one resource exists with source name: " + id.getName());
            } else if (sourceObjects.size() == 1) {
                RDFNode prevSourceObject = sourceObjects.get(0);

                //We got the previous source object, now get the Subject Node for this
                ResIterator prevSourceSubjectsIter = model.listResourcesWithProperty(sourceNameProp,
                        prevSourceObject);
                List<Resource> prevSourceSubjects = prevSourceSubjectsIter.toList();

                if (prevSourceSubjects.size() == 1) {
                    Resource subject = prevSourceSubjects.get(0);
                    model.remove(subject, sourceNameProp, prevSourceObject);
                    model.add(subject, sourceNameProp, node);
                    return subject;
                } else if (prevSourceSubjects.size() > 1) {
                    throw new KarmaException(
                            "More than one resource exists with model source name: " + prevSourceObject.toString());
                }
            }
            return null;
        }
    }

    private void loadWorksheetHistory(Resource mappingResource, KR2RMLMapping kr2rmlMapping) throws JSONException {
        JSONArray normalizedCommandsJSON = getWorksheetHistory(mappingResource);
        kr2rmlMapping.setWorksheetHistory(normalizedCommandsJSON);
    }

    private JSONArray getWorksheetHistory(Resource mappingResource) throws JSONException {
        Property hasTransformation = model.getProperty(Uris.KM_HAS_WORKSHEET_HISTORY_URI);
        NodeIterator transItr = model.listObjectsOfProperty(mappingResource, hasTransformation);
        while (transItr.hasNext()) {
            String commands = transItr.next().toString();
            return new JSONArray(commands);
        }
        return new JSONArray();
    }

    private void createPredicateObjectMaps(Resource mappingResource, KR2RMLMapping kr2rmlMapping)
            throws JSONException {
        Property hasTrMapUri = model.getProperty(Uris.KM_HAS_TRIPLES_MAP_URI);

        // Get all the triple maps
        NodeIterator trMapsResItr = model.listObjectsOfProperty(mappingResource, hasTrMapUri);
        while (trMapsResItr.hasNext()) {
            // Add the predicate object maps
            addPredicateObjectMapsForTripleMap(trMapsResItr.next().asResource(), kr2rmlMapping);
        }
    }

    private List<Resource> createSubjectMaps(Resource mappingResource, KR2RMLMapping kr2rmlMapping)
            throws JSONException {
        List<Resource> subjectMapResources = new ArrayList<>();
        Property hasTrMapUri = model.getProperty(Uris.KM_HAS_TRIPLES_MAP_URI);

        // Get all the triple maps
        NodeIterator trMapsResItr = model.listObjectsOfProperty(mappingResource, hasTrMapUri);
        while (trMapsResItr.hasNext()) {
            Resource trMapRes = trMapsResItr.next().asResource();
            SubjectMap subjMap = addSubjectMapForTripleMap(trMapRes, kr2rmlMapping, subjectMapResources);

            // Add the Triples map
            TriplesMap trMap = new TriplesMap(trMapRes.getURI(), subjMap);
            kr2rmlMapping.getTriplesMapIndex().put(trMapRes.getURI(), trMap);
            kr2rmlMapping.addTriplesMap(trMap);
            kr2rmlMapping.getAuxInfo().getTriplesMapGraph().addTriplesMap(trMap);
        }
        return subjectMapResources;
    }

    private void addPredicateObjectMapsForTripleMap(Resource trMapRes, KR2RMLMapping kr2rmlMapping)
            throws JSONException {
        int predicateIdCounter = 0;
        int objectMapCounter = 0;
        Property predObjMapProp = model.getProperty(Uris.RR_PRED_OBJ_MAP_URI);
        Property predProp = model.getProperty(Uris.RR_PREDICATE_URI);
        Property objectMapProp = model.getProperty(Uris.RR_OBJECTMAP_URI);
        Property columnProp = model.getProperty(Uris.RR_COLUMN_URI);
        Property rdfLiteralTypeProp = model.getProperty(Uris.RR_DATATYPE_URI);
        Resource rfObjClassUri = model.getResource(Uris.RR_REF_OBJECT_MAP_CLASS_URI);
        Property parentTriplesMapProp = model.getProperty(Uris.RR_PARENT_TRIPLE_MAP_URI);
        Property rdfTypeProp = model.getProperty(Uris.RDF_TYPE_URI);
        Property templateProp = model.getProperty(Uris.RR_TEMPLATE_URI);
        Property constantProp = model.getProperty(Uris.RR_CONSTANT);
        KR2RMLColumnNameFormatter formatter = kr2rmlMapping.getColumnNameFormatter();
        TriplesMap trMap = kr2rmlMapping.getTriplesMapIndex().get(trMapRes.getURI());
        if (trMap == null) {
            logger.error("No Triples Map found for resource: " + trMapRes.getURI());
            return;
        }
        NodeIterator predObjItr = model.listObjectsOfProperty(trMapRes, predObjMapProp);
        while (predObjItr.hasNext()) {
            Resource pomBlankNode = predObjItr.next().asResource();
            // Create the PredicateObjectMap object for current POM
            PredicateObjectMap pom = new PredicateObjectMap(pomBlankNode.getURI(), trMap);

            // Get the predicate for the POM
            Predicate pred = null;
            NodeIterator pomPredItr = model.listObjectsOfProperty(pomBlankNode, predProp);
            while (pomPredItr.hasNext()) {
                RDFNode pomPredNode = pomPredItr.next();
                pred = new Predicate(pomPredNode.toString() + "-" + predicateIdCounter++);

                // Check if the predicate value is a URI or a literal (such as column name)
                if (pomPredNode instanceof Resource) {
                    pred.getTemplate()
                            .addTemplateTermToSet(new StringTemplateTerm(((Resource) pomPredNode).getURI(), true));
                } else {
                    pred.setTemplate(TemplateTermSetBuilder
                            .constructTemplateTermSetFromR2rmlTemplateString(pomPredNode.toString(), formatter));
                }
            }
            pom.setPredicate(pred);

            // Get the object for the POM
            ObjectMap objMap = null;
            NodeIterator pomObjItr = model.listObjectsOfProperty(pomBlankNode, objectMapProp);

            while (pomObjItr.hasNext()) {
                Resource objNode = pomObjItr.next().asResource();

                /** Check if objBlankNode is a RefObjectMap or a normal object map with column **/
                if (model.contains(objNode, rdfTypeProp, rfObjClassUri)) {
                    NodeIterator parentTripleMapItr = model.listObjectsOfProperty(objNode, parentTriplesMapProp);
                    while (parentTripleMapItr.hasNext()) {
                        Resource parentTripleRes = parentTripleMapItr.next().asResource();
                        TriplesMap parentTM = kr2rmlMapping.getTriplesMapIndex().get(parentTripleRes.getURI());

                        // Create a RefObjectMap
                        RefObjectMap rfMap = new RefObjectMap(objNode.getURI(), parentTM);
                        objMap = new ObjectMap(getNewObjectMapId(objectMapCounter++), rfMap);

                        // Add the link between triple maps in the auxInfo
                        TriplesMapLink link = new TriplesMapLink(trMap, parentTM, pom);
                        kr2rmlMapping.getAuxInfo().getTriplesMapGraph().addLink(link);
                    }
                } else {
                    NodeIterator objMapColStmts = model.listObjectsOfProperty(objNode, columnProp);
                    // RDF Literal Type
                    Statement objMapRdfLiteralTypeStmt = model.getProperty(objNode, rdfLiteralTypeProp);
                    TemplateTermSet rdfLiteralTypeTermSet = null;
                    if (objMapRdfLiteralTypeStmt != null && objMapRdfLiteralTypeStmt.getObject().isLiteral()) {
                        StringTemplateTerm rdfLiteralTypeTerm = new StringTemplateTerm(
                                objMapRdfLiteralTypeStmt.getObject().toString(), true);
                        rdfLiteralTypeTermSet = new TemplateTermSet();
                        rdfLiteralTypeTermSet.addTemplateTermToSet(rdfLiteralTypeTerm);
                    }
                    while (objMapColStmts.hasNext()) {
                        RDFNode colNode = objMapColStmts.next();
                        objMap = new ObjectMap(getNewObjectMapId(objectMapCounter++), TemplateTermSetBuilder
                                .constructTemplateTermSetFromR2rmlColumnString(colNode.toString(), formatter),
                                rdfLiteralTypeTermSet);
                    }
                    if (objMap == null) {
                        NodeIterator templateItr = model.listObjectsOfProperty(objNode, templateProp);
                        //try a literal/constant node
                        if (templateItr == null || !templateItr.hasNext()) {
                            templateItr = model.listObjectsOfProperty(objNode, constantProp);
                        }
                        TemplateTermSet objTemplTermSet = null;
                        while (templateItr.hasNext()) {
                            RDFNode templNode = templateItr.next();
                            String template = templNode.toString();
                            boolean isUri = !templNode.isLiteral();
                            objTemplTermSet = TemplateTermSetBuilder
                                    .constructTemplateTermSetFromR2rmlTemplateString(template, isUri,
                                            kr2rmlMapping.getColumnNameFormatter());

                        }
                        objMap = new ObjectMap(getNewObjectMapId(objectMapCounter++), objTemplTermSet,
                                rdfLiteralTypeTermSet);
                    }
                    // Check if anything needs to be added to the columnNameToPredicateObjectMap Map
                    if (objMap != null)
                        addColumnNameToPredObjectMapLink(objMap, pom, kr2rmlMapping);
                }
            }
            pom.setObject(objMap);
            trMap.addPredicateObjectMap(pom);
        }

        // Try to add template to pom
        TemplateTermSet subjTemplTermSet = trMap.getSubject().getTemplate();
        if (subjTemplTermSet != null) {
            List<TemplateTerm> terms = subjTemplTermSet.getAllTerms();
            if (isValidTemplate(terms)) {
                PredicateObjectMap pom = new PredicateObjectMap(PredicateObjectMap.getNewId(), trMap);
                Predicate pred = new Predicate(Uris.CLASS_INSTANCE_LINK_URI + "-" + predicateIdCounter++);
                pred.getTemplate().addTemplateTermToSet(new StringTemplateTerm(Uris.CLASS_INSTANCE_LINK_URI, true));
                pom.setPredicate(pred);
                StringTemplateTerm rdfLiteralTypeTerm = new StringTemplateTerm("", true);
                TemplateTermSet rdfLiteralTypeTermSet = new TemplateTermSet();
                rdfLiteralTypeTermSet.addTemplateTermToSet(rdfLiteralTypeTerm);
                ObjectMap objMap = new ObjectMap(getNewObjectMapId(objectMapCounter++), subjTemplTermSet,
                        rdfLiteralTypeTermSet);
                pom.setObject(objMap);
                trMap.addPredicateObjectMap(pom);
                addColumnNameToPredObjectMapLink(objMap, pom, kr2rmlMapping);

            }
        }
    }

    private boolean isValidTemplate(List<TemplateTerm> terms) {
        if (terms == null || terms.isEmpty()) {
            return false;
        }

        for (TemplateTerm term : terms) {
            if (term instanceof ColumnTemplateTerm) {
                return true;
            }
        }
        return false;
    }

    private void addColumnNameToPredObjectMapLink(ObjectMap objMap, PredicateObjectMap pom,
            KR2RMLMapping kr2rmlMapping) {
        TemplateTermSet objTermSet = objMap.getTemplate();
        if (objTermSet == null) {
            logger.error("No matching object term set");
            return;
        }
        for (TemplateTerm term : objTermSet.getAllTerms()) {
            if (term instanceof ColumnTemplateTerm) {
                String columnName = term.getTemplateTermValue();
                String columnNameWithoutFormatting = kr2rmlMapping.getColumnNameFormatter()
                        .getColumnNameWithoutFormatting(columnName);
                List<PredicateObjectMap> existingPomList = kr2rmlMapping.getAuxInfo().getColumnNameToPredObjLinks()
                        .get(columnNameWithoutFormatting);
                if (existingPomList == null) {
                    existingPomList = new ArrayList<>();
                }
                existingPomList.add(pom);
                kr2rmlMapping.getAuxInfo().getColumnNameToPredObjLinks().put(columnNameWithoutFormatting,
                        existingPomList);
            }
        }
    }

    private String getNewObjectMapId(int objectMapCounter) {
        return "ObjectMap" + objectMapCounter;
    }

    private SubjectMap addSubjectMapForTripleMap(Resource trMapRes, KR2RMLMapping kr2rmlMapping,
            List<Resource> subjectMapResources) throws JSONException {
        SubjectMap subjMap = null;
        Property subjMapProp = model.getProperty(Uris.RR_SUBJECTMAP_URI);
        Property templateProp = model.getProperty(Uris.RR_TEMPLATE_URI);
        Property rdfTypeProp = model.getProperty(Uris.RDF_TYPE_URI);
        Property rrClassProp = model.getProperty(Uris.RR_CLASS_URI);
        Resource steinerTreeRootNodeRes = model.getResource(Uris.KM_STEINER_TREE_ROOT_NODE);

        NodeIterator subjMapsItr = model.listObjectsOfProperty(trMapRes, subjMapProp);
        while (subjMapsItr.hasNext()) {
            Resource subjMapBlankRes = subjMapsItr.next().asResource();
            subjectMapResources.add(subjMapBlankRes);

            String subjMapId = subjMapBlankRes.getId().getLabelString();
            subjMap = new SubjectMap(subjMapId);
            kr2rmlMapping.getSubjectMapIndex().put(subjMapId, subjMap);

            // Get the subject template
            NodeIterator templateItr = model.listObjectsOfProperty(subjMapBlankRes, templateProp);
            TemplateTermSet subjTemplTermSet = null;
            while (templateItr.hasNext()) {
                RDFNode templNode = templateItr.next();
                String template = templNode.toString();
                subjTemplTermSet = TemplateTermSetBuilder.constructTemplateTermSetFromR2rmlTemplateString(template,
                        kr2rmlMapping.getColumnNameFormatter());
                List<String> columnsCovered = new LinkedList<>();
                for (TemplateTerm term : subjTemplTermSet.getAllColumnNameTermElements()) {
                    columnsCovered.add(term.getTemplateTermValue());
                }
                kr2rmlMapping.getAuxInfo().getSubjectMapIdToTemplateAnchor().put(subjMap.getId(),
                        KR2RMLMappingAuxillaryInformation.findSubjectMapTemplateAnchor(columnsCovered));

            }
            subjMap.setTemplate(subjTemplTermSet);

            // Get the subject type
            NodeIterator rdfTypesItr = model.listObjectsOfProperty(subjMapBlankRes, rrClassProp);
            while (rdfTypesItr.hasNext()) {
                RDFNode typeNode = rdfTypesItr.next();

                if (typeNode.isAnon()) {
                    NodeIterator typeTemplItr = model.listObjectsOfProperty(typeNode.asResource(), templateProp);

                    while (typeTemplItr.hasNext()) {
                        RDFNode templNode = typeTemplItr.next();
                        String template = templNode.toString();
                        TemplateTermSet typeTermSet = TemplateTermSetBuilder
                                .constructTemplateTermSetFromR2rmlTemplateString(template);
                        subjMap.addRdfsType(typeTermSet);
                    }
                    continue;
                }

                if (typeNode instanceof Resource) {
                    // Skip the steiner tree root type
                    if (((Resource) typeNode).getURI().equals(Uris.KM_STEINER_TREE_ROOT_NODE))
                        continue;

                    StringTemplateTerm uriTerm = new StringTemplateTerm(((Resource) typeNode).getURI(), true);
                    TemplateTermSet typeTermSet = new TemplateTermSet();
                    typeTermSet.addTemplateTermToSet(uriTerm);
                    subjMap.addRdfsType(typeTermSet);
                } else {
                    TemplateTermSet typeTermSet = TemplateTermSetBuilder
                            .constructTemplateTermSetFromR2rmlTemplateString(typeNode.toString());
                    subjMap.addRdfsType(typeTermSet);
                }
            }

            // Check if it is as the Steiner tree root node
            if (model.contains(subjMapBlankRes, rdfTypeProp, steinerTreeRootNodeRes)) {
                subjMap.setAsSteinerTreeRootNode(true);
            }
        }
        return subjMap;
    }

    private void calculateColumnNodesCoveredByBlankNodes(KR2RMLMapping kr2rmlMapping,
            List<Resource> subjectMapResources) throws JSONException, KarmaException {
        Property termTypeProp = model.getProperty(Uris.RR_TERM_TYPE_URI);
        Resource blankNodeRes = model.getResource(Uris.RR_BLANK_NODE_URI);
        Property kmBnodePrefixProp = model.getProperty(Uris.KM_BLANK_NODE_PREFIX_URI);
        ResIterator blankNodeSubjMapItr = model.listResourcesWithProperty(termTypeProp, blankNodeRes);

        for (Resource subjMapRes : subjectMapResources) {

            if (model.contains(subjMapRes, termTypeProp, blankNodeRes)) {
                List<String> columnsCovered = new ArrayList<>();
                Resource blankNodeSubjRes = blankNodeSubjMapItr.next();

                SubjectMap subjMap = kr2rmlMapping.getSubjectMapIndex()
                        .get(blankNodeSubjRes.getId().getLabelString());
                subjMap.setAsBlankNode(true);
                NodeIterator bnodePrefixItr = model.listObjectsOfProperty(blankNodeSubjRes, kmBnodePrefixProp);
                while (bnodePrefixItr.hasNext()) {
                    kr2rmlMapping.getAuxInfo().getBlankNodesUriPrefixMap().put(subjMap.getId(),
                            bnodePrefixItr.next().toString());
                }

                TriplesMap mytm;
                for (TriplesMap tm : kr2rmlMapping.getTriplesMapList()) {
                    if (tm.getSubject().getId().equalsIgnoreCase(subjMap.getId())) {
                        mytm = tm;

                        List<PredicateObjectMap> poms = mytm.getPredicateObjectMaps();
                        for (PredicateObjectMap pom : poms) {
                            ObjectMap objMap = pom.getObject();
                            if (objMap == null) {
                                logger.error("Unable to find object map for pom :" + pom.toString());
                            }

                            TemplateTermSet templateTermSet = pom.getObject().getTemplate();
                            if (templateTermSet != null) {
                                TemplateTerm term = templateTermSet.getAllTerms().get(0);
                                if (term != null && term instanceof ColumnTemplateTerm) {
                                    columnsCovered.add(term.getTemplateTermValue());
                                }
                            }
                        }

                        if (columnsCovered.isEmpty()) {
                            //String blankNodeUriPrefix = kr2rmlMapping.getAuxInfo().getBlankNodesUriPrefixMap().get(subjMap.getId());
                            //throw new KarmaException("You need to define a URI for "+blankNodeUriPrefix+ ".");
                        }
                        break;
                    }
                }

                logger.debug("Adding columns for blank node" + subjMap.getId() + " List: " + columnsCovered);
                kr2rmlMapping.getAuxInfo().getBlankNodesColumnCoverage().put(subjMap.getId(), columnsCovered);
                kr2rmlMapping.getAuxInfo().getSubjectMapIdToTemplateAnchor().put(subjMap.getId(),
                        KR2RMLMappingAuxillaryInformation.findSubjectMapTemplateAnchor(columnsCovered));
                // Get the blank node prefix

            }
        }
    }

}