/******************************************************************************* * 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.controller.update; import java.io.PrintWriter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.json.JSONException; import org.json.JSONStringer; import org.json.JSONWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.isi.karma.modeling.alignment.Alignment; import edu.isi.karma.modeling.semantictypes.CRFColumnModel; import edu.isi.karma.rep.HNode; import edu.isi.karma.rep.HNodePath; import edu.isi.karma.rep.Worksheet; import edu.isi.karma.rep.alignment.ClassInstanceLink; import edu.isi.karma.rep.alignment.ColumnNode; import edu.isi.karma.rep.alignment.ColumnSubClassLink; import edu.isi.karma.rep.alignment.DataPropertyOfColumnLink; import edu.isi.karma.rep.alignment.InternalNode; import edu.isi.karma.rep.alignment.Label; import edu.isi.karma.rep.alignment.Link; import edu.isi.karma.rep.alignment.LinkKeyInfo; import edu.isi.karma.rep.alignment.Node; import edu.isi.karma.rep.alignment.NodeType; import edu.isi.karma.rep.alignment.SemanticType; import edu.isi.karma.rep.alignment.SemanticTypes; import edu.isi.karma.rep.alignment.SynonymSemanticTypes; import edu.isi.karma.view.VWorkspace; public class SemanticTypesUpdate extends AbstractUpdate { private Worksheet worksheet; private String vWorksheetId; private Alignment alignment; public enum JsonKeys { HNodeId, FullType, ConfidenceLevel, Origin, FullCRFModel, DisplayLabel, DisplayDomainLabel, Domain, SemanticTypesArray, isPrimary, isPartOfKey, Types, isMetaProperty, rdfLiteralType } private static Logger logger = LoggerFactory .getLogger(SemanticTypesUpdate.class); public SemanticTypesUpdate(Worksheet worksheet, String vWorksheetId, Alignment alignment) { super(); this.worksheet = worksheet; this.vWorksheetId = vWorksheetId; this.alignment = alignment; } @Override public void generateJson(String prefix, PrintWriter pw, VWorkspace vWorkspace) { SemanticTypes types = worksheet.getSemanticTypes(); Map<String, ColumnNode> hNodeIdTocolumnNodeMap = createColumnNodeMap(); Map<String, InternalNode> hNodeIdToDomainNodeMap = createDomainNodeMap(); JSONStringer jsonStr = new JSONStringer(); try { JSONWriter writer = jsonStr.object(); writer.key("worksheetId").value(vWorksheetId).key("updateType") .value("SemanticTypesUpdate"); writer.key(JsonKeys.Types.name()); writer.array(); // Iterate through all the columns for (HNodePath path : worksheet.getHeaders().getAllPaths()) { HNode node = path.getLeaf(); String nodeId = node.getId(); writer.object(); // Check if a semantic type exists for the HNode SemanticType type = types.getSemanticTypeForHNodeId(nodeId); if (type != null && type.getConfidenceLevel() != SemanticType.ConfidenceLevel.Low) { writer.key(JsonKeys.HNodeId.name()) .value(type.getHNodeId()) .key(JsonKeys.SemanticTypesArray.name()).array(); ColumnNode alignmentColumnNode = hNodeIdTocolumnNodeMap.get(type.getHNodeId()); InternalNode domainNode = hNodeIdToDomainNodeMap.get(type.getHNodeId()); if (alignmentColumnNode == null || domainNode == null) { logger.error("Column node or domain node not found in alignment." + " (This should not happen conceptually!):" + type); continue; } // Add the primary semantic type writer.object() .key(JsonKeys.Origin.name()) .value(type.getOrigin().name()) .key(JsonKeys.ConfidenceLevel.name()) .value(type.getConfidenceLevel().name()) .key(JsonKeys.isPartOfKey.name()) .value(type.isPartOfKey()) .key(JsonKeys.isPrimary.name()) .value(true); // Add the RDF literal type to show in the text box String rdfLiteralType = alignmentColumnNode.getRdfLiteralType(); rdfLiteralType = (rdfLiteralType != null && !rdfLiteralType.equals("")) ? rdfLiteralType : ""; writer.key(JsonKeys.rdfLiteralType.name()) .value(rdfLiteralType); // String domainDisplayLabel = (domainNode.getLabel().getPrefix() != null && (!domainNode.getLabel().getPrefix().equals(""))) ? // (domainNode.getLabel().getPrefix() + ":" + domainNode.getLocalId()) : domainNode.getLocalId(); if (!type.isClass()) { writer .key(JsonKeys.FullType.name()) .value(type.getType().getUri()) .key(JsonKeys.DisplayLabel.name()) .value(type.getType().getDisplayName()) .key(JsonKeys.Domain.name()) .value(domainNode.getId()) .key(JsonKeys.DisplayDomainLabel.name()) .value(domainNode.getDisplayId()); } else { writer .key(JsonKeys.FullType.name()) .value(domainNode.getId()) .key(JsonKeys.DisplayLabel.name()) .value(domainNode.getDisplayId()) .key(JsonKeys.Domain.name()) .value("") .key(JsonKeys.DisplayDomainLabel.name()) .value(""); } // Mark the special properties writer .key(JsonKeys.isMetaProperty.name()) .value(isMetaProperty(type.getType(), alignmentColumnNode)); writer.endObject(); // Iterate through the synonym semantic types SynonymSemanticTypes synTypes = types .getSynonymTypesForHNodeId(nodeId); if (synTypes != null) { for (SemanticType synType : synTypes.getSynonyms()) { writer.object() .key(JsonKeys.HNodeId.name()) .value(synType.getHNodeId()) .key(JsonKeys.FullType.name()) .value(synType.getType().getUri()) .key(JsonKeys.Origin.name()) .value(synType.getOrigin().name()) .key(JsonKeys.ConfidenceLevel.name()) .value(synType.getConfidenceLevel().name()) .key(JsonKeys.DisplayLabel.name()) .value(synType.getType().getDisplayName()) .key(JsonKeys.isPrimary.name()) .value(false); if (!synType.isClass()) { writer.key(JsonKeys.Domain.name()) .value(synType.getDomain().getUri()) .key(JsonKeys.DisplayDomainLabel.name()) .value(synType.getDomain().getDisplayName()); } else { writer.key(JsonKeys.Domain.name()) .value("") .key(JsonKeys.DisplayDomainLabel.name()) .value(""); } writer.endObject(); } } writer.endArray(); } else { writer.key(JsonKeys.HNodeId.name()).value(nodeId); writer.key(JsonKeys.SemanticTypesArray.name()).array() .endArray(); } // Populate the CRF Model CRFColumnModel colModel = worksheet.getCrfModel().getModelByHNodeId(nodeId); if (colModel != null) { writer.key(JsonKeys.FullCRFModel.name()).value(colModel.getAsJSONObject(vWorkspace.getWorkspace().getOntologyManager(), alignment)); } writer.endObject(); } writer.endArray(); writer.endObject(); pw.print(writer.toString()); } catch (JSONException e) { logger.error("Error occured while writing to JSON!", e); } } private boolean isMetaProperty(Label type, ColumnNode alignmentColumnNode) { // Check for the case of DataPropertyOfColumnLink and ColumnSubClassLink boolean case1 = (type.getUri().equals(DataPropertyOfColumnLink.getFixedLabel().getUri()) || type.getUri().equals(ColumnSubClassLink.getFixedLabel().getUri())); if (case1) return true; Set<Link> incomingLinks = alignment.getCurrentIncomingLinksToNode(alignmentColumnNode.getId()); if (incomingLinks != null && !incomingLinks.isEmpty()) { Link incomingLink = incomingLinks.iterator().next(); if (incomingLink != null && (incomingLink instanceof ClassInstanceLink) && incomingLink.getKeyType().equals(LinkKeyInfo.UriOfInstance)) return true; } return false; } private Map<String, InternalNode> createDomainNodeMap() { Map<String, InternalNode> hNodeIdToDomainNodeMap = new HashMap<String, InternalNode>(); List<Node> alignmentColumnNodes = alignment.getNodesByType(NodeType.ColumnNode); if (alignmentColumnNodes == null) return hNodeIdToDomainNodeMap; for (Node cNode : alignmentColumnNodes) { Set<Link> incomingLinks = alignment.getCurrentIncomingLinksToNode(cNode.getId()); if (incomingLinks != null && !incomingLinks.isEmpty()) { Link incomingLink = alignment.getCurrentIncomingLinksToNode(cNode.getId()).iterator().next(); if (incomingLink!= null && incomingLink.getSource() instanceof InternalNode) { hNodeIdToDomainNodeMap.put(((ColumnNode)cNode).getHNodeId() , (InternalNode)incomingLink.getSource()); } } } return hNodeIdToDomainNodeMap; } private Map<String, ColumnNode> createColumnNodeMap() { List<Node> alignmentColumnNodes = alignment.getNodesByType(NodeType.ColumnNode); Map<String, ColumnNode> hNodeIdToColumnNodeMap = new HashMap<String, ColumnNode>(); if (alignmentColumnNodes == null) return hNodeIdToColumnNodeMap; for (Node cNode : alignmentColumnNodes) { ColumnNode columnNode = (ColumnNode) cNode; hNodeIdToColumnNodeMap.put(columnNode.getHNodeId(), columnNode); } return hNodeIdToColumnNodeMap; } }