45 import java.util.Map;
46 import java.util.Map.Entry;
47 import java.util.NoSuchElementException;
48 import java.util.Set;
49 import java.util.TreeSet;
50
51 import javax.annotation.processing.Processor;
52 import javax.tools.ForwardingJavaFileObject;
53 import javax.tools.JavaFileManager;
54 import javax.tools.JavaFileObject;
55 import javax.tools.JavaFileObject.Kind;
56 import javax.tools.StandardLocation;
57
58 import com.sun.source.util.Plugin;
59 import com.sun.tools.javac.code.Source;
60 import com.sun.tools.javac.code.Source.Feature;
61 import com.sun.tools.javac.file.CacheFSInfo;
62 import com.sun.tools.javac.file.JavacFileManager;
63 import com.sun.tools.javac.jvm.Target;
64 import com.sun.tools.javac.main.Option;
65 import com.sun.tools.javac.util.Assert;
66 import com.sun.tools.javac.util.Context;
67 import com.sun.tools.javac.util.Log;
68 import com.sun.tools.javac.util.StringUtils;
69
70 /** PlatformProvider for JDK N.
71 *
72 * <p><b>This is NOT part of any supported API.
73 * If you write code that depends on this, you do so at your own risk.
74 * This code and its internal interfaces are subject to change or
75 * deletion without notice.</b>
76 */
77 public class JDKPlatformProvider implements PlatformProvider {
78
79 @Override
80 public Iterable<String> getSupportedPlatformNames() {
81 return SUPPORTED_JAVA_PLATFORM_VERSIONS;
82 }
83
84 @Override
85 public PlatformDescription getPlatform(String platformName, String options) throws PlatformNotSupported {
86 if (!SUPPORTED_JAVA_PLATFORM_VERSIONS.contains(platformName)) {
87 throw new PlatformNotSupported();
88 }
89 return getPlatformTrusted(platformName);
90 }
91
92 public PlatformDescription getPlatformTrusted(String platformName) {
93 return new PlatformDescriptionImpl(platformName);
94 }
95
96 private static final String[] symbolFileLocation = { "lib", "ct.sym" };
97
98 // These must match attributes defined in ZipFileSystem.java.
99 private static final Map<String, ?> CT_SYM_ZIP_ENV = Map.of(
100 // Symbol file should always be opened read-only.
101 "accessMode", "readOnly",
102 // Uses less accurate, but faster, timestamp information
103 // (nobody should care about timestamps in the CT symbol file).
104 "zipinfo-time", "false");
105
106 private static final Set<String> SUPPORTED_JAVA_PLATFORM_VERSIONS;
107 public static final Comparator<String> NUMERICAL_COMPARATOR = (s1, s2) -> {
108 int i1;
109 try {
110 i1 = Integer.parseInt(s1);
111 } catch (NumberFormatException ex) {
112 i1 = Integer.MAX_VALUE;
113 }
115 try {
116 i2 = Integer.parseInt(s2);
117 } catch (NumberFormatException ex) {
118 i2 = Integer.MAX_VALUE;
119 }
120 return i1 != i2 ? i1 - i2 : s1.compareTo(s2);
121 };
122
123 static {
124 SUPPORTED_JAVA_PLATFORM_VERSIONS = new TreeSet<>(NUMERICAL_COMPARATOR);
125 Path ctSymFile = findCtSym();
126 if (Files.exists(ctSymFile)) {
127 try (FileSystem fs = FileSystems.newFileSystem(ctSymFile, CT_SYM_ZIP_ENV);
128 DirectoryStream<Path> dir =
129 Files.newDirectoryStream(fs.getRootDirectories().iterator().next())) {
130 for (Path section : dir) {
131 if (section.getFileName().toString().contains("-"))
132 continue;
133 for (char ver : section.getFileName().toString().toCharArray()) {
134 String verString = Character.toString(ver);
135 Target t = Target.lookup("" + Integer.parseInt(verString, Character.MAX_RADIX));
136
137 if (t != null) {
138 SUPPORTED_JAVA_PLATFORM_VERSIONS.add(targetNumericVersion(t));
139 }
140 }
141 }
142 } catch (IOException | ProviderNotFoundException ex) {
143 }
144 }
145 }
146
147 private static String targetNumericVersion(Target target) {
148 return Integer.toString(target.ordinal() - Target.JDK1_1.ordinal() + 1);
149 }
150
151 static class PlatformDescriptionImpl implements PlatformDescription {
152
153 private final Map<Path, FileSystem> ctSym2FileSystem = new HashMap<>();
154 private final String sourceVersion;
155 private final String ctSymVersion;
156
157 PlatformDescriptionImpl(String sourceVersion) {
158 this.sourceVersion = sourceVersion;
159 this.ctSymVersion =
160 StringUtils.toUpperCase(Integer.toString(Integer.parseInt(sourceVersion), Character.MAX_RADIX));
161 }
162
163 @Override
164 public JavaFileManager getFileManager() {
165 Context context = new Context();
166 PrintWriter pw = new PrintWriter(System.err, true);
167 context.put(Log.errKey, pw);
168 CacheFSInfo.preRegister(context);
169 JavacFileManager fm = new JavacFileManager(context, true, null) {
170 @Override
171 public boolean hasLocation(Location location) {
172 return super.hasExplicitLocation(location);
173 }
174
175 @Override
176 public JavaFileObject getJavaFileForInput(Location location, String className,
177 Kind kind) throws IOException {
178 if (kind == Kind.CLASS) {
179 String fileName = className.replace('.', '/');
180 JavaFileObject result =
|
45 import java.util.Map;
46 import java.util.Map.Entry;
47 import java.util.NoSuchElementException;
48 import java.util.Set;
49 import java.util.TreeSet;
50
51 import javax.annotation.processing.Processor;
52 import javax.tools.ForwardingJavaFileObject;
53 import javax.tools.JavaFileManager;
54 import javax.tools.JavaFileObject;
55 import javax.tools.JavaFileObject.Kind;
56 import javax.tools.StandardLocation;
57
58 import com.sun.source.util.Plugin;
59 import com.sun.tools.javac.code.Source;
60 import com.sun.tools.javac.code.Source.Feature;
61 import com.sun.tools.javac.file.CacheFSInfo;
62 import com.sun.tools.javac.file.JavacFileManager;
63 import com.sun.tools.javac.jvm.Target;
64 import com.sun.tools.javac.main.Option;
65 import com.sun.tools.javac.util.Context;
66 import com.sun.tools.javac.util.Log;
67 import com.sun.tools.javac.util.StringUtils;
68
69 /** PlatformProvider for JDK N.
70 *
71 * <p><b>This is NOT part of any supported API.
72 * If you write code that depends on this, you do so at your own risk.
73 * This code and its internal interfaces are subject to change or
74 * deletion without notice.</b>
75 */
76 public class JDKPlatformProvider implements PlatformProvider {
77
78 public static final String PREVIEW_OPTION = "preview";
79 private static final String CT_SYM_PREVIEW_VERSION = "@";
80
81 @Override
82 public Iterable<String> getSupportedPlatformNames() {
83 return SUPPORTED_JAVA_PLATFORM_VERSIONS;
84 }
85
86 @Override
87 public PlatformDescription getPlatform(String platformName, String options) throws PlatformNotSupported {
88 if (!SUPPORTED_JAVA_PLATFORM_VERSIONS.contains(platformName)) {
89 throw new PlatformNotSupported();
90 }
91 if (PREVIEW_OPTION.equals(options) && !Source.DEFAULT.name.equals(platformName)) {
92 throw new PlatformNotSupported();
93 }
94 return getPlatformTrusted(platformName, options);
95 }
96
97 public PlatformDescription getPlatformTrusted(String platformName, String options) {
98 String ctSymVersion;
99
100 if (PREVIEW_OPTION.equals(options)) {
101 ctSymVersion = CT_SYM_PREVIEW_VERSION;
102 } else {
103 ctSymVersion =
104 StringUtils.toUpperCase(Integer.toString(Integer.parseInt(platformName), Character.MAX_RADIX));
105 }
106
107 return new PlatformDescriptionImpl(platformName, ctSymVersion);
108 }
109
110 private static final String[] symbolFileLocation = { "lib", "ct.sym" };
111
112 // These must match attributes defined in ZipFileSystem.java.
113 private static final Map<String, ?> CT_SYM_ZIP_ENV = Map.of(
114 // Symbol file should always be opened read-only.
115 "accessMode", "readOnly",
116 // Uses less accurate, but faster, timestamp information
117 // (nobody should care about timestamps in the CT symbol file).
118 "zipinfo-time", "false");
119
120 private static final Set<String> SUPPORTED_JAVA_PLATFORM_VERSIONS;
121 public static final Comparator<String> NUMERICAL_COMPARATOR = (s1, s2) -> {
122 int i1;
123 try {
124 i1 = Integer.parseInt(s1);
125 } catch (NumberFormatException ex) {
126 i1 = Integer.MAX_VALUE;
127 }
129 try {
130 i2 = Integer.parseInt(s2);
131 } catch (NumberFormatException ex) {
132 i2 = Integer.MAX_VALUE;
133 }
134 return i1 != i2 ? i1 - i2 : s1.compareTo(s2);
135 };
136
137 static {
138 SUPPORTED_JAVA_PLATFORM_VERSIONS = new TreeSet<>(NUMERICAL_COMPARATOR);
139 Path ctSymFile = findCtSym();
140 if (Files.exists(ctSymFile)) {
141 try (FileSystem fs = FileSystems.newFileSystem(ctSymFile, CT_SYM_ZIP_ENV);
142 DirectoryStream<Path> dir =
143 Files.newDirectoryStream(fs.getRootDirectories().iterator().next())) {
144 for (Path section : dir) {
145 if (section.getFileName().toString().contains("-"))
146 continue;
147 for (char ver : section.getFileName().toString().toCharArray()) {
148 String verString = Character.toString(ver);
149
150 if (CT_SYM_PREVIEW_VERSION.equals(verString)) {
151 continue; //ignore - preview is just an option
152 }
153
154 Target t = Target.lookup("" + Integer.parseInt(verString, Character.MAX_RADIX));
155
156 if (t != null) {
157 SUPPORTED_JAVA_PLATFORM_VERSIONS.add(targetNumericVersion(t));
158 }
159 }
160 }
161 } catch (IOException | ProviderNotFoundException ex) {
162 }
163 }
164 }
165
166 private static String targetNumericVersion(Target target) {
167 return Integer.toString(target.ordinal() - Target.JDK1_1.ordinal() + 1);
168 }
169
170 static class PlatformDescriptionImpl implements PlatformDescription {
171
172 private final Map<Path, FileSystem> ctSym2FileSystem = new HashMap<>();
173 private final String sourceVersion;
174 private final String ctSymVersion;
175
176 PlatformDescriptionImpl(String sourceVersion, String ctSymVersion) {
177 this.sourceVersion = sourceVersion;
178 this.ctSymVersion = ctSymVersion;
179 }
180
181 @Override
182 public JavaFileManager getFileManager() {
183 Context context = new Context();
184 PrintWriter pw = new PrintWriter(System.err, true);
185 context.put(Log.errKey, pw);
186 CacheFSInfo.preRegister(context);
187 JavacFileManager fm = new JavacFileManager(context, true, null) {
188 @Override
189 public boolean hasLocation(Location location) {
190 return super.hasExplicitLocation(location);
191 }
192
193 @Override
194 public JavaFileObject getJavaFileForInput(Location location, String className,
195 Kind kind) throws IOException {
196 if (kind == Kind.CLASS) {
197 String fileName = className.replace('.', '/');
198 JavaFileObject result =
|