|
1 /* |
|
2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
21 * have any questions. |
|
22 */ |
|
23 |
|
24 package evalexpr; |
|
25 |
|
26 import java.io.ByteArrayOutputStream; |
|
27 import java.io.FilterOutputStream; |
|
28 import java.io.IOException; |
|
29 import java.io.InputStream; |
|
30 import java.io.OutputStream; |
|
31 import java.io.Reader; |
|
32 import java.io.StringReader; |
|
33 import java.net.URI; |
|
34 import java.net.URISyntaxException; |
|
35 import java.nio.CharBuffer; |
|
36 import java.util.HashMap; |
|
37 import java.util.Map; |
|
38 import javax.tools.*; |
|
39 import javax.tools.JavaFileObject.Kind; |
|
40 |
|
41 /** |
|
42 * A file manager for compiling strings to byte arrays. |
|
43 * This file manager delegates to another file manager |
|
44 * to lookup classes on boot class path. |
|
45 * |
|
46 * <p><b>This is NOT part of any API supported by Sun Microsystems. |
|
47 * If you write code that depends on this, you do so at your own |
|
48 * risk. This code and its internal interfaces are subject to change |
|
49 * or deletion without notice.</b></p> |
|
50 * @author Peter von der Ahé |
|
51 */ |
|
52 public final class MemoryFileManager extends ForwardingJavaFileManager { |
|
53 /** |
|
54 * Maps binary class names to class files stored as byte arrays. |
|
55 */ |
|
56 private Map<String, byte[]> classes; |
|
57 |
|
58 /** |
|
59 * Creates a JavaFileObject representing the given compilation unit. |
|
60 * @param name a name representing this source code, for example, the name of a class |
|
61 * @param code a compilation unit (source code for a Java program) |
|
62 * @return a JavaFileObject represtenting the given compilation unit |
|
63 */ |
|
64 public static JavaFileObject makeSource(String name, String code) { |
|
65 return new JavaSourceFromString(name, code); |
|
66 } |
|
67 |
|
68 /** |
|
69 * Construct a memory file manager which delegates to the specified |
|
70 * file manager for unknown sources. |
|
71 * @param fileManager a file manager used to look up class files on class path, etc. |
|
72 */ |
|
73 public MemoryFileManager(JavaFileManager fileManager) { |
|
74 super(fileManager); |
|
75 classes = new HashMap<String, byte[]>(); |
|
76 } |
|
77 |
|
78 /** |
|
79 * Get a class loader which first search the classes stored |
|
80 * by this file mananger. |
|
81 * @return a class loader for compiled files |
|
82 */ |
|
83 @Override |
|
84 public ClassLoader getClassLoader(Location location) { |
|
85 return new ByteArrayClassLoader(classes); |
|
86 } |
|
87 |
|
88 @Override |
|
89 public JavaFileObject getJavaFileForOutput(Location location, |
|
90 String name, |
|
91 Kind kind, |
|
92 FileObject originatingSource) |
|
93 throws UnsupportedOperationException |
|
94 { |
|
95 if (originatingSource instanceof JavaSourceFromString) { |
|
96 return new JavaClassInArray(name); |
|
97 } else { |
|
98 throw new UnsupportedOperationException(); |
|
99 } |
|
100 } |
|
101 |
|
102 protected static URI uriFromString(String uri) { |
|
103 try { |
|
104 return new URI(uri); |
|
105 } catch (URISyntaxException e) { |
|
106 throw new IllegalArgumentException(e); |
|
107 } |
|
108 } |
|
109 |
|
110 /** |
|
111 * A file object representing a Java class file stored in a byte array. |
|
112 */ |
|
113 private class JavaClassInArray extends SimpleJavaFileObject { |
|
114 |
|
115 private String name; |
|
116 |
|
117 /** |
|
118 * Constructs a JavaClassInArray object. |
|
119 * @param name binary name of the class to be stored in this file object |
|
120 */ |
|
121 JavaClassInArray(String name) { |
|
122 super(uriFromString("mfm:///" + name.replace('.','/') + Kind.CLASS.extension), |
|
123 Kind.CLASS); |
|
124 this.name = name; |
|
125 } |
|
126 |
|
127 public OutputStream openOutputStream() { |
|
128 return new FilterOutputStream(new ByteArrayOutputStream()) { |
|
129 public void close() throws IOException { |
|
130 out.close(); |
|
131 ByteArrayOutputStream bos = (ByteArrayOutputStream)out; |
|
132 classes.put(name, bos.toByteArray()); |
|
133 System.out.println("compiled " + name); |
|
134 } |
|
135 }; |
|
136 } |
|
137 } |
|
138 |
|
139 /** |
|
140 * A file object used to represent source coming from a string. |
|
141 */ |
|
142 private static class JavaSourceFromString extends SimpleJavaFileObject { |
|
143 /** |
|
144 * The source code of this "file". |
|
145 */ |
|
146 final String code; |
|
147 |
|
148 /** |
|
149 * Constructs a new JavaSourceFromString. |
|
150 * @param name the name of the compilation unit represented by this file object |
|
151 * @param code the source code for the compilation unit represented by this file object |
|
152 */ |
|
153 JavaSourceFromString(String name, String code) { |
|
154 super(uriFromString("mfm:///" + name.replace('.','/') + Kind.SOURCE.extension), |
|
155 Kind.SOURCE); |
|
156 this.code = code; |
|
157 } |
|
158 |
|
159 @Override |
|
160 public CharSequence getCharContent(boolean ignoreEncodingErrors) { |
|
161 return code; |
|
162 } |
|
163 } |
|
164 |
|
165 } |