/* * Copyright 2004-2007 the Seasar Foundation and the Others. * * 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.seasar.framework.container.factory; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import org.seasar.framework.beans.BeanDesc; import org.seasar.framework.beans.PropertyDesc; import org.seasar.framework.beans.factory.BeanDescFactory; import org.seasar.framework.container.AccessTypeDef; import org.seasar.framework.container.AutoBindingDef; import org.seasar.framework.container.BindingTypeDef; import org.seasar.framework.container.ComponentDef; import org.seasar.framework.container.DestroyMethodDef; import org.seasar.framework.container.InitMethodDef; import org.seasar.framework.container.InstanceDef; import org.seasar.framework.container.PropertyDef; import org.seasar.framework.container.assembler.AccessTypeDefFactory; import org.seasar.framework.container.assembler.AutoBindingDefFactory; import org.seasar.framework.container.assembler.BindingTypeDefFactory; import org.seasar.framework.container.deployer.InstanceDefFactory; import org.seasar.framework.container.impl.ComponentDefImpl; import org.seasar.framework.container.impl.PropertyDefImpl; import org.seasar.framework.container.ognl.OgnlExpression; import org.seasar.framework.util.ClassUtil; import org.seasar.framework.util.StringUtil; /** * AnnotationHandlerの抽象クラスです。 *
* このクラスでは、主にクラス、メソッド、フィールドに書かれたアノーテションを取得します。 * アノーテションから、コンポーネントに対しての各定義の作成はサブクラスで行います。 *
* * @author vestige */ public abstract class AbstractAnnotationHandler implements AnnotationHandler { /** * COMPONENTアノテーションを表す定数名です。 */ protected static final String COMPONENT = "COMPONENT"; /** * COMPONENTアノテーションのname属性「コンポーネント名」を表すキーです。 */ protected static final String NAME = "name"; /** * COMPONENTアノテーションのinstance属性「インスタンス定義」を表すキーです。 */ protected static final String INSTANCE = "instance"; /** * COMPONENTアノテーションのautoBinding属性「自動バインディング定義」を表すキーです。 */ protected static final String AUTO_BINDING = "autoBinding"; /** * Bindingアノテーションとして識別するための定数です。 */ protected static final String BINDING_SUFFIX = "_BINDING"; /** * BindingアノテーションのbindingType属性「バインディングタイプ」を表すキーです。 */ protected static final String BINDING_TYPE = "bindingType"; /** * COMPONENTアノテーションのexternalBinding属性「外部バインディング定義」を表すキーです。 */ protected static final String EXTERNAL_BINDING = "externalBinding"; /** * 各アノテーション内のvalue属性「VALUE」を表すキーです。 */ protected static final String VALUE = "value"; /** * ASPECTアノテーションを表す定数名です。 */ protected static final String ASPECT = "ASPECT"; /** * InterTypeアノテーションを表す定数名です。 */ protected static final String INTER_TYPE = "INTER_TYPE"; /** * InitMethodアノテーションを表す定数名です。 */ protected static final String INIT_METHOD = "INIT_METHOD"; /** * DestroyMethodアノテーションを表す定数名です。 */ protected static final String DESTROY_METHOD = "DESTROY_METHOD"; /** * ASPECTアノテーションのinterceptor属性「インターセプター定義」を表すキーです。 */ protected static final String INTERCEPTOR = "interceptor"; /** * ASPECTアノテーションのpointcut属性「ポイントカット定義」を表すキーです。 */ protected static final String POINTCUT = "pointcut"; public ComponentDef createComponentDef(String className, InstanceDef instanceDef) { return createComponentDef(ClassUtil.forName(className), instanceDef); } public ComponentDef createComponentDef(String className, InstanceDef instanceDef, AutoBindingDef autoBindingDef) { return createComponentDef(ClassUtil.forName(className), instanceDef, autoBindingDef); } public ComponentDef createComponentDef(String className, InstanceDef instanceDef, AutoBindingDef autoBindingDef, boolean externalBinding) { return createComponentDef(ClassUtil.forName(className), instanceDef, autoBindingDef, externalBinding); } public ComponentDef createComponentDef(Class componentClass, InstanceDef instanceDef) { return createComponentDef(componentClass, instanceDef, null); } public ComponentDef createComponentDef(Class componentClass, InstanceDef instanceDef, AutoBindingDef autoBindingDef) { return createComponentDef(componentClass, instanceDef, autoBindingDef, false); } public void appendDI(ComponentDef componentDef) { BeanDesc beanDesc = BeanDescFactory.getBeanDesc(componentDef .getComponentClass()); for (int i = 0; i < beanDesc.getPropertyDescSize(); ++i) { PropertyDesc pd = beanDesc.getPropertyDesc(i); if (!pd.hasWriteMethod()) { continue; } PropertyDef propDef = createPropertyDef(beanDesc, pd); if (propDef == null) { continue; } componentDef.addPropertyDef(propDef); } for (int i = 0; i < beanDesc.getFieldSize(); ++i) { Field field = beanDesc.getField(i); if (componentDef.hasPropertyDef(field.getName())) { continue; } if (!isFieldInjectionTarget(field)) { continue; } PropertyDef propDef = createPropertyDef(beanDesc, field); if (propDef == null) { continue; } componentDef.addPropertyDef(propDef); } } /** * インスタンス定義を返します。 ** 指定した名前のインスタンス定義が存在しない場合、デフォルトのインスタンス定義を返します。 *
* * @param name * インスタンス定義の種類 * @param defaultInstanceDef * デフォルトのインスタンス定義(singleton) * @return インスタンス定義 */ protected InstanceDef getInstanceDef(String name, InstanceDef defaultInstanceDef) { InstanceDef instanceDef = getInstanceDef(name); if (instanceDef != null) { return instanceDef; } return defaultInstanceDef; } /** * インスタンス定義を返します。 * * @param name * インスタンス定義の種類 * @return インスタンス定義 */ protected InstanceDef getInstanceDef(String name) { if (StringUtil.isEmpty(name)) { return null; } return InstanceDefFactory.getInstanceDef(name); } /** * 自動バインディング定義を返します。 * * @param name * 自動バインディング定義の種類 * @return 自動バインディング定義 */ protected AutoBindingDef getAutoBindingDef(String name) { if (StringUtil.isEmpty(name)) { return null; } return AutoBindingDefFactory.getAutoBindingDef(name); } /** * 指定したコンポーネントクラスからコンポーネント定義を作成します。 ** 以下の設定がある場合はおのおのコンポーネント定義に設定します。 *
* static
または、final
でない場合はインジェクションが可能になります。
*
static
、final
でない場合はtrue
、そうでない場合はfalse
を返します。
*/
protected boolean isFieldInjectionTarget(Field field) {
return !Modifier.isStatic(field.getModifiers())
&& !Modifier.isFinal(field.getModifiers());
}
}