/** * AnalyzerBeans * Copyright (C) 2014 Neopost - Customer Information Management * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.eobjects.analyzer.descriptors; import java.lang.reflect.Modifier; import org.eobjects.analyzer.beans.api.Renderer; import org.eobjects.analyzer.beans.api.RendererBean; import org.eobjects.analyzer.beans.api.RenderingFormat; import org.eobjects.analyzer.result.renderer.Renderable; import org.eobjects.analyzer.util.ReflectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; final class AnnotationBasedRendererBeanDescriptor<R extends Renderer<?, ?>> extends SimpleComponentDescriptor<R> implements RendererBeanDescriptor<R> { private static final long serialVersionUID = 1L; private static final Logger logger = LoggerFactory.getLogger(AnnotationBasedRendererBeanDescriptor.class); private final Class<? extends RenderingFormat<?>> _renderingFormat; private final Class<?> _formatOutputType; private final Class<? extends Renderable> _rendererInputType; private final Class<?> _rendererOutputType; protected AnnotationBasedRendererBeanDescriptor(Class<R> rendererClass) throws DescriptorException { super(rendererClass, true); RendererBean rendererBeanAnnotation = ReflectionUtils.getAnnotation(rendererClass, RendererBean.class); if (rendererBeanAnnotation == null) { throw new DescriptorException(rendererClass + " doesn't implement the RendererBean annotation"); } _renderingFormat = rendererBeanAnnotation.value(); if (_renderingFormat == null || _renderingFormat.isInterface() || Modifier.isAbstract(_renderingFormat.getModifiers())) { throw new DescriptorException("Rendering format (" + _renderingFormat + ") is not a non-abstract class"); } _formatOutputType = ReflectionUtils.getTypeParameter(_renderingFormat, RenderingFormat.class, 0); logger.debug("Found format output type: {}", _formatOutputType); if (_formatOutputType == null) { throw new DescriptorException("Could not determine output type of rendering format: " + _renderingFormat); } @SuppressWarnings("unchecked") Class<? extends Renderable> rendererInputType = (Class<? extends Renderable>) ReflectionUtils.getTypeParameter( rendererClass, Renderer.class, 0); _rendererInputType = rendererInputType; logger.debug("Found renderer input type: {}", _rendererInputType); _rendererOutputType = ReflectionUtils.getTypeParameter(rendererClass, Renderer.class, 1); logger.debug("Found renderer output type: {}", _rendererOutputType); if (_rendererOutputType == null) { throw new DescriptorException("Could not determine output type of renderer: " + rendererClass); } if (!ReflectionUtils.is(_rendererOutputType, _formatOutputType)) { throw new DescriptorException("The renderer output type (" + _rendererOutputType + ") is not a valid instance or sub-class of format output type (" + _formatOutputType + ")"); } } @Override public Class<? extends RenderingFormat<?>> getRenderingFormat() { return _renderingFormat; } @Override public boolean isOutputApplicableFor(Class<?> requiredClass) { if (!ReflectionUtils.is(requiredClass, _formatOutputType)) { logger.debug("{} is not applicable to the format output type: {}", requiredClass, _formatOutputType); return false; } boolean result = ReflectionUtils.is(_rendererOutputType, requiredClass); if (!result) { logger.debug("{} is not applicable to the renderer output type: {}", requiredClass, _rendererOutputType); } return result; } @Override public Class<? extends Renderable> getRenderableType() { return _rendererInputType; } }