| /* |
| * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Mike Norman - July 13 2010 |
| // fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=318207 |
| package org.eclipse.persistence.tools.dbws; |
| |
| //javase imports |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.StringWriter; |
| import java.net.URI; |
| import java.util.Arrays; |
| |
| //java eXtension imports |
| import javax.tools.DiagnosticCollector; |
| import javax.tools.FileObject; |
| import javax.tools.ForwardingJavaFileManager; |
| import javax.tools.JavaCompiler; |
| import javax.tools.JavaCompiler.CompilationTask; |
| import javax.tools.JavaFileManager; |
| import javax.tools.JavaFileObject; |
| import javax.tools.JavaFileObject.Kind; |
| import javax.tools.SimpleJavaFileObject; |
| import javax.tools.StandardJavaFileManager; |
| import javax.tools.ToolProvider; |
| |
| /** |
| * <p> |
| * <b>PRIVATE:</b> InMemoryCompiler wraps a {@link javax.tools.JavaCompiler}. |
| * Only supports compiling a single file in-memory. |
| * |
| * @author mnorman |
| * |
| */ |
| public class InMemoryCompiler { |
| |
| static final Iterable<String> OPTIONS = Arrays.asList("-g:source,lines,vars"); |
| |
| protected String targetFileName; |
| protected JavaCompiler compiler; |
| protected DiagnosticCollector<JavaFileObject> diagnosticsCollector; |
| protected JavaFileManager fileManager; |
| |
| public InMemoryCompiler(String targetFileName) { |
| super(); |
| this.targetFileName = targetFileName; |
| compiler = ToolProvider.getSystemJavaCompiler(); |
| diagnosticsCollector = new DiagnosticCollector<JavaFileObject>(); |
| } |
| |
| public JavaCompiler getCompiler() { |
| return compiler; |
| } |
| |
| public DiagnosticCollector<JavaFileObject> getDiagnosticsCollector() { |
| return diagnosticsCollector; |
| } |
| |
| public byte[] compile(CharSequence source) { |
| JavaFileObject targetSource = |
| new JavaSourceFromString(targetFileName, source.toString()); |
| ByteArrayJavaFileObject targetClass = |
| new ByteArrayJavaFileObject(targetFileName); |
| Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(targetSource); |
| ByteArrayFileManager bafm = new ByteArrayFileManager( |
| compiler.getStandardFileManager(null, null, null), targetClass); |
| StringWriter sw = new StringWriter(); |
| CompilationTask task = compiler.getTask(sw, bafm, diagnosticsCollector, OPTIONS, null, |
| compilationUnits); |
| task.call(); |
| return targetClass.toByteArray(); |
| } |
| |
| // wrapper class - not really a 'FileObject', uses in-memory string 'source' |
| static class JavaSourceFromString extends SimpleJavaFileObject { |
| CharSequence source; |
| JavaSourceFromString(String name, CharSequence source) { |
| // URI trick from SimpleJavaFileObject constructor - it only recognizes |
| // ('file:/' or 'jar:/'); anything else forces the 'getCharContent' callback for Kind.SOURCE |
| super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), |
| Kind.SOURCE); |
| this.source = source; |
| } |
| @Override |
| public CharSequence getCharContent(boolean ignoreEncodingErrors) { |
| return source; |
| } |
| } |
| |
| // wrapper class - not really a 'FileObject', uses in-memory ByteArrayOutputStream 'bos' |
| static class ByteArrayJavaFileObject extends SimpleJavaFileObject { |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| public ByteArrayJavaFileObject(String name) { |
| // URI trick from SimpleJavaFileObject constructor - it only recognizes |
| // ('file:' or 'jar:'); anything else forces the 'openOutputStream' callback for Kind.CLASS |
| super(URI.create("string:///" + name.replace('.', '/') + Kind.CLASS.extension), |
| Kind.CLASS); |
| } |
| public byte[] toByteArray() { |
| return bos.toByteArray(); |
| } |
| @Override |
| public OutputStream openOutputStream() throws IOException { |
| return bos; |
| } |
| } |
| // wrapper class - compiler will use this 'FileManager' to manage compiler output |
| static class ByteArrayFileManager extends ForwardingJavaFileManager<JavaFileManager> { |
| ByteArrayJavaFileObject bajfo; |
| ByteArrayFileManager(StandardJavaFileManager sjfm, ByteArrayJavaFileObject bajfo) { |
| super(sjfm); |
| this.bajfo = bajfo; |
| } |
| @Override |
| public JavaFileObject getJavaFileForOutput(Location location, String name, Kind kind, |
| FileObject sibling) throws IOException { |
| return bajfo; |
| } |
| } |
| } |