classcomponent.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 631 行

JAVA
631
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.webbeans.component;import com.caucho.config.*;import com.caucho.config.j2ee.*;import com.caucho.config.program.ConfigProgram;import com.caucho.config.type.*;import com.caucho.config.types.*;import com.caucho.ejb3.gen.*;import com.caucho.util.*;import com.caucho.webbeans.*;import com.caucho.webbeans.bytecode.*;import com.caucho.webbeans.cfg.*;import com.caucho.webbeans.context.*;import com.caucho.webbeans.event.*;import com.caucho.webbeans.manager.*;import java.lang.reflect.*;import java.lang.annotation.*;import java.util.*;import javax.annotation.*;import javax.webbeans.*;/** * Configuration for the xml web bean component. */public class ClassComponent extends ComponentImpl {  private static final L10N L = new L10N(ClassComponent.class);  private static final Object []NULL_ARGS = new Object[0];    private Class _cl;  private boolean _isBound;  private Constructor _ctor;  private ConfigProgram []_newArgs;  private ComponentImpl []_ctorArgs;  private Object _scopeAdapter;  private HashMap<Method,ArrayList<WbInterceptor>> _interceptorMap;  private Class _proxyClass;  private String _mbeanName;  private Class _mbeanInterface;  public ClassComponent(WbWebBeans webbeans)  {    super(webbeans);  }  public void setInstanceClass(Class cl)  {    _cl = cl;    if (getTargetType() == null)      setTargetType(cl);  }  public Class getInstanceClass()  {    return _cl;  }  public void setConstructor(Constructor ctor)  {    _ctor = ctor;  }  public void setMBeanName(String name)  {    _mbeanName = name;  }  public Class getMBeanInterface()  {    return _mbeanInterface;  }  /**   * Sets the init program.   */  public void setNewArgs(ArrayList<ConfigProgram> args)  {    if (args != null) {      _newArgs = new ConfigProgram[args.size()];      args.toArray(_newArgs);    }  }  public void init()  {    introspect();    super.init();  }  /**   * Called for implicit introspection.   */  public void introspect()  {    Class cl = getInstanceClass();    Class scopeClass = null;    if (getType() == null) {      for (Annotation ann : cl.getDeclaredAnnotations()) {	if (ann.annotationType().isAnnotationPresent(ComponentType.class)) {	  if (getType() != null)	    throw new ConfigException(L.l("{0}: component type annotation @{1} conflicts with @{2}.  WebBeans components may only have a single @ComponentType.",					  cl.getName(),					  getType().getType().getName(),					  ann.annotationType().getName()));		  setType(_webbeans.createComponentType(ann.annotationType()));	}      }    }    if (getType() == null)      setType(_webbeans.createComponentType(Component.class));    if (getScope() == null) {      for (Annotation ann : cl.getDeclaredAnnotations()) {	if (ann.annotationType().isAnnotationPresent(ScopeType.class)) {	  if (scopeClass != null)	    throw new ConfigException(L.l("{0}: @ScopeType annotation @{1} conflicts with @{2}.  WebBeans components may only have a single @ScopeType.",					  cl.getName(),					  scopeClass.getName(),					  ann.annotationType().getName()));	  scopeClass = ann.annotationType();	  setScope(_webbeans.getScopeContext(scopeClass));	}      }    }    if (getName() == null) {      String name = cl.getSimpleName();      name = Character.toLowerCase(name.charAt(0)) + name.substring(1);	      setName(name);    }    introspectProduces();    introspectConstructor();    if (getBindingList().size() == 0)      introspectBindings();        introspectMBean();  }  /**   * Introspects the methods for any @Produces   */  private void introspectProduces()  {    if (_cl == null)      return;        for (Method method : _cl.getDeclaredMethods()) {      if (Modifier.isStatic(method.getModifiers()))	continue;      if (! method.isAnnotationPresent(Produces.class))	continue;      if (method.isAnnotationPresent(In.class))	throw error(method, L.l("@Produces method may not have an @In annotation."));      ProducesComponent comp = new ProducesComponent(_webbeans, this, method);      _webbeans.addWbComponent(comp);            comp.init();    }  }  /**   * Introspects the constructor   */  protected void introspectConstructor()  {    if (_ctor != null)      return;        try {      Constructor best = null;      Constructor second = null;      for (Constructor ctor : _cl.getDeclaredConstructors()) {	if (_newArgs != null	    && ctor.getParameterTypes().length != _newArgs.length) {	  continue;	}	else if (best == null) {	  best = ctor;	}	else if (hasBindingAnnotation(ctor)) {	  if (best != null && hasBindingAnnotation(best))	    throw new ConfigException(L.l("WebBean {0} has two constructors with binding annotations.",					  ctor.getDeclaringClass().getName()));	  best = ctor;	  second = null;	}	else if (ctor.getParameterTypes().length == 0) {	  best = ctor;	}	else if (best.getParameterTypes().length == 0) {	}	else {	  second = ctor;	}      }      if (second != null)	throw new ConfigException(L.l("{0}: WebBean does not have a unique constructor.  One constructor must be marked with @In or have a binding annotation.",				      _cl.getName()));      if (best == null)	throw new ConfigException(L.l("{0}: no constructor found",				      _cl.getName()));      _ctor = best;    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw ConfigException.create(e);    }  }  /**   * Introspects for MBeans annotation   */  private void introspectMBean()  {    if (_cl == null)      return;    else if (_mbeanInterface != null)      return;        for (Class iface : _cl.getInterfaces()) {      if (iface.getName().endsWith("MBean")	  || iface.getName().endsWith("MXBean")) {	_mbeanInterface = iface;	return;      }    }  }  protected String getMBeanName()  {    if (_mbeanName != null)      return _mbeanName;    if (_mbeanInterface == null)      return null;        String typeName = _mbeanInterface.getSimpleName();    if (typeName.endsWith("MXBean"))      typeName = typeName.substring(0, typeName.length() - "MXBean".length());    else if (typeName.endsWith("MBean"))      typeName = typeName.substring(0, typeName.length() - "MBean".length());    String name = getName();    if (name == null)      return "type=" + typeName;    else if (name.equals(""))      return "type=" + typeName + ",name=default";    else      return "type=" + typeName + ",name=" + name;  }  /**   * Creates a new instance of the component.   */  @Override  public Object get(ConfigContext env)  {    try {      Object value;      boolean isNew = false;      if (env.canInject(_scope)) {	if (_scope != null) {	  value = _scope.get(this, false);	  	  if (value != null)	    return value;	}	else {	  value = env.get(this);	  	  if (value != null)	    return value;	}      	value = createNew(env);		if (_scope != null) {	  _scope.put(this, value);	  env = new ConfigContext(this, value, _scope);	}	else	  env.put(this, value);		init(value, env);      }      else {	if (env != null) {	  value = env.get(this);	  if (value != null)	    return value;	}	value = _scopeAdapter;	if (value == null) {	  ScopeAdapter scopeAdapter = ScopeAdapter.create(getInstanceClass());	  _scopeAdapter = scopeAdapter.wrap(this);	  value = _scopeAdapter;	}	env.put(this, value);      }      return value;    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw new RuntimeException(e);    }  }  @Override  protected Object createNew(ConfigContext env)  {    try {      if (! _isBound)	bind();            Object []args;      if (_ctorArgs != null && _ctorArgs.length > 0) {	args = new Object[_ctorArgs.length];	for (int i = 0; i < args.length; i++)	  args[i] = _ctorArgs[i].create();      }      else	args = NULL_ARGS;            Object value = _ctor.newInstance(args);      if (isSingleton())	SerializationAdapter.setHandle(value, getHandle());      if (env != null)	env.put(this, value);      return value;    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw new RuntimeException(e);    }  }  /**   * Binds parameters   */  public void bind()  {    synchronized (this) {      if (_isBound)	return;      _isBound = true;      ArrayList<ConfigProgram> injectList = new ArrayList<ConfigProgram>();      InjectIntrospector.introspectInject(injectList, _cl);      _injectProgram = new ConfigProgram[injectList.size()];      injectList.toArray(_injectProgram);            ArrayList<ConfigProgram> initList = new ArrayList<ConfigProgram>();      InjectIntrospector.introspectInit(initList, _cl);      _initProgram = new ConfigProgram[initList.size()];      initList.toArray(_initProgram);            ArrayList<ConfigProgram> destroyList = new ArrayList<ConfigProgram>();      InjectIntrospector.introspectDestroy(destroyList, _cl);      _destroyProgram = new ConfigProgram[destroyList.size()];      destroyList.toArray(_destroyProgram);            if (_ctor == null)	introspectConstructor();      if (_ctor != null) {	String loc = _ctor.getDeclaringClass().getName() + "(): ";	Type []param = _ctor.getGenericParameterTypes();	Annotation [][]paramAnn = _ctor.getParameterAnnotations();	ComponentImpl []ctorArgs = new ComponentImpl[param.length];	for (int i = 0; i < param.length; i++) {	  ComponentImpl arg;	  	  if (_newArgs != null && i < _newArgs.length) {	    ConfigProgram argProgram = _newArgs[i];	    ConfigType type = TypeFactory.getType(param[i]);	    ctorArgs[i] = createArg(type, argProgram);	  }	  if (ctorArgs[i] == null)	    ctorArgs[i] = _webbeans.bindParameter(loc, param[i], paramAnn[i]);	  if (ctorArgs[i] == null)	    throw new ConfigException(L.l("{0} does not have valid arguments",					  _ctor));	}		_ctorArgs = ctorArgs;      }      introspectObservers();      /*      introspectInterceptors();      if (_interceptorMap != null) {	_proxyClass = InterceptorGenerator.gen(getInstanceClass(),					       _ctor, _interceptorMap);	Constructor proxyCtor = _proxyClass.getConstructors()[0];	_ctor = proxyCtor;      }      */      PojoBean bean = new PojoBean(_cl);      bean.setSingleton(isSingleton());      bean.introspect();      Class instanceClass = bean.generateClass();      if (instanceClass == _cl && isSingleton())	instanceClass = SerializationAdapter.gen(_cl);      if (instanceClass != null && instanceClass != _cl) {	try {	  if (_ctor != null)	    _ctor = instanceClass.getConstructor(_ctor.getParameterTypes());	  	  setInstanceClass(instanceClass);	} catch (Exception e) {	  throw ConfigException.create(e);	}      }    }  }  protected ComponentImpl createArg(ConfigType type, ConfigProgram program)  {    Object value = program.configure(type);    if (value != null)      return new SingletonComponent(getWebBeans(), value);    else      return null;  }    /**   * Introspects the methods for any @Produces   */  protected void introspectBindings()  {    ArrayList<WbBinding> bindings = new ArrayList<WbBinding>();        for (Annotation ann : getInstanceClass().getAnnotations()) {      if (ann.annotationType().isAnnotationPresent(BindingType.class))	bindings.add(new WbBinding(ann));      if (ann instanceof Named)	setName(((Named) ann).value());    }    if (bindings.size() > 0)      setBindingList(bindings);  }  /**   * Introspects any observers.   */  protected void introspectObservers()  {    for (Method method : getInstanceClass().getDeclaredMethods()) {      int param = findObserverAnnotation(method);      if (param < 0)	continue;      if (method.isAnnotationPresent(In.class))	throw error(method, "@Observer may not have an @In attribute");      ArrayList<WbBinding> bindingList = new ArrayList<WbBinding>();            Annotation [][]annList = method.getParameterAnnotations();      if (annList != null && annList[param] != null) {	for (Annotation ann : annList[param]) {	  if (ann.annotationType().isAnnotationPresent(EventBindingType.class))	    bindingList.add(new WbBinding(ann));	}      }      ObserverImpl observer = new ObserverImpl(this, method, param);      observer.setBindingList(bindingList);      _webbeans.getContainer().addObserver(observer);    }  }  /**   * Introspects any intercepted methods   */  protected void introspectInterceptors()  {    for (Method method : getInstanceClass().getMethods()) {      if (method.getDeclaringClass().equals(Object.class))	continue;            ArrayList<Annotation> interceptorTypes = findInterceptorTypes(method);      if (interceptorTypes == null)	continue;      ArrayList<WbInterceptor> interceptors	= _webbeans.findInterceptors(interceptorTypes);      if (interceptors != null) {	if (_interceptorMap == null)	  _interceptorMap = new HashMap<Method,ArrayList<WbInterceptor>>();	_interceptorMap.put(method, interceptors);      }    }  }  private ArrayList<Annotation> findInterceptorTypes(Method method)  {    ArrayList<Annotation> types = null;    for (Annotation ann : method.getAnnotations()) {      if (ann.annotationType().isAnnotationPresent(InterceptorBindingType.class)) {	if (types == null)	  types = new ArrayList<Annotation>();	types.add(ann);      }    }    return types;  }    private boolean hasBindingAnnotation(Constructor ctor)  {    if (ctor.isAnnotationPresent(In.class))      return true;    Annotation [][]paramAnn = ctor.getParameterAnnotations();    for (Annotation []annotations : paramAnn) {      for (Annotation ann : annotations) {	if (ann.annotationType().isAnnotationPresent(BindingType.class))	  return true;      }    }    return false;  }  private int findObserverAnnotation(Method method)  {    Annotation [][]paramAnn = method.getParameterAnnotations();    int observer = -1;    for (int i = 0; i < paramAnn.length; i++) {      for (Annotation ann : paramAnn[i]) {	if (ann instanceof Observes) {	  if (observer >= 0)	    throw WebBeansContainer.error(method, L.l("Only one param may have an @Observer"));	  	  observer = i;	}      }    }    return observer;  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?