/******************************************************************************* * 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.children; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; 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.nodetypes.NodeType; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.exception.PendingVariableException; import org.simantics.viewpoint.ontology.ViewpointResource; /** * A child contribution adds child nodes to the instances of a specific node type. * @author Hannu Niemistö */ public class ChildContribution { double priority; String identifier; NodeType parentNodeType; NodeType childNodeType; ChildRule childRule; public ChildContribution(String identifier, double priority, NodeType parentNodeType, NodeType childNodeType, ChildRule childRule) throws InvalidContribution { if(!childRule.isCompatible( parentNodeType.getContentType() )) throw new InvalidContribution("Child rule is not compatible with the parent content type."); this.parentNodeType = parentNodeType; this.childNodeType = childNodeType; this.childRule = childRule; this.identifier = identifier; this.priority = priority; } public static ChildContribution create(ReadGraph g, Resource childContributionResource) throws DatabaseException, InvalidContribution { ViewpointResource vr = ViewpointResource.getInstance(g); Resource parentNodeTypeResource = g.getSingleObject(childContributionResource, vr.ChildContribution_HasParentNodeType); NodeType parentNodeType = g.adapt(parentNodeTypeResource, NodeType.class); Resource childNodeTypeResource = g.getSingleObject(childContributionResource, vr.ChildContribution_HasChildNodeType); NodeType childNodeType = g.adapt(childNodeTypeResource, NodeType.class); Resource childRuleResource = g.getSingleObject(childContributionResource, vr.ChildContribution_HasRule); ChildRule childRule = g.adapt(childRuleResource, ChildRule.class); String identifier = g.getPossibleRelatedValue(childContributionResource, vr.ChildContribution_identifier, Bindings.STRING); if(identifier == null) identifier = ""; if("".equals(identifier)) { identifier = g.getPossibleURI(childContributionResource); if(identifier == null) identifier = NameUtils.getSafeName(g, childContributionResource, true); } Double priority = g.getPossibleRelatedValue(childContributionResource, vr.ChildContribution_priority, Bindings.DOUBLE); if(priority == null) priority = 0.0; return new ChildContribution(identifier, priority, parentNodeType, childNodeType, childRule); } public NodeType getParentNodeType() { return parentNodeType; } public NodeType getChildNodeType() { return childNodeType; } public String getIdentifier() { return identifier; } public double getPriority() { return priority; } /** * Given a parent node context returns a child node contexts contributed by * this contribution. */ public Collection getChildren(ReadGraph graph, NodeContext parent) { try { Object parentContent = parent.getConstant(BuiltinKeys.INPUT); Collection childContents = childRule.getChildren(graph, parentContent); if(childContents.isEmpty()) return Collections.emptyList(); ArrayList children = new ArrayList(childContents.size()); for(Object childContent : childContents) { NodeContext child = childNodeType.createNodeContext(graph, childContent); if(child != null) children.add(child); } return children; } catch(PendingVariableException e) { return Collections.emptyList(); } catch(DatabaseException e) { e.printStackTrace(); // TODO return some kind of error node return Collections.emptyList(); } } /** * Given a child node context returns a collection of possible parent node contexts. */ public Collection getParents(ReadGraph graph, NodeContext child) { try { Object childContent = child.getConstant(BuiltinKeys.INPUT); Collection parentContents = childRule.getParents(graph, childContent); if(parentContents.isEmpty()) return Collections.emptyList(); ArrayList parents = new ArrayList(parentContents.size()); for(Object parentContent : parentContents) { NodeContext parent = parentNodeType.createNodeContext(graph, parentContent); if(parent != null) parents.add(parent); } return parents; } catch(DatabaseException e) { e.printStackTrace(); return Collections.emptyList(); } } public boolean hasChildren(ReadGraph graph, NodeContext parent) { try { Object parentContent = parent.getConstant(BuiltinKeys.INPUT); Collection childContents = childRule.getChildren(graph, parentContent); if(childContents.isEmpty()) return false; for(Object childContent : childContents) { NodeContext child = childNodeType.createNodeContext(graph, childContent); if(child != null) return true; } } catch(DatabaseException e) { e.printStackTrace(); } return false; } @Override public String toString() { return identifier; } }