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

org.rapidpm.proxybuilder.generator.Generator Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
/*
 * Copyright [2014] [www.rapidpm.org / Sven Ruppert ([email protected])]
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package org.rapidpm.proxybuilder.generator;

import javax.tools.*;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * Created by Sven Ruppert on 06.01.14.
 */
public class Generator {


  private static final Method DEFINE_CLASS_METHOD;
  private static final JavaCompiler JAVA_COMPILER;

  private Generator() { }

  static {
    try {
      DEFINE_CLASS_METHOD = Proxy.class.getDeclaredMethod("defineClass0", ClassLoader.class, String.class, byte[].class, int.class, int.class);
      DEFINE_CLASS_METHOD.setAccessible(true);
    } catch (NoSuchMethodException e) {
      throw new ExceptionInInitializerError(e);
    }
    JAVA_COMPILER = ToolProvider.getSystemJavaCompiler();
    if (JAVA_COMPILER == null) {
      throw new UnsupportedOperationException(
          "Cannot find java compiler! " +
              "Probably only JRE installed.");
    }
  }

  public static Class make(ClassLoader loader, String className, CharSequence javaSource) {
    GeneratedClassFile gcf = new GeneratedClassFile();
    DiagnosticCollector dc = new DiagnosticCollector<>();
    boolean result = compile(className, javaSource, gcf, dc);
    return processResults(loader, javaSource, gcf, dc, result);
  }

  private static boolean compile(String className, CharSequence javaSource, GeneratedClassFile gcf, DiagnosticCollector dc) {
    GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
    GeneratingJavaFileManager fileManager = new GeneratingJavaFileManager(JAVA_COMPILER.getStandardFileManager(dc, null, null), gcf);
    JavaCompiler.CompilationTask task = JAVA_COMPILER.getTask(null, fileManager, dc, null, null, Arrays.asList(gjsf));
    return task.call();
  }

  private static Class processResults(
      ClassLoader loader, CharSequence javaSource,
      GeneratedClassFile gcf, DiagnosticCollector dc,
      boolean result) {
    if (result) {
      return createClass(loader, gcf);
    } else {
// use your logging system of choice here
      System.err.println("Compile failed:");
      System.err.println(javaSource);
      dc.getDiagnostics().stream().forEach(System.err::println);
      throw new IllegalArgumentException("Could not create proxy - compile failed");
    }
  }

  private static Class createClass(ClassLoader loader, GeneratedClassFile gcf) {
    try {
      byte[] data = gcf.getClassAsBytes();
      return (Class) DEFINE_CLASS_METHOD.invoke(null, loader, null, data, 0, data.length);
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      throw new IllegalArgumentException("Proxy problem", e);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy