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 | |
|
26 | |
package com.sun.tools.javafx.script; |
27 | |
|
28 | |
import com.sun.tools.javafx.util.JavafxFileManager; |
29 | |
import java.io.*; |
30 | |
import java.net.URI; |
31 | |
import java.nio.CharBuffer; |
32 | |
import java.util.Map; |
33 | |
import java.util.*; |
34 | |
import java.util.HashMap; |
35 | |
import java.util.Set; |
36 | |
import javax.lang.model.element.NestingKind; |
37 | |
import javax.tools.*; |
38 | |
import javax.tools.JavaFileObject.Kind; |
39 | |
import java.net.URL; |
40 | |
import java.net.URI; |
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | 40 | public final class MemoryFileManager extends ForwardingJavaFileManager { |
48 | |
private ClassLoader parentClassLoader; |
49 | 37 | List<SimpleJavaFileObject> buffers = new ArrayList<SimpleJavaFileObject>(); |
50 | |
|
51 | |
|
52 | |
private final static String EXT = ".fx"; |
53 | |
|
54 | |
private Map<String, byte[]> classBytes; |
55 | |
|
56 | |
public MemoryFileManager(JavaFileManager fileManager, ClassLoader cl) { |
57 | 37 | super(fileManager); |
58 | 37 | classBytes = new HashMap<String, byte[]>(); |
59 | 37 | parentClassLoader = cl; |
60 | 37 | } |
61 | |
|
62 | |
public Map<String, byte[]> getClassBytes() { |
63 | 18 | return classBytes; |
64 | |
} |
65 | |
|
66 | |
@Override |
67 | |
public void close() throws IOException { |
68 | 18 | classBytes = new HashMap<String, byte[]>(); |
69 | 18 | } |
70 | |
|
71 | |
@Override |
72 | |
public void flush() throws IOException { |
73 | 87 | } |
74 | |
|
75 | |
|
76 | |
|
77 | |
|
78 | |
private static class ClassResource extends SimpleJavaFileObject { |
79 | |
URL url; |
80 | |
static URI toURI(URL u) { |
81 | |
try { |
82 | 0 | return u.toURI(); |
83 | 0 | } catch (Exception e) { |
84 | 0 | throw new RuntimeException(e); |
85 | |
} |
86 | |
} |
87 | |
public ClassResource(URL u) { |
88 | 0 | super(toURI(u), Kind.CLASS); |
89 | 0 | this.url = u; |
90 | 0 | } |
91 | |
|
92 | |
@Override |
93 | |
public InputStream openInputStream() throws IOException { |
94 | 0 | return url.openStream(); |
95 | |
} |
96 | |
} |
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | 49 | private static class StringInputBuffer extends SimpleJavaFileObject { |
102 | |
final String code; |
103 | |
final boolean isFXSourceFile; |
104 | |
String binaryName; |
105 | |
|
106 | |
public String getBinaryName() { |
107 | 216 | return binaryName.equals("__FX_SCRIPT__.fx") ? "__FX_SCRIPT__" : binaryName; |
108 | |
} |
109 | |
|
110 | |
StringInputBuffer(String name, String code) { |
111 | 37 | super(toURI(name), Kind.SOURCE); |
112 | 37 | this.code = code; |
113 | 37 | binaryName = name; |
114 | 37 | isFXSourceFile = name.endsWith(JavafxFileManager.FX_SOURCE_SUFFIX); |
115 | 37 | } |
116 | |
|
117 | |
@Override |
118 | |
public CharBuffer getCharContent(boolean ignoreEncodingErrors) { |
119 | 49 | return CharBuffer.wrap(code); |
120 | |
} |
121 | |
|
122 | |
public Reader openReader() { |
123 | 0 | return new StringReader(code); |
124 | |
} |
125 | |
|
126 | |
@Override |
127 | |
public Kind getKind() { |
128 | |
|
129 | 300 | return JavaFileObject.Kind.SOURCE; |
130 | |
} |
131 | |
|
132 | |
@Override |
133 | |
public String getName() { |
134 | 714 | return super.getName(); |
135 | |
} |
136 | |
|
137 | |
@Override |
138 | |
public NestingKind getNestingKind() { |
139 | 0 | return super.getNestingKind(); |
140 | |
} |
141 | |
|
142 | |
@Override |
143 | |
public boolean isNameCompatible(String simpleName, Kind kind) { |
144 | 47 | return super.isNameCompatible(simpleName, kind); |
145 | |
} |
146 | |
|
147 | |
@Override |
148 | |
public InputStream openInputStream() throws IOException { |
149 | 0 | return super.openInputStream(); |
150 | |
} |
151 | |
|
152 | |
@Override |
153 | |
public OutputStream openOutputStream() throws IOException { |
154 | 0 | return super.openOutputStream(); |
155 | |
} |
156 | |
|
157 | |
@Override |
158 | |
public Reader openReader(boolean ignoreEncodingErrors) throws IOException { |
159 | 0 | return super.openReader(ignoreEncodingErrors); |
160 | |
} |
161 | |
|
162 | |
@Override |
163 | |
public Writer openWriter() throws IOException { |
164 | 0 | return super.openWriter(); |
165 | |
} |
166 | |
} |
167 | |
|
168 | |
|
169 | |
|
170 | |
|
171 | 40 | private class ClassOutputBuffer extends SimpleJavaFileObject { |
172 | |
private String name; |
173 | |
|
174 | 40 | ClassOutputBuffer(String name) { |
175 | 40 | super(toURI(name), Kind.CLASS); |
176 | 40 | this.name = name; |
177 | 40 | } |
178 | |
|
179 | |
public String getBinaryName() { |
180 | 0 | return name; |
181 | |
} |
182 | |
|
183 | |
@Override |
184 | |
public OutputStream openOutputStream() { |
185 | 40 | return new FilterOutputStream(new ByteArrayOutputStream()) { |
186 | |
@Override |
187 | |
public void close() throws IOException { |
188 | 40 | out.close(); |
189 | 40 | ByteArrayOutputStream bos = (ByteArrayOutputStream)out; |
190 | 40 | classBytes.put(name, bos.toByteArray()); |
191 | 40 | } |
192 | |
}; |
193 | |
} |
194 | |
} |
195 | |
@Override |
196 | |
public FileObject getFileForInput(Location location, |
197 | |
String packageName, |
198 | |
String relativeName) throws IOException { |
199 | |
|
200 | 0 | return super.getFileForInput(location, packageName, relativeName); |
201 | |
} |
202 | |
|
203 | |
@Override |
204 | |
public FileObject getFileForOutput(Location location, |
205 | |
String packageName, |
206 | |
String relativeName, |
207 | |
FileObject sibling) throws IOException { |
208 | |
|
209 | 0 | return super.getFileForOutput(location, packageName, relativeName, sibling); |
210 | |
} |
211 | |
|
212 | |
@Override |
213 | |
public JavaFileObject getJavaFileForInput(JavaFileManager.Location location, |
214 | |
String className, |
215 | |
Kind kind) throws IOException { |
216 | 0 | if (kind == Kind.CLASS) { |
217 | 0 | URL res = |
218 | |
parentClassLoader.getResource(className.replace('.', '/') + ".class"); |
219 | 0 | if (res != null) { |
220 | 0 | return new ClassResource(res); |
221 | |
} |
222 | |
} |
223 | 0 | return super.getJavaFileForInput(location, className, kind); |
224 | |
} |
225 | |
|
226 | |
@Override |
227 | |
public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, |
228 | |
String className, |
229 | |
Kind kind, |
230 | |
FileObject sibling) throws IOException { |
231 | 40 | if (kind == Kind.CLASS) { |
232 | 40 | ClassOutputBuffer buf = new ClassOutputBuffer(className); |
233 | 40 | buffers.add(buf); |
234 | 40 | return buf; |
235 | |
} else { |
236 | 0 | return super.getJavaFileForOutput(location, className, kind, sibling); |
237 | |
} |
238 | |
} |
239 | |
@Override |
240 | |
public Iterable list(JavaFileManager.Location location, |
241 | |
String packageName, |
242 | |
Set kinds, |
243 | |
boolean recurse) |
244 | |
throws IOException |
245 | |
{ |
246 | 696 | Iterable result = super.list(location, packageName, kinds, recurse); |
247 | 696 | List results = new LinkedList(); |
248 | 696 | for (Object o : result) { |
249 | 35448 | results.add(o); |
250 | |
} |
251 | 696 | String prefix = packageName.equals("") ? "" : packageName + "."; |
252 | 696 | for (SimpleJavaFileObject b : buffers) { |
253 | 712 | String name = b.getName().replace("/", "."); |
254 | 712 | name = name.substring(1, name.length() - (name.endsWith(EXT) ? EXT.length() : 0)); |
255 | 712 | if (prefix.length() == 0) { |
256 | 112 | if (!name.contains(".")) { |
257 | 108 | results.add(b); |
258 | |
} |
259 | |
} else { |
260 | 600 | if (name.startsWith(prefix)) { |
261 | 0 | name = name.substring(prefix.length()); |
262 | 0 | if (!name.contains(".")) { |
263 | 0 | results.add(b); |
264 | |
} |
265 | |
} |
266 | |
} |
267 | 712 | } |
268 | 696 | return results; |
269 | |
} |
270 | |
|
271 | |
JavaFileObject makeStringSource(String name, String code) { |
272 | 37 | StringInputBuffer buffer = new StringInputBuffer(name, code); |
273 | 37 | buffers.add(buffer); |
274 | 37 | return buffer; |
275 | |
} |
276 | |
|
277 | |
@Override |
278 | |
public String inferBinaryName(Location location, JavaFileObject file) { |
279 | 71112 | if (file instanceof StringInputBuffer) { |
280 | 216 | return ((StringInputBuffer)file).getBinaryName(); |
281 | 70896 | } else if (file instanceof ClassOutputBuffer) { |
282 | 0 | return ((ClassOutputBuffer)file).getBinaryName(); |
283 | |
} |
284 | 70896 | return super.inferBinaryName(location, file); |
285 | |
} |
286 | |
|
287 | |
static URI toURI(String name) { |
288 | 77 | File file = new File(name); |
289 | 77 | if (file.exists()) { |
290 | 1 | return file.toURI(); |
291 | |
} else { |
292 | |
try { |
293 | 76 | final StringBuilder newUri = new StringBuilder(); |
294 | 76 | newUri.append("mfm:///"); |
295 | 76 | newUri.append(name.replace('.', '/')); |
296 | 76 | if(name.endsWith(EXT)) newUri.replace(newUri.length() - EXT.length(), newUri.length(), EXT); |
297 | 76 | return URI.create(newUri.toString()); |
298 | 0 | } catch (Exception exp) { |
299 | 0 | return URI.create("mfm:///com/sun/tools/javafx/script/javafx_source"); |
300 | |
} |
301 | |
} |
302 | |
} |
303 | |
} |