1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.objectweb.fractal.cecilia.adl.idl;
25
26 import static java.util.Arrays.asList;
27 import static org.objectweb.fractal.adl.NodeUtil.castNodeError;
28 import static org.objectweb.fractal.cecilia.adl.idl.util.Util.getImportedAST;
29
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36
37 import org.objectweb.fractal.adl.ADLException;
38 import org.objectweb.fractal.adl.Definition;
39 import org.objectweb.fractal.adl.DefinitionVisitor;
40 import org.objectweb.fractal.adl.Node;
41 import org.objectweb.fractal.adl.attributes.Attributes;
42 import org.objectweb.fractal.adl.attributes.AttributesContainer;
43 import org.objectweb.fractal.adl.components.ComponentContainer;
44 import org.objectweb.fractal.adl.interfaces.Interface;
45 import org.objectweb.fractal.adl.interfaces.InterfaceContainer;
46 import org.objectweb.fractal.api.Component;
47 import org.objectweb.fractal.api.NoSuchInterfaceException;
48 import org.objectweb.fractal.api.control.BindingController;
49 import org.objectweb.fractal.api.control.IllegalBindingException;
50 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
51 import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinition;
52 import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinitionContainer;
53 import org.objectweb.fractal.cecilia.adl.idl.ast.Import;
54 import org.objectweb.fractal.cecilia.adl.idl.ast.ImportContainer;
55 import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
56 import org.objectweb.fractal.task.core.TaskException;
57
58
59
60
61
62
63 public class RecursiveIDLDispatchVisitor extends AbstractTaskFactoryUser
64 implements
65 DefinitionVisitor,
66 BindingController {
67
68
69 public static final String TASK_FILE_NAME = "org.objectweb.fractal.cecilia.adl.idl.IDLTask";
70
71
72
73
74
75
76 public static final String CLIENT_VISITORITF_NAME = "client-visitor";
77
78 public Map<String, IDLDefinitionVisitor> visitorsItf = new HashMap<String, IDLDefinitionVisitor>();
79
80
81
82
83
84 public Component visit(final List<Node> path, final Definition container,
85 final Map<Object, Object> context) throws ADLException, TaskException {
86
87 final List<Component> taskComponents = new ArrayList<Component>();
88 final Set<String> visitedIDL = new HashSet<String>();
89
90 visiteComponentContainer(path, (ComponentContainer) container,
91 taskComponents, visitedIDL, context);
92 return taskFactoryItf
93 .newCompositeTask(taskComponents, TASK_FILE_NAME, null);
94 }
95
96
97
98
99
100 private void visiteComponentContainer(final List<Node> path,
101 final ComponentContainer container, final List<Component> taskComponents,
102 final Set<String> visitedIDL, final Map<Object, Object> context)
103 throws ADLException, TaskException {
104
105 path.add(container);
106 try {
107 for (final org.objectweb.fractal.adl.components.Component subComp : container
108 .getComponents()) {
109 visiteComponentContainer(path, subComp, taskComponents, visitedIDL,
110 context);
111 }
112
113 if (container instanceof InterfaceContainer) {
114 for (final Interface itf : ((InterfaceContainer) container)
115 .getInterfaces()) {
116 invokeVisitors(path, castNodeError(itf, IDLDefinitionContainer.class)
117 .getIDLDefinition(), taskComponents, visitedIDL, context);
118 }
119 }
120 if (container instanceof AttributesContainer) {
121 final Attributes attributes = ((AttributesContainer) container)
122 .getAttributes();
123 if (attributes != null) {
124 invokeVisitors(path, castNodeError(attributes,
125 IDLDefinitionContainer.class).getIDLDefinition(), taskComponents,
126 visitedIDL, context);
127 }
128 }
129
130 } finally {
131 path.remove(path.size() - 1);
132 }
133 }
134
135 private void invokeVisitors(final List<Node> path,
136 final IDLDefinition idlDefinition, final List<Component> taskComponents,
137 final Set<String> visitedIDL, final Map<Object, Object> context)
138 throws ADLException, TaskException {
139
140
141
142
143 if (!visitedIDL.add(idlDefinition.getName())) return;
144
145
146 for (final IDLDefinitionVisitor idlVisitor : visitorsItf.values()) {
147 final Component task = idlVisitor.visit(path, idlDefinition, context);
148 if (task != null) taskComponents.add(task);
149 }
150 if (idlDefinition instanceof ImportContainer) {
151 for (final Import imp : ((ImportContainer) idlDefinition).getImports()) {
152 final Node importedAST = getImportedAST(imp);
153 if (importedAST instanceof IDLDefinition) {
154 final IDLDefinition importedDef = (IDLDefinition) importedAST;
155 invokeVisitors(path, importedDef, taskComponents, visitedIDL, context);
156 }
157 }
158 }
159 }
160
161
162
163
164
165 @Override
166 public String[] listFc() {
167 final List<String> interfaceList = new ArrayList<String>(visitorsItf
168 .keySet());
169 interfaceList.addAll(asList(super.listFc()));
170 return interfaceList.toArray(new String[interfaceList.size()]);
171 }
172
173 @Override
174 public Object lookupFc(final String clientItfName)
175 throws NoSuchInterfaceException {
176
177 if (clientItfName == null) {
178 throw new IllegalArgumentException("Interface name can't be null");
179 }
180
181 if (clientItfName.startsWith(CLIENT_VISITORITF_NAME)) {
182 return visitorsItf.get(clientItfName);
183 } else {
184 return super.lookupFc(clientItfName);
185 }
186 }
187
188 @Override
189 public void bindFc(final String clientItfName, final Object serverItf)
190 throws NoSuchInterfaceException, IllegalBindingException,
191 IllegalLifeCycleException {
192
193 if (clientItfName == null) {
194 throw new IllegalArgumentException("Interface name can't be null");
195 }
196
197 if (clientItfName.startsWith(CLIENT_VISITORITF_NAME)) {
198 visitorsItf.put(clientItfName, (IDLDefinitionVisitor) serverItf);
199 } else {
200 super.bindFc(clientItfName, serverItf);
201 }
202 }
203
204 @Override
205 public void unbindFc(final String clientItfName)
206 throws NoSuchInterfaceException, IllegalBindingException,
207 IllegalLifeCycleException {
208
209 if (clientItfName == null) {
210 throw new IllegalArgumentException("Interface name can't be null");
211 }
212
213 if (clientItfName.startsWith(CLIENT_VISITORITF_NAME)) {
214 visitorsItf.remove(clientItfName);
215 } else {
216 super.unbindFc(clientItfName);
217 }
218 }
219 }