/*
* Copyright (C) 2015 Red Hat, Inc. and/or its affiliates.
*
* 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.errai.ioc.rebind.ioc.graph.impl;
import java.util.Arrays;
import java.util.Collection;
import javax.enterprise.inject.Alternative;
import org.jboss.errai.ioc.client.api.IOCProvider;
import org.jboss.errai.ioc.rebind.ioc.graph.api.DependencyGraphBuilder;
import org.jboss.errai.ioc.rebind.ioc.graph.api.DependencyGraphBuilder.InjectableType;
import org.jboss.errai.ioc.rebind.ioc.graph.api.Injectable;
import org.jboss.errai.ioc.rebind.ioc.injector.api.WiringElementType;
/**
* An enum with priority categories for resolved dependencies. The enum values
* are in descending order of priority.
*
* When the {@link DependencyGraphBuilder} resolves dependencies, injectables
* will be filtered by priority and only injectables in the highest non-empty
* priority will be considered.
*
* @see DependencyGraphBuilder#createGraph()
* @author Max Barkley <mbarkley@redhat.com>
*/
public enum ResolutionPriority {
/**
* Category for {@link Alternative} beans that have been enabled.
*/
EnabledAlternative {
@Override
public boolean matches(final Injectable injectable) {
return injectable.getWiringElementTypes().contains(WiringElementType.AlternativeBean)
&& !InjectableType.Disabled.equals(injectable.getInjectableType());
}
},
/**
* Category for {@link WindowScoped} {@link jsinterop.annotations.JsType} beans so that the local instance does not
* override the single global instance.
*/
WindowScopedJsType {
@Override
public boolean matches(final Injectable injectable) {
return injectable.getInjectableType().equals(InjectableType.JsType)
&& injectable.getWiringElementTypes().contains(WiringElementType.SharedSingleton);
}
},
/**
* Category for explicitly scoped concrete types, or producer methods.
*/
NormalType {
final Collection<InjectableType> matchingTypes = Arrays.<InjectableType> asList(InjectableType.Type,
InjectableType.Producer);
@Override
public boolean matches(final Injectable injectable) {
return matchingTypes.contains(injectable.getInjectableType())
&& !injectable.getWiringElementTypes().contains(WiringElementType.Simpleton);
}
},
/**
* Category for injectables that may or may not be satisfied by separately compiled GWT modules at runtime.
*/
JsType {
@Override
public boolean matches(final Injectable injectable) {
return InjectableType.JsType.equals(injectable.getInjectableType());
}
},
/**
* Category for types form {@link IOCProvider providers}.
*/
Provided {
private final Collection<InjectableType> providerTypes = Arrays.<InjectableType> asList(InjectableType.Provider,
InjectableType.ContextualProvider);
@Override
public boolean matches(final Injectable injectable) {
return providerTypes.contains(injectable.getInjectableType());
}
},
/**
* Category for injectables provided by
* {@link DependencyGraphBuilder#addExtensionInjectable(org.jboss.errai.codegen.meta.MetaClass, org.jboss.errai.ioc.rebind.ioc.graph.api.Qualifier, Class, WiringElementType...)
* extensions}.
*/
Extension {
private final Collection<InjectableType> extensionTypes = Arrays.asList(InjectableType.Extension, InjectableType.ExtensionProvided);
@Override
public boolean matches(final Injectable injectable) {
return extensionTypes.contains(injectable.getInjectableType());
}
},
/**
* Category for concrete types with no explicit scopes or injection points, and that are default constructible.
*/
Simpleton {
@Override
public boolean matches(final Injectable injectable) {
return injectable.getWiringElementTypes().contains(WiringElementType.Simpleton);
}
},
/**
* Category for disabled beans. These cannot satisfy dependencies, but are used for giving hints when errors occur.
*/
Disabled {
@Override
public boolean matches(final Injectable injectable) {
return InjectableType.Disabled.equals(injectable.getInjectableType());
}
};
public abstract boolean matches(final Injectable injectable);
public static ResolutionPriority getMatchingPriority(final Injectable injectable) {
for (final ResolutionPriority priority : values()) {
if (priority.matches(injectable)) {
return priority;
}
}
throw new RuntimeException("The injectable " + injectable + " does not match any resolution priority.");
}
public static Iterable<ResolutionPriority> enabledValues() {
return () -> Arrays.stream(values()).filter(p -> !Disabled.equals(p)).iterator();
}
}