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.compiler;
25
26 import java.io.File;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.LinkedHashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.ExecutorService;
35 import java.util.concurrent.Executors;
36 import java.util.concurrent.Future;
37 import java.util.logging.Level;
38 import java.util.logging.Logger;
39
40 import org.objectweb.fractal.adl.ADLException;
41 import org.objectweb.fractal.adl.util.FractalADLLogManager;
42 import org.objectweb.fractal.cecilia.adl.file.FileProvider;
43 import org.objectweb.fractal.cecilia.adl.file.FutureFileCollectionProvider;
44 import org.objectweb.fractal.cecilia.adl.file.FutureFileProvider;
45 import org.objectweb.fractal.cecilia.adl.file.SourceFileWriter;
46 import org.objectweb.fractal.task.core.Executable;
47 import org.objectweb.fractal.task.core.primitive.annotations.ClientInterface;
48 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
49 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
50 import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
51
52 @TaskParameters("id")
53 @ServerInterfaces(@ServerInterface(name = "file-provider", signature = FileProvider.class, record = "role:linkedFile, id:%", parameters = "id"))
54 public abstract class AbstractLinkTask implements Executable, FileProvider {
55
56
57 protected final String outputName;
58
59 protected List<String> flags;
60
61 protected final File outputDir;
62
63 protected final int nThreads;
64
65
66 protected File linkedFile;
67
68
69 protected static Logger depLogger = FractalADLLogManager
70 .getLogger("dep");
71
72 protected static Logger ioLogger = FractalADLLogManager
73 .getLogger("io");
74
75
76
77
78
79
80 @ClientInterface(name = "source-file-provider", signature = FutureFileProvider.class, record = "role:compiledFile, id:%", parameters = "id")
81 public final Map<String, FutureFileProvider> fileProviderItfs = new HashMap<String, FutureFileProvider>();
82
83
84 @ClientInterface(name = "source-file-collection-provider", signature = FutureFileCollectionProvider.class, record = "role:compiledFileCollection, id:%", parameters = "id")
85 public final Map<String, FutureFileCollectionProvider> fileCollectionProviderItfs = new HashMap<String, FutureFileCollectionProvider>();
86
87
88
89
90
91
92
93
94
95
96
97 public AbstractLinkTask(final String outputName, final File outputDir,
98 final List<String> flags, final int nThreads) {
99 this.outputName = outputName;
100 this.outputDir = outputDir;
101 this.flags = flags;
102 this.nThreads = nThreads;
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 protected abstract File link(File outputFile, Collection<File> inputFiles)
122 throws ADLException, InterruptedException;
123
124
125
126
127
128 protected File getOutputFile() {
129 final File outFile = new File(outputName);
130 if (outFile.isAbsolute())
131 return outFile;
132 else
133 return new File(outputDir, outputName);
134 }
135
136
137
138
139
140 public void execute() throws Exception {
141 ExecutorService executorService = null;
142 try {
143 executorService = Executors.newFixedThreadPool(nThreads);
144
145
146 final Collection<Future<File>> futureFiles = new LinkedHashSet<Future<File>>();
147
148
149 for (final FutureFileProvider fileProvider : fileProviderItfs.values()) {
150 futureFiles.add(fileProvider.getFile(executorService));
151 }
152
153
154 for (final FutureFileCollectionProvider collectionProvider : fileCollectionProviderItfs
155 .values()) {
156 futureFiles.addAll(collectionProvider.getFiles(executorService));
157 }
158
159 final Collection<File> inputFiles = new ArrayList<File>(futureFiles.size());
160 linkedFile = getOutputFile();
161 final long outputTimestamp = linkedFile.lastModified();
162 boolean relink = false;
163 for (final Future<File> futureFile : futureFiles) {
164 File inputFile;
165 try {
166 inputFile = futureFile.get();
167 } catch (final ExecutionException e) {
168 if (e.getCause() instanceof ADLException)
169 throw (ADLException) e.getCause();
170 else
171 throw e;
172 }
173 inputFiles.add(inputFile);
174 if (inputFile.lastModified() > outputTimestamp) {
175 if (depLogger.isLoggable(Level.FINE))
176 depLogger.fine("Input file '" + inputFile
177 + " is more recent than file '" + linkedFile + "', recompile.");
178 relink = true;
179 }
180 }
181
182 if (relink) {
183 SourceFileWriter.createOutputDir(linkedFile.getParentFile());
184 linkedFile = link(linkedFile, inputFiles);
185 } else if (depLogger.isLoggable(Level.FINE)) {
186 depLogger.fine("Output file '" + linkedFile
187 + "' is up to date, do not recompile.");
188 }
189 }
190 finally {
191
192 executorService.shutdown();
193 }
194 }
195
196
197
198
199
200 public File getFile() {
201 return linkedFile;
202 }
203 }