X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.browsing.ui.model%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fmodel%2Factions%2FActionBrowseContext.java;fp=bundles%2Forg.simantics.browsing.ui.model%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fmodel%2Factions%2FActionBrowseContext.java;h=e1c67bebcd4727a8a9b5a270c3e7626cec00e501;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/actions/ActionBrowseContext.java b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/actions/ActionBrowseContext.java new file mode 100644 index 000000000..e1c67bebc --- /dev/null +++ b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/actions/ActionBrowseContext.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 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.browsing.ui.model.actions; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jface.action.Action; +import org.simantics.browsing.ui.BuiltinKeys; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.model.InvalidContribution; +import org.simantics.browsing.ui.model.browsecontexts.BrowseContexts; +import org.simantics.browsing.ui.model.browsecontexts.ResolveActionBrowseContext; +import org.simantics.browsing.ui.model.nodetypes.EntityNodeType; +import org.simantics.browsing.ui.model.nodetypes.NodeType; +import org.simantics.browsing.ui.model.nodetypes.NodeTypeMultiMap; +import org.simantics.browsing.ui.model.nodetypes.SpecialNodeType; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.viewpoint.ontology.ViewpointResource; + +/** + * ActionBrowseContext holds all contributions related to given set of action browse contexts. + * + * @author Hannu Niemistö + */ +public class ActionBrowseContext { + NodeTypeMultiMap actionContributions = new NodeTypeMultiMap(); + // TODO: remove these two temporary mechanisms + THashSet removableNodeTypes = new THashSet(); + THashSet renameableNodeTypes = new THashSet(); + NodeTypeMultiMap removalContributions = new NodeTypeMultiMap(); + NodeTypeMultiMap renamingContributions = new NodeTypeMultiMap(); + + private final String[] uris; + + private ActionBrowseContext(String[] uris) { + if (uris == null) + throw new NullPointerException("null URIs"); + this.uris = uris; + } + + public String[] getURIs() { + return uris; + } + + public static ActionBrowseContext get(ReadGraph graph,NodeContext context,ActionBrowseContext defaultContext) throws DatabaseException { + ActionBrowseContext mbc = graph.syncRequest(new ResolveActionBrowseContext(context)); + if(mbc != null) return mbc; + ActionBrowseContext parentContext = (ActionBrowseContext)context.getConstant(BuiltinKeys.ACTION_BROWSE_CONTEXT); + if(parentContext != null) return parentContext; + return defaultContext; + } + + public static ActionBrowseContext create(ReadGraph g, Collection browseContextResources) throws DatabaseException, InvalidContribution { + ViewpointResource vr = ViewpointResource.getInstance(g); + ActionBrowseContext browseContext = new ActionBrowseContext( BrowseContexts.toSortedURIs(g, browseContextResources) ); + for(Resource browseContextResource : findSubcontexts(g, browseContextResources)) { + for(Resource actionContributionResource : + g.getObjects(browseContextResource, vr.BrowseContext_HasActionContribution)) { + try { + ActionContribution.load(g, actionContributionResource, + browseContext.actionContributions + ); + } catch(DatabaseException e) { + e.printStackTrace(); + } + } + for(Resource canRemove : g.getObjects(browseContextResource, vr.BrowseContext_SupportsRemovalOf)) + browseContext.removableNodeTypes.add(canRemove); + for(Resource canRemove : g.getObjects(browseContextResource, vr.BrowseContext_SupportsRenamingOf)) + browseContext.renameableNodeTypes.add(canRemove); + + for (Resource testContribution : g.getObjects(browseContextResource, vr.BrowseContext_HasTestContribution)) { + try { + Set types = g.getTypes(testContribution); + if (types.contains(vr.RemovalTestContribution)) + TestContribution.load(g, testContribution, browseContext.removalContributions); + if (types.contains(vr.RenamingTestContribution)) + TestContribution.load(g, testContribution, browseContext.renamingContributions); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + } + return browseContext; + } + + private static Collection findSubcontexts(ReadGraph g, + Collection browseContexts) throws DatabaseException { + ViewpointResource vr = ViewpointResource.getInstance(g); + HashSet result = new HashSet(browseContexts); + ArrayList stack = new ArrayList(browseContexts); + while(!stack.isEmpty()) { + Resource cur = stack.remove(stack.size()-1); + for(Resource sc : g.getObjects(cur, vr.BrowseContext_Includes)) + if(result.add(sc)) + stack.add(sc); + } + return result; + } + + private static NodeType getNodeType(ReadGraph graph, NodeContext parent) throws DatabaseException { + NodeType nodeType = parent.getConstant(NodeType.TYPE); + if(nodeType == null) { + // TODO remove this code when root of model browser is fixed + Object input = parent.getConstant(BuiltinKeys.INPUT); + if(input instanceof Resource) + nodeType = EntityNodeType.getNodeTypeFor(graph, (Resource)input); + } + return nodeType; + } + + public Map> getActions(ReadGraph graph, NodeContext parent, Collection all) throws DatabaseException { + NodeType nodeType = getNodeType(graph, parent); + if(nodeType == null) + return Collections.emptyMap(); + THashMap> map = new THashMap>(); + for(ActionContribution contribution : actionContributions.get(graph, nodeType)) { + CategorizedAction action = contribution.getAction(graph, parent, all); + if(action != null) { + List actions = map.get(action.category); + if(actions == null) { + actions = new ArrayList(); + map.put(action.category, actions); + } + actions.add(action.action); + } + } + return map; + } + + @Override + public int hashCode() { + return Arrays.hashCode(uris); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ActionBrowseContext other = (ActionBrowseContext) obj; + return Arrays.equals(uris, other.uris); + } + + @Override + public String toString() { + return getClass().getSimpleName() + Arrays.toString(uris); + } + + /* + * This is an attempt to improve removal logic with SpecialNodeTypes. However it + * should not be considered as a final solution. + */ + public boolean canRemove(ReadGraph graph, NodeContext parent) throws DatabaseException { + return testContributions(graph, parent, removalContributions, removableNodeTypes); + } + + /* + * This is an attempt to improve renaming logic with SpecialNodeTypes. However it + * should not be considered as a final solution. + */ + public boolean canRename(ReadGraph graph, NodeContext parent) throws DatabaseException { + return testContributions(graph, parent, renamingContributions, renameableNodeTypes); + } + + private boolean testContributions( + ReadGraph graph, + NodeContext parent, + NodeTypeMultiMap contributions, + Set allowedSpecialTypes) throws DatabaseException { + NodeType nodeType = getNodeType(graph, parent); + if (nodeType == null) + // Return true for now if node type is not available + // to prevent older and more custom solutions such as + // property view tables from breaking up. + return true; + + // TODO: this is a previous temporary solution that should probably be removed + if (nodeType instanceof SpecialNodeType + && allowedSpecialTypes.contains(((SpecialNodeType) nodeType).resource)) + return true; + + for (TestContribution contribution : contributions.get(graph, nodeType)) { + if (!contribution.test(graph, parent)) + return false; + } + return true; + } + +}