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.implementations;
25
26 import static org.objectweb.fractal.cecilia.adl.SourceCodeHelper.appendSortedSourceCodes;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import org.objectweb.fractal.adl.ADLException;
37 import org.objectweb.fractal.adl.Definition;
38 import org.objectweb.fractal.adl.DefinitionVisitor;
39 import org.objectweb.fractal.adl.Node;
40 import org.objectweb.fractal.adl.components.ComponentContainer;
41 import org.objectweb.fractal.adl.error.GenericErrors;
42 import org.objectweb.fractal.api.Component;
43 import org.objectweb.fractal.api.NoSuchInterfaceException;
44 import org.objectweb.fractal.api.control.IllegalBindingException;
45 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
46 import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
47 import org.objectweb.fractal.cecilia.adl.compiler.CompilationTaskFactory;
48 import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
49 import org.objectweb.fractal.cecilia.adl.file.SourceFile;
50 import org.objectweb.fractal.cecilia.adl.file.SourceFileProvider;
51 import org.objectweb.fractal.cecilia.adl.file.SourceFileWriter;
52 import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
53 import org.objectweb.fractal.task.core.Executable;
54 import org.objectweb.fractal.task.core.TaskException;
55 import org.objectweb.fractal.task.core.primitive.annotations.ClientInterface;
56 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
57 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
58
59 public class GlobalInitVisitor extends AbstractTaskFactoryUser
60 implements
61 DefinitionVisitor {
62
63 public static final String COMPOSTION = "org.objectweb.fractal.cecilia.adl.implementations.GlobalInitCompilation";
64
65
66
67
68
69
70 public static final String COMPILATION_TASK_FACTORY_ITF_NAME = "compilation-task-factory";
71
72
73 public CompilationTaskFactory compilationTaskFactoryItf;
74
75
76
77
78
79
80
81
82
83 public Component visit(final List<Node> path, final Definition container,
84 final Map<Object, Object> context) throws ADLException, TaskException {
85 final Collection<Component> tasks = new ArrayList<Component>();
86 tasks.add(createGlobalInitialisationDeclarationTask(container, context));
87 tasks.add(createGlobalInitialisationCompilationTask(container, context));
88 return taskFactoryItf.newCompositeTask(tasks, COMPOSTION, null, container);
89 }
90
91
92
93
94
95 protected Component createGlobalInitialisationDeclarationTask(
96 final Definition container, final Map<Object, Object> context)
97 throws TaskException {
98 return taskFactoryItf
99 .newPrimitiveTask(new GlobalInitialisationDeclatationTask(
100 (File) context.get("adlBuildDirectory"), container.getName()));
101 }
102
103 protected Component createGlobalInitialisationCompilationTask(
104 final Definition container, final Map<Object, Object> context)
105 throws TaskException {
106 return compilationTaskFactoryItf
107 .newCompileTask("globalInit", null, context);
108 }
109
110
111
112
113
114 @ServerInterfaces(@ServerInterface(name = "global-init-code", signature = SourceFileProvider.class, record = "role:globalInitFile"))
115 public static class GlobalInitialisationDeclatationTask
116 implements
117 Executable,
118 SourceFileProvider {
119
120
121 public static final String FILE_NAME_SUFFIX = ".init.c";
122
123 protected final File adlBuildDirectory;
124
125 protected final String definitionName;
126
127
128 protected SourceFile sourceFile;
129
130
131
132
133
134
135
136
137
138 @ClientInterface(name = "constructor-declaration-provider", signature = SourceCodeProvider.class, record = "role:globalInit, type:declaration")
139 public final Map<String, SourceCodeProvider> declatationsItfs = new HashMap<String, SourceCodeProvider>();
140
141
142 @ClientInterface(name = "constructor-call-provider", signature = SourceCodeProvider.class, record = "role:globalInit, type:call, kind:constructor")
143 public final Map<String, SourceCodeProvider> constructorCallsItfs = new HashMap<String, SourceCodeProvider>();
144
145
146 @ClientInterface(name = "destructor-call-provider", signature = SourceCodeProvider.class, record = "role:globalInit, type:call, kind:destructor")
147 public final Map<String, SourceCodeProvider> destructorCallsItfs = new HashMap<String, SourceCodeProvider>();
148
149
150
151
152
153
154
155
156
157
158 public GlobalInitialisationDeclatationTask(final File adlBuildDirectory,
159 final String definitionName) {
160 this.adlBuildDirectory = adlBuildDirectory;
161 this.definitionName = definitionName;
162 }
163
164
165
166
167
168 protected void prepareSourceCode(final CodeWriter cw) throws Exception {
169
170 cw.appendln("// --------------------------------------------------------"
171 + "---------------------");
172 cw.appendln("// declaration of global constructor/destructor functions");
173 cw.appendln("// --------------------------------------------------------"
174 + "---------------------");
175 cw.endl();
176
177 appendSortedSourceCodes(cw, declatationsItfs.values());
178
179 cw.appendln("void __cecilia_global_constructor__(void) {");
180 appendSortedSourceCodes(cw, constructorCallsItfs.values());
181 cw.appendln("}");
182
183 cw.appendln("void __cecilia_global_destructor__(void) {");
184 appendSortedSourceCodes(cw, destructorCallsItfs.values());
185 cw.appendln("}");
186 }
187
188 protected String getFileName() {
189 return definitionName.replace('.', '_') + FILE_NAME_SUFFIX;
190 }
191
192 protected String getSignature() {
193 return definitionName + "_init";
194 }
195
196
197
198
199
200 public void execute() throws Exception {
201 final String fileName = getFileName();
202 final File outputFile = new File(adlBuildDirectory, fileName);
203
204 final CodeWriter cw = new CodeWriter();
205 cw.appendln("// THIS FILE HAS BEEN GENERATED BY THE CECILIA ADL "
206 + "COMPILER.");
207 cw.appendln("// DO NOT EDIT").endl();
208 prepareSourceCode(cw);
209
210 try {
211 SourceFileWriter.writeToFile(outputFile, cw.toString());
212 } catch (final IOException e) {
213 throw new ADLException(GenericErrors.INTERNAL_ERROR, e,
214 "An error occurs while writing to file '"
215 + outputFile.getAbsolutePath() + "'");
216 }
217
218 sourceFile = new SourceFile(getSignature(), outputFile);
219 }
220
221
222
223
224
225 public SourceFile getSourceFile() {
226 return sourceFile;
227 }
228 }
229
230
231
232
233
234 @Override
235 public String[] listFc() {
236 final String[] superItfs = super.listFc();
237 final String[] itfs = new String[superItfs.length + 1];
238 System.arraycopy(superItfs, 0, itfs, 0, superItfs.length);
239 itfs[superItfs.length] = COMPILATION_TASK_FACTORY_ITF_NAME;
240 return itfs;
241 }
242
243 @Override
244 public void bindFc(final String clientItfName, final Object serverItf)
245 throws NoSuchInterfaceException, IllegalBindingException,
246 IllegalLifeCycleException {
247
248 if (clientItfName == null) {
249 throw new IllegalArgumentException("Interface name can't be null");
250 }
251
252 if (clientItfName.equals(COMPILATION_TASK_FACTORY_ITF_NAME))
253 compilationTaskFactoryItf = (CompilationTaskFactory) serverItf;
254 else
255 super.bindFc(clientItfName, serverItf);
256 }
257
258 @Override
259 public Object lookupFc(final String clientItfName)
260 throws NoSuchInterfaceException {
261
262 if (clientItfName == null) {
263 throw new IllegalArgumentException("Interface name can't be null");
264 }
265
266 if (clientItfName.equals(COMPILATION_TASK_FACTORY_ITF_NAME))
267 return compilationTaskFactoryItf;
268 else
269 return super.lookupFc(clientItfName);
270 }
271
272 @Override
273 public void unbindFc(final String clientItfName)
274 throws NoSuchInterfaceException, IllegalBindingException,
275 IllegalLifeCycleException {
276
277 if (clientItfName == null) {
278 throw new IllegalArgumentException("Interface name can't be null");
279 }
280
281 if (clientItfName.equals(COMPILATION_TASK_FACTORY_ITF_NAME))
282 compilationTaskFactoryItf = null;
283 else
284 super.unbindFc(clientItfName);
285 }
286 }