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 + -
显示快捷键?