You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by ge...@apache.org on 2008/12/21 23:40:57 UTC

svn commit: r728541 [2/2] - in /incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: component/ component/xml/ config/ container/ decorator/ decorator/xml/ deployment/ deployment/stereotype/ event/ event/xml/ inject/xml/ interc...

Modified: incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLAnnotationTypeManager.java
URL: http://svn.apache.org/viewvc/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLAnnotationTypeManager.java?rev=728541&r1=728540&r2=728541&view=diff
==============================================================================
--- incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLAnnotationTypeManager.java (original)
+++ incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLAnnotationTypeManager.java Sun Dec 21 14:40:56 2008
@@ -36,7 +36,7 @@
 	
 	private Set<Class<? extends Annotation>> xmlBindingTypes = new CopyOnWriteArraySet<Class<? extends Annotation>>();
 	
-	private Map<Class<? extends Annotation>, Set<Class<? extends Annotation>>> xmlInterceptorBindingTypes = new ConcurrentHashMap<Class<? extends Annotation>, Set<Class<? extends Annotation>>>();
+	private Map<Class<? extends Annotation>, Set<Annotation>> xmlInterceptorBindingTypes = new ConcurrentHashMap<Class<? extends Annotation>, Set<Annotation>>();
 	
 	private Set<Class<? extends Annotation>> xmlStereoTypes = new CopyOnWriteArraySet<Class<? extends Annotation>>();
 	
@@ -70,9 +70,9 @@
 		return false;
 	}
 	
-	public void addStereoType(Class<? extends Annotation> bindingType, Element decleration, String name, String errorMessage)
+	public void addStereoType(Class<? extends Annotation> stereoType, Element decleration, String name, String errorMessage)
 	{
-		WebBeansUtil.checkStereoTypeClass(bindingType);
+		WebBeansUtil.checkStereoTypeClass(stereoType);
 		
 		StereoTypeManager manager = StereoTypeManager.getInstance();
 		
@@ -80,12 +80,12 @@
 		manager.addStereoTypeModel(model);
 		
 		
-		xmlStereoTypes.add(bindingType);
+		xmlStereoTypes.add(stereoType);
 	}
 	
-	public boolean isStereoTypeExist(Class<? extends Annotation> bindingType)
+	public boolean isStereoTypeExist(Class<? extends Annotation> stereoType)
 	{
-		if(xmlStereoTypes.contains(bindingType))
+		if(xmlStereoTypes.contains(stereoType))
 		{
 			return true;
 		}
@@ -93,12 +93,12 @@
 		return false;
 	}
 
-	public void addInterceotorBindingTypeInheritAnnotation(Class<? extends Annotation> bindingType, Class<? extends Annotation> inherit)
+	public void addInterceotorBindingTypeInheritAnnotation(Class<? extends Annotation> bindingType, Annotation inherit)
 	{
-		Set<Class<? extends Annotation>> inherits =  xmlInterceptorBindingTypes.get(bindingType);
+		Set<Annotation> inherits =  xmlInterceptorBindingTypes.get(bindingType);
 		if(inherits == null)
 		{
-			inherits = new HashSet<Class<? extends Annotation>>();
+			inherits = new HashSet<Annotation>();
 			inherits.add(inherit);
 			xmlInterceptorBindingTypes.put(bindingType, inherits);
 		}
@@ -123,7 +123,7 @@
 		return Collections.unmodifiableSet(xmlBindingTypes);
 	}
 	
-	public Set<Class<? extends Annotation>> getInterceptorBindingTypeInherites(Class<? extends Annotation> interceptorBindingType)
+	public Set<Annotation> getInterceptorBindingTypeInherites(Class<? extends Annotation> interceptorBindingType)
 	{
 		return Collections.unmodifiableSet(xmlInterceptorBindingTypes.get(interceptorBindingType));
 	}

Modified: incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLDefinitionUtil.java
URL: http://svn.apache.org/viewvc/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLDefinitionUtil.java?rev=728541&r1=728540&r2=728541&view=diff
==============================================================================
--- incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLDefinitionUtil.java (original)
+++ incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLDefinitionUtil.java Sun Dec 21 14:40:56 2008
@@ -17,25 +17,44 @@
 package org.apache.webbeans.xml;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.interceptor.AroundInvoke;
 import javax.webbeans.Decorator;
 import javax.webbeans.DeploymentType;
-import javax.webbeans.Interceptor;
 import javax.webbeans.Named;
+import javax.webbeans.NonBinding;
+import javax.webbeans.NonexistentFieldException;
 import javax.webbeans.NonexistentTypeException;
 import javax.webbeans.ScopeType;
 import javax.webbeans.Specializes;
+import javax.webbeans.UnsatisfiedDependencyException;
+import javax.webbeans.manager.Bean;
+import javax.webbeans.manager.Interceptor;
 
 import org.apache.webbeans.WebBeansConstants;
+import org.apache.webbeans.component.AbstractComponent;
 import org.apache.webbeans.component.xml.XMLComponentImpl;
 import org.apache.webbeans.component.xml.XMLProducerComponentImpl;
