001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.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 2057 2007-11-21 15:35:32Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.deployment.annotations.helper.bean;
025:
026: import org.ow2.easybeans.asm.Opcodes;
027: import org.ow2.easybeans.asm.Type;
028: import org.ow2.easybeans.deployment.annotations.JMethod;
029: import org.ow2.easybeans.deployment.annotations.exceptions.ResolverException;
030: import org.ow2.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata;
031: import org.ow2.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata;
032: import org.ow2.easybeans.deployment.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: MethodAnnotationMetadata beanMethod = beanclassAnnotationMetadata
123: .getMethodAnnotationMetadata(method);
124:
125: // overriding ?
126: boolean overrided = true;
127: overrided = !((method.getAccess() & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE);
128:
129: // Add only if it is not present or if current method is not
130: // overriding super method (it means super method is private)
131: if (beanMethod == null
132: || (!overrided && beanMethod != null && !beanMethod
133: .isInherited())) {
134: // Add a clone of the method to bean class
135: MethodAnnotationMetadata clonedMethodAnnotationMetadata = (MethodAnnotationMetadata) methodAnnotationMetadata
136: .clone();
137: // set new class linked to this method metadata
138: clonedMethodAnnotationMetadata
139: .setClassAnnotationMetadata(beanclassAnnotationMetadata);
140:
141: // method is inherited
142: clonedMethodAnnotationMetadata.setInherited(true,
143: super ClassMetadata);
144:
145: beanclassAnnotationMetadata
146: .addMethodAnnotationMetadata(clonedMethodAnnotationMetadata);
147:
148: // lifecycle / aroundInvoke
149: if (clonedMethodAnnotationMetadata
150: .isPostConstruct()) {
151: beanclassAnnotationMetadata
152: .addPostConstructMethodMetadata(clonedMethodAnnotationMetadata);
153: }
154: if (clonedMethodAnnotationMetadata.isPreDestroy()) {
155: beanclassAnnotationMetadata
156: .addPreDestroyMethodMetadata(clonedMethodAnnotationMetadata);
157: }
158: if (clonedMethodAnnotationMetadata.isPostActivate()) {
159: beanclassAnnotationMetadata
160: .addPostActivateMethodMetadata(clonedMethodAnnotationMetadata);
161: }
162: if (clonedMethodAnnotationMetadata.isPrePassivate()) {
163: beanclassAnnotationMetadata
164: .addPrePassivateMethodMetadata(clonedMethodAnnotationMetadata);
165: }
166: if (clonedMethodAnnotationMetadata.isAroundInvoke()) {
167: beanclassAnnotationMetadata
168: .addAroundInvokeMethodMetadata(clonedMethodAnnotationMetadata);
169: }
170: }
171: }
172:
173: // Loop again
174: addMethodMetadata(beanclassAnnotationMetadata,
175: superClassMetadata);
176:
177: }
178: }
179:
180: }
|