001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free SoftwareFoundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.ejb.hessian;
031:
032: import com.caucho.vfs.Path;
033: import com.caucho.vfs.Vfs;
034:
035: import javax.transaction.xa.XAException;
036: import javax.transaction.xa.XAResource;
037: import javax.transaction.xa.Xid;
038: import java.util.logging.Level;
039: import java.util.logging.Logger;
040:
041: /**
042: * Resource
043: */
044: public class HessianXAResource implements XAResource {
045: private static final Logger log = Logger
046: .getLogger(HessianXAResource.class.getName());
047:
048: private String _url;
049: private Path _path;
050:
051: public HessianXAResource(String url) {
052: _url = url;
053:
054: _path = Vfs.lookup(url);
055: }
056:
057: public boolean isSameRM(XAResource xares) {
058: if (!(xares instanceof HessianXAResource))
059: return false;
060:
061: HessianXAResource rm = (HessianXAResource) xares;
062:
063: return _url.equals(rm._url);
064: }
065:
066: public void start(Xid xid, int flags) throws XAException {
067: }
068:
069: public void end(Xid xid, int flags) throws XAException {
070: }
071:
072: public boolean setTransactionTimeout(int seconds)
073: throws XAException {
074: return true;
075: }
076:
077: public int getTransactionTimeout() throws XAException {
078: return 0;
079: }
080:
081: public int prepare(Xid xid) throws XAException {
082: try {
083: Object value = MetaStub.call(_path, "prepare",
084: xidToString(xid));
085: } catch (Throwable e) {
086: log.log(Level.WARNING, e.toString(), e);
087:
088: throw new XAException(e.toString());
089: }
090:
091: // also rdonly
092:
093: return XA_OK;
094: }
095:
096: public Xid[] recover(int flag) throws XAException {
097: // XXX: should query
098:
099: return null;
100: }
101:
102: public void forget(Xid xid) throws XAException {
103: }
104:
105: public void rollback(Xid xid) throws XAException {
106: try {
107: MetaStub.call(_path, "rollback", xidToString(xid));
108: } catch (Throwable e) {
109: log.log(Level.WARNING, e.toString(), e);
110:
111: throw new XAException(e.toString());
112: }
113: }
114:
115: public void commit(Xid xid, boolean onephase) throws XAException {
116: try {
117: if (onephase)
118: MetaStub
119: .call(_path, "commitOnePhase", xidToString(xid));
120: else
121: MetaStub.call(_path, "commit", xidToString(xid));
122: } catch (Throwable e) {
123: log.log(Level.WARNING, e.toString(), e);
124:
125: throw new XAException(e.toString());
126: }
127: }
128:
129: private static String xidToString(Xid xid) {
130: byte[] id = xid.getGlobalTransactionId();
131:
132: StringBuilder sb = new StringBuilder();
133:
134: for (int i = 0; i < id.length; i++) {
135: byte b = id[i];
136:
137: sb.append(toHex((b >> 4) & 0xf));
138: sb.append(toHex(b & 0xf));
139: }
140:
141: return sb.toString();
142: }
143:
144: private static char toHex(int d) {
145: if (d < 10)
146: return (char) ('0' + d);
147: else
148: return (char) ('a' + d - 10);
149: }
150: }
|