-import org.apache.webbeans.deployment.StereoTypeManager;
-import org.apache.webbeans.deployment.StereoTypeModel;
+import org.apache.webbeans.container.InjectionResolver;
+import org.apache.webbeans.decorator.WebBeansDecoratorConfig;
+import org.apache.webbeans.event.NotificationManager;
+import org.apache.webbeans.event.TransactionalObserverType;
+import org.apache.webbeans.event.xml.BeanObserverXMLImpl;
 import org.apache.webbeans.exception.WebBeansConfigurationException;
+import org.apache.webbeans.inject.xml.XMLInjectionPointModel;
+import org.apache.webbeans.intercept.InterceptorData;
+import org.apache.webbeans.intercept.InterceptorUtil;
+import org.apache.webbeans.intercept.WebBeansInterceptorConfig;
+import org.apache.webbeans.intercept.webbeans.WebBeansInterceptor;
 import org.apache.webbeans.proxy.JavassistProxyFactory;
 import org.apache.webbeans.util.AnnotationUtil;
 import org.apache.webbeans.util.Asserts;
@@ -79,7 +98,7 @@
 			throw new WebBeansConfigurationException(errorMessage + "Simple WebBeans component implementation class : " + clazz.getName() + " can not be non-static inner class");	
 		}				
 		
-		if(clazz.isAnnotationPresent(Interceptor.class))
+		if(clazz.isAnnotationPresent(javax.webbeans.Interceptor.class))
 		{
 			boolean found = XMLUtil.isElementChildExistWithWebBeansNameSpace(webBeanDecleration, WebBeansConstants.WEB_BEANS_XML_INTERCEPTOR_ELEMENT);
 			if(!found)
@@ -100,7 +119,7 @@
 	}
 	
 	
