1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package fulmine.model.container;
17
18 import java.util.Map;
19
20 import fulmine.IDomain;
21 import fulmine.IType;
22 import fulmine.Type;
23 import fulmine.context.IFrameworkContext;
24 import fulmine.model.container.impl.Record;
25 import fulmine.model.field.containerdefinition.IContainerDefinitionField;
26 import fulmine.protocol.specification.FrameReader;
27 import fulmine.util.collection.CollectionFactory;
28 import fulmine.util.log.AsyncLog;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public final class ContainerFactory implements IContainerFactory
44 {
45 private final static AsyncLog LOG = new AsyncLog(ContainerFactory.class);
46
47
48
49
50
51 private final Map<IType, IContainerDefinitionField> staticDefinitions;
52
53
54
55
56
57 private final Map<IType, IContainerFactory.IContainerBuilder> builders;
58
59
60 private final IContainerFactory.IContainerBuilder defaultBuilder;
61
62
63
64
65 public ContainerFactory()
66 {
67 super();
68 this.defaultBuilder = new RecordBuilder();
69 builders = CollectionFactory.newMap();
70 staticDefinitions = CollectionFactory.newMap();
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public synchronized void registerBuilder(IType type,
89 IContainerFactory.IContainerBuilder builder)
90 {
91 if (type.value() < Type.BASE_USER_START)
92 {
93 throw new IllegalArgumentException("Cannot register types below "
94 + Type.BASE_USER_START);
95 }
96 final IContainerFactory.IContainerBuilder previous =
97 builders.put(type, builder);
98 if (previous != null)
99 {
100 LOG.warn("Previous builder " + previous
101 + " has been overwritten with a new builder " + builder
102 + " for type " + type);
103 }
104 final IContainerDefinitionField definition =
105 builder.createContainerDefinition();
106 if (definition != null)
107 {
108 if (!definition.isDynamic())
109 {
110 staticDefinitions.put(type, definition);
111 }
112 }
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public synchronized boolean containsType(IType type)
128 {
129 return builders.containsKey(type);
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 public synchronized IContainerDefinitionField getDefinition(IType type)
148 {
149 if (!containsType(type))
150 {
151 throw new IllegalArgumentException("No definition registered for "
152 + type + ", builders are=" + builders
153 + ", is this a dynamic type?"
154 + " (dynamic types do not register their definition)");
155 }
156 return staticDefinitions.get(type);
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 @SuppressWarnings("unchecked")
177 public synchronized <T extends IContainer> T createContainer(
178 String nativeContextIdentity, String identity, IType type,
179 IDomain domain, IFrameworkContext hostContext, boolean local)
180 {
181
182
183
184
185
186
187 boolean alreadyInContext = FrameReader.inContext();
188 try
189 {
190 if (!local && !alreadyInContext)
191 {
192 FrameReader.inContext.set(Boolean.TRUE);
193 }
194 IContainer container;
195 if (containsType(type))
196 {
197 container =
198 builders.get(type).createContainer(nativeContextIdentity,
199 identity, type, domain, hostContext, local);
200 }
201 else
202 {
203 container =
204 defaultBuilder.createContainer(nativeContextIdentity,
205 identity, type, domain, hostContext, local);
206 }
207 container.start();
208 return (T) container;
209 }
210 finally
211 {
212 if (!local && !alreadyInContext)
213 {
214 FrameReader.inContext.remove();
215 }
216 }
217 }
218
219
220
221
222
223
224 private static final class RecordBuilder implements
225 IContainerFactory.IContainerBuilder
226 {
227 public IContainer createContainer(String nativeContextIdentity,
228 String identity, IType type, IDomain domain,
229 IFrameworkContext hostContext, boolean local)
230 {
231 return new Record(nativeContextIdentity, identity, type, domain,
232 hostContext, local);
233 }
234
235 public IContainerDefinitionField createContainerDefinition()
236 {
237 return null;
238 }
239
240 public String toString()
241 {
242 return "Builder<Record>";
243 }
244 }
245
246 public void destroy()
247 {
248 this.builders.clear();
249 this.staticDefinitions.clear();
250 }
251 }