// 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);
    }
  }
}