-	public static void checkTypeMetaDataClasses(Set<Class<? extends Annotation>> typeSet, String errorMessage)
+	public static void checkTypeMetaDataClasses(List<Class<? extends Annotation>> typeSet, String errorMessage)
 	{
 		if(typeSet != null && !typeSet.isEmpty())
 		{
@@ -115,7 +134,7 @@
 						AnnotationUtil.isStereoTypeAnnotation(clazz) ||
 						clazz.equals(Named.class) ||
 						clazz.equals(Specializes.class) ||
-						clazz.equals(Interceptor.class) ||
+						clazz.equals(javax.webbeans.Interceptor.class) ||
 						clazz.equals(Decorator.class))
 				{
 					continue;
@@ -129,8 +148,20 @@
 		
 	}
 
-	public static <T> Class<? extends Annotation> defineXMLTypeMetaData(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet, Class<? extends Annotation> defineType, String errorMessage)
+	/**
+	 * Gets applicable annotation class for given defineType 
+	 * parameter from the given annotation set.
+	 * 
+	 * @param component webbeans component
+	 * @param annotationSet type-level metadata annotation set
+	 * @param defineType annotation type class
+	 * @param errorMessage error message for the operation
+	 * 
+	 * @return applicable annotation class for given defineType parameter from the given set
+	 */
+	public static <T> Class<? extends Annotation> defineXMLTypeMetaData(AbstractComponent<T> component, List<Class<? extends Annotation>> annotationSet, Class<? extends Annotation> defineType, String errorMessage)
 	{
+		//Found annotation for given defineType parameter
 		Class<? extends Annotation> metaType = null;
 		
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
@@ -155,72 +186,140 @@
 		return metaType;
 	}
 	
-	public static <T> boolean defineXMLBindingType(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet)
+	public static <T> boolean defineXMLBindingType(XMLComponentImpl<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList, String errorMessage)
 	{
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
 		boolean found = false;
+		int i = 0;
 		while(it.hasNext())
 		{
 			Class<? extends Annotation> temp = it.next();
 			if(AnnotationUtil.isBindingAnnotation(temp))
 			{
+				Method[] methods =temp.getDeclaredMethods();
+				
+				for(Method method : methods)
+				{
+					Class<?> clazz = method.getReturnType();
+					if(clazz.isArray() || clazz.isAnnotation())
+					{
+						if(!AnnotationUtil.isAnnotationExist(method.getAnnotations(), NonBinding.class))
+						{
+							throw new WebBeansConfigurationException(errorMessage + "WebBeans definition class : " + component.getReturnType().getName() + 
+									" @BindingType : " + temp.getName() + " must have @NonBinding valued members for its array-valued and annotation valued members");
+						}
+					}					
+				}			
+				
 				if(!found)
 				{
 					found = true;
 				}
 				
-				component.addBindingType(JavassistProxyFactory.createNewAnnotationProxy(temp));
+				i++;
+				
+				component.addBindingType(XMLUtil.getXMLDefinedAnnotationMember(annotationElementList.get(i), temp, errorMessage));
 			}
 		}
 		
 		return found;
 	}
 	
-	public static <T> boolean defineXMLInterceptorType(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet)
+	public static <T> void defineXMLClassLevelInterceptorType(XMLComponentImpl<T> component, List<Class<? extends Annotation>> annotationSet,  List<Element> annotationElementList, String errorMessage)
 	{
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
-		boolean found = false;
+		
+		Set<Annotation> bindingTypeSet = new HashSet<Annotation>();
+		int i = 0;
 		while(it.hasNext())
 		{
 			Class<? extends Annotation> temp = it.next();
 			if(AnnotationUtil.isInterceptorBindingAnnotation(temp))
 			{
-				if(!found)
+				bindingTypeSet.add(XMLUtil.getXMLDefinedAnnotationMember(annotationElementList.get(i), temp, errorMessage));
+			}
+			
+			i++;
+		}
+		
+		Set<Annotation> stereoTypesSet = component.getStereoTypes();
+		Annotation[] stereoTypes = new Annotation[stereoTypesSet.size()];
+		stereoTypes = stereoTypesSet.toArray(stereoTypes);
+		for(Annotation stero : stereoTypes)
+		{
+			if(AnnotationUtil.isInterceptorBindingMetaAnnotationExist(stero.annotationType().getDeclaredAnnotations()))
+			{
+				Annotation[] steroInterceptorBindings = AnnotationUtil.getInterceptorBindingMetaAnnotations(stero.annotationType().getDeclaredAnnotations());
+				
+				for(Annotation ann : steroInterceptorBindings)
 				{
-					found = true;
+					bindingTypeSet.add(ann);
 				}
-				
-				//component.add(temp);
 			}
 		}
 		
-		return found;
+		Annotation[] anns = new Annotation[bindingTypeSet.size()];
+		anns = bindingTypeSet.toArray(anns);
+		
+		Set<Interceptor> set = WebBeansInterceptorConfig.findDeployedWebBeansInterceptor(anns);
+		
+		WebBeansInterceptorConfig.addComponentInterceptors(set, component.getInterceptorStack());
+		
+	}
+	
+	public static <T> void defineXMLMethodLevelInterceptorType(XMLComponentImpl<T> component, Method interceptorMethod, Element interceptorMethodElement, String errorMessage)
+	{
+		List<Element> bindingTypes = interceptorMethodElement.elements();
+		Set<Annotation> bindingTypesSet = new HashSet<Annotation>();
+		for(Element bindingType : bindingTypes)
+		{
+			Class<? extends Annotation> annot = (Class<? extends Annotation>) XMLUtil.getElementJavaType(bindingType);
+			Annotation bindingAnnot = XMLUtil.getXMLDefinedAnnotationMember(bindingType, annot, errorMessage);
+			
+			bindingTypesSet.add(bindingAnnot);
+		}
+		
+		Annotation[] result = new Annotation[bindingTypesSet.size()];
+		result = bindingTypesSet.toArray(result);
+
+		Set<Interceptor> setInterceptors = WebBeansInterceptorConfig.findDeployedWebBeansInterceptor(result);
+		Iterator<Interceptor> it = setInterceptors.iterator();
+
+		List<InterceptorData> stack = component.getInterceptorStack();
+		while (it.hasNext())
+		{
+			WebBeansInterceptor interceptor = (WebBeansInterceptor) it.next();
+
+			WebBeansUtil.configureInterceptorMethods(interceptor,interceptor.getClazz(), AroundInvoke.class, false, true, stack, interceptorMethod, true);
+			WebBeansUtil.configureInterceptorMethods(interceptor,interceptor.getClazz(), PostConstruct.class, false, true, stack, interceptorMethod, true);
+			WebBeansUtil.configureInterceptorMethods(interceptor,interceptor.getClazz(), PreDestroy.class, false, true, stack, interceptorMethod, true);
+		}
+		
 	}
+		
+		
 	
-	public static <T> boolean defineXMLStereoType(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet)
+	
+	/**
+	 * Configures the webbeans component stereotype. 
+	 * 
+	 * @param component webbeans component
+	 * @param annotationSet set of type-level metadata annotation set
+	 */
+	public static <T> void defineXMLStereoType(AbstractComponent<T> component, List<Class<? extends Annotation>> annotationSet)
 	{
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
-		boolean found = false;
 		while(it.hasNext())
 		{
 			Class<? extends Annotation> temp = it.next();
 			if(AnnotationUtil.isStereoTypeAnnotation(temp))
 			{
-				if(!found)
-				{
-					found = true;
-				}
-				
-				//Add new stereotype model
-				StereoTypeManager.getInstance().addStereoTypeModel(new StereoTypeModel(temp));
-				//component.addXMLStereoType(temp);
+				component.addStereoType(JavassistProxyFactory.createNewAnnotationProxy(temp));
 			}
 		}
-		
-		return found;
 	}
 	
-	public static <T> boolean defineXMLName(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet)
+	public static <T> boolean defineXMLName(AbstractComponent<T> component, List<Class<? extends Annotation>> annotationSet)
 	{
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
 		while(it.hasNext())
@@ -235,7 +334,7 @@
 		return false;
 	}
 	
-	public static <T> void defineXMLSpecializes(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet)
+	public static <T> void defineXMLSpecializes(XMLComponentImpl<T> component, List<Class<? extends Annotation>> annotationSet)
 	{
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
 		while(it.hasNext())
@@ -248,29 +347,50 @@
 		}
 	}
 	
