/*
* Copyright (C) 2010-2011 sunjumper@163.com
*
* 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 mfinder.spring;
import java.util.List;
import mfinder.ActionFactory;
import mfinder.ActionInvocation;
import mfinder.MFinderException;
import mfinder.ObjectFactory;
import mfinder.config.Configuration;
import mfinder.impl.DefaultActionFactory;
import mfinder.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;
/**
* 提供与springframework集成的ActionFactory。
* 未完成 Action指定path属性的输入。
*/
public class DefaultActionFactoryBean implements FactoryBean<ActionFactory>, InitializingBean,
DisposableBean, ApplicationContextAware {
/** Logger available to subclasses */
protected final Logger logger = LoggerFactory.getLogger(getClass());
/**
* Location of a single MFinder XML config file.
* 不保证ActionFactory属性的重复加载。
*/
private Resource configLocation;
/* ActionFactory类 */
private Class<? extends ActionFactory> actionFactoryClass = null;
/* Action工厂 */
private ActionFactory actionFactory;
/** @see DefaultActionFactory#defaultInterceptorStack */
private String defaultInterceptorStack = null;
/** @see DefaultActionFactory#defaultResultType */
private String defaultResultType = null;
/** @see DefaultActionFactory#actionInvocationClass */
private Class<? extends ActionInvocation> actionInvocationClass;
/** @see DefaultActionFactory#extension */
private String extension = null;
/** @see DefaultActionFactory#actionCacheNumber */
private int actionCacheNumber = -1;
/** @see DefaultActionFactory#objectFactory */
private ObjectFactory objectFactory;
/* 拦截器的bean名称和类名称的集合 */
private List<Object> interceptors = null;
/* 拦截栈的bean名称和类名称的集合 */
private List<Object> interceptorStacks = null;
/* 结果类型的bean名称和类名称的集合 */
private List<Object> resultTypes = null;
/* 结果对象的bean名称和类名称的集合 */
private List<Object> results = null;
/* Action的bean名称和类名称的集合 */
private List<Object> actions = null;
/**
* springframework 的ApplicationContext对象。
*/
private ApplicationContext applicationContext;
/**
* 返回ActionFactory。
* 如果ActionFactory未实例化则抛出异常。
*
* @return 不为<code>null</code>)的ActionFactory
*
* @throws IllegalStateException 如果ActionFactory未实例化。
*/
protected final ActionFactory getActionFactory() {
if (this.actionFactory == null) {
throw new IllegalStateException("ActionFactory not initialized yet");
}
return this.actionFactory;
}
/**
* 初始化ActionFactory。
*
* @see #buildActionFactory()
* @see #afterActionFactoryCreation(mfinder.ActionFactory)
*/
@Override
public void afterPropertiesSet() throws Exception {
logger.info("Creating MFinder ActionFactory");
//不保证ActionFactory属性的重复加载
if (configLocation != null) {
logger.info("Load configuration : " + configLocation.getURL());
this.actionFactory = new Configuration().load(configLocation.getInputStream()).getFactory();
} else {
this.actionFactory = actionFactoryClass == null
? new DefaultActionFactory()
: actionFactoryClass.newInstance();
}
afterActionFactoryCreation(actionFactory);
this.actionFactory = buildActionFactory();
}
/**
* 在bean工厂关闭时移除ActionFactory中所有关联关系。
*
* @throws MFinderException 如果发生错误。
*/
@Override
public void destroy() throws MFinderException {
logger.info("Closing MFinder ActionFactory");
try {
beforeActionFactoryDestruction();
} finally {
this.actionFactory.clear();
}
}
/**
* 返回ActionFactory对象,默认为单例状态。
*/
@Override
public ActionFactory getObject() {
return this.actionFactory;
}
@Override
public Class<? extends ActionFactory> getObjectType() {
return actionFactory == null ? null : actionFactory.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
/**
* 初始化 MFinder ActionFactory。
*
* @return 已初始化的ActionFactory。
*
* @throws Exception 如果初始化失败。
*/
protected ActionFactory buildActionFactory() throws Exception {
logger.info("Building MFinder ActionFactory [{}]", actionFactory.getClass().getName());
if (actionFactory instanceof DefaultActionFactory) {
DefaultActionFactory defaultFactory = (DefaultActionFactory) this.actionFactory;
//set object factory, default use spring object facrtory
defaultFactory.setObjectFactory(objectFactory == null
? new SpringObjectFactory(applicationContext)
: objectFactory);
if (StringUtil.isNotNull(defaultInterceptorStack))
defaultFactory.setDefaultInterceptorStack(defaultInterceptorStack);
if (StringUtil.isNotNull(defaultResultType))
defaultFactory.setDefaultResultType(defaultResultType);
if (actionInvocationClass != null)
defaultFactory.setActionInvocationClass(actionInvocationClass);
defaultFactory.setExtension(extension);
if (actionCacheNumber > 0)
defaultFactory.setActionCacheNumber(actionCacheNumber);
if (interceptors != null) {
for (Object obj : interceptors) {
defaultFactory.addInterceptors(
obj instanceof String
? Class.forName((String) obj)
: obj);
}
}
if (interceptorStacks != null) {
for (Object obj : interceptorStacks) {
defaultFactory.addInterceptorStacks(
obj instanceof String
? Class.forName((String) obj)
: obj);
}
}
if (resultTypes != null) {
for (Object obj : resultTypes) {
defaultFactory.addResultTypes(
obj instanceof String
? Class.forName((String) obj)
: obj);
}
}
if (results != null) {
for (Object obj : results) {
defaultFactory.addResults(
obj instanceof String
? Class.forName((String) obj)
: obj);
}
}
if (actions != null) {
for (Object obj : actions) {
defaultFactory.addActions(
obj instanceof String
? Class.forName((String) obj)
: obj);
}
}
}
return actionFactory;
}
/**
* Hook that allows post-processing after the ActionFactory has been
* successfully created. The ActionFactory is already available through
* <code>getActionFactory()</code> at this point.
* <p>This implementation is empty.
*
* @param actionFactory ActionFactory。
*
* @see #getActionFactory()
*/
protected void afterActionFactoryCreation(ActionFactory actionFactory) {
}
/**
* Hook that allows shutdown processing before the ActionFactory
* will be closed. The ActionFactory is still available through
* <code>getActionFactory()</code> at this point.
* <p>This implementation is empty.
*
* @see #getActionFactory()
*/
protected void beforeActionFactoryDestruction() {
}
////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* Set the location of a single MFinder XML config file.
*
* @param configLocation Location of a single MFinder XML config file.
*
* @see mfinder.config.Configuration#load(java.io.InputStream)
*/
public void setConfigLocation(Resource configLocation) {
this.configLocation = configLocation;
}
/**
* 返回Action的bean名称和类名称的集合。
*
* @return Action的bean名称和类名称的集合。
*/
public List<Object> getActions() {
return actions;
}
/**
* 设置Action的bean名称和类名称的集合。
*
* @param actions Action的bean名称和类名称的集合。
*/
public void setActions(List<Object> actions) {
this.actions = actions;
}
/**
* 设置ActionFactory类名称。
*
* @param actionFactoryClass ActionFactory类名称。
*/
public void setActionFactoryClass(String actionFactoryClass) throws ClassNotFoundException {
if (StringUtil.isNotNull(actionFactoryClass))
this.actionFactoryClass = (Class<? extends ActionFactory>) Class.forName(actionFactoryClass);
}
/**
* @see ActionFactory#getObjectFactory()
*/
public ObjectFactory getObjectFactory() {
return objectFactory;
}
/**
* @see DefaultActionFactory#setObjectFactory(mfinder.ObjectFactory)
*/
public void setObjectFactory(ObjectFactory objectFactory) {
this.objectFactory = objectFactory;
}
/**
* @see ActionFactory#getDefaultInterceptorStack()
*/
public String getDefaultInterceptorStack() {
return defaultInterceptorStack;
}
/**
* @see DefaultActionFactory#setDefaultInterceptorStack(java.lang.String)
*/
public void setDefaultInterceptorStack(String defaultInterceptorStack) {
this.defaultInterceptorStack = defaultInterceptorStack;
}
/**
* @see ActionFactory#getDefaultResultType()
*/
public String getDefaultResultType() {
return defaultResultType;
}
/**
* @see DefaultActionFactory#setDefaultResultType(java.lang.String)
*/
public void setDefaultResultType(String defaultResultType) {
this.defaultResultType = defaultResultType;
}
/**
* @see DefaultActionFactory#setActionInvocationClass(java.lang.Class)
*/
public void setActionInvocationClass(String actionInvocationClass) throws ClassNotFoundException {
if (StringUtil.isNotNull(actionInvocationClass))
this.actionInvocationClass = (Class<? extends ActionInvocation>) Class.forName(actionInvocationClass);
}
/**
* @see DefaultActionFactory#getExtension()
*/
public String getExtension() {
return extension;
}
/**
* @see DefaultActionFactory#setExtension(java.lang.String)
*/
public void setExtension(String extension) {
this.extension = extension;
}
/**
* @see DefaultActionFactory#getActionCacheNumber()
*/
public int getActionCacheNumber() {
return actionCacheNumber;
}
/**
* @see DefaultActionFactory#setActionCacheNumber(int)
*/
public void setActionCacheNumber(int actionCacheNumber) {
this.actionCacheNumber = actionCacheNumber;
}
/**
* 返回拦截栈的bean名称和类名称的集合。
*
* @return 拦截栈的bean名称和类名称的集合。
*/
public List<Object> getInterceptorStacks() {
return interceptorStacks;
}
/**
* 设置拦截栈的bean名称和类名称的集合。
*
* @param interceptorStacks 拦截栈的bean名称和类名称的集合。
*/
public void setInterceptorStacks(List<Object> interceptorStacks) {
this.interceptorStacks = interceptorStacks;
}
/**
* 返回拦截器的bean名称和类名称的集合。
*
* @return 拦截器的bean名称和类名称的集合。
*/
public List<Object> getInterceptors() {
return interceptors;
}
/**
* 设置拦截器的bean名称和类名称的集合。
*
* @param interceptors 拦截器的bean名称和类名称的集合。
*/
public void setInterceptors(List<Object> interceptors) {
this.interceptors = interceptors;
}
/**
* 返回结果类型的bean名称和类名称的集合。
*
* @return 结果类型的bean名称和类名称的集合。
*/
public List<Object> getResultTypes() {
return resultTypes;
}
/**
* 设置结果类型的bean名称和类名称的集合。
*
* @param resultTypes 结果类型的bean名称和类名称的集合。
*/
public void setResultTypes(List<Object> resultTypes) {
this.resultTypes = resultTypes;
}
/**
* 返回结果对象的bean名称和类名称的集合。
*
* @return 结果对象的bean名称和类名称的集合。
*/
public List<Object> getResults() {
return results;
}
/**
* 设置结果对象的bean名称和类名称的集合。
*
* @param results 结果对象的bean名称和类名称的集合。
*/
public void setResults(List<Object> results) {
this.results = results;
}
}