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.primitive.thinkMC.source;
25
26 import static org.objectweb.fractal.adl.NodeUtil.castNodeError;
27 import static org.objectweb.fractal.cecilia.adl.directives.DirectiveHelper.getCFlags;
28 import static org.objectweb.fractal.cecilia.adl.directives.DirectiveHelper.getLdFlags;
29 import static org.objectweb.fractal.cecilia.adl.implementations.ImplementationDecorationUtil.getCode;
30
31 import java.io.File;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.concurrent.ExecutorService;
39 import java.util.concurrent.Future;
40
41 import org.objectweb.fractal.adl.ADLException;
42 import org.objectweb.fractal.adl.CompilerError;
43 import org.objectweb.fractal.adl.ComponentVisitor;
44 import org.objectweb.fractal.adl.Node;
45 import org.objectweb.fractal.adl.components.ComponentContainer;
46 import org.objectweb.fractal.adl.error.GenericErrors;
47 import org.objectweb.fractal.adl.implementations.Implementation;
48 import org.objectweb.fractal.adl.implementations.ImplementationContainer;
49 import org.objectweb.fractal.api.Component;
50 import org.objectweb.fractal.api.NoSuchInterfaceException;
51 import org.objectweb.fractal.api.control.IllegalBindingException;
52 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
53 import org.objectweb.fractal.cecilia.adl.compiler.CompilationTaskFactory;
54 import org.objectweb.fractal.cecilia.adl.compiler.OutputFormat;
55 import org.objectweb.fractal.cecilia.adl.compiler.OutputFormatContainer;
56 import org.objectweb.fractal.cecilia.adl.directives.Include;
57 import org.objectweb.fractal.cecilia.adl.directives.IncludeContainer;
58 import org.objectweb.fractal.cecilia.adl.file.FileCollectionProvider;
59 import org.objectweb.fractal.cecilia.adl.file.FileProvider;
60 import org.objectweb.fractal.cecilia.adl.file.FutureFileCollectionProvider;
61 import org.objectweb.fractal.cecilia.adl.file.FutureFileProvider;
62 import org.objectweb.fractal.cecilia.adl.file.SourceFile;
63 import org.objectweb.fractal.cecilia.adl.file.SourceFileProvider;
64 import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
65 import org.objectweb.fractal.task.core.TaskException;
66 import org.objectweb.fractal.task.core.primitive.annotations.ClientInterface;
67 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
68 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
69 import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
70
71 public class CompilationVisitor extends AbstractTaskFactoryUser
72 implements
73 ComponentVisitor {
74
75
76 public static final String COMPILATION_COMPOSITION = "org.objectweb.fractal.cecilia.primitive.thinkMC.Compilation";
77
78
79 public static final String COMPILATION_TASK_FACTORY_ITF_NAME = "compilation-task-factory";
80
81
82 public CompilationTaskFactory compilationTaskFactoryItf;
83
84
85
86
87
88
89
90
91 public Component visit(final List<Node> path,
92 final ComponentContainer container, final Map<Object, Object> context)
93 throws ADLException, TaskException {
94 final Implementation impl = castNodeError(container,
95 ImplementationContainer.class).getImplementation();
96 if (impl == null) {
97 throw new CompilerError(GenericErrors.INTERNAL_ERROR,
98 "This visitor is only applicable for primitive component.");
99 }
100
101
102 final List<String> cFlags = new ArrayList<String>();
103 cFlags.addAll(getCFlags(container));
104
105 boolean archiveOutput = false;
106 if (container instanceof OutputFormatContainer
107 && ((OutputFormatContainer) container).getOutput() != null) {
108 final String outputFormat = ((OutputFormatContainer) container)
109 .getOutput().getFormat();
110 if (OutputFormat.ARCHIVE_OUTPUT_FORMAT.equals(outputFormat))
111 archiveOutput = true;
112 }
113
114 final Collection<Component> tasks = new ArrayList<Component>();
115
116
117 tasks.add(createFileProviderAggregatorTask(container));
118
119
120 tasks.add(createComponentCompilationTask(container, cFlags, context));
121
122 if (impl instanceof IncludeContainer
123 && ((IncludeContainer) impl).getIncludes().length != 0) {
124 final Include[] includes = ((IncludeContainer) impl).getIncludes();
125
126 for (final Include include : includes) {
127
128 final SourceFile code = (SourceFile) getCode((Node) include);
129 if ((code).isAssemblyFile()) {
130
131
132 tasks.add(createAssemblyFileProvider(container, include, code));
133 }
134
135 tasks.add(createModuleCompilationTask(include, cFlags, context));
136 }
137 }
138
139 if (archiveOutput) {
140 tasks.add(createArchiveTask(container, null, context));
141 }
142
143
144 final boolean doLink = path.isEmpty();
145 if (doLink) {
146 final List<String> ldFlags = new ArrayList<String>();
147 ldFlags.addAll(getLdFlags(container));
148 tasks.add(compilationTaskFactoryItf.newLinkTask(container, null,
149 ldFlags, context));
150 }
151
152 return createCompilationComposition(container, tasks, archiveOutput, doLink);
153 }
154
155
156
157
158
159 protected Component createFileProviderAggregatorTask(
160 final ComponentContainer container) throws TaskException {
161 return taskFactoryItf.newPrimitiveTask(new FileProviderAggregatorTask(),
162 container);
163 }
164
165 protected Component createModuleCompilationTask(final Include include,
166 final List<String> cFlag, final Map<Object, Object> context)
167 throws TaskException {
168 return compilationTaskFactoryItf.newCompileTask(include, cFlag, context);
169 }
170
171 protected Component createComponentCompilationTask(
172 final ComponentContainer container, final List<String> cFlag,
173 final Map<Object, Object> context) throws TaskException {
174 return compilationTaskFactoryItf.newCompileTask(container, cFlag, context);
175 }
176
177 protected Component createAssemblyFileProvider(
178 final ComponentContainer container, final Include include,
179 final SourceFile code) throws TaskException {
180 return taskFactoryItf.newPrimitiveTask(new AssemblyFileProvider(code),
181 container, include);
182 }
183
184 protected Component createArchiveTask(final ComponentContainer container,
185 final List<String> cFlag, final Map<Object, Object> context)
186 throws TaskException {
187 return compilationTaskFactoryItf.newArchiveTask(container, null, cFlag,
188 context);
189 }
190
191 protected Component createCompilationComposition(
192 final ComponentContainer container, final Collection<Component> tasks,
193 final boolean archiveOutput, final boolean doLink) throws TaskException {
194 return taskFactoryItf.newCompositeTask(tasks, COMPILATION_COMPOSITION,
195 null, container, archiveOutput, doLink);
196 }
197
198
199
200
201
202
203
204
205
206
207 @TaskParameters("componentNode")
208 @ServerInterfaces(@ServerInterface(name = "component-compiled-files-provider", signature = FutureFileCollectionProvider.class, record = "role:outputFiles, id:%", parameters = "componentNode"))
209 public static class FileProviderAggregatorTask
210 implements
211 FutureFileCollectionProvider {
212
213 protected Collection<Future<File>> providedFiles;
214
215
216
217
218
219
220
221
222 @ClientInterface(name = "file-providers", signature = FutureFileProvider.class, record = "role:aggregatorInputFile, id:%", parameters = "componentNode")
223 public final Map<String, FutureFileProvider> clientProviderItfs = new HashMap<String, FutureFileProvider>();
224
225
226
227
228
229 @ClientInterface(name = "runtime-compiled-files", signature = FutureFileProvider.class, record = "role:runtimeCompiledFile, id:%", parameters = "componentNode")
230 public final Map<String, FutureFileProvider> runtimeProviderItfs = new HashMap<String, FutureFileProvider>();
231
232
233
234
235
236 @ClientInterface(name = "runtime-compiled-file-collections", signature = FutureFileCollectionProvider.class, record = "role:runtimeCompiledFileCollection, id:%", parameters = "componentNode")
237 public final Map<String, FutureFileCollectionProvider> runtimeCollectionProviderItfs = new HashMap<String, FutureFileCollectionProvider>();
238
239
240
241
242
243 public synchronized Collection<Future<File>> getFiles(
244 final ExecutorService executorService) {
245 if (providedFiles == null) {
246 providedFiles = new HashSet<Future<File>>();
247 for (final FutureFileProvider fileProvider : clientProviderItfs
248 .values()) {
249 providedFiles.add(fileProvider.getFile(executorService));
250 }
251
252 for (final FutureFileProvider fileProvider : runtimeProviderItfs
253 .values()) {
254 providedFiles.add(fileProvider.getFile(executorService));
255 }
256
257 for (final FutureFileCollectionProvider fileCollectionProvider : runtimeCollectionProviderItfs
258 .values()) {
259 providedFiles
260 .addAll(fileCollectionProvider.getFiles(executorService));
261 }
262 }
263 return providedFiles;
264 }
265 }
266
267
268
269
270
271 @TaskParameters({"componentNode", "moduleNode"})
272 @ServerInterfaces(@ServerInterface(name = "assembly-file-provider", signature = SourceFileProvider.class, record = "role:componentAssemblyModuleFile, id:%, module:%", parameters = {
273 "componentNode", "moduleNode"}))
274 public static class AssemblyFileProvider implements SourceFileProvider {
275
276 protected final SourceFile assemblyFile;
277
278
279
280
281
282
283
284
285 public AssemblyFileProvider(final SourceFile assemblyFile) {
286 this.assemblyFile = assemblyFile;
287 }
288
289
290
291
292
293 public SourceFile getSourceFile() {
294 return assemblyFile;
295 }
296 }
297
298
299
300
301
302 @Override
303 public String[] listFc() {
304 final String[] superItfs = super.listFc();
305 final String[] itfs = new String[superItfs.length + 1];
306 System.arraycopy(superItfs, 0, itfs, 0, superItfs.length);
307 itfs[superItfs.length] = COMPILATION_TASK_FACTORY_ITF_NAME;
308 return itfs;
309 }
310
311 @Override
312 public void bindFc(final String clientItfName, final Object serverItf)
313 throws NoSuchInterfaceException, IllegalBindingException,
314 IllegalLifeCycleException {
315
316 if (clientItfName == null) {
317 throw new IllegalArgumentException("Interface name can't be null");
318 }
319
320 if (clientItfName.equals(COMPILATION_TASK_FACTORY_ITF_NAME))
321 compilationTaskFactoryItf = (CompilationTaskFactory) serverItf;
322 else
323 super.bindFc(clientItfName, serverItf);
324 }
325
326 @Override
327 public Object lookupFc(final String clientItfName)
328 throws NoSuchInterfaceException {
329
330 if (clientItfName == null) {
331 throw new IllegalArgumentException("Interface name can't be null");
332 }
333
334 if (clientItfName.equals(COMPILATION_TASK_FACTORY_ITF_NAME))
335 return compilationTaskFactoryItf;
336 else
337 return super.lookupFc(clientItfName);
338 }
339
340 @Override
341 public void unbindFc(final String clientItfName)
342 throws NoSuchInterfaceException, IllegalBindingException,
343 IllegalLifeCycleException {
344
345 if (clientItfName == null) {
346 throw new IllegalArgumentException("Interface name can't be null");
347 }
348
349 if (clientItfName.equals(COMPILATION_TASK_FACTORY_ITF_NAME))
350 compilationTaskFactoryItf = null;
351 else
352 super.unbindFc(clientItfName);
353 }
354 }