--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.browsing.ui.model.children;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.simantics.browsing.ui.BuiltinKeys;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.model.InvalidContribution;\r
+import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.PendingVariableException;\r
+import org.simantics.viewpoint.ontology.ViewpointResource;\r
+\r
+/**\r
+ * A child contribution adds child nodes to the instances of a specific node type.\r
+ * @author Hannu Niemistö\r
+ */\r
+public class ChildContribution {\r
+ \r
+ double priority;\r
+ String identifier;\r
+ NodeType parentNodeType;\r
+ NodeType childNodeType;\r
+ ChildRule childRule;\r
+ \r
+ public ChildContribution(String identifier, double priority, NodeType parentNodeType, NodeType childNodeType,\r
+ ChildRule childRule) throws InvalidContribution {\r
+ if(!childRule.isCompatible(\r
+ parentNodeType.getContentType()\r
+ ))\r
+ throw new InvalidContribution("Child rule is not compatible with the parent content type.");\r
+ this.parentNodeType = parentNodeType;\r
+ this.childNodeType = childNodeType;\r
+ this.childRule = childRule;\r
+ this.identifier = identifier;\r
+ this.priority = priority;\r
+ }\r
+\r
+ public static ChildContribution create(ReadGraph g, Resource childContributionResource) throws DatabaseException, InvalidContribution {\r
+ ViewpointResource vr = ViewpointResource.getInstance(g);\r
+ \r
+ Resource parentNodeTypeResource = g.getSingleObject(childContributionResource, vr.ChildContribution_HasParentNodeType);\r
+ NodeType parentNodeType = g.adapt(parentNodeTypeResource, NodeType.class);\r
+ \r
+ Resource childNodeTypeResource = g.getSingleObject(childContributionResource, vr.ChildContribution_HasChildNodeType);\r
+ NodeType childNodeType = g.adapt(childNodeTypeResource, NodeType.class);\r
+ \r
+ Resource childRuleResource = g.getSingleObject(childContributionResource, vr.ChildContribution_HasRule);\r
+ ChildRule childRule = g.adapt(childRuleResource, ChildRule.class);\r
+ \r
+ String identifier = g.getPossibleRelatedValue(childContributionResource, vr.ChildContribution_identifier, Bindings.STRING);\r
+ if(identifier == null) identifier = "";\r
+ if("".equals(identifier)) {\r
+ identifier = g.getPossibleURI(childContributionResource);\r
+ if(identifier == null) identifier = NameUtils.getSafeName(g, childContributionResource, true);\r
+ }\r
+ \r
+ Double priority = g.getPossibleRelatedValue(childContributionResource, vr.ChildContribution_priority, Bindings.DOUBLE);\r
+ if(priority == null) priority = 0.0;\r
+ \r
+ return new ChildContribution(identifier, priority, parentNodeType, childNodeType, childRule);\r
+ \r
+ }\r
+\r
+ public NodeType getParentNodeType() {\r
+ return parentNodeType;\r
+ }\r
+ \r
+ public NodeType getChildNodeType() {\r
+ return childNodeType;\r
+ }\r
+ \r
+ public String getIdentifier() {\r
+ return identifier;\r
+ }\r
+\r
+ public double getPriority() {\r
+ return priority;\r
+ }\r
+ \r
+ /**\r
+ * Given a parent node context returns a child node contexts contributed by\r
+ * this contribution.\r
+ */\r
+ public Collection<NodeContext> getChildren(ReadGraph graph, NodeContext parent) {\r
+ try {\r
+ Object parentContent = parent.getConstant(BuiltinKeys.INPUT);\r
+ Collection<?> childContents = childRule.getChildren(graph, parentContent);\r
+ if(childContents.isEmpty())\r
+ return Collections.emptyList();\r
+ ArrayList<NodeContext> children = new ArrayList<NodeContext>(childContents.size());\r
+ for(Object childContent : childContents) {\r
+ NodeContext child = childNodeType.createNodeContext(graph, childContent);\r
+ if(child != null)\r
+ children.add(child);\r
+ }\r
+ return children;\r
+ } catch(PendingVariableException e) {\r
+ return Collections.emptyList();\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ // TODO return some kind of error node\r
+ return Collections.emptyList();\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Given a child node context returns a collection of possible parent node contexts.\r
+ */\r
+ public Collection<NodeContext> getParents(ReadGraph graph, NodeContext child) {\r
+ try {\r
+ Object childContent = child.getConstant(BuiltinKeys.INPUT);\r
+ Collection<?> parentContents = childRule.getParents(graph, childContent);\r
+ if(parentContents.isEmpty())\r
+ return Collections.emptyList();\r
+ ArrayList<NodeContext> parents = new ArrayList<NodeContext>(parentContents.size());\r
+ for(Object parentContent : parentContents) {\r
+ NodeContext parent = parentNodeType.createNodeContext(graph, parentContent);\r
+ if(parent != null)\r
+ parents.add(parent);\r
+ }\r
+ return parents;\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ return Collections.emptyList();\r
+ }\r
+ }\r
+\r
+ public boolean hasChildren(ReadGraph graph, NodeContext parent) {\r
+ try {\r
+ Object parentContent = parent.getConstant(BuiltinKeys.INPUT);\r
+ Collection<?> childContents = childRule.getChildren(graph, parentContent);\r
+ if(childContents.isEmpty())\r
+ return false;\r
+ for(Object childContent : childContents) {\r
+ NodeContext child = childNodeType.createNodeContext(graph, childContent);\r
+ if(child != null)\r
+ return true;\r
+ }\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return false;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return identifier;\r
+ }\r
+ \r
+}\r