Package org.apache.aries.proxy.impl

Source Code of org.apache.aries.proxy.impl.AbstractProxyManager

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.aries.proxy.impl;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.concurrent.Callable;

import org.apache.aries.proxy.InvocationListener;
import org.apache.aries.proxy.ProxyManager;
import org.apache.aries.proxy.UnableToProxyException;
import org.apache.aries.proxy.weaving.WovenProxy;
import org.apache.aries.util.AriesFrameworkUtil;
import org.osgi.framework.Bundle;

public abstract class AbstractProxyManager implements ProxyManager
{
  public final Object createDelegatingProxy(Bundle clientBundle, Collection<Class<?>> classes,
      Callable<Object> dispatcher, Object template)
    throws UnableToProxyException
  {
    return createDelegatingInterceptingProxy(clientBundle, classes, dispatcher, template, null);
  }
 
  public Object createInterceptingProxy(Bundle clientBundle,
      Collection<Class<?>> classes, Object delegate, InvocationListener listener)
      throws UnableToProxyException {
   
    if (delegate instanceof WovenProxy) {
      WovenProxy proxy = ((WovenProxy) delegate).
              org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance(
              new SingleInstanceDispatcher(delegate), listener);
      return proxy;
    } else {
      return createDelegatingInterceptingProxy(clientBundle, classes,
          new SingleInstanceDispatcher(delegate), delegate, listener);
    }
  }

  public final Object createDelegatingInterceptingProxy(Bundle clientBundle, Collection<Class<?>> classes,
      Callable<Object> dispatcher, Object template, InvocationListener listener)
      throws UnableToProxyException
  {
    if(dispatcher == null)
      throw new NullPointerException(NLS.MESSAGES.getMessage("no.dispatcher"));
   
    if (template instanceof WovenProxy) {
      WovenProxy proxy = ((WovenProxy) template).
             org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance(
             dispatcher, listener);
      return proxy;
    }
   
    Object proxyObject = duplicateProxy(classes, dispatcher, template, listener);
   
    if (proxyObject == null) {
      proxyObject = createNewProxy(clientBundle, classes, dispatcher, listener);
    }
   
    return proxyObject;
  }
  
  public final Callable<Object> unwrap(Object proxy)
  {
    Callable<Object> target = null;
   
    if(proxy instanceof WovenProxy) {
      //Woven proxies are a bit different, they can be proxies without
      //having a dispatcher, so we fake one up if we need to
     
      WovenProxy wp = (WovenProxy) proxy;
      if(wp.org_apache_aries_proxy_weaving_WovenProxy_isProxyInstance()) {
        target = wp.org_apache_aries_proxy_weaving_WovenProxy_unwrap();
        if(target == null) {
          target = new SingleInstanceDispatcher(proxy);
        }
      }
    } else {
      InvocationHandler ih = getInvocationHandler(proxy);
     
      if (ih instanceof ProxyHandler) {
        target = ((ProxyHandler)ih).getTarget();
      }
    }
    return target;
  }
 
  public final boolean isProxy(Object proxy)
  {
    return (proxy != null &&
        ((proxy instanceof WovenProxy && ((WovenProxy)proxy).org_apache_aries_proxy_weaving_WovenProxy_isProxyInstance()) ||
        getInvocationHandler(proxy) instanceof ProxyHandler));
  }
 
  protected abstract Object createNewProxy(Bundle clientBundle, Collection<Class<?>> classes,
      Callable<Object> dispatcher, InvocationListener listener) throws UnableToProxyException;
  protected abstract InvocationHandler getInvocationHandler(Object proxy);
  protected abstract boolean isProxyClass(Class<?> clazz);

  protected synchronized ClassLoader getClassLoader(final Bundle clientBundle, Collection<Class<?>> classes)
  {
    if (clientBundle.getState() == Bundle.UNINSTALLED) {
      throw new IllegalStateException(NLS.MESSAGES.getMessage("bundle.uninstalled", clientBundle.getSymbolicName(), clientBundle.getVersion(), clientBundle.getBundleId()));
    }
   
    ClassLoader cl = null;
   
    if (classes.size() == 1) cl = classes.iterator().next().getClassLoader();

    if (cl == null) {
      // First of all see if the AriesFrameworkUtil can get the classloader, if it can we go with that.
      cl = AriesFrameworkUtil.getClassLoaderForced(clientBundle);
    }
   
    return cl;
  }

  private Object duplicateProxy(Collection<Class<?>> classes, Callable<Object> dispatcher,
      Object template, InvocationListener listener)
  {
    Object proxyObject = null;
    Class<?> classToProxy = null;
   
    if (template != null) {
      if(isProxyClass(template.getClass()))
        classToProxy = template.getClass();
    } else if (classes.size() == 1) {

      classToProxy = classes.iterator().next();

      if(!!!isProxyClass(classToProxy))
        classToProxy = null;
    }

    if (classToProxy != null) {
      try {
        /*
         * the class is already a proxy, we should just invoke
         * the constructor to get a new instance of the proxy
         * with a new Collaborator using the specified delegate
         */
        if(WovenProxy.class.isAssignableFrom(classToProxy)) {
          Constructor<?> c = classToProxy.getDeclaredConstructor(Callable.class,
              InvocationListener.class);
          c.setAccessible(true);
          proxyObject = c.newInstance(dispatcher, listener);
        } else {
          proxyObject = classToProxy.getConstructor(InvocationHandler.class).
          newInstance(new ProxyHandler(this, dispatcher, listener));
        }
      } catch (InvocationTargetException e) {
      } catch (NoSuchMethodException e) {
      } catch (InstantiationException e) {
      } catch (IllegalArgumentException e) {
      } catch (SecurityException e) {
      } catch (IllegalAccessException e) {
      }
    }
   
    return proxyObject;
  }
}
TOP

Related Classes of org.apache.aries.proxy.impl.AbstractProxyManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.