001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.spring.annotation;
016    
017    import com.liferay.portal.kernel.annotation.TransactionDefinition;
018    import com.liferay.portal.kernel.annotation.Transactional;
019    import com.liferay.portal.util.PropsValues;
020    
021    import java.io.Serializable;
022    
023    import java.lang.reflect.AnnotatedElement;
024    import java.lang.reflect.Method;
025    
026    import java.util.ArrayList;
027    import java.util.LinkedList;
028    import java.util.List;
029    import java.util.Queue;
030    
031    import org.springframework.transaction.annotation.TransactionAnnotationParser;
032    import org.springframework.transaction.interceptor.NoRollbackRuleAttribute;
033    import org.springframework.transaction.interceptor.RollbackRuleAttribute;
034    import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
035    import org.springframework.transaction.interceptor.TransactionAttribute;
036    
037    /**
038     * @author         Michael Young
039     * @author         Shuyang Zhou
040     * @deprecated
041     */
042    public class PortalTransactionAnnotationParser
043            implements TransactionAnnotationParser, Serializable {
044    
045            public TransactionAttribute parseTransactionAnnotation(
046                    AnnotatedElement annotatedElement) {
047    
048                    //Transactional annotation = annotatedElement.getAnnotation(
049                    //        Transactional.class);
050    
051                    Transactional annotation = null;
052    
053                    Queue<Class<?>> candidateQueue = new LinkedList<Class<?>>();
054    
055                    if (annotatedElement instanceof Method) {
056                            Method method = (Method)annotatedElement;
057    
058                            candidateQueue.offer(method.getDeclaringClass());
059    
060                            annotation = _deepSearchMethods(method, candidateQueue);
061                    }
062                    else {
063                            candidateQueue.offer((Class<?>)annotatedElement);
064    
065                            annotation = _deepSearchTypes(candidateQueue);
066                    }
067    
068                    if (annotation == null || !annotation.enabled()) {
069                            return null;
070                    }
071    
072                    RuleBasedTransactionAttribute ruleBasedTransactionAttribute =
073                            new RuleBasedTransactionAttribute();
074    
075                    int isolationLevel = annotation.isolation().value();
076    
077                    if (isolationLevel == TransactionDefinition.ISOLATION_COUNTER) {
078                            ruleBasedTransactionAttribute.setIsolationLevel(
079                                    PropsValues.TRANSACTION_ISOLATION_COUNTER);
080                    }
081                    else if (isolationLevel == TransactionDefinition.ISOLATION_PORTAL) {
082                            ruleBasedTransactionAttribute.setIsolationLevel(
083                                    PropsValues.TRANSACTION_ISOLATION_PORTAL);
084                    }
085                    else {
086                            ruleBasedTransactionAttribute.setIsolationLevel(isolationLevel);
087                    }
088    
089                    ruleBasedTransactionAttribute.setPropagationBehavior(
090                            annotation.propagation().value());
091                    ruleBasedTransactionAttribute.setReadOnly(annotation.readOnly());
092                    ruleBasedTransactionAttribute.setTimeout(annotation.timeout());
093    
094                    List<RollbackRuleAttribute> rollBackAttributes =
095                            new ArrayList<RollbackRuleAttribute>();
096    
097                    Class<?>[] rollbackFor = annotation.rollbackFor();
098    
099                    for (int i = 0; i < rollbackFor.length; i++) {
100                            RollbackRuleAttribute rollbackRuleAttribute =
101                                    new RollbackRuleAttribute(rollbackFor[i]);
102    
103                            rollBackAttributes.add(rollbackRuleAttribute);
104                    }
105    
106                    String[] rollbackForClassName = annotation.rollbackForClassName();
107    
108                    for (int i = 0; i < rollbackForClassName.length; i++) {
109                            RollbackRuleAttribute rollbackRuleAttribute =
110                                    new RollbackRuleAttribute(rollbackForClassName[i]);
111    
112                            rollBackAttributes.add(rollbackRuleAttribute);
113                    }
114    
115                    Class<?>[] noRollbackFor = annotation.noRollbackFor();
116    
117                    for (int i = 0; i < noRollbackFor.length; ++i) {
118                            NoRollbackRuleAttribute noRollbackRuleAttribute =
119                                    new NoRollbackRuleAttribute(noRollbackFor[i]);
120    
121                            rollBackAttributes.add(noRollbackRuleAttribute);
122                    }
123    
124                    String[] noRollbackForClassName = annotation.noRollbackForClassName();
125    
126                    for (int i = 0; i < noRollbackForClassName.length; ++i) {
127                            NoRollbackRuleAttribute noRollbackRuleAttribute =
128                                    new NoRollbackRuleAttribute(noRollbackForClassName[i]);
129    
130                            rollBackAttributes.add(noRollbackRuleAttribute);
131                    }
132    
133                    ruleBasedTransactionAttribute.getRollbackRules().addAll(
134                            rollBackAttributes);
135    
136                    return ruleBasedTransactionAttribute;
137            }
138    
139            private Transactional _deepSearchMethods(
140                    Method method, Queue<Class<?>> candidateQueue) {
141    
142                    Transactional annotation = method.getAnnotation(Transactional.class);
143    
144                    if (annotation != null) {
145                            return annotation;
146                    }
147    
148                    if (candidateQueue.isEmpty()) {
149                            return null;
150                    }
151    
152                    Class<?> clazz = candidateQueue.poll();
153    
154                    if (method.getDeclaringClass() != clazz) {
155                            try {
156                                    Method specificMethod = clazz.getDeclaredMethod(
157                                            method.getName(), method.getParameterTypes());
158    
159                                    annotation = specificMethod.getAnnotation(Transactional.class);
160    
161                                    if (annotation != null) {
162                                            return annotation;
163                                    }
164                            }
165                            catch (Exception e) {
166                            }
167                    }
168    
169                    annotation = clazz.getAnnotation(Transactional.class);
170    
171                    if (annotation == null) {
172                            _queueSuperTypes(clazz, candidateQueue);
173    
174                            return _deepSearchMethods(method, candidateQueue);
175                    }
176                    else {
177                            return annotation;
178                    }
179            }
180    
181            private Transactional _deepSearchTypes(Queue<Class<?>> candidateQueue) {
182                    if (candidateQueue.isEmpty()) {
183                            return null;
184                    }
185    
186                    Class<?> clazz = candidateQueue.poll();
187    
188                    Transactional annotation = clazz.getAnnotation(Transactional.class);
189    
190                    if (annotation == null) {
191                            _queueSuperTypes(clazz, candidateQueue);
192    
193                            return _deepSearchTypes(candidateQueue);
194                    }
195                    else {
196                            return annotation;
197                    }
198            }
199    
200            private void _queueSuperTypes(
201                    Class<?> clazz, Queue<Class<?>> candidateQueue) {
202    
203                    Class<?> supperClass = clazz.getSuperclass();
204    
205                    if ((supperClass != null) && (supperClass != Object.class)) {
206                            candidateQueue.offer(supperClass);
207                    }
208    
209                    Class<?>[] interfaces = clazz.getInterfaces();
210    
211                    for (Class<?> inter : interfaces) {
212                            candidateQueue.offer(inter);
213                    }
214            }
215    
216    }