001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util.spring.transaction;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    
020    import java.lang.reflect.Method;
021    
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import org.springframework.transaction.TransactionException;
026    import org.springframework.transaction.TransactionStatus;
027    import org.springframework.transaction.TransactionSystemException;
028    
029    /**
030     * <p>
031     * A class loader proxy implementation for a transaction status object created
032     * by the transaction manager within the portal and serialized back and forth
033     * between the portal and plugin class loader.
034     * </p>
035     *
036     * @author Micha Kiener
037     * @author Brian Wing Shun Chan
038     */
039    public class TransactionStatusClp implements TransactionStatus {
040    
041            public TransactionStatusClp(Object remoteTransactionStatus) {
042                    _remoteTransactionStatus = remoteTransactionStatus;
043    
044                    if (_remoteMethods == null) {
045                            initRemoteMethods(remoteTransactionStatus);
046                    }
047            }
048    
049            @Override
050            public Object createSavepoint() throws TransactionException {
051                    try {
052                            Method method = _remoteMethods.get("createSavepoint");
053    
054                            return method.invoke(_remoteTransactionStatus);
055                    }
056                    catch (Exception e) {
057                            _log.error(e, e);
058    
059                            throw new TransactionSystemException(e.getMessage());
060                    }
061            }
062    
063            @Override
064            public void flush() {
065                    try {
066                            Method method = _remoteMethods.get("flush");
067    
068                            method.invoke(_remoteTransactionStatus);
069                    }
070                    catch (Exception e) {
071                            _log.error(e, e);
072    
073                            throw new TransactionSystemException(e.getMessage());
074                    }
075            }
076    
077            public Object getRemoteTransactionStatus() {
078                    return _remoteTransactionStatus;
079            }
080    
081            @Override
082            public boolean hasSavepoint() {
083                    try {
084                            Method method = _remoteMethods.get("hasSavepoint");
085    
086                            return (Boolean)method.invoke(_remoteTransactionStatus);
087                    }
088                    catch (Exception e) {
089                            _log.error(e, e);
090    
091                            throw new RuntimeException(e.getMessage());
092                    }
093            }
094    
095            @Override
096            public boolean isCompleted() {
097                    try {
098                            Method method = _remoteMethods.get("isCompleted");
099    
100                            return (Boolean)method.invoke(_remoteTransactionStatus);
101                    }
102                    catch (Exception e) {
103                            _log.error(e, e);
104    
105                            throw new RuntimeException(e.getMessage());
106                    }
107            }
108    
109            @Override
110            public boolean isNewTransaction() {
111                    try {
112                            Method method = _remoteMethods.get("isNewTransaction");
113    
114                            return (Boolean)method.invoke(_remoteTransactionStatus);
115                    }
116                    catch (Exception e) {
117                            _log.error(e, e);
118    
119                            throw new RuntimeException(e.getMessage());
120                    }
121            }
122    
123            @Override
124            public boolean isRollbackOnly() {
125                    try {
126                            Method method = _remoteMethods.get("isRollbackOnly");
127    
128                            return (Boolean)method.invoke(_remoteTransactionStatus);
129                    }
130                    catch (Exception e) {
131                            _log.error(e, e);
132    
133                            throw new RuntimeException(e.getMessage());
134                    }
135            }
136    
137            @Override
138            public void releaseSavepoint(Object savepoint) throws TransactionException {
139                    try {
140                            Method method = _remoteMethods.get("releaseSavepoint");
141    
142                            method.invoke(_remoteTransactionStatus);
143                    }
144                    catch (Exception e) {
145                            _log.error(e, e);
146    
147                            throw new TransactionSystemException(e.getMessage());
148                    }
149            }
150    
151            @Override
152            public void rollbackToSavepoint(Object savepoint)
153                    throws TransactionException {
154    
155                    try {
156                            Method method = _remoteMethods.get("rollbackToSavepoint");
157    
158                            method.invoke(_remoteTransactionStatus);
159                    }
160                    catch (Exception e) {
161                            _log.error(e, e);
162    
163                            throw new TransactionSystemException(e.getMessage());
164                    }
165            }
166    
167            @Override
168            public void setRollbackOnly() {
169                    try {
170                            Method method = _remoteMethods.get("setRollbackOnly");
171    
172                            method.invoke(_remoteTransactionStatus);
173                    }
174                    catch (Exception e) {
175                            _log.error(e, e);
176    
177                            throw new RuntimeException(e.getMessage());
178                    }
179            }
180    
181            protected void initRemoteMethods(Object remoteTransactionStatus) {
182                    _remoteMethods = new HashMap<String, Method>();
183    
184                    Method[] methods = TransactionStatus.class.getMethods();
185    
186                    for (Method method : methods) {
187                            _remoteMethods.put(method.getName(), method);
188                    }
189            }
190    
191            private static Log _log = LogFactoryUtil.getLog(TransactionStatusClp.class);
192    
193            private static Map<String, Method> _remoteMethods;
194    
195            private Object _remoteTransactionStatus;
196    
197    }