]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/TypeBindingFactory.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / binding / factory / TypeBindingFactory.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/TypeBindingFactory.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/TypeBindingFactory.java
new file mode 100644 (file)
index 0000000..cd4304b
--- /dev/null
@@ -0,0 +1,115 @@
+package org.simantics.databoard.binding.factory;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.error.BindingConstructionException;\r
+import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
+import org.simantics.databoard.type.Datatype;\r
+\r
+/**\r
+ * Type Factory constructs data types from reflection requests.\r
+ * Successfully constructed types are placed in the repository that was given \r
+ * at construction time.\r
+ *  \r
+ * @author Toni Kalajainen\r
+ */\r
+public abstract class TypeBindingFactory implements BindingScheme {\r
+       \r
+       /**\r
+        * Map of failed constructions. \r
+        */\r
+       protected Map<Datatype, BindingConstructionException> failures = new HashMap<Datatype, BindingConstructionException>();\r
+       \r
+       /**\r
+        * Map that contains in incomplete constructions.\r
+        */\r
+       protected Map<Datatype, Binding> inprogress = new HashMap<Datatype, Binding>();\r
+       \r
+       /**\r
+        * Repository where successful constructions are placed. \r
+        */\r
+       protected Map<Datatype, Binding> repository;    \r
+       \r
+       /**\r
+        * Create a scheme factory. \r
+        */\r
+       public TypeBindingFactory() {\r
+               this.repository = new HashMap<Datatype, Binding>();\r
+       }\r
+       \r
+       /**\r
+        * Create scheme factory that appends constructed bindings to the user given\r
+        * repository  \r
+        * \r
+        * @param repository repository where bindings are placed\r
+        */\r
+       public TypeBindingFactory(Map<Datatype, Binding> repository) {\r
+               this.repository = repository;\r
+       }\r
+       \r
+       /**\r
+        * Get Repository\r
+        * @return binding repository\r
+        */\r
+       public Map<Datatype, Binding> getRepository() {\r
+               return repository;\r
+       }\r
+\r
+       /**\r
+        * Constructs a binding to comply to datatype request.\r
+        * This is the method sub-classes implement. \r
+        * The implementation should use the inprogress -map for construction of \r
+        * bindings that have component types.\r
+        * \r
+        *  e.g. \r
+        *   inprogress.put(request, notCompletelyConstructedBinding);\r
+        *   Binding componentBinding = construct( componentRequest );\r
+        *   notCompletelyConstructedBinding.setChild( componentBinding );\r
+        *   inprogress.remove(request);\r
+        *   \r
+        * try-finally is not needed.\r
+        * \r
+        * @param request\r
+        * @return\r
+        * @throws BindingConstructionException\r
+        */\r
+       protected abstract Binding doConstruct(Datatype request) throws BindingConstructionException;\r
+       \r
+       public Binding construct(Datatype request) throws BindingConstructionException\r
+       {\r
+               if (failures.containsKey(request)) throw failures.get(request);\r
+               if (inprogress.containsKey(request)) return inprogress.get(request);\r
+               if (repository.containsKey(request)) return repository.get(request);\r
+               \r
+               // Start construction\r
+               try {                   \r
+                       Binding binding = doConstruct(request);\r
+                       repository.put(request, binding);\r
+                       return binding;\r
+               } catch (BindingConstructionException e) {\r
+                       inprogress.remove( request );\r
+                       failures.put(request, e);\r
+                       throw e;\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public Binding getBinding(Datatype type)\r
+                       throws BindingConstructionException {           \r
+               return construct(type);\r
+       }\r
+       \r
+       @Override\r
+       public Binding getBindingUnchecked(Datatype type)\r
+                       throws RuntimeBindingConstructionException {\r
+               try {\r
+                       return construct(type);\r
+               } catch (BindingConstructionException e) {\r
+                       throw new RuntimeBindingConstructionException(e);\r
+               }\r
+       }       \r
+       \r
+\r
+}\r