org.jboss.weld.environment.deployment.discovery.AbstractDiscoveryStrategy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weld-servlet-shaded Show documentation
Show all versions of weld-servlet-shaded Show documentation
This jar bundles all the bits of Weld and CDI required for running in a Servlet container.
/*
* 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;
}
}