001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: InheritanceMethodResolver.java 486 2006-05-22 15:46:08Z benoitf $
023: * --------------------------------------------------------------------------
024: */package com.bm.ejb3metadata.annotations.helper.bean;
025:
026: import org.ejb3unit.asm.Type;
027:
028: import com.bm.ejb3metadata.annotations.JMethod;
029: import com.bm.ejb3metadata.annotations.exceptions.ResolverException;
030: import com.bm.ejb3metadata.annotations.metadata.ClassAnnotationMetadata;
031: import com.bm.ejb3metadata.annotations.metadata.EjbJarAnnotationMetadata;
032: import com.bm.ejb3metadata.annotations.metadata.MethodAnnotationMetadata;
033:
034: /**
035: * This class adds method meta data to bean class from the super class.<br>
036: * TODO: Try to analyze super class from a super classloader if not found in the
037: * current ejb-jar
038: * @see <a href="http://www.jcp.org/en/jsr/detail?id=220">EJB 3.0 Spec ?4.6.2</a><br><p>
039: * A super class can't be a bean class (stateless, stateful, etc) so the
040: * method metadata don't need to be cloned</p>
041: * @author Florent Benoit
042: */
043: public final class InheritanceMethodResolver {
044:
045: /**
046: * java.lang.object internal name.
047: */
048: private static final String JAVA_LANG_OBJECT = Type
049: .getInternalName(Object.class);
050:
051: /**
052: * Helper class, no public constructor.
053: */
054: private InheritanceMethodResolver() {
055:
056: }
057:
058: /**
059: * Found all method meta data of the super class and adds them to the class
060: * being analyzed.
061: * @param classAnnotationMetadata class to analyze
062: * @throws ResolverException if the super class in not in the given ejb-jar
063: */
064: public static void resolve(
065: final ClassAnnotationMetadata classAnnotationMetadata)
066: throws ResolverException {
067: addMethodMetadata(classAnnotationMetadata,
068: classAnnotationMetadata);
069: }
070:
071: /**
072: * Adds method meta data on the first class by iterating on the second given
073: * class.
074: * @param beanclassAnnotationMetadata class where to add method metadata
075: * @param visitingClassAnnotationMetadata takes method metadata from super
076: * class of the given class
077: * @throws ResolverException if a super class metadata is not found from
078: * ejb-jar
079: */
080: private static void addMethodMetadata(
081: final ClassAnnotationMetadata beanclassAnnotationMetadata,
082: final ClassAnnotationMetadata visitingClassAnnotationMetadata)
083: throws ResolverException {
084:
085: // Analyze super classes of the given class
086: String super Class = visitingClassAnnotationMetadata
087: .getSuperName();
088:
089: if (super Class != null) {
090:
091: // If super class is java.lang.Object, break the loop
092: if (super Class.equals(JAVA_LANG_OBJECT)) {
093: return;
094: }
095:
096: // Get parent meta-data
097: EjbJarAnnotationMetadata ejbJarAnnotationMetadata = beanclassAnnotationMetadata
098: .getEjbJarAnnotationMetadata();
099:
100: // Get meta data of the super class
101: ClassAnnotationMetadata super ClassMetadata = ejbJarAnnotationMetadata
102: .getClassAnnotationMetadata(super Class);
103:
104: if (super ClassMetadata == null) {
105: // TODO : I18n
106: throw new ResolverException(
107: "The class "
108: + beanclassAnnotationMetadata
109: + " extends the class "
110: + super Class
111: + "but this class seems to be outside of the ejb-jar");
112: }
113:
114: // Takes method metadata of the super class and adds them to the
115: // bean class
116: // Note : the flag inherited is set to true
117: for (MethodAnnotationMetadata methodAnnotationMetadata : super ClassMetadata
118: .getMethodAnnotationMetadataCollection()) {
119: // check that the method has not be redefined
120: JMethod method = methodAnnotationMetadata.getJMethod();
121:
122: // Add only if it is not present.
123: if (beanclassAnnotationMetadata
124: .getMethodAnnotationMetadata(method) == null) {
125: // Add a clone of the method to bean class
126: MethodAnnotationMetadata clonedMethodAnnotationMetadata = (MethodAnnotationMetadata) methodAnnotationMetadata
127: .clone();
128: // set new class linked to this method metadata
129: clonedMethodAnnotationMetadata
130: .setClassAnnotationMetadata(beanclassAnnotationMetadata);
131: beanclassAnnotationMetadata
132: .addMethodAnnotationMetadata(clonedMethodAnnotationMetadata);
133:
134: // method is inherited
135: clonedMethodAnnotationMetadata.setInherited(true,
136: super ClassMetadata);
137:
138: // lifecycle / aroundInvoke
139: if (clonedMethodAnnotationMetadata
140: .isPostConstruct()) {
141: beanclassAnnotationMetadata
142: .addPostConstructMethodMetadata(clonedMethodAnnotationMetadata);
143: }
144: if (clonedMethodAnnotationMetadata.isPreDestroy()) {
145: beanclassAnnotationMetadata
146: .addPreDestroyMethodMetadata(clonedMethodAnnotationMetadata);
147: }
148: if (clonedMethodAnnotationMetadata.isPostActivate()) {
149: beanclassAnnotationMetadata
150: .addPostActivateMethodMetadata(clonedMethodAnnotationMetadata);
151: }
152: if (clonedMethodAnnotationMetadata.isPrePassivate()) {
153: beanclassAnnotationMetadata
154: .addPrePassivateMethodMetadata(clonedMethodAnnotationMetadata);
155: }
156: if (clonedMethodAnnotationMetadata.isAroundInvoke()) {
157: beanclassAnnotationMetadata
158: .addAroundInvokeMethodMetadata(clonedMethodAnnotationMetadata);
159: }
160: }
161: }
162:
163: // Loop again
164: addMethodMetadata(beanclassAnnotationMetadata,
165: superClassMetadata);
166:
167: }
168: }
169:
170: }
|