blob: cf78a5cb10b97769aeb4e431889aa4cc0e6aa194 [file] [log] [blame]
/**
* 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.apache.aries.cdi.container.internal.util;
import java.lang.reflect.Executable;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMember;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.ProcessBean;
import javax.enterprise.inject.spi.ProcessManagedBean;
import javax.enterprise.inject.spi.ProcessProducerField;
import javax.enterprise.inject.spi.ProcessProducerMethod;
import javax.enterprise.inject.spi.ProcessSessionBean;
import javax.enterprise.inject.spi.ProcessSyntheticBean;
import org.jboss.weld.util.Types;
import org.osgi.service.cdi.ServiceScope;
import org.osgi.service.cdi.annotations.Service;
import org.osgi.service.cdi.annotations.ServiceInstance;
public class Annotates {
private Annotates() {
// no instances
}
public static Map<String, Object> componentProperties(Annotated annotated) {
return Maps.merge(annotated.getAnnotations());
}
@SuppressWarnings("unchecked")
public static <X> Class<X> declaringClass(Object instance) {
Class<?> declaringClass = null;
if (instance instanceof AnnotatedMember) {
AnnotatedMember<?> af = (AnnotatedMember<?>)instance;
declaringClass = af.getDeclaringType().getJavaClass();
}
else if (instance instanceof AnnotatedParameter) {
AnnotatedParameter<?> ap = (AnnotatedParameter<?>)instance;
Parameter javaParameter = ap.getJavaParameter();
Executable executable = javaParameter.getDeclaringExecutable();
declaringClass = executable.getDeclaringClass();
}
else if (instance instanceof AnnotatedType) {
AnnotatedType<?> annotatedType = (AnnotatedType<?>)instance;
declaringClass = annotatedType.getJavaClass();
}
else if (instance instanceof Annotated) {
Annotated annotated = (Annotated)instance;
declaringClass = Types.getRawTypes(new Type[] {annotated.getBaseType()})[0];
}
else if (instance instanceof ProcessManagedBean) {
ProcessManagedBean<?> bean = (ProcessManagedBean<?>)instance;
declaringClass = bean.getAnnotatedBeanClass().getJavaClass();
}
else if (instance instanceof ProcessSessionBean) {
ProcessSessionBean<?> bean = (ProcessSessionBean<?>)instance;
declaringClass = bean.getAnnotatedBeanClass().getJavaClass();
}
else if (instance instanceof ProcessProducerMethod) {
ProcessProducerMethod<?, ?> producer = (ProcessProducerMethod<?, ?>)instance;
declaringClass = producer.getAnnotatedProducerMethod().getDeclaringType().getJavaClass();
}
else if (instance instanceof ProcessProducerField) {
ProcessProducerField<?, ?> producer = (ProcessProducerField<?, ?>)instance;
declaringClass = producer.getAnnotatedProducerField().getDeclaringType().getJavaClass();
}
else if (instance instanceof ProcessSyntheticBean) {
ProcessSyntheticBean<?> synthetic = (ProcessSyntheticBean<?>)instance;
declaringClass = synthetic.getBean().getBeanClass();
}
else if (instance instanceof ProcessBean) {
ProcessBean<?> processBean = (ProcessBean<?>)instance;
declaringClass = processBean.getBean().getBeanClass();
}
return (Class<X>)declaringClass;
}
public static List<Class<?>> serviceClasses(Annotated annotated) {
List<Class<?>> serviceTypes = new ArrayList<>();
List<java.lang.reflect.AnnotatedType> ats = new ArrayList<>();
if (annotated instanceof AnnotatedType) {
Class<?> annotatedClass = ((AnnotatedType<?>)annotated).getJavaClass();
Optional.ofNullable(annotatedClass.getAnnotatedSuperclass()).ifPresent(at -> ats.add(at));
ats.addAll(Arrays.asList(annotatedClass.getAnnotatedInterfaces()));
for (java.lang.reflect.AnnotatedType at : ats) {
Optional.ofNullable(at.getAnnotation(Service.class)).ifPresent(
service -> {
if (service.value().length > 0) {
throw new IllegalArgumentException(
String.format(
"@Service on type_use must not specify a value: %s",
annotatedClass));
}
Type type = at.getType();
if (!(type instanceof Class)) {
throw new IllegalArgumentException(
String.format(
"@Service on type_use must only be specified on non-generic types: %s",
annotatedClass));
}
serviceTypes.add((Class<?>)type);
}
);
}
Service service = annotated.getAnnotation(Service.class);
if (service == null) {
return serviceTypes;
}
if (!serviceTypes.isEmpty()) {
throw new IllegalArgumentException(
String.format(
"@Service must not be applied to type and type_use: %s",
annotated));
}
if (service.value().length > 0) {
serviceTypes.addAll(Arrays.asList(service.value()));
}
else if (annotatedClass.getInterfaces().length > 0) {
serviceTypes.addAll(Arrays.asList(annotatedClass.getInterfaces()));
}
else {
serviceTypes.add(annotatedClass);
}
}
else if (annotated instanceof AnnotatedMethod) {
Service service = annotated.getAnnotation(Service.class);
if (service == null) {
return serviceTypes;
}
Class<?> returnType = ((AnnotatedMethod<?>)annotated).getJavaMember().getReturnType();
if (service.value().length > 0) {
serviceTypes.addAll(Arrays.asList(service.value()));
}
else if (returnType.getInterfaces().length > 0) {
serviceTypes.addAll(Arrays.asList(returnType.getInterfaces()));
}
else {
serviceTypes.add(returnType);
}
}
else if (annotated instanceof AnnotatedField) {
Service service = annotated.getAnnotation(Service.class);
if (service == null) {
return serviceTypes;
}
Class<?> fieldType = ((AnnotatedField<?>)annotated).getJavaMember().getType();
if (service.value().length > 0) {
serviceTypes.addAll(Arrays.asList(service.value()));
}
else if (fieldType.getInterfaces().length > 0) {
serviceTypes.addAll(Arrays.asList(fieldType.getInterfaces()));
}
else {
serviceTypes.add(fieldType);
}
}
return serviceTypes;
}
public static List<String> serviceClassNames(Annotated annotated) {
return serviceClasses(annotated).stream().map(
st -> st.getName()
).sorted().collect(Collectors.toList());
}
public static ServiceScope serviceScope(Annotated annotated) {
ServiceInstance serviceInstance = annotated.getAnnotation(ServiceInstance.class);
if (serviceInstance != null) {
return serviceInstance.value();
}
return ServiceScope.SINGLETON;
}
}