-	public static <T> void defineXMLInterceptors(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet, String errorMessage)
+	public static <T> void defineXMLInterceptors(XMLComponentImpl<T> component, List<Class<? extends Annotation>> annotationSet,List<Element> annotationElementList,  String errorMessage)
 	{
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
 		boolean found = false;
+		
+		Set<Annotation> interceptorBindingTypes = new HashSet<Annotation>();
+		int i = 0;
 		while(it.hasNext())
 		{
 			Class<? extends Annotation> temp = it.next();
-			if(temp.equals(Interceptor.class))
+			if(temp.equals(javax.webbeans.Interceptor.class))
 			{
 				if(found)
 				{
-					throw new WebBeansConfigurationException(errorMessage);
+					throw new WebBeansConfigurationException(errorMessage + "More than one <Interceptor> element exist for class : " + component.getReturnType().getName());
 				}
 				else
 				{
 					found = true;
-					WebBeansUtil.defineSimpleWebBeansInterceptors(temp);
 				}
 			}
+			else if(AnnotationUtil.isInterceptorBindingAnnotation(temp))
+			{
+				Element annotationElement = annotationElementList.get(i);
+				Annotation bindingAnnotation = XMLUtil.getXMLDefinedAnnotationMember(annotationElement, temp, errorMessage);
+				interceptorBindingTypes.add(bindingAnnotation);
+			}
+			
+			i++;
 		}
+		
+		if(interceptorBindingTypes.size() == 0)
+		{
+			throw new WebBeansConfigurationException(errorMessage + "<Interceptor> decleration must have one interceptor binding type for class : " + component.getReturnType().getName());
+		}
+		
+		Annotation[] anns = new Annotation[interceptorBindingTypes.size()];
+		anns = interceptorBindingTypes.toArray(anns);
+		InterceptorUtil.checkLifecycleConditions(component.getReturnType(), anns, errorMessage+"Lifecycle interceptor : " + component.getReturnType().getName()+ " interceptor binding type must be defined as @Target{TYPE}");
+		
+		WebBeansInterceptorConfig.configureInterceptorClass((XMLComponentImpl<Object>)component, anns);
 	}
 	
-	public static <T> void defineXMLDecorators(XMLComponentImpl<T> component, Set<Class<? extends Annotation>> annotationSet, String errorMessage)
+	public static <T> void defineXMLDecorators(XMLComponentImpl<T> component, List<Class<? extends Annotation>> annotationSet, Element decoratorDecleration, String errorMessage)
 	{
 		Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
 		boolean found = false;
@@ -281,21 +401,73 @@
 			{
 				if(found)
 				{
-					throw new WebBeansConfigurationException(errorMessage);
+					throw new WebBeansConfigurationException(errorMessage+"More than one <Decorator> element exist");
 				}
 				else
 				{
 					found = true;
-					WebBeansUtil.defineSimpleWebBeansDecorators(temp);
+				}
+			}
+		}
+		
+		if(found)
+		{
+			List<Element> childs = decoratorDecleration.elements();
+			for(Element child : childs)
+			{
+				if (XMLUtil.getElementNameSpace(child).equals(XMLUtil.getElementNameSpace(decoratorDecleration)) && XMLUtil.isElementHasDecoratesChild(child))
+				{
+					 Field field = ClassUtil.getFieldWithName(component.getReturnType(), child.getName());
+					 if(field == null)
+					 {
+						 throw new NonexistentFieldException(errorMessage + "Field with name : " + child.getName() + " not found in the decorator class : " + component.getReturnType().getName());
+					 }
+					 
+					 Element decorates = child.element(WebBeansConstants.WEB_BEANS_XML_DECORATES_ELEMENT);
+					 Element type = (Element)decorates.elements().get(0);
+					 
+					 Class<?> apType = XMLUtil.getElementJavaType(type);
+					 
+					 if(!field.getType().isAssignableFrom(apType))
+					 {
+						 throw new WebBeansConfigurationException(errorMessage + "Field name : " + field.getName() + " xml defined class type must be assignable to the field actual class type");
+					 }
+					 
+					 XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(type, errorMessage);
+					 
+					 WebBeansDecoratorConfig.configureXMLDecoratorClass((AbstractComponent<Object>)component,model);
+				}
+				else
+				{
+					throw new WebBeansConfigurationException(errorMessage+ "Delegate decleration must defined exactly one child element with name Decorates");
 				}
 			}
 		}
 	}
 	
