/******************************************************************************* * 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.Collection; import java.util.LinkedList; import java.util.List; import org.jgrapht.graph.DirectedWeightedMultigraph; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.isi.karma.config.ModelingConfiguration; import edu.isi.karma.config.ModelingConfigurationRegistry; import edu.isi.karma.controller.command.CommandException; import edu.isi.karma.controller.command.CommandType; import edu.isi.karma.controller.command.WorksheetSelectionCommand; import edu.isi.karma.controller.command.selection.SuperSelection; import edu.isi.karma.controller.history.HistoryJsonUtil.ClientJsonKeys; import edu.isi.karma.controller.history.HistoryJsonUtil.ParameterType; import edu.isi.karma.controller.update.ErrorUpdate; 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.GraphUtil; import edu.isi.karma.modeling.alignment.SemanticModel; import edu.isi.karma.modeling.alignment.learner.ModelLearner; import edu.isi.karma.modeling.ontology.OntologyManager; import edu.isi.karma.modeling.semantictypes.SemanticTypeUtil; import edu.isi.karma.rep.HNode; 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.ColumnSemanticTypeStatus; import edu.isi.karma.rep.alignment.DefaultLink; import edu.isi.karma.rep.alignment.LinkStatus; import edu.isi.karma.rep.alignment.Node; import edu.isi.karma.rep.alignment.SemanticType; import edu.isi.karma.webserver.WorkspaceKarmaHomeRegistry; import edu.isi.karma.view.VWorksheet; import edu.isi.karma.view.VWorkspace; import edu.isi.karma.view.VWorkspaceRegistry; public class SuggestModelCommand extends WorksheetSelectionCommand { private String worksheetName; private Alignment initialAlignment = null; private DirectedWeightedMultigraph<Node, DefaultLink> initialGraph = null; private List<Node> steinerNodes; // private final boolean addVWorksheetUpdate; private static Logger logger = LoggerFactory .getLogger(SuggestModelCommand.class); protected SuggestModelCommand(String id, String model, String worksheetId, boolean addVWorksheetUpdate, String selectionId) { super(id, model, worksheetId, selectionId); // this.addVWorksheetUpdate = addVWorksheetUpdate; /** NOTE Not saving this command in history for now since we are * not letting CRF model assign semantic types automatically. This command * was being saved in history to keep track of the semantic types * that were assigned by the CRF Model **/ // addTag(CommandTag.Modeling); } @Override public String getCommandName() { return this.getClass().getSimpleName(); } @Override public String getTitle() { return "Suggest Model"; } @Override public String getDescription() { return worksheetName; } @Override public CommandType getCommandType() { return CommandType.undoable; } @SuppressWarnings("unchecked") @Override public UpdateContainer doIt(Workspace workspace) throws CommandException { ModelingConfiguration modelingConfiguration = ModelingConfigurationRegistry.getInstance().getModelingConfiguration(WorkspaceKarmaHomeRegistry.getInstance().getKarmaHome(workspace.getId())); UpdateContainer c = new UpdateContainer(); Worksheet worksheet = workspace.getWorksheet(worksheetId); SuperSelection selection = getSuperSelection(worksheet); OntologyManager ontologyManager = workspace.getOntologyManager(); if(ontologyManager.isEmpty()) return new UpdateContainer(new ErrorUpdate("No ontology loaded.")); worksheetName = worksheet.getTitle(); String alignmentId = AlignmentManager.Instance().constructAlignmentId(workspace.getId(), worksheetId); Alignment alignment = AlignmentManager.Instance().getAlignment(workspace.getId(), worksheetId); if (alignment == null) { logger.info("Alignment is NULL for " + worksheetId); return new UpdateContainer(new ErrorUpdate( "Alignment is NULL for " + worksheetId)); } if (initialAlignment == null) { initialAlignment = alignment.getAlignmentClone(); initialGraph = (DirectedWeightedMultigraph<Node, DefaultLink>)alignment.getGraph().clone(); List<HNode> orderedNodeIds = new ArrayList<>(); worksheet.getHeaders().getSortedLeafHNodes(orderedNodeIds); List<String> visibleHNodeIds = null; VWorkspace vWorkspace = VWorkspaceRegistry.getInstance().getVWorkspace(workspace.getId()); if (vWorkspace != null) { VWorksheet viewWorksheet = vWorkspace.getViewFactory().getVWorksheetByWorksheetId(worksheetId); visibleHNodeIds = viewWorksheet.getHeaderVisibleLeafNodes(); } if (orderedNodeIds != null) { for (int i = 0; i < orderedNodeIds.size(); i++) { String hNodeId = orderedNodeIds.get(i).getId(); if (visibleHNodeIds != null && !visibleHNodeIds.contains(hNodeId)) continue; ColumnNode cn = alignment.getColumnNodeByHNodeId(hNodeId); if (cn.getSemanticTypeStatus() == ColumnSemanticTypeStatus.NotAssigned) { worksheet.getSemanticTypes().unassignColumnSemanticType(hNodeId); List<SemanticType> suggestedSemanticTypes = new SemanticTypeUtil().getColumnSemanticSuggestions(workspace, worksheet, cn, 4, selection); cn.setLearnedSemanticTypes(suggestedSemanticTypes); cn.includeInAutoModel(); } } } } else { // Replace the current alignment with the old alignment alignment = initialAlignment; alignment.setGraph(initialGraph); if(!this.isExecutedInBatch()) alignment.align(); AlignmentManager.Instance().addAlignmentToMap(alignmentId, alignment); } steinerNodes = alignment.computeSteinerNodes(); ModelLearner modelLearner; if (modelingConfiguration.getKnownModelsAlignment()) modelLearner = new ModelLearner(alignment.getGraphBuilder(), steinerNodes); else modelLearner = new ModelLearner(ontologyManager, alignment.getLinksByStatus(LinkStatus.ForcedByUser), steinerNodes); // logger.info(GraphUtil.defaultGraphToString(ModelLearningGraph.getInstance(ontologyManager, ModelLearningGraphType.Compact).getGraphBuilder().getGraph())); SemanticModel model = modelLearner.getModel(); if (model == null) { logger.error("could not learn any model for this source!"); return new UpdateContainer(new ErrorUpdate( "Error occured while generating a semantic model for the source.")); } // logger.info(GraphUtil.labeledGraphToString(model.getGraph())); List<SemanticType> semanticTypes = new LinkedList<>(); alignment.updateAlignment(model, semanticTypes); logger.info(GraphUtil.labeledGraphToString(alignment.getSteinerTree())); // Set<ColumnNode> alignmentColumnNodes = alignment.getSourceColumnNodes(); // if (alignmentColumnNodes != null) { // for (ColumnNode cn : alignmentColumnNodes) { // worksheet.getSemanticTypes().unassignColumnSemanticType(cn.getHNodeId()); // } // } // if (semanticTypes != null) { // for (SemanticType st : semanticTypes) // worksheet.getSemanticTypes().addType(st); // } try { // Save the semantic types in the input parameter JSON saveSemanticTypesInformation(worksheet, workspace, worksheet.getSemanticTypes().getListOfTypes()); // Add the visualization update c.append(computeAlignmentAndSemanticTypesAndCreateUpdates(workspace)); } catch (Exception e) { logger.error("Error occured while generating the model Reason:.", e); return new UpdateContainer(new ErrorUpdate( "Error occured while generating the model for the source.")); } c.add(new TagsUpdate()); return c; } private void saveSemanticTypesInformation(Worksheet worksheet, Workspace workspace , Collection<SemanticType> semanticTypes) throws JSONException { JSONArray typesArray = new JSONArray(); // Add the vworksheet information JSONObject vwIDJObj = new JSONObject(); vwIDJObj.put(ClientJsonKeys.name.name(), ParameterType.worksheetId.name()); vwIDJObj.put(ClientJsonKeys.type.name(), ParameterType.worksheetId.name()); vwIDJObj.put(ClientJsonKeys.value.name(), worksheetId); typesArray.put(vwIDJObj); for (SemanticType type: semanticTypes) { // Add the hNode information JSONObject hNodeJObj = new JSONObject(); hNodeJObj.put(ClientJsonKeys.name.name(), ParameterType.hNodeId.name()); hNodeJObj.put(ClientJsonKeys.type.name(), ParameterType.hNodeId.name()); hNodeJObj.put(ClientJsonKeys.value.name(), type.getHNodeId()); typesArray.put(hNodeJObj); // Add the semantic type information JSONObject typeJObj = new JSONObject(); typeJObj.put(ClientJsonKeys.name.name(), ClientJsonKeys.SemanticType.name()); typeJObj.put(ClientJsonKeys.type.name(), ParameterType.other.name()); typeJObj.put(ClientJsonKeys.value.name(), type.getJSONArrayRepresentation()); typesArray.put(typeJObj); } setInputParameterJson(typesArray.toString()); } @Override public UpdateContainer undoIt(Workspace workspace) { UpdateContainer c = new UpdateContainer(); Worksheet worksheet = workspace.getWorksheet(worksheetId); OntologyManager ontologyManager = workspace.getOntologyManager(); if(ontologyManager.isEmpty()) return new UpdateContainer(new ErrorUpdate("No ontology loaded.")); String alignmentId = AlignmentManager.Instance().constructAlignmentId(workspace.getId(), worksheetId); Alignment alignment = AlignmentManager.Instance().getAlignment(alignmentId); if (alignment == null) { logger.info("Alignment is NULL for " + worksheetId); return new UpdateContainer(new ErrorUpdate( "Please align the worksheet before generating R2RML Model!")); } // Set<ColumnNode> alignmentColumnNodes = alignment.getSourceColumnNodes(); // if (alignmentColumnNodes != null) { // for (ColumnNode cn : alignmentColumnNodes) { // if (!cn.hasUserType()) // worksheet.getSemanticTypes().unassignColumnSemanticType(cn.getHNodeId()); // } // } alignment = initialAlignment; alignment.setGraph(initialGraph); if(!this.isExecutedInBatch()) alignment.align(); AlignmentManager.Instance().addAlignmentToMap(alignmentId, alignment); try { // Save the semantic types in the input parameter JSON saveSemanticTypesInformation(worksheet, workspace, worksheet.getSemanticTypes().getListOfTypes()); c.append(this.computeAlignmentAndSemanticTypesAndCreateUpdates(workspace)); // Add the visualization update } catch (Exception e) { logger.error("Error occured while generating the model Reason:.", e); return new UpdateContainer(new ErrorUpdate( "Error occured while generating the model for the source.")); } c.add(new TagsUpdate()); return c; } }