// Copyright 2008 Google Inc.
//
// 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 com.google.gwtorm.server;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Hacked ClassLoader to inject generated code into the parent.
 * <p>
 * This ClassLoader allows our code generators to inject their generated classes
 * into the parent ClassLoader, which should be the same ClassLoader that
 * defined the application's Schema interface extension. This is necessary to
 * ensure the generated classes can access protected and default-access fields
 * within the entities.
 */
public class GeneratedClassLoader extends ClassLoader {
  private static final boolean debugCodeGen;

  private static final Method defineClass;

  static {
    debugCodeGen = "true".equals(System.getProperty("gwtorm.debugCodeGen"));

    Method m;
    try {
      m =
          ClassLoader.class.getDeclaredMethod("defineClass", String.class,
              byte[].class, Integer.TYPE, Integer.TYPE);
      m.setAccessible(true);
    } catch (SecurityException e) {
      throw new LinkageError("No defineClass in ClassLoader");
    } catch (NoSuchMethodException e) {
      throw new LinkageError("No defineClass in ClassLoader");
    }
    defineClass = m;
  }

  public GeneratedClassLoader(final ClassLoader parent) {
    super(parent);
  }

  public void defineClass(final String name, final byte[] code)
      throws OrmException {
    if (debugCodeGen) {
      final File outClassFile =
          new File("generated_classes/" + name.replace('.', '/') + ".class");
      outClassFile.getParentFile().mkdirs();
      try {
        final FileOutputStream out = new FileOutputStream(outClassFile);
        try {
          out.write(code);
        } finally {
          out.close();
        }
      } catch (IOException e) {
        throw new OrmException("Cannot save debug class " + outClassFile, e);
      }
    }

    try {
      defineClass.invoke(getParent(), name, code, Integer.valueOf(0), Integer
          .valueOf(code.length));
    } catch (IllegalArgumentException e) {
      throw new OrmException("Unable to inject class " + name, e);
    } catch (SecurityException e) {
      throw new OrmException("Unable to inject class " + name, e);
    } catch (IllegalAccessException e) {
      throw new OrmException("Unable to inject class " + name, e);
    } catch (InvocationTargetException e) {
      throw new OrmException("Unable to inject class " + name, e);
    }
  }
}