+	/**
+	 * Returns newly created and configures xml webbeans producer component.
+	 *  
+	 * @param component webbeans component that defines producer method
+	 * @param producesMethod producer method
+	 * @param producerMethodElement produce method xml element
+	 * @param errorMessage error message
+	 * 
+	 * @return newly created and configures xml webbeans producer component.
+	 * 
+	 * @see XMLProducerComponentImpl
+	 */
 	public static <T> XMLProducerComponentImpl<T> defineXMLProducerMethod(XMLComponentImpl<T> component, Method producesMethod, Element producerMethodElement, String errorMessage)
 	{
-		List<Element> childElements = producerMethodElement.elements();
 		boolean producesDefined = false;
+		List<Element> childElements = producerMethodElement.elements();
+		Class<T> type = null;
+		Element typeElement = null;
+		Element arrayElement = null;
+		List<Class<? extends Annotation>> memberLevelMetaData = new ArrayList<Class<? extends Annotation>>();
+		List<Element> memberLevelElement = new ArrayList<Element>();
+		List<XMLInjectionPointModel> injectedParameters = new ArrayList<XMLInjectionPointModel>();
+		
 		for(Element childElement : childElements)
 		{
 			if(XMLUtil.isElementInWebBeansNameSpaceWithName(childElement, WebBeansConstants.WEB_BEANS_XML_PRODUCES_ELEMENT))
@@ -311,33 +483,45 @@
 				
 				List<Element> producesElementChilds = childElement.elements();
 				boolean definedType = false;
+								
 				for(Element producesElementChild : producesElementChilds)
-				{
-					Class<?> type = XMLUtil.getElementJavaType(producesElementChild);
-					if(type == null)
-					{
-						throw new NonexistentTypeException(errorMessage + "Java type : " + XMLUtil.getElementJavaClassName(producesElementChild) + " does not exist in the <Produces> element child");
-					}
-					else if(type.isArray() || type.isEnum())
+				{	
+					if(producesElementChild.getName().equals(WebBeansConstants.WEB_BEANS_XML_ARRAY_ELEMENT))
 					{
-						throw new WebBeansConfigurationException(errorMessage + "Java type must be class, interface or annotation type in the <Produces> childs");
-					}
-					else if(type.isAnnotation())
-					{
-						//Class<? extends Annotation> annotationType = (Class<? extends Annotation>)type;
-						
-						
+						arrayElement = producesElementChild;
+						definedType = true;
 					}
 					else
 					{
-						if(definedType)
+						type = (Class<T>)XMLUtil.getElementJavaType(producesElementChild); 
+						if(type == null)
 						{
-							throw new WebBeansConfigurationException(errorMessage + "More than one Java type in the <Produces> element");
+							throw new NonexistentTypeException(errorMessage + "Java type : " + XMLUtil.getElementJavaClassName(producesElementChild) + " does not exist in the <Produces> element child");
 						}
-						else
+
+						else if(type.isAnnotation())
 						{
-							definedType = true;
+							memberLevelMetaData.add((Class<? extends Annotation>)type);
+							memberLevelElement.add(producesElementChild);
 						}
+						else
+						{
+							if(!type.isAssignableFrom(producesMethod.getReturnType()) && !producesMethod.getReturnType().isAssignableFrom(type))
+							{
+								throw new WebBeansConfigurationException(errorMessage + "Defined returned method type is not compatible for producer method name : " 
+										+ producesMethod.getName() + " in class : " + component.getReturnType().getName() );
+							}
+							
+							if(definedType)
+							{
+								throw new WebBeansConfigurationException(errorMessage + "More than one Java type in the <Produces> element");
+							}
+							else
+							{
+								typeElement = producesElementChild;
+								definedType = true;
+							}
+						}						
 					}
 				}
 				
@@ -346,9 +530,232 @@
 					throw new WebBeansConfigurationException(errorMessage + "<Produces> element must define at least one java type child");
 				}
 			}
+			else
+			{
+				XMLInjectionPointModel injectionPointModel = XMLUtil.getInjectionPointModel(childElement, errorMessage);
+				injectedParameters.add(injectionPointModel);
+				
+			}
 		}
 		
