1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.objectweb.fractal.cecilia.primitive.thinkMC.controllers;
26
27 import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isClient;
28 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerDecorationUtil.setCustomBindingController;
29 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerDecorationUtil.setDataSuffix;
30 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerDecorationUtil.setVTable;
31 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface.AC;
32 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface.BC;
33 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface.BINDING_CONTROLLER_SIGNATURE;
34 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface.CI;
35 import static org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface.COMPONENT_IDENTITY_SIGNATURE;
36 import static org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil.setNoStaticBinding;
37
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Map;
41
42 import org.objectweb.fractal.adl.ADLException;
43 import org.objectweb.fractal.adl.attributes.Attributes;
44 import org.objectweb.fractal.adl.attributes.AttributesContainer;
45 import org.objectweb.fractal.adl.components.ComponentContainer;
46 import org.objectweb.fractal.adl.error.GenericErrors;
47 import org.objectweb.fractal.adl.implementations.ImplementationContainer;
48 import org.objectweb.fractal.adl.interfaces.Interface;
49 import org.objectweb.fractal.adl.interfaces.InterfaceContainer;
50 import org.objectweb.fractal.adl.types.TypeInterface;
51 import org.objectweb.fractal.cecilia.adl.controllers.AbstractControllerChecker;
52 import org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface;
53 import org.objectweb.fractal.cecilia.adl.idl.ast.Field;
54 import org.objectweb.fractal.cecilia.adl.idl.ast.FieldContainer;
55 import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinitionContainer;
56 import org.objectweb.fractal.cecilia.adl.idl.ast.RecordDefinition;
57
58
59
60
61 public class PrimitiveControllerLoader extends AbstractControllerChecker {
62
63
64
65
66
67 @Override
68 protected void checkComponent(final ComponentContainer container)
69 throws ADLException {
70 if (container instanceof ImplementationContainer
71 && (((ImplementationContainer) container).getImplementation() == null))
72 throw new ADLException(GenericErrors.GENERIC_ERROR,
73 "'primitive' controller can only be used for primitive components",
74 container);
75 }
76
77 @Override
78 protected List<Interface> getControllerInterfaces(
79 final ComponentContainer container, final Map<Object, Object> context)
80 throws ADLException {
81 final List<Interface> controllerItfs = new ArrayList<Interface>();
82 final Interface ciItf = getComponentIdentityInterface(container, context);
83 if (ciItf != null) controllerItfs.add(ciItf);
84
85 final Interface bcItf = getBindingControllerInterface(container, context);
86 if (bcItf != null) controllerItfs.add(bcItf);
87
88 final Interface acItf = getAttributeControllerInterface(container, context);
89 if (acItf != null) controllerItfs.add(acItf);
90
91 checkCustomLifeCycleControllerInterface(container, context);
92
93 return controllerItfs;
94 }
95
96
97
98
99
100 protected void checkCustomLifeCycleControllerInterface(
101 final ComponentContainer container, final Map<Object, Object> context)
102 throws ADLException {
103
104 final List<TypeInterface> lcc = this.getServerInterfacesBySignature(
105 ControllerInterface.LIFECYCLE_CONTROLLER_SIGNATURE,
106 (InterfaceContainer) container);
107
108 if (lcc.size() > 1) {
109 throw new ADLException(GenericErrors.GENERIC_ERROR,
110 "It is not allowed to specify TWO " + ControllerInterface.LCC
111 + " interfaces");
112 }
113
114
115 if (lcc.size() == 1) {
116
117 final TypeInterface lifeCycleControllerItf = lcc.get(0);
118
119
120 if (!lifeCycleControllerItf.getName().equals(ControllerInterface.LCC)) {
121 throw new ADLException(GenericErrors.GENERIC_ERROR,
122 "Custom server interface of type "
123 + ControllerInterface.LIFECYCLE_CONTROLLER_SIGNATURE
124 + " must be called '" + ControllerInterface.LCC + "'",
125 lifeCycleControllerItf);
126 }
127 }
128
129 }
130
131 protected Interface getComponentIdentityInterface(
132 final ComponentContainer container, final Map<Object, Object> context)
133 throws ADLException {
134 final InterfaceContainer itfContainer = (InterfaceContainer) container;
135 TypeInterface ciItf = getInterface(CI, itfContainer);
136 if (ciItf == null) {
137 ciItf = newServerInterfaceNode(CI, COMPONENT_IDENTITY_SIGNATURE);
138 setVTable(ciItf, "__cecilia_default_ComponentMeths");
139 setDataSuffix(ciItf, "CI_data");
140 setItfCode(ciItf, context, "fractal.lib.CIdelegate");
141 } else {
142 checkServerInterface(ciItf);
143
144 itfContainer.removeInterface(ciItf);
145 }
146 return ciItf;
147 }
148
149 protected Interface getBindingControllerInterface(
150 final ComponentContainer container, final Map<Object, Object> context)
151 throws ADLException {
152 final InterfaceContainer itfContainer = (InterfaceContainer) container;
153 TypeInterface bcItf = getInterface(BC, itfContainer);
154 if (isComponentNeedBindingControllerInterfaces(itfContainer)
155 && bcItf == null) {
156 bcItf = newServerInterfaceNode(BC, BINDING_CONTROLLER_SIGNATURE);
157 setVTable(bcItf, "__cecilia_default_BindingControllerMeths");
158 setDataSuffix(bcItf, "BC_data");
159 setItfCode(bcItf, context, "fractal.lib.BCdelegate");
160 } else if (bcItf != null) {
161 checkServerInterface(bcItf);
162
163 itfContainer.removeInterface(bcItf);
164
165
166
167 for (final Interface i : itfContainer.getInterfaces()) {
168 if (isClient(i)) setNoStaticBinding(i, true);
169 }
170
171 setCustomBindingController(bcItf, true);
172 }
173 return bcItf;
174 }
175
176 protected Interface getAttributeControllerInterface(
177 final ComponentContainer container, final Map<Object, Object> context)
178 throws ADLException {
179 final InterfaceContainer itfContainer = (InterfaceContainer) container;
180 TypeInterface acItf = getInterface(AC, itfContainer);
181
182 if (container instanceof AttributesContainer
183 && ((AttributesContainer) container).getAttributes() != null
184 && acItf == null) {
185
186 final Attributes attributes = ((AttributesContainer) container)
187 .getAttributes();
188
189 final RecordDefinition recordDefinition = (RecordDefinition) ((IDLDefinitionContainer) attributes)
190 .getIDLDefinition();
191
192 final boolean hasConstFields = isComponentNeedAttributeControllerConstAwareDelegate(recordDefinition);
193
194 acItf = newServerInterfaceNode(AC,
195 ControllerInterface.ATTRIBUTE_CONTROLLER_SIGNATURE);
196 setDataSuffix(acItf, "AC_data");
197
198 if (hasConstFields) {
199 setItfCode(acItf, context, "fractal.lib.ACdelegate_constattributes");
200 setVTable(acItf, "__cecilia_AttributeControllerConstAttributesMeths");
201 } else {
202 setItfCode(acItf, context, "fractal.lib.ACdelegate");
203 setVTable(acItf, "__cecilia_default_AttributeControllerMeths");
204 }
205 } else if (acItf != null) {
206 checkServerInterface(acItf);
207
208 itfContainer.removeInterface(acItf);
209 }
210 return acItf;
211 }
212
213
214
215
216
217
218 protected boolean isComponentNeedBindingControllerInterfaces(
219 final InterfaceContainer container) {
220 for (final Interface itf : container.getInterfaces()) {
221 if (isClient(itf)) return true;
222 }
223 return false;
224 }
225
226
227
228
229
230
231 protected boolean isComponentNeedAttributeControllerConstAwareDelegate(
232 final RecordDefinition recordDefinition) {
233
234 final Field[] fields = ((FieldContainer) recordDefinition).getFields();
235
236 for (final Field f : fields) {
237 if (f.getQualifier().equals(Field.CONST)) {
238 return true;
239 }
240 }
241 return false;
242 }
243
244 }