| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.webbeans.inject.impl; |
| |
| import java.io.IOException; |
| import java.io.NotSerializableException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Member; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| import java.lang.reflect.Type; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import javax.decorator.Delegate; |
| import javax.enterprise.inject.spi.Annotated; |
| import javax.enterprise.inject.spi.AnnotatedConstructor; |
| 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.Bean; |
| import javax.enterprise.inject.spi.InjectionPoint; |
| |
| import org.apache.webbeans.config.WebBeansContext; |
| import org.apache.webbeans.container.BeanManagerImpl; |
| import org.apache.webbeans.event.EventUtil; |
| import org.apache.webbeans.portable.AnnotatedElementFactory; |
| import org.apache.webbeans.util.Asserts; |
| import org.apache.webbeans.util.OwbCustomObjectInputStream; |
| import org.apache.webbeans.util.WebBeansUtil; |
| |
| public class InjectionPointImpl implements InjectionPoint, Serializable |
| { |
| private static final long serialVersionUID = 1047233127758068484L; |
| |
| private Set<Annotation> qualifierAnnotations; |
| |
| private Bean<?> ownerBean; |
| |
| private Member injectionMember; |
| |
| private Type injectionType; |
| |
| private Annotated annotated; |
| |
| private boolean transientt; |
| |
| private boolean delegate; |
| |
| InjectionPointImpl(Bean<?> ownerBean, Collection<Annotation> qualifiers, AnnotatedField<?> annotatedField) |
| { |
| this(ownerBean, annotatedField.getBaseType(), qualifiers, annotatedField, |
| annotatedField.getJavaMember(), annotatedField.isAnnotationPresent(Delegate.class), |
| annotatedField.getJavaMember() == null? false : Modifier.isTransient(annotatedField.getJavaMember().getModifiers())); |
| } |
| |
| InjectionPointImpl(Bean<?> ownerBean, Collection<Annotation> qualifiers, AnnotatedParameter<?> parameter) |
| { |
| this(ownerBean, parameter.getBaseType(), qualifiers, parameter, parameter.getDeclaringCallable().getJavaMember(), parameter.isAnnotationPresent(Delegate.class), false); |
| } |
| |
| /** |
| * This constructor is used to create a 'virtual' InjectionPoint. |
| * This is needed if an InjectionPoint was needed during a programmatic lookup or 3rd party beans. |
| */ |
| InjectionPointImpl(Bean<?> bean) |
| { |
| Asserts.assertNotNull(bean, "bean"); |
| this.ownerBean = bean; |
| this.injectionType = bean.getBeanClass(); |
| this.qualifierAnnotations = bean.getQualifiers() == null ? |
| Collections.<Annotation>emptySet() : |
| Collections.unmodifiableSet(new HashSet<>(bean.getQualifiers())); |
| this.annotated = null; |
| this.injectionMember = null; |
| this.delegate = false; |
| this.transientt = false; |
| } |
| |
| public InjectionPointImpl(Bean<?> ownerBean, Type type, Collection<Annotation> qualifiers, Annotated annotated, Member member, boolean delegate, boolean isTransient) |
| { |
| if (type == null) |
| { |
| throw new IllegalArgumentException("type is null"); |
| } |
| if (member == null) |
| { |
| throw new IllegalArgumentException("member is null"); |
| } |
| Asserts.assertNotNull(qualifiers, "qualifiers"); |
| this.ownerBean = ownerBean; |
| injectionType = type; |
| qualifierAnnotations = Collections.unmodifiableSet(new HashSet<>(qualifiers)); |
| this.annotated = annotated; |
| injectionMember = member; |
| this.delegate = delegate; |
| transientt = isTransient; |
| if(!WebBeansUtil.checkObtainsInjectionPointConditions(this)) |
| { |
| EventUtil.checkObservableInjectionPointConditions(this); |
| } |
| } |
| |
| @Override |
| public Bean<?> getBean() |
| { |
| return ownerBean; |
| } |
| |
| @Override |
| public Set<Annotation> getQualifiers() |
| { |
| |
| return qualifierAnnotations; |
| } |
| |
| @Override |
| public Member getMember() |
| { |
| return injectionMember; |
| } |
| |
| @Override |
| public Type getType() |
| { |
| |
| return injectionType; |
| } |
| |
| |
| @Override |
| public Annotated getAnnotated() |
| { |
| return annotated; |
| } |
| |
| @Override |
| public boolean isDelegate() |
| { |
| return delegate; |
| } |
| |
| @Override |
| public boolean isTransient() |
| { |
| return transientt; |
| } |
| |
| private void writeObject(java.io.ObjectOutputStream op) throws IOException |
| { |
| ObjectOutputStream out = new ObjectOutputStream(op); |
| |
| |
| if (ownerBean != null) |
| { |
| //Write the owning bean class |
| out.writeObject(ownerBean.getBeanClass()); |
| |
| // and it's Qualifiers |
| Set<Annotation> qualifiers = ownerBean.getQualifiers(); |
| writeQualifiers(out, qualifiers); |
| } |
| else |
| { |
| if (annotated instanceof AnnotatedMember) |
| { |
| Class<?> beanClass = ((AnnotatedMember) annotated).getDeclaringType().getJavaClass(); |
| out.writeObject(beanClass); |
| out.writeObject('~'); |
| } |
| else |
| { |
| throw new NotSerializableException("Cannot detect bean class of InjetionPoint"); |
| } |
| } |
| |
| |
| if(injectionMember instanceof Field) |
| { |
| out.writeByte(0); |
| out.writeUTF(injectionMember.getName()); |
| writeQualifiers(out, qualifierAnnotations); |
| } |
| |
| if(injectionMember instanceof Method) |
| { |
| out.writeByte(1); |
| out.writeUTF(injectionMember.getName()); |
| Method method = (Method) injectionMember; |
| Class<?>[] parameters = method.getParameterTypes(); |
| out.writeObject(parameters); |
| |
| AnnotatedParameter<?> ap = (AnnotatedParameter<?>) annotated; |
| out.writeByte(ap.getPosition()); |
| } |
| |
| if(injectionMember instanceof Constructor) |
| { |
| out.writeByte(2); |
| Constructor<?> constr = (Constructor<?>) injectionMember; |
| Class<?>[] parameters = constr.getParameterTypes(); |
| out.writeObject(parameters); |
| |
| AnnotatedParameter<?> ap = (AnnotatedParameter<?>) annotated; |
| out.writeByte(ap.getPosition()); |
| } |
| |
| out.writeBoolean(delegate); |
| out.writeBoolean(transientt); |
| out.flush(); |
| |
| } |
| |
| @SuppressWarnings("unchecked") |
| private void readObject(java.io.ObjectInputStream inp) throws IOException, ClassNotFoundException |
| { |
| |
| ObjectInputStream in = new OwbCustomObjectInputStream(inp, WebBeansUtil.getCurrentClassLoader()); |
| |
| Class<?> ownerBeanClass = (Class<?>)in.readObject(); |
| Set<Annotation> ownerQualifiers = readQualifiers(in); |
| |
| WebBeansContext webBeansContext = WebBeansContext.currentInstance(); |
| AnnotatedElementFactory annotatedElementFactory = webBeansContext.getAnnotatedElementFactory(); |
| |
| //process annotations |
| BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl(); |
| Set<Bean<?>> beans = beanManager.getBeans(ownerBeanClass, |
| ownerQualifiers.toArray(new Annotation[ownerQualifiers.size()])); |
| ownerBean = beanManager.resolve(beans); |
| |
| // determine type of injection point member (0=field, 1=method, 2=constructor) and read... |
| int c = in.readByte(); |
| if(c == 0) |
| { |
| String fieldName = in.readUTF(); |
| Field field = webBeansContext.getSecurityService().doPrivilegedGetDeclaredField(ownerBeanClass, fieldName); |
| |
| injectionMember = field; |
| |
| AnnotatedType<?> annotatedType = annotatedElementFactory.newAnnotatedType(ownerBeanClass); |
| annotated = annotatedElementFactory.newAnnotatedField(field, annotatedType); |
| injectionType = field.getGenericType(); |
| |
| qualifierAnnotations = readQualifiers(in); |
| } |
| else if(c == 1) |
| { |
| String methodName = in.readUTF(); |
| Class<?>[] parameters = (Class<?>[])in.readObject(); |
| |
| Method method = webBeansContext.getSecurityService().doPrivilegedGetDeclaredMethod(ownerBeanClass, methodName, parameters); |
| injectionMember = method; |
| |
| AnnotatedType<?> annotatedType = annotatedElementFactory.newAnnotatedType(ownerBeanClass); |
| AnnotatedMethod<Object> am = (AnnotatedMethod<Object>)annotatedElementFactory. |
| newAnnotatedMethod((Method) injectionMember,annotatedType); |
| List<AnnotatedParameter<Object>> annParameters = am.getParameters(); |
| |
| annotated = annParameters.get(in.readByte()); |
| injectionType = annotated.getBaseType(); |
| } |
| else if(c == 2) |
| { |
| Class<?>[] parameters = (Class<?>[])in.readObject(); |
| try |
| { |
| injectionMember = ownerBeanClass.getConstructor(parameters); |
| |
| } |
| catch(NoSuchMethodException e) |
| { |
| injectionMember = null; |
| } |
| |
| AnnotatedType<Object> annotatedType = (AnnotatedType<Object>)annotatedElementFactory.newAnnotatedType(ownerBeanClass); |
| AnnotatedConstructor<Object> am = annotatedElementFactory |
| .newAnnotatedConstructor((Constructor<Object>) injectionMember,annotatedType); |
| List<AnnotatedParameter<Object>> annParameters = am.getParameters(); |
| |
| annotated = annParameters.get(in.readByte()); |
| injectionType = annotated.getBaseType(); |
| } |
| |
| delegate = in.readBoolean(); |
| transientt = in.readBoolean(); |
| } |
| |
| private void writeQualifiers(ObjectOutputStream out, Set<Annotation> qualifiers) throws IOException |
| { |
| for (Annotation qualifier : qualifiers) |
| { |
| out.writeObject('-'); // throw-away delimiter so alternating annotations don't get swallowed in the read. |
| out.writeObject(qualifier); |
| } |
| |
| // terminate character |
| out.writeObject('~'); |
| } |
| |
| private Set<Annotation> readQualifiers(ObjectInputStream in) throws IOException, ClassNotFoundException |
| { |
| Set<Annotation> qualifiers = new HashSet<>(); |
| while(!in.readObject().equals('~')) // read throw-away '-' or '~' terminal delimiter. |
| { |
| Annotation ann = (Annotation) in.readObject(); // now read the annotation. |
| qualifiers.add(ann); |
| } |
| return qualifiers; |
| } |
| |
| public String toString() |
| { |
| StringBuilder buffer = new StringBuilder(); |
| if(injectionMember instanceof Constructor) |
| { |
| Constructor<?> constructor = (Constructor<?>) injectionMember; |
| buffer.append("Constructor Injection Point, constructor name : ").append(constructor.getName()).append(", Bean Owner : [").append(ownerBean).append("]"); |
| } |
| else if(injectionMember instanceof Method) |
| { |
| Method method = (Method) injectionMember; |
| buffer.append("Method Injection Point, method name : ").append(method.getName()).append(", Bean Owner : [").append(ownerBean).append("]"); |
| } |
| else if(injectionMember instanceof Field) |
| { |
| Field field = (Field) injectionMember; |
| buffer.append("Field Injection Point, field name : ").append(field.getName()).append(", Bean Owner : [").append(ownerBean).append("]"); |
| } |
| |
| return buffer.toString(); |
| } |
| } |