-		return null;
+		XMLProducerComponentImpl<T> producerComponentImpl = configureProduerMethod(component, producesMethod, injectedParameters, 
+				type, arrayElement, typeElement, errorMessage);
+		
+		configureProducerTypeLevelMetaData(producerComponentImpl, producesMethod, producerMethodElement, memberLevelMetaData, memberLevelElement, component, errorMessage);
+
+		
+		return producerComponentImpl;
+	}
+	
+	/**
+	 * Configures and returns the newly created producer method
+	 * webbeans component.
+	 * 
+	 * @param parentComponent producer method webbeans parent component
+	 * @param producesMethod producer method
+	 * @param injectedParameters injected parameters of the producer method
+	 * @param type java class type of the producer method return type, null if
+	 * 		  the return type is defined as an Array element.
+	 * @param arrayElement if the return type is array type, this parameter is the Array element definition
+	 * @param typeElement if the return type is a Java type, this parameter is the Java type element
+	 * @param errorMessage error message
+	 * 
+	 * @return new xml defines producer method component
+	 * 
+	 * @see XMLProducerComponentImpl
+	 */
+	private static <T> XMLProducerComponentImpl<T> configureProduerMethod(AbstractComponent<?> parentComponent, Method producesMethod, List<XMLInjectionPointModel> injectedParameters, Class<T> type, Element arrayElement, Element typeElement, String errorMessage)
+	{
+		/*New producer webbeans component*/
+		XMLProducerComponentImpl<T> producerComponentImpl = new XMLProducerComponentImpl<T>(parentComponent, type);
+		
+		/*Check return type is the array type*/
+		if(arrayElement != null)
+		{
+			/*Configures array type*/
+			XMLUtil.defineXMLProducerApiTypeFromArrayElement(producerComponentImpl, arrayElement, errorMessage);	
+		}
+		/*Return type is java type*/
+		else
+		{
+			/*Configures the java api types and actual type parameters*/
+			XMLInjectionPointModel model = XMLUtil.getArrayInjectionPointModel(typeElement, errorMessage);
+			
+			producerComponentImpl.setActualTypeArguments(model.getActualTypeArguments());
+			producerComponentImpl.addApiType(model.getInjectionClassType());
+		}
+		
+		/*Set creator method*/
+		producerComponentImpl.setCreatorMethod(producesMethod);
+		
+		/*Configures producer method injected parameters*/
+		for(XMLInjectionPointModel injectionPointModel : injectedParameters)
+		{
+			producerComponentImpl.addProducerMethodInjectionPointModel(injectionPointModel);
+		}
+				
+		return producerComponentImpl;
+		
+	}
+	
+	/**
+	 * Configures xml defined producer method webbeans type level
+	 * metadatas.
+	 * 
+	 * @param producerComponentImpl xml webbeans producer component
+	 * @param producesMethod producer method
+	 * @param producerMethodElement producer method xml element
+	 * @param memberLevelMetaData member level annotations
+	 * @param memberLevelElement member level xml elements
+	 * @param component parent component that defines producer method
+	 * @param errorMessage error message
+	 * 
+	 * @return type level metadata  configured webbeans
+	 * 
+	 * @see XMLProducerComponentImpl
+	 */
+	private static <T> XMLProducerComponentImpl<T> configureProducerTypeLevelMetaData(XMLProducerComponentImpl<T> producerComponentImpl, Method producesMethod, Element producerMethodElement,List<Class<? extends Annotation>> memberLevelMetaData,List<Element> memberLevelElement ,XMLComponentImpl<T> component,String errorMessage)
+	{
+		
+		for(Class<? extends Annotation> memberLevelMetaDataClass : memberLevelMetaData)
+		{
+			if(!memberLevelMetaDataClass.isAnnotationPresent(DeploymentType.class) &&
+					!memberLevelMetaDataClass.isAnnotationPresent(ScopeType.class) &&
+					!AnnotationUtil.isStereoTypeAnnotation(memberLevelMetaDataClass) &&
+					!memberLevelMetaDataClass.equals(Named.class))
+			{
+				throw new WebBeansConfigurationException(errorMessage + "Defined annotations for producer method name : " 
+						+ producesMethod.getName() + " in class : " + component.getReturnType().getName() + " is not correct");
+			}
+		}
+		
+		WebBeansXMLConfigurator.configureProducerTypeLevelMetaData(producerComponentImpl, memberLevelMetaData, memberLevelElement, producerMethodElement);
+		
+		return producerComponentImpl;
+	}
+	
+	/**
+	 * Configures the disposal method of the webbeans component
+	 * using the xml configuration.
+	 * 
+	 * @param component producer method webbeans component
+	 * @param disposalMethod disposal method defined in the xml
+	 * @param disposalMethodElement disposal method xml element
+	 * @param errorMessage error message used in exceptions
+	 * 
+	 * @throws WebBeansConfigurationException if more than one Disposal element
+	 * exist for the given disposal method element
+	 * @throws UnsatisfiedDependencyException if no producer method found for given disposal method
+	 */
+	public static <T> void defineXMLDisposalMethod(XMLComponentImpl<T> component, Method disposalMethod, Element disposalMethodElement, String errorMessage)
+	{
+		/*Disposal method element childs*/
+		List<Element> disposalChildElements = disposalMethodElement.elements();
+		
+		/*Multiple <Disposes> element control parameter*/
+		boolean disposalDefined = false;
+		
+		/*Other parameter elements other than @Disposes*/
+		List<Element> otherParameterElements = new ArrayList<Element>();
+		
+		XMLProducerComponentImpl<?> producerComponent = null;
+		
+		for(Element childElement : disposalChildElements)
+		{
+			if(XMLUtil.isElementInWebBeansNameSpaceWithName(childElement, WebBeansConstants.WEB_BEANS_XML_DISPOSES_ELEMENT))
+			{
+				if(disposalDefined == false)
+				{
+					disposalDefined = true;
+				}
+				else
+				{
+					throw new WebBeansConfigurationException(errorMessage + "More than one <Disposal> element is defined for defining disposal method : " + disposalMethod.getName());
+				}
+				
+				Element typeElement = (Element)childElement.elements().get(0);
+				
+				/*Find disposal method model*/
+				XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(typeElement, errorMessage);
+				
+				/*Binding types for disposal method*/
+				Set<Annotation> bindingTypes = model.getBindingTypes();
+				Annotation[] bindingAnns = new Annotation[bindingTypes.size()];
+				bindingAnns = bindingTypes.toArray(bindingAnns);
+				
+				Set<Bean<T>> set = InjectionResolver.getInstance().implResolveByType(model.getInjectionClassType(), model.getActualTypeArguments(),bindingAnns);
+				producerComponent = (XMLProducerComponentImpl<?>) set.iterator().next();
+				
+				if(producerComponent == null)
+				{
+					throw new UnsatisfiedDependencyException(errorMessage + "Producer method component of the disposal method : " + disposalMethod.getName() + "is not found");
+				}
+
+				producerComponent.setDisposalMethod(disposalMethod);			
+				
+			}
+			/*Disposal method parameter other than @Disposes*/
+			else
+			{
+				otherParameterElements.add(childElement);
+			}
+		}//end of for childs
+		
+		/*Add other params injection point models*/
+		for(Element otherElement : otherParameterElements)
+		{
+			XMLInjectionPointModel injectionPointParamModel = XMLUtil.getInjectionPointModel(otherElement, errorMessage);
+			producerComponent.addDisposalMethodInjectionPointModel(injectionPointParamModel);
+		}	
 	}
 	
