All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oms3.compiler.MemoryOutputJavaFileManager Maven / Gradle / Ivy

There is a newer version: 0.8.1
Show newest version
package oms3.compiler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import javax.tools.JavaFileObject.Kind;

/**
 * A java file manager that stores output in memory, delegating all other
 * functions to another file manager.
 * 
 */
public class MemoryOutputJavaFileManager extends ForwardingJavaFileManager {

    /**
     * Maps class names to file objects.
     */
    Map outputMap = new HashMap();
    List classPathUrls = new ArrayList();

    /**
     * Constructs a MemoryOutputJavaFileManager.
     *
     * @param fileManager the underlying file manager to use.
     */
    public MemoryOutputJavaFileManager(JavaFileManager fileManager) {
        super(fileManager);
    }

    /**
     * Adds a URL that classes may be loaded from.  All classes from this
     * URL will be added to the classpath.
     *
     * @param url the URL to add.
     *
     * @throws NullPointerException if url is null.
     */
    public void addClassPathUrl(URL url) {
        if (url == null) {
            throw new NullPointerException("url == null");
        }
        classPathUrls.add(url);
    }

    /**
     * Returns the base URL of the specified class.
     * 

* * For example, if java.lang.String exists at * http://base.net/parent/java/lang/String.class, the base URL * is http://base.net/parent/. * * @param clazz the class. * * @return a base URL where the class is located. * * @throws IllegalArgumentException if a URL cannot be obtained. */ public static URL baseUrlOfClass(Class clazz) { try { String name = clazz.getName(); URL url = clazz.getResource("/" + name.replace('.', '/') + ".class"); int curPos = 0; do { curPos = name.indexOf('.', curPos + 1); if (curPos >= 0) { url = new URL(url, ".."); } } while (curPos >= 0); return url; } catch (MalformedURLException e) { throw new IllegalArgumentException("Invalid URL for class " + clazz.getName(), e); } } @Override public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException { if (kind != Kind.CLASS) { throw new IOException("Only class output supported, kind=" + kind); } try { MemoryOutputJavaFileObject output = new MemoryOutputJavaFileObject(new URI(className), kind); outputMap.put(className, output); return output; } catch (URISyntaxException e) { throw new IOException(e); } } @Override public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException { JavaFileObject result; if (StandardLocation.CLASS_OUTPUT == location && Kind.CLASS == kind) { result = outputMap.get(className); if (result == null) { result = super.getJavaFileForInput(location, className, kind); } } else { result = super.getJavaFileForInput(location, className, kind); } return result; } @Override public String inferBinaryName(Location location, JavaFileObject file) { if (file instanceof UrlJavaFileObject) { UrlJavaFileObject urlFile = (UrlJavaFileObject) file; return urlFile.getBinaryName(); } else { return super.inferBinaryName(location, file); } } @Override public Iterable list(Location location, String packageName, Set kinds, boolean recurse) throws IOException { //Special handling for Privateer classes when building with Maven //Maven does not set the classpath but instead uses a custom //classloader to load test classes which means the compiler //tool cannot normally see standard Privateer classes so //we put in a workaround here if (StandardLocation.CLASS_PATH == location && kinds.contains(Kind.CLASS)) { List results = new ArrayList(); Iterable superResults = super.list(location, packageName, kinds, recurse); for (JavaFileObject superResult : superResults) { results.add(superResult); } //Now process classpath URLs for (URL curClassPathUrl : classPathUrls) { String directory = packageName.replace('.', '/') + '/'; URL loadUrl = new URL(curClassPathUrl, directory); try { List additionalClasses = listClassesFromUrl(loadUrl, packageName); results.addAll(additionalClasses); } catch (IOException e) { //This happens if the file does not exist //Move onto next one } } return results; } else { Iterable results = super.list(location, packageName, kinds, recurse); return results; } } /** * Lists all files at a specified URL. * * @param base the URL. * @param packageName the package name of classes to list. * * @return a list of class files. * * @throws IOException if an I/O error occurs. */ protected List listClassesFromUrl(URL base, String packageName) throws IOException { //TODO this will only work with file:// not jar:// if (base == null) { throw new NullPointerException("base == null"); } List list = new ArrayList(); URLConnection connection = base.openConnection(); connection.connect(); String encoding = connection.getContentEncoding(); if (encoding == null) { encoding = "UTF-8"; } BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding)); try { String curLine; do { curLine = reader.readLine(); if (curLine != null && curLine.endsWith(".class")) { try { String curSimpleName = curLine.substring(0, curLine.length() - ".class".length()); String binaryName; if (packageName == null) { binaryName = curSimpleName; } else { binaryName = packageName + "." + curSimpleName; } list.add(new UrlJavaFileObject(curLine, new URL(base, curLine), Kind.CLASS, binaryName)); } catch (URISyntaxException e) { throw new IOException("Error parsing URL " + curLine + ".", e); } } } while (curLine != null); } finally { reader.close(); } return list; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy