/*** * 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; } }