/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
* All rights reserved.
*
* 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 br.com.caelum.vraptor.core;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import br.com.caelum.iogi.Instantiator;
import br.com.caelum.iogi.spi.DependencyProvider;
import br.com.caelum.iogi.spi.ParameterNamesProvider;
import br.com.caelum.vraptor.Convert;
import br.com.caelum.vraptor.Converter;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.config.ApplicationConfiguration;
import br.com.caelum.vraptor.config.Configuration;
import br.com.caelum.vraptor.converter.BigDecimalConverter;
import br.com.caelum.vraptor.converter.BigIntegerConverter;
import br.com.caelum.vraptor.converter.BooleanConverter;
import br.com.caelum.vraptor.converter.ByteConverter;
import br.com.caelum.vraptor.converter.CharacterConverter;
import br.com.caelum.vraptor.converter.DoubleConverter;
import br.com.caelum.vraptor.converter.EnumConverter;
import br.com.caelum.vraptor.converter.FloatConverter;
import br.com.caelum.vraptor.converter.IntegerConverter;
import br.com.caelum.vraptor.converter.LocaleBasedCalendarConverter;
import br.com.caelum.vraptor.converter.LocaleBasedDateConverter;
import br.com.caelum.vraptor.converter.LongConverter;
import br.com.caelum.vraptor.converter.PrimitiveBooleanConverter;
import br.com.caelum.vraptor.converter.PrimitiveByteConverter;
import br.com.caelum.vraptor.converter.PrimitiveCharConverter;
import br.com.caelum.vraptor.converter.PrimitiveDoubleConverter;
import br.com.caelum.vraptor.converter.PrimitiveFloatConverter;
import br.com.caelum.vraptor.converter.PrimitiveIntConverter;
import br.com.caelum.vraptor.converter.PrimitiveLongConverter;
import br.com.caelum.vraptor.converter.PrimitiveShortConverter;
import br.com.caelum.vraptor.converter.ShortConverter;
import br.com.caelum.vraptor.converter.StringConverter;
import br.com.caelum.vraptor.converter.jodatime.DateMidnightConverter;
import br.com.caelum.vraptor.converter.jodatime.DateTimeConverter;
import br.com.caelum.vraptor.converter.jodatime.LocalDateConverter;
import br.com.caelum.vraptor.converter.jodatime.LocalDateTimeConverter;
import br.com.caelum.vraptor.converter.jodatime.LocalTimeConverter;
import br.com.caelum.vraptor.deserialization.DefaultDeserializers;
import br.com.caelum.vraptor.deserialization.Deserializer;
import br.com.caelum.vraptor.deserialization.Deserializers;
import br.com.caelum.vraptor.deserialization.Deserializes;
import br.com.caelum.vraptor.deserialization.DeserializesHandler;
import br.com.caelum.vraptor.deserialization.FormDeserializer;
import br.com.caelum.vraptor.deserialization.JsonDeserializer;
import br.com.caelum.vraptor.deserialization.XMLDeserializer;
import br.com.caelum.vraptor.deserialization.XStreamXMLDeserializer;
import br.com.caelum.vraptor.http.DefaultFormatResolver;
import br.com.caelum.vraptor.http.DefaultResourceTranslator;
import br.com.caelum.vraptor.http.EncodingHandlerFactory;
import br.com.caelum.vraptor.http.FormatResolver;
import br.com.caelum.vraptor.http.ParameterNameProvider;
import br.com.caelum.vraptor.http.ParametersProvider;
import br.com.caelum.vraptor.http.ParanamerNameProvider;
import br.com.caelum.vraptor.http.UrlToResourceTranslator;
import br.com.caelum.vraptor.http.iogi.InstantiatorWithErrors;
import br.com.caelum.vraptor.http.iogi.IogiParametersProvider;
import br.com.caelum.vraptor.http.iogi.VRaptorDependencyProvider;
import br.com.caelum.vraptor.http.iogi.VRaptorInstantiator;
import br.com.caelum.vraptor.http.iogi.VRaptorParameterNamesProvider;
import br.com.caelum.vraptor.http.ognl.EmptyElementsRemoval;
import br.com.caelum.vraptor.http.ognl.OgnlFacade;
import br.com.caelum.vraptor.http.ognl.OgnlParametersProvider;
import br.com.caelum.vraptor.http.route.DefaultRouter;
import br.com.caelum.vraptor.http.route.DefaultTypeFinder;
import br.com.caelum.vraptor.http.route.Evaluator;
import br.com.caelum.vraptor.http.route.JavaEvaluator;
import br.com.caelum.vraptor.http.route.NoRoutesConfiguration;
import br.com.caelum.vraptor.http.route.PathAnnotationRoutesParser;
import br.com.caelum.vraptor.http.route.Router;
import br.com.caelum.vraptor.http.route.RoutesConfiguration;
import br.com.caelum.vraptor.http.route.RoutesParser;
import br.com.caelum.vraptor.http.route.TypeFinder;
import br.com.caelum.vraptor.interceptor.DefaultTypeNameExtractor;
import br.com.caelum.vraptor.interceptor.DeserializingInterceptor;
import br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor;
import br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor;
import br.com.caelum.vraptor.interceptor.FlashInterceptor;
import br.com.caelum.vraptor.interceptor.ForwardToDefaultViewInterceptor;
import br.com.caelum.vraptor.interceptor.InstantiateInterceptor;
import br.com.caelum.vraptor.interceptor.InterceptorRegistry;
import br.com.caelum.vraptor.interceptor.OutjectResult;
import br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor;
import br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor;
import br.com.caelum.vraptor.interceptor.TopologicalSortedInterceptorRegistry;
import br.com.caelum.vraptor.interceptor.TypeNameExtractor;
import br.com.caelum.vraptor.interceptor.download.DownloadInterceptor;
import br.com.caelum.vraptor.interceptor.multipart.CommonsUploadMultipartInterceptor;
import br.com.caelum.vraptor.interceptor.multipart.DefaultMultipartConfig;
import br.com.caelum.vraptor.interceptor.multipart.DefaultServletFileUploadCreator;
import br.com.caelum.vraptor.interceptor.multipart.MultipartConfig;
import br.com.caelum.vraptor.interceptor.multipart.MultipartInterceptor;
import br.com.caelum.vraptor.interceptor.multipart.NullMultipartInterceptor;
import br.com.caelum.vraptor.interceptor.multipart.ServletFileUploadCreator;
import br.com.caelum.vraptor.interceptor.multipart.UploadedFileConverter;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.ConverterHandler;
import br.com.caelum.vraptor.ioc.InterceptorStereotypeHandler;
import br.com.caelum.vraptor.ioc.ResourceHandler;
import br.com.caelum.vraptor.ioc.StereotypeHandler;
import br.com.caelum.vraptor.proxy.InstanceCreator;
import br.com.caelum.vraptor.proxy.JavassistProxifier;
import br.com.caelum.vraptor.proxy.ObjenesisInstanceCreator;
import br.com.caelum.vraptor.proxy.Proxifier;
import br.com.caelum.vraptor.proxy.ReflectionInstanceCreator;
import br.com.caelum.vraptor.resource.DefaultMethodNotAllowedHandler;
import br.com.caelum.vraptor.resource.DefaultResourceNotFoundHandler;
import br.com.caelum.vraptor.resource.MethodNotAllowedHandler;
import br.com.caelum.vraptor.resource.ResourceNotFoundHandler;
import br.com.caelum.vraptor.restfulie.RestHeadersHandler;
import br.com.caelum.vraptor.restfulie.headers.DefaultRestDefaults;
import br.com.caelum.vraptor.restfulie.headers.DefaultRestHeadersHandler;
import br.com.caelum.vraptor.restfulie.headers.RestDefaults;
import br.com.caelum.vraptor.serialization.DefaultRepresentationResult;
import br.com.caelum.vraptor.serialization.HTMLSerialization;
import br.com.caelum.vraptor.serialization.HibernateProxyInitializer;
import br.com.caelum.vraptor.serialization.I18nMessageSerialization;
import br.com.caelum.vraptor.serialization.JSONPSerialization;
import br.com.caelum.vraptor.serialization.JSONSerialization;
import br.com.caelum.vraptor.serialization.NullProxyInitializer;
import br.com.caelum.vraptor.serialization.ProxyInitializer;
import br.com.caelum.vraptor.serialization.RepresentationResult;
import br.com.caelum.vraptor.serialization.XMLSerialization;
import br.com.caelum.vraptor.serialization.xstream.XStreamBuilder;
import br.com.caelum.vraptor.serialization.xstream.XStreamBuilderImpl;
import br.com.caelum.vraptor.serialization.xstream.XStreamConverters;
import br.com.caelum.vraptor.serialization.xstream.XStreamJSONPSerialization;
import br.com.caelum.vraptor.serialization.xstream.XStreamJSONSerialization;
import br.com.caelum.vraptor.serialization.xstream.XStreamXMLSerialization;
import br.com.caelum.vraptor.validator.BeanValidator;
import br.com.caelum.vraptor.validator.DIConstraintValidatorFactory;
import br.com.caelum.vraptor.validator.DefaultBeanValidator;
import br.com.caelum.vraptor.validator.DefaultValidator;
import br.com.caelum.vraptor.validator.MessageConverter;
import br.com.caelum.vraptor.validator.MessageInterpolatorFactory;
import br.com.caelum.vraptor.validator.MethodValidatorFactoryCreator;
import br.com.caelum.vraptor.validator.MethodValidatorInterceptor;
import br.com.caelum.vraptor.validator.NullBeanValidator;
import br.com.caelum.vraptor.validator.Outjector;
import br.com.caelum.vraptor.validator.ReplicatorOutjector;
import br.com.caelum.vraptor.validator.ValidatorCreator;
import br.com.caelum.vraptor.validator.ValidatorFactoryCreator;
import br.com.caelum.vraptor.view.AcceptHeaderToFormat;
import br.com.caelum.vraptor.view.DefaultAcceptHeaderToFormat;
import br.com.caelum.vraptor.view.DefaultHttpResult;
import br.com.caelum.vraptor.view.DefaultLogicResult;
import br.com.caelum.vraptor.view.DefaultPageResult;
import br.com.caelum.vraptor.view.DefaultPathResolver;
import br.com.caelum.vraptor.view.DefaultRefererResult;
import br.com.caelum.vraptor.view.DefaultStatus;
import br.com.caelum.vraptor.view.DefaultValidationViewsFactory;
import br.com.caelum.vraptor.view.EmptyResult;
import br.com.caelum.vraptor.view.FlashScope;
import br.com.caelum.vraptor.view.HttpResult;
import br.com.caelum.vraptor.view.LogicResult;
import br.com.caelum.vraptor.view.PageResult;
import br.com.caelum.vraptor.view.PathResolver;
import br.com.caelum.vraptor.view.RefererResult;
import br.com.caelum.vraptor.view.SessionFlashScope;
import br.com.caelum.vraptor.view.Status;
import br.com.caelum.vraptor.view.ValidationViewsFactory;
import com.thoughtworks.xstream.converters.SingleValueConverter;
/**
* List of base components to vraptor.<br/>
* Those components should be available with any chosen ioc implementation.
*
* @author guilherme silveira
*/
public final class BaseComponents {
static final Logger logger = LoggerFactory.getLogger(BaseComponents.class);
private final static Map<Class<?>, Class<?>> APPLICATION_COMPONENTS = classMap(
EncodingHandlerFactory.class, EncodingHandlerFactory.class,
AcceptHeaderToFormat.class, DefaultAcceptHeaderToFormat.class,
Converters.class, DefaultConverters.class,
InterceptorRegistry.class, TopologicalSortedInterceptorRegistry.class,
InterceptorHandlerFactory.class,DefaultInterceptorHandlerFactory.class,
MultipartConfig.class, DefaultMultipartConfig.class,
UrlToResourceTranslator.class, DefaultResourceTranslator.class,
Router.class, DefaultRouter.class,
TypeNameExtractor.class, DefaultTypeNameExtractor.class,
ResourceNotFoundHandler.class, DefaultResourceNotFoundHandler.class,
MethodNotAllowedHandler.class, DefaultMethodNotAllowedHandler.class,
RoutesConfiguration.class, NoRoutesConfiguration.class,
Deserializers.class, DefaultDeserializers.class,
Proxifier.class, JavassistProxifier.class,
InstanceCreator.class, getInstanceCreator(),
ParameterNameProvider.class, ParanamerNameProvider.class,
TypeFinder.class, DefaultTypeFinder.class,
RoutesParser.class, PathAnnotationRoutesParser.class,
Routes.class, DefaultRoutes.class,
RestDefaults.class, DefaultRestDefaults.class,
Evaluator.class, JavaEvaluator.class,
StaticContentHandler.class, DefaultStaticContentHandler.class,
SingleValueConverter.class, XStreamConverters.NullConverter.class,
ProxyInitializer.class, getProxyInitializerImpl()
);
private final static Map<Class<?>, Class<?>> CACHED_COMPONENTS = classMap(
);
private static final Map<Class<?>, Class<?>> PROTOTYPE_COMPONENTS = classMap(
InterceptorStack.class, DefaultInterceptorStack.class,
RequestExecution.class, EnhancedRequestExecution.class,
XStreamBuilder.class, XStreamBuilderImpl.class
);
private static final Map<Class<?>, Class<?>> REQUEST_COMPONENTS = classMap(
MethodInfo.class, DefaultMethodInfo.class,
LogicResult.class, DefaultLogicResult.class,
PageResult.class, DefaultPageResult.class,
HttpResult.class, DefaultHttpResult.class,
RefererResult.class, DefaultRefererResult.class,
PathResolver.class, DefaultPathResolver.class,
ValidationViewsFactory.class, DefaultValidationViewsFactory.class,
Result.class, DefaultResult.class,
Validator.class, DefaultValidator.class,
Outjector.class, ReplicatorOutjector.class,
DownloadInterceptor.class, DownloadInterceptor.class,
EmptyResult.class, EmptyResult.class,
ExecuteMethodInterceptor.class, ExecuteMethodInterceptor.class,
ExceptionHandlerInterceptor.class, ExceptionHandlerInterceptor.class,
ExceptionMapper.class, DefaultExceptionMapper.class,
FlashInterceptor.class, FlashInterceptor.class,
ForwardToDefaultViewInterceptor.class, ForwardToDefaultViewInterceptor.class,
InstantiateInterceptor.class, InstantiateInterceptor.class,
DeserializingInterceptor.class, DeserializingInterceptor.class,
JsonDeserializer.class, JsonDeserializer.class,
FormDeserializer.class, FormDeserializer.class,
Localization.class, JstlLocalization.class,
OutjectResult.class, OutjectResult.class,
ParametersInstantiatorInterceptor.class, ParametersInstantiatorInterceptor.class,
ResourceLookupInterceptor.class, ResourceLookupInterceptor.class,
Status.class, DefaultStatus.class,
XMLDeserializer.class, XStreamXMLDeserializer.class,
XMLSerialization.class, XStreamXMLSerialization.class,
JSONSerialization.class, XStreamJSONSerialization.class,
JSONPSerialization.class, XStreamJSONPSerialization.class,
HTMLSerialization.class, HTMLSerialization.class,
I18nMessageSerialization.class, I18nMessageSerialization.class,
RepresentationResult.class, DefaultRepresentationResult.class,
FormatResolver.class, DefaultFormatResolver.class,
Configuration.class, ApplicationConfiguration.class,
RestHeadersHandler.class, DefaultRestHeadersHandler.class,
FlashScope.class, SessionFlashScope.class,
XStreamConverters.class, XStreamConverters.class,
MessageConverter.class, MessageConverter.class
);
@SuppressWarnings({"unchecked", "rawtypes"})
private static final Set<Class<? extends Converter<?>>> BUNDLED_CONVERTERS = new HashSet(Arrays.asList(
BigDecimalConverter.class,
BigIntegerConverter.class,
BooleanConverter.class,
ByteConverter.class,
CharacterConverter.class,
DoubleConverter.class,
EnumConverter.class,
FloatConverter.class,
IntegerConverter.class,
LocaleBasedCalendarConverter.class,
LocaleBasedDateConverter.class,
LongConverter.class,
PrimitiveBooleanConverter.class,
PrimitiveByteConverter.class,
PrimitiveCharConverter.class,
PrimitiveDoubleConverter.class,
PrimitiveFloatConverter.class,
PrimitiveIntConverter.class,
PrimitiveLongConverter.class,
PrimitiveShortConverter.class,
ShortConverter.class,
StringConverter.class,
UploadedFileConverter.class));
@SuppressWarnings("unchecked")
private static final Class<? extends StereotypeHandler>[] STEREOTYPE_HANDLERS = new Class[] {
ResourceHandler.class,
ConverterHandler.class,
InterceptorStereotypeHandler.class,
DeserializesHandler.class
};
@SuppressWarnings("unchecked")
private static final Class<? extends Annotation>[] STEREOTYPES = new Class[] {
Resource.class,
Convert.class,
Component.class,
Deserializes.class,
Intercepts.class
};
private BaseComponents() {
throw new InstantiationError( "Must not instantiate this class" );
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static final Set<Class<? extends Deserializer>> DESERIALIZERS = new HashSet(Arrays.asList(
XMLDeserializer.class,
JsonDeserializer.class,
FormDeserializer.class));
public static Set<Class<? extends Deserializer>> getDeserializers() {
return DESERIALIZERS;
}
private static Class<? extends ProxyInitializer> getProxyInitializerImpl() {
try {
Class.forName("org.hibernate.proxy.HibernateProxy");
return HibernateProxyInitializer.class;
} catch (ClassNotFoundException e) {
return NullProxyInitializer.class;
}
}
private static Class<? extends InstanceCreator> getInstanceCreator() {
if (isClassPresent("org.objenesis.ObjenesisStd")) {
return ObjenesisInstanceCreator.class;
}
return ReflectionInstanceCreator.class;
}
public static Map<Class<?>, Class<?>> getCachedComponents() {
return Collections.unmodifiableMap(CACHED_COMPONENTS);
}
public static Map<Class<?>, Class<?>> getApplicationScoped() {
if (!isClassPresent("ognl.OgnlRuntime")) {
APPLICATION_COMPONENTS.put(DependencyProvider.class, VRaptorDependencyProvider.class);
}
// try put beanval 1.1 or beanval 1.0 if available
if (isClassPresent("javax.validation.executable.ExecutableValidator")) {
APPLICATION_COMPONENTS.put(ValidatorCreator.class, ValidatorCreator.class);
APPLICATION_COMPONENTS.put(MethodValidatorFactoryCreator.class, MethodValidatorFactoryCreator.class);
APPLICATION_COMPONENTS.put(DIConstraintValidatorFactory.class, DIConstraintValidatorFactory.class);
APPLICATION_COMPONENTS.put(MessageInterpolatorFactory.class, MessageInterpolatorFactory.class);
} else if (isClassPresent("javax.validation.Validation")) {
APPLICATION_COMPONENTS.put(ValidatorCreator.class, ValidatorCreator.class);
APPLICATION_COMPONENTS.put(ValidatorFactoryCreator.class, ValidatorFactoryCreator.class);
APPLICATION_COMPONENTS.put(MessageInterpolatorFactory.class, MessageInterpolatorFactory.class);
}
return Collections.unmodifiableMap(APPLICATION_COMPONENTS);
}
public static Map<Class<?>, Class<?>> getRequestScoped() {
// try put beanval 1.1 or beanval 1.0 if available
if (isClassPresent("javax.validation.executable.ExecutableValidator")) {
REQUEST_COMPONENTS.put(BeanValidator.class, DefaultBeanValidator.class);
REQUEST_COMPONENTS.put(MethodValidatorInterceptor.class, MethodValidatorInterceptor.class);
} else if (isClassPresent("javax.validation.Validation")) {
REQUEST_COMPONENTS.put(BeanValidator.class, DefaultBeanValidator.class);
} else {
REQUEST_COMPONENTS.put(BeanValidator.class, NullBeanValidator.class);
}
if (isClassPresent("org.apache.commons.fileupload.FileItem")) {
REQUEST_COMPONENTS.put(MultipartInterceptor.class, CommonsUploadMultipartInterceptor.class);
REQUEST_COMPONENTS.put(ServletFileUploadCreator.class, DefaultServletFileUploadCreator.class);
} else {
logger.warn("There is neither commons-fileupload nor servlet3 handlers registered. " +
"If you are willing to upload a file, please add the commons-fileupload in " +
"your classpath or use a Servlet 3 Container");
REQUEST_COMPONENTS.put(MultipartInterceptor.class, NullMultipartInterceptor.class);
}
if (isClassPresent("ognl.OgnlRuntime")) {
REQUEST_COMPONENTS.put(ParametersProvider.class, OgnlParametersProvider.class);
REQUEST_COMPONENTS.put(EmptyElementsRemoval.class, EmptyElementsRemoval.class);
REQUEST_COMPONENTS.put(OgnlFacade.class, OgnlFacade.class);
} else {
REQUEST_COMPONENTS.put(ParametersProvider.class, IogiParametersProvider.class);
REQUEST_COMPONENTS.put(ParameterNamesProvider.class, VRaptorParameterNamesProvider.class);
REQUEST_COMPONENTS.put(InstantiatorWithErrors.class, VRaptorInstantiator.class);
REQUEST_COMPONENTS.put(Instantiator.class, VRaptorInstantiator.class);
}
return Collections.unmodifiableMap(REQUEST_COMPONENTS);
}
private static boolean isClassPresent(String className) {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
private static void registerIfClassPresent(Set<Class<? extends Converter<?>>> components, String className, Class<? extends Converter<?>>... types) {
if (components.contains(types[0])) {
return;
}
try {
Class.forName(className);
for (Class<? extends Converter<?>> type : types) {
components.add(type);
}
} catch (ClassNotFoundException e) { /*ok, don't register*/ }
}
public static Map<Class<?>, Class<?>> getPrototypeScoped() {
return Collections.unmodifiableMap(PROTOTYPE_COMPONENTS);
}
@SuppressWarnings("unchecked")
public static Set<Class<? extends Converter<?>>> getBundledConverters() {
registerIfClassPresent(BUNDLED_CONVERTERS, "org.joda.time.LocalDate",
LocalDateConverter.class, LocalTimeConverter.class, LocalDateTimeConverter.class,
DateTimeConverter.class, DateMidnightConverter.class);
return BUNDLED_CONVERTERS;
}
public static Class<? extends Annotation>[] getStereotypes() {
return STEREOTYPES;
}
public static Class<? extends StereotypeHandler>[] getStereotypeHandlers() {
return STEREOTYPE_HANDLERS;
}
private static Map<Class<?>, Class<?>> classMap(Class<?>... items) {
HashMap<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
Iterator<Class<?>> it = Arrays.asList(items).iterator();
while (it.hasNext()) {
Class<?> key = it.next();
Class<?> value = it.next();
if (value == null) {
throw new IllegalArgumentException("The number of items should be even.");
}
map.put(key, value);
}
return map;
}
}