All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.weld.manager.Enabled Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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.jboss.weld.manager;

import com.google.common.base.Function;
import org.jboss.weld.bootstrap.spi.BeansXml;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.exceptions.DeploymentException;
import org.jboss.weld.logging.messages.ValidatorMessage;
import org.jboss.weld.metadata.MetadataImpl;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.jboss.weld.resources.spi.ResourceLoadingException;
import org.jboss.weld.util.reflection.Reflections;

import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.Interceptor;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.google.common.collect.Lists.transform;
import static java.util.Collections.unmodifiableCollection;
import static org.jboss.weld.logging.messages.ValidatorMessage.ALTERNATIVE_BEAN_CLASS_SPECIFIED_MULTIPLE_TIMES;
import static org.jboss.weld.logging.messages.ValidatorMessage.ALTERNATIVE_STEREOTYPE_SPECIFIED_MULTIPLE_TIMES;
import static org.jboss.weld.logging.messages.ValidatorMessage.DECORATOR_SPECIFIED_TWICE;
import static org.jboss.weld.logging.messages.ValidatorMessage.INTERCEPTOR_SPECIFIED_TWICE;

/**
 * @author Nicklas Karlsson
 * @author Ales Justin
 */
public class Enabled {

    private static class ClassLoader implements Function, Metadata>> {

        private final ResourceLoader resourceLoader;

        public ClassLoader(ResourceLoader resourceLoader) {
            this.resourceLoader = resourceLoader;
        }

        public Metadata> apply(Metadata from) {
            String location = from.getLocation();
            try {
                return new MetadataImpl>(Reflections.>cast(resourceLoader.classForName(from.getValue())), location);
            } catch (ResourceLoadingException e) {
                throw new ResourceLoadingException(e.getMessage() + "; location: " + location, e.getCause());
            } catch (Exception e) {
                throw new ResourceLoadingException(e.getMessage() + "; location: " + location, e);
            }
        }

    }

    public static Enabled of(BeansXml beansXml, ResourceLoader resourceLoader) {
        if (beansXml == null) {
            return EMPTY_ENABLED;
        } else {
            ClassLoader classLoader = new ClassLoader(resourceLoader);
            ClassLoader annotationLoader = new ClassLoader(resourceLoader);
            return new Enabled(transform(beansXml.getEnabledAlternativeStereotypes(), annotationLoader), transform(beansXml.getEnabledAlternativeClasses(), classLoader), transform(beansXml.getEnabledDecorators(), classLoader), transform(beansXml.getEnabledInterceptors(), classLoader));
        }
    }

    public static final Enabled EMPTY_ENABLED = new Enabled(Collections.>>emptyList(), Collections.>>emptyList(), Collections.>>emptyList(), Collections.>>emptyList());

    private final Map, Metadata>> alternativeStereotypes;
    private final Map, Metadata>> alternativeClasses;
    private final Map, Metadata>> decorators;
    private final Map, Metadata>> interceptors;
    private final Comparator> decoratorComparator;
    private final Comparator> interceptorComparator;

    private Enabled(List>> alternativeStereotypes, List>> alternativeClasses, List>> decorators, List>> interceptors) {
        this.alternativeStereotypes = createMetadataMap(alternativeStereotypes, ALTERNATIVE_STEREOTYPE_SPECIFIED_MULTIPLE_TIMES);
        this.alternativeClasses = createMetadataMap(alternativeClasses, ALTERNATIVE_BEAN_CLASS_SPECIFIED_MULTIPLE_TIMES);
        this.decorators = createMetadataMap(decorators, DECORATOR_SPECIFIED_TWICE);
        this.interceptors = createMetadataMap(interceptors, INTERCEPTOR_SPECIFIED_TWICE);
        final List> decoratorTypes = transform(decorators, new RemoveMetadataWrapperFunction>());
        final List> interceptorTypes = transform(interceptors, new RemoveMetadataWrapperFunction>());
        this.decoratorComparator = new Comparator>() {

            public int compare(Decorator o1, Decorator o2) {
                int p1 = decoratorTypes.indexOf(o1.getBeanClass());
                int p2 = decoratorTypes.indexOf(o2.getBeanClass());
                return p1 - p2;
            }

        };
        this.interceptorComparator = new Comparator>() {

            public int compare(Interceptor o1, Interceptor o2) {
                int p1 = interceptorTypes.indexOf(o1.getBeanClass());
                int p2 = interceptorTypes.indexOf(o2.getBeanClass());
                return p1 - p2;
            }

        };
    }

    private static  Map> createMetadataMap(List> metadata, ValidatorMessage specifiedTwiceMessage) {
        Map> result = new HashMap>();
        for (Metadata value : metadata) {
            if (result.containsKey(value.getValue())) {
                throw new DeploymentException(specifiedTwiceMessage, metadata);
            }
            result.put(value.getValue(), value);
        }
        return result;
    }

    public Collection>> getAlternativeStereotypes() {
        return unmodifiableCollection(alternativeStereotypes.values());
    }

    public Metadata> getAlternativeStereotype(Class annotationType) {
        return alternativeStereotypes.get(annotationType);
    }

    public Collection>> getAlternativeClasses() {
        return unmodifiableCollection(alternativeClasses.values());
    }

    public Metadata> getAlternativeClass(Class clazz) {
        return alternativeClasses.get(clazz);
    }

    public Collection>> getDecorators() {
        return unmodifiableCollection(decorators.values());
    }

    public Metadata> getDecorator(Class clazz) {
        return decorators.get(clazz);
    }

    public Collection>> getInterceptors() {
        return unmodifiableCollection(interceptors.values());
    }

    public Metadata> getInterceptor(Class clazz) {
        return interceptors.get(clazz);
    }

    public Comparator> getDecoratorComparator() {
        return decoratorComparator;
    }

    public Comparator> getInterceptorComparator() {
        return interceptorComparator;
    }

}