]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/binding/classfactory/TypeClassFactory.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / binding / classfactory / TypeClassFactory.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.databoard.binding.classfactory;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.HashMap;\r
16 import java.util.List;\r
17 import java.util.Map;\r
18 import org.simantics.databoard.binding.error.BindingConstructionException;\r
19 import org.simantics.databoard.binding.factory.TypeRepository;\r
20 import org.simantics.databoard.binding.reflection.BindingRequest;\r
21 import org.simantics.databoard.type.Datatype;\r
22 \r
23 /**\r
24  * Creates class for a type. \r
25  * \r
26  * @author toni.kalajainen\r
27  */\r
28 public class TypeClassFactory {\r
29         \r
30         /**\r
31          * Map of failed constructions. \r
32          */\r
33         Map<Datatype, BindingConstructionException> failures = new HashMap<Datatype, BindingConstructionException>();\r
34         \r
35         /**\r
36          * Map that contains in incomplete constructions.\r
37          */\r
38         Map<Datatype, Datatype> inprogress = new HashMap<Datatype, Datatype>();\r
39         \r
40         /**\r
41          * Repository where successful constructions are placed. \r
42          */\r
43         TypeRepository repository;\r
44         \r
45         List<TypeClassSubFactory> subFactories = new ArrayList<TypeClassSubFactory>();  \r
46         \r
47         public TypeClassFactory() {\r
48                 repository = new TypeRepository(); \r
49         }\r
50         \r
51         public TypeClassFactory(TypeRepository repository)\r
52         {\r
53                 this.repository = repository;\r
54         }       \r
55         \r
56         public void addFactory(TypeClassSubFactory factory) \r
57         {\r
58                 if (!subFactories.contains(factory)) {\r
59                         this.subFactories.add(factory);\r
60                 }\r
61         }\r
62         \r
63         public void addFactoryFirst(TypeClassSubFactory factory) \r
64         {\r
65                 if (!subFactories.contains(factory)) {\r
66                         this.subFactories.add(0, factory);\r
67                 }\r
68         }\r
69         \r
70         \r
71         public BindingRequest getClass(Datatype type) throws BindingConstructionException\r
72         {\r
73                 Datatype progress = inprogress.get(type);\r
74                 if (progress != null) { synchronized(progress) {} }\r
75                 if (failures.containsKey(type)) throw failures.get(type);\r
76                 if (repository.containsType(type)) return repository.getRequestForType(type);\r
77                 \r
78                 // Start construction\r
79                 synchronized(type) {\r
80                         inprogress.put(type, type);\r
81                         try {   \r
82                                 BindingRequest br = null;\r
83                                 for ( TypeClassSubFactory sf : subFactories ) {\r
84                                         br = sf.construct(this, type);\r
85                                         if ( br != null ) break;\r
86                                 }\r
87                                 if (br==null) throw new BindingConstructionException("Failed to create BindingRequest for type "+type);\r
88                                 repository.put(type, br);\r
89                                 return br;\r
90                         } catch (RuntimeException e) {\r
91                                 failures.put(type, new BindingConstructionException(e));\r
92                                 throw e;\r
93                         } catch (BindingConstructionException bce) {\r
94                                 failures.put(type, bce);\r
95                                 throw bce;\r
96                         } finally {\r
97                                 inprogress.remove(type);\r
98                         }\r
99                 }\r
100                 \r
101         }\r
102         \r
103         public TypeRepository getRepository() {\r
104                 return repository;\r
105         }\r
106         \r
107 }\r