/* * 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.aop.interceptors; import java.lang.reflect.Method; import org.aopalliance.intercept.MethodInvocation; import org.seasar.framework.container.ComponentDef; import org.seasar.framework.container.ComponentNotFoundRuntimeException; import org.seasar.framework.container.ContainerConstants; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.assembler.AbstractBindingTypeDef; import org.seasar.framework.container.util.BindingUtil; import org.seasar.framework.message.MessageFormatter; import org.seasar.framework.util.StringUtil; /** * getterメソッドに適用されて、S2コンテナからルックアップしたコンポーネントを返すインターセプタです。 * * @author koichik * @see AbstractBindingTypeDef */ public class DependencyLookupInterceptor extends AbstractInterceptor { private static final long serialVersionUID = 1L; public Object invoke(final MethodInvocation invocation) throws Throwable { final Method method = invocation.getMethod(); final String methodName = method.getName(); final Class propType = method.getReturnType(); if (!methodName.startsWith("get") || method.getParameterTypes().length != 0 || propType == null) { throw new IllegalStateException(MessageFormatter.getSimpleMessage( "ESSR0103", new Object[] { method })); } final S2Container container = getComponentDef(invocation) .getContainer(); final String propName = StringUtil .decapitalize(methodName.substring(3)); // Seasar2.4の型による自動バインディング相当のルックアップ if (container.hasComponentDef(propType)) { final ComponentDef cd = container.getComponentDef(propType); if (isAutoBindable(propName, propType, cd)) { return cd.getComponent(); } } // 名前による自動バインディング相当のルックアップ if (container.hasComponentDef(propName)) { final ComponentDef cd = container.getComponentDef(propName); final Object component = cd.getComponent(); if (propType.isInstance(component)) { return component; } } // 型による自動バインディング相当のルックアップ if (BindingUtil.isAutoBindable(propType)) { if (container.hasComponentDef(propType)) { final ComponentDef cd = container.getComponentDef(propType); return cd.getComponent(); } } // 配列の要素型による自動バインディング相当のルックアップ if (BindingUtil.isAutoBindableArray(propType)) { Class clazz = propType.getComponentType(); Object[] components = container.findAllComponents(clazz); if (components.length > 0) { return components; } } throw new ComponentNotFoundRuntimeException(propName); } /** * プロパティにコンポーネントを自動バインディング可能なら<code>true</code>を返します。 * * @param propertyName * プロパティ名 * @param propertyType * プロパティの型 * @param cd * コンポーネント定義 * @return プロパティにコンポーネントを自動バインディング可能なら<code>true</code> */ protected boolean isAutoBindable(final String propertyName, final Class propertyType, final ComponentDef cd) { return cd.getComponentName() != null && (cd.getComponentName().equalsIgnoreCase(propertyName) || StringUtil .endsWithIgnoreCase(cd.getComponentName(), ContainerConstants.PACKAGE_SEP + propertyName)); } }