-}
+	public static <T,K> void defineXMLObservesMethod(XMLComponentImpl<T> component, Method observesMethod, Element observesMethodElement, String errorMessage)
+	{
+		component.addObservableMethod(observesMethod);
+		
+		/*Observes method element childs*/
+		List<Element> observesChildElements = observesMethodElement.elements();
+		
+		/*Other parameter elements other than @Observes*/
+		List<Element> otherParameterElements = new ArrayList<Element>();
+		
+		BeanObserverXMLImpl<K> beanObserver = new BeanObserverXMLImpl<K>(component,observesMethod,false,TransactionalObserverType.NONE);
+		
+		Class<K> eventType = null;
+		
+		for(Element childElement : observesChildElements)
+		{
+			if(XMLUtil.isElementInWebBeansNameSpaceWithName(childElement, WebBeansConstants.WEB_BEANS_XML_OBSERVES_ELEMENT))
+			{
+				Element typeElement = (Element)childElement.elements().get(0);
+				
+				eventType = (Class<K>)XMLUtil.getElementJavaType(typeElement);
+				
+				/*Find observes method model*/
+				XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(typeElement, errorMessage);
+				
+				/*Binding types for disposal method*/
+				Set<Annotation> bindingTypes = model.getBindingTypes();
+				Annotation[] bindingAnns = new Annotation[bindingTypes.size()];
+				bindingAnns = bindingTypes.toArray(bindingAnns);
+				
+				beanObserver.addXMLInjectionObservesParameter(model);
+				
+				NotificationManager.getInstance().addObserver(beanObserver, eventType, bindingAnns);
+				
+			}
+			/*Disposal method parameter other than @Disposes*/
+			else
+			{
+				otherParameterElements.add(childElement);
+			}
+		}//end of for childs
+		
+		/*Add other params injection point models*/
+		for(Element otherElement : otherParameterElements)
+		{
+			XMLInjectionPointModel injectionPointParamModel = XMLUtil.getInjectionPointModel(otherElement, errorMessage);
+			beanObserver.addXMLInjectionObservesParameter(injectionPointParamModel);
+		}	
+	}
+}
\ No newline at end of file

Modified: incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLUtil.java
URL: http://svn.apache.org/viewvc/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLUtil.java?rev=728541&r1=728540&r2=728541&view=diff
==============================================================================
--- incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLUtil.java (original)
+++ incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/xml/XMLUtil.java Sun Dec 21 14:40:56 2008
@@ -18,12 +18,15 @@
 
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import javax.webbeans.DuplicateBindingTypeException;
 import javax.webbeans.NonexistentTypeException;
@@ -31,7 +34,9 @@
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
 import org.apache.webbeans.WebBeansConstants;
+import org.apache.webbeans.annotation.CurrentLiteral;
 import org.apache.webbeans.annotation.WebBeansAnnotation;
+import org.apache.webbeans.component.xml.XMLProducerComponentImpl;
 import org.apache.webbeans.exception.WebBeansConfigurationException;
 import org.apache.webbeans.exception.WebBeansException;
 import org.apache.webbeans.inject.xml.XMLInjectionPointModel;
@@ -335,6 +340,18 @@
 		return false;
 	}
 	
+	
+	public static boolean isElementHasDecoratesChild(Element element)
+	{
+		nullCheckForElement(element);
+		if(isElementChildExistWithWebBeansNameSpace(element, WebBeansConstants.WEB_BEANS_XML_DECORATES_ELEMENT))
+		{
+			return true;
+		}
+		
+		return false;
+	}
+	
 	/**
 	 * Returns true if this element defines field, false otherwise.
 	 * 
@@ -590,7 +607,7 @@
 						}
 					}
 					
-					bindingAnnots.add(getInjectionPointAnnotationMember(childElement, annotClazz, errorMessage));
+					bindingAnnots.add(getXMLDefinedAnnotationMember(childElement, annotClazz, errorMessage));
 				}
 				else
 				{
@@ -622,6 +639,11 @@
 			typeArray = typeArguments.toArray(typeArray);
 			model = new XMLInjectionPointModel(clazz,typeArray);
 			
+			if(bindingAnnots.isEmpty())
+			{
+				model.addBindingType(new CurrentLiteral());
+			}
+			
 			for(Annotation annot : bindingAnnots)
 			{
 				model.addBindingType(annot);
@@ -640,7 +662,7 @@
 	 * 
 	 * @return new annotation with members configures
 	 */
