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

org.jboss.weld.environment.deployment.discovery.AbstractDiscoveryStrategy Maven / Gradle / Ivy

Go to download

This jar bundles all the bits of Weld and CDI required for running in a Servlet container.

There is a newer version: 6.0.0.Beta4
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2014, Red Hat, Inc. and/or its affiliates, 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.environment.deployment.discovery;

import java.lang.annotation.Annotation;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

import javax.annotation.Priority;

import org.jboss.weld.bootstrap.api.Bootstrap;
import org.jboss.weld.bootstrap.spi.BeansXml;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.environment.deployment.WeldBeanDeploymentArchive;
import org.jboss.weld.environment.deployment.discovery.BeanArchiveScanner.ScanResult;
import org.jboss.weld.environment.logging.CommonLogger;
import org.jboss.weld.exceptions.UnsupportedOperationException;
import org.jboss.weld.resources.spi.ClassFileServices;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.jboss.weld.util.ServiceLoader;

/**
 *
 * @author Matej Briškár
 * @author Martin Kouba
 * @author Jozef Hartinger
 */
public abstract class AbstractDiscoveryStrategy implements DiscoveryStrategy {

    protected final ResourceLoader resourceLoader;

    protected final Bootstrap bootstrap;

    protected final Set> initialBeanDefiningAnnotations;

    protected BeanArchiveScanner scanner;

    private final List handlers;

    /**
     *
     * @param resourceLoader
     * @param bootstrap
     * @param initialBeanDefiningAnnotations
     */
    public AbstractDiscoveryStrategy(ResourceLoader resourceLoader, Bootstrap bootstrap, Set> initialBeanDefiningAnnotations) {
        this.resourceLoader = resourceLoader;
        this.bootstrap = bootstrap;
        this.handlers = new LinkedList();
        this.initialBeanDefiningAnnotations = initialBeanDefiningAnnotations;
    }

    @Override
    public void setScanner(BeanArchiveScanner scanner) {
        this.scanner = scanner;
    }

    @Override
    public Set performDiscovery() {

        if (scanner == null) {
            scanner = new DefaultBeanArchiveScanner(resourceLoader, bootstrap);
        }

        final List beanArchiveBuilders = new ArrayList();
        final Set processedRefs = new HashSet();

        List beanArchiveHandlers = initBeanArchiveHandlers();

        for (ScanResult scanResult : scanner.scan()) {
            final String ref = scanResult.getBeanArchiveRef();
            if (processedRefs.contains(ref)) {
                throw CommonLogger.LOG.invalidScanningResult(ref);
            }
            CommonLogger.LOG.processingBeanArchiveReference(ref);
            processedRefs.add(ref);
            BeanArchiveBuilder builder = null;
            for (BeanArchiveHandler handler : beanArchiveHandlers) {
                builder = handler.handle(ref);
                if (builder != null) {
                    CommonLogger.LOG.beanArchiveReferenceHandled(ref, handler);
                    builder.setId(scanResult.getBeanArchiveId());
                    builder.setBeansXml(scanResult.getBeansXml());
                    beanArchiveBuilders.add(builder);
                    break;
                }
            }
            if (builder == null) {
                CommonLogger.LOG.beanArchiveReferenceCannotBeHandled(ref, beanArchiveHandlers);
            }
        }

        beforeDiscovery(beanArchiveBuilders);
        Set archives = new HashSet();

        for (Iterator iterator = beanArchiveBuilders.iterator(); iterator.hasNext();) {
            BeanArchiveBuilder builder = iterator.next();
            BeansXml beansXml = builder.getBeansXml();
            if(beansXml != null) {
                switch (beansXml.getBeanDiscoveryMode()) {
                    case ALL:
                        addToArchives(archives, processAllDiscovery(builder));
                        break;
                    case ANNOTATED:
                        addToArchives(archives, processAnnotatedDiscovery(builder));
                        break;
                    case NONE:
                        addToArchives(archives, processNoneDiscovery(builder));
                        break;
                    default:
                        throw CommonLogger.LOG.undefinedBeanDiscoveryValue(beansXml.getBeanDiscoveryMode());
                }
            } else {
                // A candidate for an implicit bean archive with no beans.xml
                addToArchives(archives, processAnnotatedDiscovery(builder));
            }
        }
        for (WeldBeanDeploymentArchive archive : archives) {
            archive.getServices().add(ResourceLoader.class, resourceLoader);
        }
        afterDiscovery(archives);
        return archives;
    }

    @Override
    public ClassFileServices getClassFileServices() {
        // By default no bytecode scanning facility available
        return null;
    }

    protected void addToArchives(Set deploymentArchives, WeldBeanDeploymentArchive bda) {
        if (bda == null) {
            return;
        }
        if (bda.isEmpty()) {
            // Most probably an unsuccessful candidate for an implicit bean archive with no beans.xml
            CommonLogger.LOG.debugv("Empty bean deployment archive ignored: {0}", bda.getId());
            return;
        }
        deploymentArchives.add(bda);
    }

    /**
     * Initialize the strategy before accessing found BeanArchiveBuilder builders. Best used for saving some information before the process method for each
     * builder is called.
     */
    protected void beforeDiscovery(Collection builders) {
        // No-op
    }

    protected void afterDiscovery(Set archives) {
        // No-op
    }

    /**
     * Process the bean archive with bean-discovery-mode of none. The archive is ignored by default.
     */
    protected WeldBeanDeploymentArchive processNoneDiscovery(BeanArchiveBuilder builder) {
        return null;
    }

    /**
     * Process the bean archive with bean-discovery-mode of annotated.
     */
    protected WeldBeanDeploymentArchive processAnnotatedDiscovery(BeanArchiveBuilder builder) {
        throw new UnsupportedOperationException();
    }

    /**
     * Process the bean archive with bean-discovery-mode of all.
     */
    protected WeldBeanDeploymentArchive processAllDiscovery(BeanArchiveBuilder builder) {
        return builder.build();
    }

    @Override
    public void registerHandler(BeanArchiveHandler handler) {
        handlers.add(handler);
    }

    List initBeanArchiveHandlers() {
        List> entries = new ArrayList<>();

        // Add programatically added handlers
        for (ListIterator iterator = handlers.listIterator(); iterator.hasNext();) {
            entries.add(new SimpleEntry<>(handlers.size() - iterator.nextIndex(), iterator.next()));
        }

        // Load additional bean archive handlers - use Weld ServiceLoader so that we can use the given ResourceLoader
        for (Metadata meta : ServiceLoader.load(BeanArchiveHandler.class, resourceLoader)) {
            BeanArchiveHandler handler = meta.getValue();
            CommonLogger.LOG.debugv("Additional BeanArchiveHandler loaded: {0}", handler.getClass());
            entries.add(new SimpleEntry<>(getPriority(handler), handler));
        }

        Collections.sort(entries, new Comparator>() {
            @Override
            public int compare(SimpleEntry o1, SimpleEntry o2) {
                return Integer.compare(o2.getKey(), o1.getKey());
            }
        });

        List beanArchiveHandlers = new ArrayList<>(entries.size());
        for (SimpleEntry entry : entries) {
            beanArchiveHandlers.add(entry.getValue());
        }
        return beanArchiveHandlers;
    }

    private static int getPriority(BeanArchiveHandler handler) {
        Priority priority = handler.getClass().getAnnotation(Priority.class);
        if (priority != null) {
            return priority.value();
        }
        return 0;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy