-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in 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.common;\r
-\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.IAdaptable;\r
-import org.simantics.browsing.ui.BuiltinKeys;\r
-import org.simantics.browsing.ui.NodeContext;\r
-import org.simantics.browsing.ui.NodeContext.ConstantKey;\r
-import org.simantics.browsing.ui.content.Viewpoint;\r
-import org.simantics.utils.datastructures.ArrayMap;\r
-\r
-/**\r
- * Use this class in {@link Viewpoint}, and particularly\r
- * {@link Viewpoint#getChildren()} implementations to construct new INodeContext\r
- * instances.\r
- * \r
- * @author Antti Villberg\r
- * @author Tuukka Lehtonen\r
- */\r
-public final class NodeContextBuilder {\r
-\r
- private static Set<ConstantKey<?>> SINGLE_INPUT_KEYS =\r
- Collections.<ConstantKey<?>> singleton(BuiltinKeys.INPUT);\r
-\r
- MapNodeContext context;\r
-\r
- private static class InputNodeContext implements NodeContext {\r
-\r
- final Object input;\r
-\r
- private InputNodeContext(Object input) {\r
- this.input = input;\r
- }\r
-\r
- @SuppressWarnings({ "unchecked", "rawtypes" })\r
- @Override\r
- public Object getAdapter(Class adapter) {\r
- if (NodeContext.class.equals(adapter))\r
- return this;\r
- if (input != null) {\r
- if (adapter.isAssignableFrom(input.getClass()))\r
- return input;\r
- if (input instanceof IAdaptable)\r
- return ((IAdaptable) input).getAdapter(adapter);\r
- }\r
- return null;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public <T> T getConstant(ConstantKey<T> key) {\r
- return key == BuiltinKeys.INPUT ? (T) input : null;\r
- }\r
-\r
- @Override\r
- public Set<ConstantKey<?>> getKeys() {\r
- return SINGLE_INPUT_KEYS;\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- return ((input == null) ? 0 : input.hashCode());\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (this == obj)\r
- return true;\r
- if (obj == null)\r
- return false;\r
- if (getClass() != obj.getClass())\r
- return false;\r
- InputNodeContext other = (InputNodeContext) obj;\r
- if (input == null) {\r
- if (other.input != null)\r
- return false;\r
- } else if (!input.equals(other.input))\r
- return false;\r
- return true;\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return "InputNodeContext(" + hashCode() + ") [" + input + "]";\r
- }\r
- }\r
-\r
- public static class MapNodeContext implements NodeContext {\r
-\r
- private Map<ConstantKey<?>, Object> data;\r
- private int hash;\r
-\r
- private MapNodeContext() {\r
- }\r
-\r
- void makeHash() {\r
- this.hash = (data == null) ? 0 : data.hashCode();\r
- }\r
-\r
- @SuppressWarnings({ "unchecked", "rawtypes" })\r
- @Override\r
- public Object getAdapter(Class adapter) {\r
- if (NodeContext.class.equals(adapter))\r
- return this;\r
- Object input = data.get(BuiltinKeys.INPUT);\r
- if (input != null) {\r
- if (adapter.isAssignableFrom(input.getClass()))\r
- return input;\r
- if (input instanceof IAdaptable)\r
- return ((IAdaptable) input).getAdapter(adapter);\r
- }\r
- return null;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public <T> T getConstant(ConstantKey<T> key) {\r
- return data != null ? (T) data.get(key) : null;\r
- }\r
-\r
- @Override\r
- public Set<ConstantKey<?>> getKeys() {\r
- return data.keySet();\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- return hash;\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (this == obj)\r
- return true;\r
- if (obj == null)\r
- return false;\r
- if (getClass() != obj.getClass())\r
- return false;\r
- MapNodeContext other = (MapNodeContext) obj;\r
- if (data == null) {\r
- if (other.data != null)\r
- return false;\r
- } else if (!data.equals(other.data))\r
- return false;\r
- return true;\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return "MapNodeContext(" + hashCode() + ") [" + (data != null ? data : "") + "]";\r
- }\r
- }\r
-\r
- public NodeContextBuilder() {\r
- this.context = new MapNodeContext();\r
- }\r
-\r
- public <T> NodeContextBuilder define(ConstantKey<T> key, T value) {\r
- if (context.data == null)\r
- context.data = new HashMap<ConstantKey<?>, Object>();\r
- context.data.put(key, value);\r
- return this;\r
- }\r
-\r
- public NodeContext createContext() {\r
- context.makeHash();\r
- return context;\r
- }\r
-\r
- /**\r
- * A special case builder for an INodeContext that will only take one\r
- * (key,value) pair and insert that into the built INodeContext.\r
- * \r
- * <p>\r
- * This method works around the need to create NodeContextBuilder instances.\r
- * </p>\r
- * \r
- * <p>\r
- * Notice that your input key and value must properly implement\r
- * <code>equals</code> and <code>hashCode</code> in order for\r
- * GraphExplorer's automatic node expansion state tracking to work.\r
- * </p>\r
- * \r
- * @param key\r
- * @param value\r
- * @return an INodeContext containing a single constant as specified by\r
- * <code>key</code> and <code>value</code>\r
- */\r
- public static <T> NodeContext buildWithSingleData(ConstantKey<T> key, T value) {\r
- MapNodeContext context = new MapNodeContext();\r
- context.data = Collections.<ConstantKey<?>, Object>singletonMap(key, value);\r
- context.makeHash();\r
- return context;\r
- }\r
-\r
- /**\r
- * A generic case builder for an INodeContext that will take as many\r
- * (key,value) pairs as it is given and insert all of them into a map\r
- * that is backing the built INodeContext implementation.\r
- * \r
- * <p>\r
- * This method works around the need to create NodeContextBuilder instances.\r
- * </p>\r
- * \r
- * <p>\r
- * Notice that your input keys and values must properly implement\r
- * <code>equals</code> and <code>hashCode</code> in order for\r
- * GraphExplorer's automatic node expansion state tracking to work.\r
- * </p>\r
- * \r
- * @param keyValuePairs\r
- * @return an INodeContext containing the specified key,value pairs as its\r
- * constants\r
- */\r
- public static <T> NodeContext buildWithData(Object... keyValuePairs) {\r
- assert keyValuePairs.length % 2 == 0;\r
- MapNodeContext context = new MapNodeContext();\r
- int size = keyValuePairs.length;\r
- Map<ConstantKey<?>, Object> map = new HashMap<ConstantKey<?>, Object>(size);\r
-\r
- for (int i = 0; i < keyValuePairs.length; i += 2) {\r
- map.put((ConstantKey<?>) keyValuePairs[i], keyValuePairs[i+1]);\r
- }\r
-\r
- context.data = map;\r
- context.makeHash();\r
- return context;\r
- }\r
-\r
- /**\r
- * A generic case builder for an INodeContext that will take as many\r
- * (key,value) pairs as it is given and insert all of them into a map that\r
- * is backing the built INodeContext implementation. This method takes the\r
- * keys and values separately, which allows the use of {@link ArrayMap} that\r
- * provides a space-optimized Map implementation. Note that the key set of\r
- * an {@link ArrayMap} is immutable.\r
- * \r
- * <p>\r
- * This method works around the need to create NodeContextBuilder instances.\r
- * </p>\r
- * \r
- * <p>\r
- * Notice that your input keys and values must properly implement\r
- * <code>equals</code> and <code>hashCode</code> in order for\r
- * GraphExplorer's automatic node expansion state tracking to work.\r
- * </p>\r
- * \r
- * @param keys the keys of the map, must equal values array in size\r
- * @param values the values of the map, must equal keys array in size\r
- * @return a <code>NodeContext</code> containing the specified key,value\r
- * pairs as its constants\r
- */\r
- public static <T> NodeContext buildWithData(ConstantKey<?>[] keys, Object[] values) {\r
- assert keys.length == values.length;\r
- MapNodeContext context = new MapNodeContext();\r
- Map<ConstantKey<?>, Object> map = new ArrayMap<ConstantKey<?>, Object>(keys, values);\r
- context.data = map;\r
- context.makeHash();\r
- return context;\r
- }\r
-\r
- /**\r
- * A special case builder for an INodeContext that will only take one\r
- * (key,value) pair and insert that into the built INodeContext.\r
- * \r
- * <p>\r
- * This method works around the need to create NodeContextBuilder instances.\r
- * </p>\r
- * \r
- * <p>\r
- * Notice that your input object must properly implement <code>equals</code>\r
- * and <code>hashCode</code> in order for GraphExplorer's automatic node\r
- * expansion state tracking to work.\r
- * </p>\r
- * \r
- * @param input\r
- * @return an INodeContext containing the specified object as with the key\r
- * {@link BuiltinKeys#INPUT}\r
- */\r
- public static NodeContext buildWithInput(Object input) {\r
- return new InputNodeContext(input);\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.common;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.simantics.browsing.ui.BuiltinKeys;
+import org.simantics.browsing.ui.NodeContext;
+import org.simantics.browsing.ui.NodeContext.ConstantKey;
+import org.simantics.browsing.ui.content.Viewpoint;
+import org.simantics.utils.datastructures.ArrayMap;
+
+/**
+ * Use this class in {@link Viewpoint}, and particularly
+ * {@link Viewpoint#getChildren()} implementations to construct new INodeContext
+ * instances.
+ *
+ * @author Antti Villberg
+ * @author Tuukka Lehtonen
+ */
+public final class NodeContextBuilder {
+
+ private static Set<ConstantKey<?>> SINGLE_INPUT_KEYS =
+ Collections.<ConstantKey<?>> singleton(BuiltinKeys.INPUT);
+
+ MapNodeContext context;
+
+ private static class InputNodeContext implements NodeContext {
+
+ final Object input;
+
+ private InputNodeContext(Object input) {
+ this.input = input;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (NodeContext.class.equals(adapter))
+ return this;
+ if (input != null) {
+ if (adapter.isAssignableFrom(input.getClass()))
+ return input;
+ if (input instanceof IAdaptable)
+ return ((IAdaptable) input).getAdapter(adapter);
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T getConstant(ConstantKey<T> key) {
+ return key == BuiltinKeys.INPUT ? (T) input : null;
+ }
+
+ @Override
+ public Set<ConstantKey<?>> getKeys() {
+ return SINGLE_INPUT_KEYS;
+ }
+
+ @Override
+ public int hashCode() {
+ return ((input == null) ? 0 : input.hashCode());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ InputNodeContext other = (InputNodeContext) obj;
+ if (input == null) {
+ if (other.input != null)
+ return false;
+ } else if (!input.equals(other.input))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "InputNodeContext(" + hashCode() + ") [" + input + "]";
+ }
+ }
+
+ public static class MapNodeContext implements NodeContext {
+
+ private Map<ConstantKey<?>, Object> data;
+ private int hash;
+
+ private MapNodeContext() {
+ }
+
+ void makeHash() {
+ this.hash = (data == null) ? 0 : data.hashCode();
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (NodeContext.class.equals(adapter))
+ return this;
+ Object input = data.get(BuiltinKeys.INPUT);
+ if (input != null) {
+ if (adapter.isAssignableFrom(input.getClass()))
+ return input;
+ if (input instanceof IAdaptable)
+ return ((IAdaptable) input).getAdapter(adapter);
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T getConstant(ConstantKey<T> key) {
+ return data != null ? (T) data.get(key) : null;
+ }
+
+ @Override
+ public Set<ConstantKey<?>> getKeys() {
+ return data.keySet();
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MapNodeContext other = (MapNodeContext) obj;
+ if (data == null) {
+ if (other.data != null)
+ return false;
+ } else if (!data.equals(other.data))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "MapNodeContext(" + hashCode() + ") [" + (data != null ? data : "") + "]";
+ }
+ }
+
+ public NodeContextBuilder() {
+ this.context = new MapNodeContext();
+ }
+
+ public <T> NodeContextBuilder define(ConstantKey<T> key, T value) {
+ if (context.data == null)
+ context.data = new HashMap<ConstantKey<?>, Object>();
+ context.data.put(key, value);
+ return this;
+ }
+
+ public NodeContext createContext() {
+ context.makeHash();
+ return context;
+ }
+
+ /**
+ * A special case builder for an INodeContext that will only take one
+ * (key,value) pair and insert that into the built INodeContext.
+ *
+ * <p>
+ * This method works around the need to create NodeContextBuilder instances.
+ * </p>
+ *
+ * <p>
+ * Notice that your input key and value must properly implement
+ * <code>equals</code> and <code>hashCode</code> in order for
+ * GraphExplorer's automatic node expansion state tracking to work.
+ * </p>
+ *
+ * @param key
+ * @param value
+ * @return an INodeContext containing a single constant as specified by
+ * <code>key</code> and <code>value</code>
+ */
+ public static <T> NodeContext buildWithSingleData(ConstantKey<T> key, T value) {
+ MapNodeContext context = new MapNodeContext();
+ context.data = Collections.<ConstantKey<?>, Object>singletonMap(key, value);
+ context.makeHash();
+ return context;
+ }
+
+ /**
+ * A generic case builder for an INodeContext that will take as many
+ * (key,value) pairs as it is given and insert all of them into a map
+ * that is backing the built INodeContext implementation.
+ *
+ * <p>
+ * This method works around the need to create NodeContextBuilder instances.
+ * </p>
+ *
+ * <p>
+ * Notice that your input keys and values must properly implement
+ * <code>equals</code> and <code>hashCode</code> in order for
+ * GraphExplorer's automatic node expansion state tracking to work.
+ * </p>
+ *
+ * @param keyValuePairs
+ * @return an INodeContext containing the specified key,value pairs as its
+ * constants
+ */
+ public static <T> NodeContext buildWithData(Object... keyValuePairs) {
+ assert keyValuePairs.length % 2 == 0;
+ MapNodeContext context = new MapNodeContext();
+ int size = keyValuePairs.length;
+ Map<ConstantKey<?>, Object> map = new HashMap<ConstantKey<?>, Object>(size);
+
+ for (int i = 0; i < keyValuePairs.length; i += 2) {
+ map.put((ConstantKey<?>) keyValuePairs[i], keyValuePairs[i+1]);
+ }
+
+ context.data = map;
+ context.makeHash();
+ return context;
+ }
+
+ /**
+ * A generic case builder for an INodeContext that will take as many
+ * (key,value) pairs as it is given and insert all of them into a map that
+ * is backing the built INodeContext implementation. This method takes the
+ * keys and values separately, which allows the use of {@link ArrayMap} that
+ * provides a space-optimized Map implementation. Note that the key set of
+ * an {@link ArrayMap} is immutable.
+ *
+ * <p>
+ * This method works around the need to create NodeContextBuilder instances.
+ * </p>
+ *
+ * <p>
+ * Notice that your input keys and values must properly implement
+ * <code>equals</code> and <code>hashCode</code> in order for
+ * GraphExplorer's automatic node expansion state tracking to work.
+ * </p>
+ *
+ * @param keys the keys of the map, must equal values array in size
+ * @param values the values of the map, must equal keys array in size
+ * @return a <code>NodeContext</code> containing the specified key,value
+ * pairs as its constants
+ */
+ public static <T> NodeContext buildWithData(ConstantKey<?>[] keys, Object[] values) {
+ assert keys.length == values.length;
+ MapNodeContext context = new MapNodeContext();
+ Map<ConstantKey<?>, Object> map = new ArrayMap<ConstantKey<?>, Object>(keys, values);
+ context.data = map;
+ context.makeHash();
+ return context;
+ }
+
+ /**
+ * A special case builder for an INodeContext that will only take one
+ * (key,value) pair and insert that into the built INodeContext.
+ *
+ * <p>
+ * This method works around the need to create NodeContextBuilder instances.
+ * </p>
+ *
+ * <p>
+ * Notice that your input object must properly implement <code>equals</code>
+ * and <code>hashCode</code> in order for GraphExplorer's automatic node
+ * expansion state tracking to work.
+ * </p>
+ *
+ * @param input
+ * @return an INodeContext containing the specified object as with the key
+ * {@link BuiltinKeys#INPUT}
+ */
+ public static NodeContext buildWithInput(Object input) {
+ return new InputNodeContext(input);
+ }
+
+}