-	private static Annotation getInjectionPointAnnotationMember(Element annotationElement, Class<? extends Annotation> annotClazz, String errorMessage)
+	public static Annotation getXMLDefinedAnnotationMember(Element annotationElement, Class<? extends Annotation> annotClazz, String errorMessage)
 	{
 		 String value = annotationElement.getTextTrim();
 		 List<Attribute> attrs = annotationElement.attributes();
@@ -780,35 +802,111 @@
 	/**
 	 * Injection point with array type.
 	 * 
-	 * @param typeElement injection point API type
+	 * @param typeElement array element
 	 * @param errorMessage error message 
 	 * 
 	 * @return new injection point model
 	 */	
-	private static XMLInjectionPointModel getArrayInjectionPointModel(Element typeElement, String errorMessage)
+	public static XMLInjectionPointModel getArrayInjectionPointModel(Element typeElement, String errorMessage)
 	{
 		XMLInjectionPointModel model = null;
 		
 		List<Element> childElements =  typeElement.elements();
-		if(childElements.size() != 1)
+		boolean isElementTypeDefined = false;
+		
+		Set<Annotation> anns = new HashSet<Annotation>();
+		for(Element childElement : childElements)
 		{
-			throw new WebBeansConfigurationException(errorMessage + "<Array> element can not have more than one child element. It has one child element that declares its type");
+			Class<?> clazz = XMLUtil.getElementJavaType(childElement);
+			
+			if(clazz == null)
+			{
+				throw new NonexistentTypeException(errorMessage + "Class with name : " + XMLUtil.getElementJavaClassName(childElement) + " is not found for Array element type");
+			}
+			
+			if(clazz.isAnnotation())
+			{
+				anns.add(getXMLDefinedAnnotationMember(childElement, (Class< ? extends Annotation>) clazz, errorMessage));
+			}
+			else if(clazz.isArray() || clazz.isEnum())
+			{
+				throw new WebBeansConfigurationException(errorMessage + "<Array> element child with Java type : " + getElementJavaClassName(typeElement) + " must be class or interface type");
+			}
+			else
+			{
+				if(isElementTypeDefined)
+				{
+					throw new WebBeansConfigurationException(errorMessage + "<Array> element can not have more than one child element. It has one child element that declares its type");
+				}
+				else
+				{
+					model = new XMLInjectionPointModel(clazz);
+					isElementTypeDefined = true;
+				}
+			}
 		}
-		else
+		
+		if(anns.size() == 0)
 		{
-			Element child = childElements.get(0);
-			Class<?> arrayType = getElementJavaType(child);
-			if(arrayType == null)
+			model.addBindingType(new CurrentLiteral());
+		}
+		
+		for(Annotation ann : anns)
+		{
+			model.addBindingType(ann);
+		}
+				
+		return model;
+	}
+	
+	public static <T> void defineXMLProducerApiTypeFromArrayElement(XMLProducerComponentImpl<T> component, Element typeElement, String errorMessage)
+	{
+		List<Element> childElements =  typeElement.elements();
+		boolean isElementTypeDefined = false;
+		
+		Set<Annotation> anns = new HashSet<Annotation>();
+		for(Element childElement : childElements)
+		{
+			Class<?> clazz = XMLUtil.getElementJavaType(childElement);
+			
+			if(clazz == null)
+			{
+				throw new NonexistentTypeException(errorMessage + "Class with name : " + XMLUtil.getElementJavaClassName(childElement) + " is not found for Array element type");
+			}
+			
+			if(clazz.isAnnotation())
 			{
-				throw new WebBeansConfigurationException(errorMessage + "<Array> element child with Java type : " + getElementJavaClassName(child) + " is not found in the deployment");
+				anns.add(getXMLDefinedAnnotationMember(childElement, (Class< ? extends Annotation>) clazz, errorMessage));
 			}
-			else if(arrayType.isArray() || arrayType.isEnum())
+			else if(clazz.isArray() || clazz.isEnum())
 			{
 				throw new WebBeansConfigurationException(errorMessage + "<Array> element child with Java type : " + getElementJavaClassName(typeElement) + " must be class or interface type");
 			}
+			else
+			{
+				if(isElementTypeDefined)
+				{
+					throw new WebBeansConfigurationException(errorMessage + "<Array> element can not have more than one child element. It has one child element that declares its type");
+				}
+				else
+				{
+					isElementTypeDefined = true;
+					component.addApiType(Array.newInstance(clazz, 0).getClass());
+				}
+			}
 		}
 		
-		return model;
+		if(anns.size() == 0)
+		{
+			component.addBindingType(new CurrentLiteral());
+		}
+		
+		for(Annotation ann : anns)
+		{
+			component.addBindingType(ann);
+		}
+				
 	}
 	
+	
 }
\ No newline at end of file