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.adl.bindings;
26
27 import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isCollection;
28 import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isServer;
29 import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isSingleton;
30 import static org.objectweb.fractal.cecilia.adl.bindings.BindingDecorationUtil.getServerInterface;
31 import static org.objectweb.fractal.cecilia.adl.bindings.BindingDecorationUtil.isStaticallyBoundFalse;
32 import static org.objectweb.fractal.cecilia.adl.bindings.BindingDecorationUtil.setClientInterface;
33 import static org.objectweb.fractal.cecilia.adl.bindings.BindingDecorationUtil.setServerInterface;
34 import static org.objectweb.fractal.cecilia.adl.bindings.BindingDecorationUtil.setStaticallyBound;
35 import static org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil.getContainer;
36 import static org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil.isNoStaticBinding;
37 import static org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil.setBoundTo;
38 import static org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil.setContainer;
39
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44
45 import org.objectweb.fractal.adl.ADLException;
46 import org.objectweb.fractal.adl.Definition;
47 import org.objectweb.fractal.adl.NodeUtil;
48 import org.objectweb.fractal.adl.bindings.Binding;
49 import org.objectweb.fractal.adl.bindings.TypeBindingLoader;
50 import org.objectweb.fractal.adl.components.Component;
51 import org.objectweb.fractal.adl.components.ComponentContainer;
52 import org.objectweb.fractal.adl.error.NodeErrorLocator;
53 import org.objectweb.fractal.adl.implementations.ImplementationContainer;
54 import org.objectweb.fractal.adl.interfaces.Interface;
55 import org.objectweb.fractal.adl.interfaces.InterfaceContainer;
56 import org.objectweb.fractal.adl.types.TypeInterface;
57 import org.objectweb.fractal.adl.util.FractalADLLogManager;
58 import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinition;
59 import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinitionContainer;
60 import org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public class BindingResolverLoader extends TypeBindingLoader {
83
84
85
86
87
88 protected Map<TypeInterface, List<Binding>> clientInterfaceBindings;
89
90
91
92
93
94 @Override
95 public Definition load(final String name, final Map<Object, Object> context)
96 throws ADLException {
97
98 clientInterfaceBindings = new HashMap<TypeInterface, List<Binding>>();
99
100 final Definition d = super.load(name, context);
101 addDecoration(d, context);
102 resolvBinding(d, d, context);
103
104
105 clientInterfaceBindings = null;
106
107 return d;
108 }
109
110
111
112
113
114 @Override
115 protected boolean ignoreBinding(final Binding binding,
116 final String fromCompName, final String fromItfName,
117 final String toCompName, final String toItfName) {
118 return false;
119 }
120
121
122
123
124
125 @Override
126 protected void checkBinding(final Binding binding, final Interface fromItf,
127 final String fromCompName, final String fromItfName,
128 final Interface toItf, final String toCompName, final String toItfName,
129 final Map<Object, Object> context) throws ADLException {
130
131 NodeUtil.castNodeError(fromItf, TypeInterface.class);
132 NodeUtil.castNodeError(toItf, TypeInterface.class);
133
134 super.checkBinding(binding, fromItf, fromCompName, fromItfName, toItf,
135 toCompName, toItfName, context);
136
137
138 checkBindingSignaturesCompatibility(binding, fromItf, toItf);
139
140 setClientInterface(binding, fromItf);
141 setServerInterface(binding, toItf);
142
143 if (toCompName.equals("this") && isCollection(toItf)) {
144
145
146
147 if (!fromItfName.equals(toItfName)) {
148 throw new ADLException(BindingErrors.COMPOSITE_CLIENT_COLLECTION,
149 binding);
150 }
151 }
152
153 List<Binding> bindings = clientInterfaceBindings.get(fromItf);
154 if (bindings == null) {
155 bindings = new ArrayList<Binding>();
156 clientInterfaceBindings.put((TypeInterface) fromItf, bindings);
157 }
158 bindings.add(binding);
159 }
160
161
162
163
164
165 protected void checkBindingSignaturesCompatibility(final Binding binding,
166 final Interface clientItf, final Interface serverItf) throws ADLException {
167
168 if (!(clientItf instanceof IDLDefinitionContainer)
169 || !(serverItf instanceof IDLDefinitionContainer)) return;
170
171 final IDLDefinition clientIDLDefinition = ((IDLDefinitionContainer) clientItf)
172 .getIDLDefinition();
173
174 if (clientIDLDefinition != null
175 && InterfaceDecorationUtil
176 .isInheritancePathDecorationPresent(clientIDLDefinition)) {
177
178 final String clientItfSignature = InterfaceDecorationUtil
179 .getInheritancePathDecoration(clientIDLDefinition).get(0);
180
181 final IDLDefinition serverIDLDefinition = ((IDLDefinitionContainer) serverItf)
182 .getIDLDefinition();
183
184 final List<String> serverItfInheritancePath = InterfaceDecorationUtil
185 .getInheritancePathDecoration(serverIDLDefinition);
186
187 if (!serverItfInheritancePath.contains(clientItfSignature)) {
188
189 throw new ADLException(
190 org.objectweb.fractal.adl.bindings.BindingErrors.INVALID_SIGNATURE,
191 binding, new NodeErrorLocator(clientItf), new NodeErrorLocator(
192 serverItf));
193 }
194 } else {
195 FractalADLLogManager.STEP
196 .warning("WARNING: the "
197 + InterfaceDecorationUtil.INHERITANCE_PATH_DECORATION
198 + " is not set, so binding signature compatibility check is not performed");
199 }
200
201 }
202
203 protected void addDecoration(final Object node,
204 final Map<Object, Object> context) {
205 if (node instanceof InterfaceContainer) {
206 final InterfaceContainer interfaceContainer = (InterfaceContainer) node;
207 for (final Interface itf : interfaceContainer.getInterfaces())
208 setContainer(itf, interfaceContainer);
209 }
210 if (node instanceof ComponentContainer) {
211 for (final Component component : ((ComponentContainer) node)
212 .getComponents())
213 addDecoration(component, context);
214 }
215 }
216
217 private void resolvBinding(final Object node, final Object topLevelNode,
218 final Map<Object, Object> context) throws ADLException {
219 if (isPrimitive(node)) {
220
221 if (!(node instanceof InterfaceContainer)) return;
222 final InterfaceContainer itfContainer = (InterfaceContainer) node;
223 for (final Interface itf : itfContainer.getInterfaces()) {
224 if (isServer(itf)) continue;
225
226
227 final TypeInterface clientItf = (TypeInterface) itf;
228
229
230
231
232 final boolean staticBindingAllowed = (!isNoStaticBinding(clientItf))
233 && isSingleton(clientItf);
234
235 final List<Binding> bindings = clientInterfaceBindings.get(clientItf);
236
237
238 if (bindings == null) {
239 continue;
240 }
241
242
243 for (final Binding binding : bindings) {
244
245 if (staticBindingAllowed) setStaticallyBound(binding, true);
246
247 walkBindingGraph(clientItf, binding, staticBindingAllowed);
248 }
249 }
250 } else if (node instanceof ComponentContainer) {
251 for (final Component comp : ((ComponentContainer) node).getComponents()) {
252 resolvBinding(comp, topLevelNode, context);
253 }
254 }
255 }
256
257 protected void walkBindingGraph(final TypeInterface clientItf,
258 final Binding binding, final boolean staticBindingAllowed)
259 throws ADLException {
260 final TypeInterface serverItf = (TypeInterface) getServerInterface(binding);
261 final InterfaceContainer serverComponent = getContainer(serverItf);
262
263
264 if (!isPrimitive(serverComponent)) {
265
266 if (isServer(serverItf)
267 && (serverItf.getName().endsWith("controller")
268 || serverItf.getName().equals("component") || serverItf.getName()
269 .equals("factory"))) {
270 setBoundTo(clientItf, serverItf);
271 return;
272 }
273
274 final List<Binding> serverBindings = clientInterfaceBindings
275 .get(serverItf);
276
277 if (serverBindings == null) {
278 return;
279 }
280
281
282 if (serverBindings.size() > 1 && isServer(serverItf)) {
283 throw new ADLException(BindingErrors.COMPOSITE_SERVER_COLLECTION,
284 serverItf);
285 }
286
287 for (final Binding b : serverBindings) {
288
289
290
291
292 if (staticBindingAllowed && !isStaticallyBoundFalse(b))
293 setStaticallyBound(b, true);
294 else
295
296
297
298 setStaticallyBound(b, false);
299
300
301
302
303 walkBindingGraph(clientItf, b, staticBindingAllowed);
304 }
305 } else {
306
307
308 setBoundTo(clientItf, serverItf);
309 }
310 }
311
312 protected static boolean isPrimitive(final Object component) {
313 return component instanceof ImplementationContainer
314 && ((ImplementationContainer) component).getImplementation() != null;
315 }
316 }