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

org.kitesdk.compat.DynConstructors Maven / Gradle / Ivy

Go to download

The Kite Hadoop Compatibility module provides dynamic bindings to use multiple versions of hadoop APIs.

There is a newer version: 1.1.0
Show newest version
/*
 * Copyright 2013 Cloudera 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 org.kitesdk.compat;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class DynConstructors {
  public static class Ctor extends DynMethods.UnboundMethod {
    private final Constructor ctor;
    private final Class constructed;

    private Ctor(Constructor constructor, Class constructed) {
      super(null, "newInstance");
      this.ctor = constructor;
      this.constructed = constructed;
    }

    public Class getConstructedClass() {
      return constructed;
    }

    public C newInstanceChecked(Object... args) throws Exception {
      try {
        return ctor.newInstance(args);
      } catch (InstantiationException e) {
        throw e;
      } catch (IllegalAccessException e) {
        throw e;
      } catch (InvocationTargetException e) {
        // rethrow the cause is an exception
        Throwables.propagateIfPossible(e.getCause(), Exception.class);
        // otherwise, propagate the throwable
        throw Throwables.propagate(e.getCause());
      }
    }

    public C newInstance(Object... args) {
      try {
        return newInstanceChecked(args);
      } catch (Exception e) {
        throw Throwables.propagate(e);
      }
    }

    @Override
    @SuppressWarnings("unchecked")
    public  R invoke(Object target, Object... args) {
      Preconditions.checkArgument(target == null,
          "Invalid call to constructor: target must be null");
      return (R) newInstance(target, args);
    }

    @Override
    @SuppressWarnings("unchecked")
    public  R invokeChecked(Object target, Object... args) throws Exception {
      Preconditions.checkArgument(target == null,
          "Invalid call to constructor: target must be null");
      return (R) newInstanceChecked(args);
    }

    @Override
    public boolean isStatic() {
      return true;
    }

    @Override
    public String toString() {
      return Objects.toStringHelper(this)
          .add("constructor", ctor)
          .add("class", constructed)
          .toString();
    }
  }

  public static class Builder {
    private final Class baseClass;
    private ClassLoader loader = Thread.currentThread().getContextClassLoader();
    private Ctor ctor = null;

    public Builder(Class baseClass) {
      this.baseClass = baseClass;
    }

    public Builder() {
      this.baseClass = null;
    }

    /**
     * Set the {@link ClassLoader} used to lookup classes by name.
     * 

* If not set, the current thread's ClassLoader is used. * * @param loader a ClassLoader * @return this Builder for method chaining */ public Builder loader(ClassLoader loader) { this.loader = loader; return this; } public Builder impl(Class... types) { impl(baseClass, types); return this; } public Builder impl(String className, Class... types) { // don't do any work if an implementation has been found if (ctor != null) { return this; } try { Class targetClass = Class.forName(className, true, loader); impl(targetClass, types); } catch (NoClassDefFoundError e) { // cannot load this implementation } catch (ClassNotFoundException e) { // not the right implementation } return this; } public Builder impl(Class targetClass, Class... types) { // don't do any work if an implementation has been found if (ctor != null) { return this; } try { ctor = new Ctor(targetClass.getConstructor(types), targetClass); } catch (NoSuchMethodException e) { // not the right implementation } return this; } public Builder hiddenImpl(Class... types) { hiddenImpl(baseClass, types); return this; } @SuppressWarnings("unchecked") public Builder hiddenImpl(String className, Class... types) { // don't do any work if an implementation has been found if (ctor != null) { return this; } try { Class targetClass = Class.forName(className, true, loader); hiddenImpl(targetClass, types); } catch (NoClassDefFoundError e) { // cannot load this implementation } catch (ClassNotFoundException e) { // not the right implementation } return this; } public Builder hiddenImpl(Class targetClass, Class... types) { // don't do any work if an implementation has been found if (ctor != null) { return this; } try { Constructor hidden = targetClass.getDeclaredConstructor(types); AccessController.doPrivileged(new MakeAccessible(hidden)); ctor = new Ctor(hidden, targetClass); } catch (SecurityException e) { // unusable } catch (NoSuchMethodException e) { // not the right implementation } return this; } @SuppressWarnings("unchecked") public Ctor buildChecked() throws NoSuchMethodException { if (ctor != null) { return ctor; } throw new NoSuchMethodException( "Cannot find constructor for " + baseClass); } @SuppressWarnings("unchecked") public Ctor build() { if (ctor != null) { return ctor; } throw new RuntimeException("Cannot find constructor for " + baseClass); } } private static class MakeAccessible implements PrivilegedAction { private Constructor hidden; public MakeAccessible(Constructor hidden) { this.hidden = hidden; } @Override public Void run() { hidden.setAccessible(true); return null; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy