001    /**
002     * Copyright (c) 2000-2010 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            public Object createSavepoint() throws TransactionException {
050                    try {
051                            Method method = _remoteMethods.get("createSavepoint");
052    
053                            return method.invoke(_remoteTransactionStatus);
054                    }
055                    catch (Exception e) {
056                            _log.error(e, e);
057    
058                            throw new TransactionSystemException(e.getMessage());
059                    }
060            }
061    
062            public void flush() {
063                    try {
064                            Method method = _remoteMethods.get("flush");
065    
066                            method.invoke(_remoteTransactionStatus);
067                    }
068                    catch (Exception e) {
069                            _log.error(e, e);
070    
071                            throw new TransactionSystemException(e.getMessage());
072                    }
073            }
074    
075            public Object getRemoteTransactionStatus() {
076                    return _remoteTransactionStatus;
077            }
078    
079            public boolean hasSavepoint() {
080                    try {
081                            Method method = _remoteMethods.get("hasSavepoint");
082    
083                            return (Boolean)method.invoke(_remoteTransactionStatus);
084                    }
085                    catch (Exception e) {
086                            _log.error(e, e);
087    
088                            throw new RuntimeException(e.getMessage());
089                    }
090            }
091    
092            public boolean isCompleted() {
093                    try {
094                            Method method = _remoteMethods.get("isCompleted");
095    
096                            return (Boolean)method.invoke(_remoteTransactionStatus);
097                    }
098                    catch (Exception e) {
099                            _log.error(e, e);
100    
101                            throw new RuntimeException(e.getMessage());
102                    }
103            }
104    
105            public boolean isNewTransaction() {
106                    try {
107                            Method method = _remoteMethods.get("isNewTransaction");
108    
109                            return (Boolean)method.invoke(_remoteTransactionStatus);
110                    }
111                    catch (Exception e) {
112                            _log.error(e, e);
113    
114                            throw new RuntimeException(e.getMessage());
115                    }
116            }
117    
118            public boolean isRollbackOnly() {
119                    try {
120                            Method method = _remoteMethods.get("isRollbackOnly");
121    
122                            return (Boolean)method.invoke(_remoteTransactionStatus);
123                    }
124                    catch (Exception e) {
125                            _log.error(e, e);
126    
127                            throw new RuntimeException(e.getMessage());
128                    }
129            }
130    
131            public void releaseSavepoint(Object savepoint) throws TransactionException {
132                    try {
133                            Method method = _remoteMethods.get("releaseSavepoint");
134    
135                            method.invoke(_remoteTransactionStatus);
136                    }
137                    catch (Exception e) {
138                            _log.error(e, e);
139    
140                            throw new TransactionSystemException(e.getMessage());
141                    }
142            }
143    
144            public void rollbackToSavepoint(Object savepoint)
145                    throws TransactionException {
146    
147                    try {
148                            Method method = _remoteMethods.get("rollbackToSavepoint");
149    
150                            method.invoke(_remoteTransactionStatus);
151                    }
152                    catch (Exception e) {
153                            _log.error(e, e);
154    
155                            throw new TransactionSystemException(e.getMessage());
156                    }
157            }
158    
159            public void setRollbackOnly() {
160                    try {
161                            Method method = _remoteMethods.get("setRollbackOnly");
162    
163                            method.invoke(_remoteTransactionStatus);
164                    }
165                    catch (Exception e) {
166                            _log.error(e, e);
167    
168                            throw new RuntimeException(e.getMessage());
169                    }
170            }
171    
172            protected void initRemoteMethods(Object remoteTransactionStatus) {
173                    _remoteMethods = new HashMap<String, Method>();
174    
175                    Method[] methods = TransactionStatus.class.getMethods();
176    
177                    for (Method method : methods) {
178                            _remoteMethods.put(method.getName(), method);
179                    }
180            }
181    
182            private static Log _log = LogFactoryUtil.getLog(TransactionStatusClp.class);
183    
184            private static Map<String, Method> _remoteMethods;
185    
186            private Object _remoteTransactionStatus;
187    
188    }