/*
* Copyright 2004-2015 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.intertype;
import java.util.HashSet;
import java.util.Set;
import javax.interceptor.Interceptors;
import org.seasar.framework.container.ComponentDef;
import org.seasar.framework.container.InterTypeDef;
import org.seasar.framework.container.PropertyDef;
import org.seasar.framework.container.factory.AnnotationHandler;
import org.seasar.framework.container.factory.IntertypeDefBuilder;
import org.seasar.framework.container.impl.InterTypeDefImpl;
import org.seasar.framework.container.impl.PropertyDefImpl;
import org.seasar.framework.ejb.EJB3BusinessMethodDesc;
import org.seasar.framework.ejb.EJB3Desc;
import org.seasar.framework.ejb.EJB3DescFactory;
import org.seasar.framework.ejb.EJB3InterceptorDesc;
import org.seasar.framework.ejb.impl.EJB3InterceptorSupportInterType;
/**
* {@link EJB3InterceptorSupportInterType EJB3をサポートするインタータイプ}の{@link InterTypeDef}を作成するコンポーネントの実装クラスです。
*
* @author koichik
*/
public class EJB3IntertypeDefBuilder implements IntertypeDefBuilder {
public void appendIntertypeDef(final AnnotationHandler annotationHandler,
final ComponentDef componentDef) {
final Class<?> componentClass = componentDef.getComponentClass();
if (componentClass == null) {
return;
}
final EJB3Desc ejb3Desc = EJB3DescFactory.getEJB3Desc(componentClass);
if (ejb3Desc == null) {
return;
}
final EJB3InterceptorSupportInterType interType = new EJB3InterceptorSupportInterType();
for (final Class<?> interceptorClass : getInterceptorClasses(ejb3Desc)) {
interType.addInterceptor(interceptorClass);
componentDef.addPropertyDef(createPropertyDef(annotationHandler,
interceptorClass));
}
componentDef.addInterTypeDef(new InterTypeDefImpl(interType));
}
/**
* {@link Interceptors}アノテーションで指定されたインターセプタクラスの配列を返します。
*
* @param ejb3desc
* {@link EJB3Desc}
* @return {@link Interceptors}アノテーションで指定されたインターセプタクラスの配列
*/
protected Set<Class<?>> getInterceptorClasses(final EJB3Desc ejb3desc) {
final Set<Class<?>> interceptorClasses = new HashSet<Class<?>>();
for (final EJB3InterceptorDesc interceptorDesc : ejb3desc
.getInterceptors()) {
interceptorClasses.add(interceptorDesc.getInterceptorClass());
}
for (final EJB3BusinessMethodDesc methodDesc : ejb3desc
.getBusinessMethods()) {
for (final EJB3InterceptorDesc interceptorDesc : methodDesc
.getInterceptors()) {
interceptorClasses.add(interceptorDesc.getInterceptorClass());
}
}
return interceptorClasses;
}
/**
* {@link EJB3InterceptorSupportInterType}が追加するプロパティに、 {@link Interceptors}アノテーションで指定されたインターセプタを設定する、
* {@link PropertyDef}を作成して返します。
*
* @param annotationHandler
* アノテーションハンドラ
* @param interceptorClass
* {@link Interceptors}アノテーションで指定されたインターセプタクラス
* @return {@link PropertyDef}
*/
protected PropertyDef createPropertyDef(
final AnnotationHandler annotationHandler,
final Class<?> interceptorClass) {
final PropertyDefImpl propDef = new PropertyDefImpl(
EJB3InterceptorSupportInterType.getFieldName(interceptorClass));
propDef.setChildComponentDef(createInterceptorComponentDef(
annotationHandler, interceptorClass));
return propDef;
}
/**
* {@link Interceptors}アノテーションで指定されたインターセプタをコンポーネントとして登録する
* {@link ComponentDef}を作成して返します。
*
* @param annotationHandler
* アノテーションハンドラ
* @param interceptorClass
* {@link Interceptors}アノテーションで指定されたインターセプタクラス
* @return {@link ComponentDef}
*/
protected ComponentDef createInterceptorComponentDef(
final AnnotationHandler annotationHandler,
final Class<?> interceptorClass) {
final ComponentDef interceptorCd = annotationHandler
.createComponentDef(interceptorClass, null);
annotationHandler.appendDI(interceptorCd);
annotationHandler.appendInitMethod(interceptorCd);
annotationHandler.appendDestroyMethod(interceptorCd);
annotationHandler.appendAspect(interceptorCd);
annotationHandler.appendInterType(interceptorCd);
return interceptorCd;
}
}