/******************************************************************************* * 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.command.alignment; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import org.jgrapht.graph.DirectedWeightedMultigraph; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.isi.karma.controller.command.CommandException; import edu.isi.karma.controller.command.CommandType; import edu.isi.karma.controller.command.WorksheetCommand; import edu.isi.karma.controller.command.selection.SuperSelectionManager; import edu.isi.karma.controller.update.AlignmentSVGVisualizationUpdate; import edu.isi.karma.controller.update.ErrorUpdate; import edu.isi.karma.controller.update.SemanticTypesUpdate; import edu.isi.karma.controller.update.TagsUpdate; import edu.isi.karma.controller.update.UpdateContainer; import edu.isi.karma.modeling.alignment.Alignment; import edu.isi.karma.modeling.alignment.AlignmentManager; import edu.isi.karma.modeling.alignment.LinkIdFactory; import edu.isi.karma.rep.HNodePath; import edu.isi.karma.rep.Worksheet; import edu.isi.karma.rep.Workspace; import edu.isi.karma.rep.alignment.ColumnNode; import edu.isi.karma.rep.alignment.DefaultLink; import edu.isi.karma.rep.alignment.LabeledLink; import edu.isi.karma.rep.alignment.Node; import edu.isi.karma.rep.alignment.SemanticType; import edu.isi.karma.rep.alignment.SemanticTypes; import edu.isi.karma.rep.metadata.TagsContainer.TagName; public class UnassignSemanticTypeCommand extends WorksheetCommand { private final String hNodeId; private String columnName; private ArrayList<SemanticType> oldSemanticTypes; private Alignment oldAlignment; private DirectedWeightedMultigraph<Node, DefaultLink> oldGraph; public enum JsonKeys { edgeSourceId, edgeId, edgeTargetId, edgeSourceUri, edgeTargetUri } private static Logger logger = LoggerFactory .getLogger(UnassignSemanticTypeCommand.class); public UnassignSemanticTypeCommand(String id, String model, String hNodeId, String worksheetId) { super(id, model, worksheetId); this.hNodeId = hNodeId; addTag(CommandTag.SemanticType); } @Override public String getCommandName() { return this.getClass().getSimpleName(); } @Override public String getTitle() { return "Unassign Semantic Type"; } @Override public String getDescription() { return columnName; } @Override public CommandType getCommandType() { return CommandType.undoable; } @SuppressWarnings("unchecked") @Override public UpdateContainer doIt(Workspace workspace) throws CommandException { Worksheet worksheet = workspace.getWorksheet(worksheetId); // Save the old SemanticType object for undo SemanticTypes types = worksheet.getSemanticTypes(); oldSemanticTypes = types.getSemanticTypeForHNodeId(hNodeId); HashMap<String, SemanticType> semanticIdMap = new HashMap<>(); for(SemanticType type : oldSemanticTypes) { String semId = LinkIdFactory.getLinkId(type.getType().getUri(), type.getDomainId(), type.getHNodeId()); semanticIdMap.put(semId, type); } Alignment alignment = AlignmentManager.Instance().getAlignment(workspace.getId(), worksheetId); oldAlignment = alignment.getAlignmentClone(); oldGraph = (DirectedWeightedMultigraph<Node, DefaultLink>)alignment.getGraph().clone(); ColumnNode columnNode = alignment.getColumnNodeByHNodeId(hNodeId); Set<LabeledLink> alignmentEdges = alignment.getCurrentIncomingLinksToNode(hNodeId); for(LabeledLink edge: alignmentEdges) { String linkId = edge.getId(); SemanticType type = semanticIdMap.get(linkId); types.removeType(type); columnNode.unassignUserType(type); columnNode.setForced(false); LabeledLink currentLink = alignment.getLinkById(linkId); alignment.removeLink(linkId); Node domain = currentLink.getSource(); if (domain != null) { String domainId = domain.getId(); if (alignment.isNodeIsolatedInTree(domainId)) alignment.removeNode(domainId); } } if(!this.isExecutedInBatch()) alignment.align(); // Get the column name HNodePath currentPath = null; List<HNodePath> columnPaths = worksheet.getHeaders().getAllPaths(); for (HNodePath path : columnPaths) { if (path.getLeaf().getId().equals(hNodeId)) { currentPath = path; columnName = path.getLeaf().getColumnName(); break; } } // Remove the nodes (if any) from the outlier tag Collection<edu.isi.karma.rep.Node> nodes = new ArrayList<>(); //TODO What does that mean? worksheet.getDataTable().collectNodes(currentPath, nodes, SuperSelectionManager.DEFAULT_SELECTION); Set<String> nodeIds = new HashSet<>(); for (edu.isi.karma.rep.Node node : nodes) { nodeIds.add(node.getId()); } workspace.getTagsContainer().getTag(TagName.Outlier) .removeNodeIds(nodeIds); // Update the container UpdateContainer c = new UpdateContainer(); c.add(new SemanticTypesUpdate(worksheet, worksheetId)); // Add the alignment update try { c.add(new AlignmentSVGVisualizationUpdate(worksheetId)); } catch (Exception e) { logger.error("Error occured while unassigning the semantic type!",e); return new UpdateContainer(new ErrorUpdate("Error occured while unassigning the semantic type!")); } c.add(new TagsUpdate()); return c; } @Override public UpdateContainer undoIt(Workspace workspace) { Worksheet worksheet = workspace.getWorksheet(worksheetId); // Add the old SemanticType object if it is not null SemanticTypes types = worksheet.getSemanticTypes(); if (oldSemanticTypes != null) { types.setType(oldSemanticTypes); } // Update the container UpdateContainer c = new UpdateContainer(); // Update with old alignment String alignmentId = AlignmentManager.Instance().constructAlignmentId(workspace.getId(), worksheetId); AlignmentManager.Instance().addAlignmentToMap(alignmentId, oldAlignment); oldAlignment.setGraph(oldGraph); try { c.add(new SemanticTypesUpdate(worksheet, worksheetId)); c.add(new AlignmentSVGVisualizationUpdate(worksheetId)); } catch (Exception e) { logger.error("Error occured during undo of unassigning the semantic type!", e); return new UpdateContainer(new ErrorUpdate("Error occured during undo of unassigning the semantic type!")); } return c; } public ArrayList<SemanticType> getOldSemanticTypes() { return oldSemanticTypes; } @Override public Set<String> getInputColumns() { return new HashSet<>(Arrays.asList(hNodeId)); } @Override public Set<String> getOutputColumns() { return new HashSet<>(Arrays.asList(hNodeId)); } }