/******************************************************************************* * Copyright (c) 2014 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.charts.ui; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.simantics.Simantics; import org.simantics.browsing.ui.common.ErrorLogger; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.ObjectUtils; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.adapter.DropActionFactory; import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable; import org.simantics.db.layer0.request.PossibleModel; import org.simantics.db.layer0.variable.RVI; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.VariableReference; import org.simantics.db.layer0.variable.Variables; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.modeling.PropertyVariables; import org.simantics.modeling.PropertyVariablesImpl; import org.simantics.modeling.utils.VariableReferences; import org.simantics.utils.datastructures.Callback; import org.simantics.utils.datastructures.collections.CollectionUtils; import org.simantics.utils.ui.ISelectionUtils; /** * @author Tuukka Lehtonen */ public class SubscriptionDropActionFactory implements DropActionFactory { @Override public Runnable create(ReadGraph g, Object target, Object source, int operation) throws DatabaseException { //System.out.println("DROP: " + source + " -> " + target); final Resource subscription = ISelectionUtils.getSinglePossibleKey(target, SelectionHints.KEY_MAIN, Resource.class); if (subscription == null) return null; Resource targetModel = g.syncRequest(new PossibleModel(subscription)); if(source instanceof RVI) { RVI rvi = (RVI)source; List refs = CollectionUtils.toList(new VariableReference(rvi, getDatatype(g, targetModel, rvi), null)); if (!refs.isEmpty()) return addSubscriptions(g, subscription, refs, Collections.emptySet()); } else { List vars = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, PropertyVariables.class); if (!vars.isEmpty()) { // FIXME: this is a hack for indexed value support vars = PropertyVariablesImpl.resolve(g, vars); List references = g.syncRequest(VariableReferences.toReferences(targetModel, vars)); if (!references.isEmpty()) return addSubscriptions(g, subscription, references, Collections.emptySet()); } else { List srcs = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, Resource.class); ModelingResources MOD = ModelingResources.getInstance(g); Set movedItems = new HashSet(); for (Resource src : srcs) { if (g.isInstanceOf(src, MOD.Subscription_Item)) { Resource model = g.syncRequest(new PossibleModel(src)); if (ObjectUtils.objectEquals(targetModel, model)) movedItems.add(src); } } if (!movedItems.isEmpty()) return addSubscriptions(g, subscription, Collections.emptyList(), movedItems); } } return null; } private Runnable addSubscriptions(ReadGraph graph, final Resource subscription, final List references, final Set movedSubscriptionItems) throws DatabaseException { final AddVariableToChartAction action = new AddVariableToChartAction(null, subscription, references); action.init(graph); return new Runnable() { @Override public void run() { action.run(); if(!movedSubscriptionItems.isEmpty()) { Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for (Resource item : movedSubscriptionItems) { graph.deny(item, L0.PartOf); graph.claim(subscription, L0.ConsistsOf, item); } } }, new Callback() { @Override public void run(DatabaseException e) { if (e != null) ErrorLogger.defaultLogError(e); } }); } } }; } static Datatype getDatatype(ReadGraph graph, Resource resource, RVI rvi) throws DatabaseException { Variable configuration = Variables.getConfigurationContext(graph, resource); Variable active = graph.syncRequest(new PossibleActiveVariableFromVariable(configuration)); Variable var = rvi.resolve(graph, active != null ? active : configuration); return var.getDatatype(graph); } }