/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/AbstractRDBMSStore.java,v 1.10.2.3 2004/11/22 16:35:11 ozeigermann Exp $
* $Revision: 1.10.2.3 $
* $Date: 2004/11/22 16:35:11 $
*
* ====================================================================
*
* Copyright 1999-2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.slide.store.impl.rdbms;
import java.lang.reflect.Constructor;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.apache.commons.transaction.util.xa.AbstractTransactionalResource;
import org.apache.commons.transaction.util.xa.TransactionalResource;
import org.apache.slide.common.AbstractXAServiceBase;
import org.apache.slide.common.Service;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.ServiceConnectionFailedException;
import org.apache.slide.common.ServiceDisconnectionFailedException;
import org.apache.slide.common.ServiceInitializationFailedException;
import org.apache.slide.common.ServiceParameterErrorException;
import org.apache.slide.common.ServiceParameterMissingException;
import org.apache.slide.common.ServiceResetFailedException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.search.basic.BasicExpressionFactory;
import org.apache.slide.search.basic.IBasicExpressionFactory;
import org.apache.slide.search.basic.IBasicExpressionFactoryProvider;
import org.apache.slide.security.NodePermission;
import org.apache.slide.store.ContentStore;
import org.apache.slide.store.LockStore;
import org.apache.slide.store.NodeStore;
import org.apache.slide.store.RevisionDescriptorStore;
import org.apache.slide.store.RevisionDescriptorsStore;
import org.apache.slide.store.SecurityStore;
import org.apache.slide.store.SequenceStore;
import org.apache.slide.store.impl.rdbms.expression.RDBMSExpressionFactory;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.logger.Logger;
/**
* J2EE store implementation - implements the shared parts of
* the two (content, descriptors) J2EE stores for the new Indexed DB Schema.
*
* @version $Revision: 1.10.2.3 $
*/
public abstract class AbstractRDBMSStore
extends AbstractXAServiceBase
implements
LockStore,
NodeStore,
RevisionDescriptorsStore,
RevisionDescriptorStore,
SecurityStore,
ContentStore,
SequenceStore,
IBasicExpressionFactoryProvider {
protected static final String LOG_CHANNEL = AbstractRDBMSStore.class.getName();
protected RDBMSAdapter adapter;
protected boolean alreadyInitialized = false;
protected int isSequenceSupported = 0;
protected boolean useRdbmsExpressionFactory;
/**
* Indicates whether the transaction manager will commit / rollback
* the transaction or the store is in charge of it. Slide's internal
* TM does not commit / rollback, but TMs more aligned to the spec (e.g. JBoss' TM) do.
*/
protected boolean tmCommits = false;
/**
* Initializes the data source with a set of parameters.
*
* @param parameters Hashtable containing the parameters' name
* and associated value
* @exception ServiceParameterErrorException Incorrect service parameter
* @exception ServiceParameterMissingException Service parameter missing
*/
public void setParameters(Hashtable parameters)
throws ServiceParameterErrorException, ServiceParameterMissingException {
// Adapter class
String value = (String) parameters.get("adapter");
if (value == null) {
adapter = new StandardRDBMSAdapter(this, getLogger());
} else {
try {
Class adapterClass = Class.forName(value);
Constructor ctor = adapterClass.getConstructor(new Class[] { Service.class, Logger.class });
adapter = (RDBMSAdapter) ctor.newInstance(new Object[] { this, getLogger()});
} catch (Exception e) {
// reflection exception
getLogger().log(
"Error instantiating Adapter '" + value + "' (" + e.getMessage() + ")",
LOG_CHANNEL,
Logger.ERROR);
}
}
if (adapter != null) {
adapter.setParameters(parameters);
}
// Use RDBMSExpressionFactory?
value = (String) parameters.get("use-rdbms-expression-factory");
this.useRdbmsExpressionFactory = Boolean.valueOf(value).booleanValue();
// XXX need to initialize it here, as some security requests access the store before initialization
try {
initialize(null);
} catch (ServiceInitializationFailedException e) {
// XXX this is not very satisfactory...
throw new ServiceParameterErrorException(this, e.getMessage());
}
}
/**
* Establishes the global connection to the data source.
*
* @exception ServiceConnectionFailedException if the connection failed
*/
public void connect() throws ServiceConnectionFailedException {
}
/**
* Returns connection status.
*/
public boolean isConnected() {
return true;
}
/**
* Closes the global connection to the data source.
*
* @exception ServiceDisconnectionFailedException if closing the connection
* failed
*/
public void disconnect() throws ServiceDisconnectionFailedException {
}
/**
* Does nothing.
*
* @exception ServiceResetFailedException Reset failed
*/
public void reset() throws ServiceResetFailedException {
}
// ----------------------------------------------------- XAResource Methods
/**
* Get the transaction timeout value for this XAResource.
* Just returns 0, we don't have a way of doing transaction timeouts
* with the connection.
*/
public int getTransactionTimeout() throws XAException {
return 0;
}
/**
* Set transaction timeout, not implemented (returns false).
*/
public boolean setTransactionTimeout(int timeout) throws XAException {
return false;
}
public Xid[] recover(int flag) throws XAException {
getLogger().log("recover() for thread: " + Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
TransactionalResource id = getCurrentlyActiveTransactionalResource();
if (id != null && id.getStatus() == STATUS_PREPARED) {
Xid[] xids = new Xid[1];
xids[0] = id.getXid();
return xids;
} else
return new Xid[0];
}
public boolean isSameRM(XAResource xares) throws XAException {
return (xares == this);
}
// ----------------------------------------------- IBasicExpressionFactoryProvider Implementation
public IBasicExpressionFactory getBasicExpressionFactory() {
if (this.useRdbmsExpressionFactory) {
return new RDBMSExpressionFactory(this);
}
else {
return new BasicExpressionFactory();
}
}
// ----------------------------------------------- SequenceStore Implementation
/**
* @see org.apache.slide.store.SequenceStore#createSequence(java.lang.String)
*/
public boolean createSequence(String sequenceName) throws ServiceAccessException {
if (!isSequenceSupported()) {
throw new ServiceAccessException(this, "Sequences not supported");
}
Connection connection = null;
try {
connection = getNewConnection();
return ((SequenceAdapter) adapter).createSequence(connection, sequenceName);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
}
/**
* @see org.apache.slide.store.SequenceStore#isSequenceSupported()
*/
public boolean isSequenceSupported() {
// cache it for better performance as support of an adapter will
// not change will running, it is either yes or no all the time
if (isSequenceSupported > 0)
return true;
if (isSequenceSupported < 0)
return false;
Connection connection = null;
try {
connection = getNewConnection();
if (adapter instanceof SequenceAdapter && ((SequenceAdapter) adapter).isSequenceSupported(connection)) {
isSequenceSupported = 1;
return true;
} else {
isSequenceSupported = -1;
return false;
}
} catch (SQLException e) {
getLogger().log(
"Error while trying to check for sequence support. Assuming false",
e,
LOG_CHANNEL,
Logger.ERROR);
isSequenceSupported = -1;
return false;
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
}
/**
* @see org.apache.slide.store.SequenceStore#nextSequenceValue(java.lang.String)
*/
public long nextSequenceValue(String sequenceName) throws ServiceAccessException {
if (!isSequenceSupported()) {
throw new ServiceAccessException(this, "Sequences not supported");
}
Connection connection = null;
try {
connection = getNewConnection();
return ((SequenceAdapter) adapter).nextSequenceValue(connection, sequenceName);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
}
/**
* @see org.apache.slide.store.SequenceStore#sequenceExists(java.lang.String)
*/
public boolean sequenceExists(String sequenceName) throws ServiceAccessException {
if (!isSequenceSupported()) {
throw new ServiceAccessException(this, "Sequences not supported");
}
Connection connection = null;
try {
connection = getNewConnection();
return ((SequenceAdapter) adapter).sequenceExists(connection, sequenceName);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
}
// ----------------------------------------------- NodeStore Implementation
/**
* Retrieve an object.
*
* @param uri Uri of the object we want to retrieve
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectNotFoundException The object to retrieve was not found
*/
public ObjectNode retrieveObject(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
if (getCurrentlyActiveTransactionalResource() == null) {
Connection connection = null;
try {
connection = getNewConnection();
return adapter.retrieveObject(connection, uri);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
} else {
return adapter.retrieveObject(getCurrentConnection(), uri);
}
}
/**
* Update an object.
*
* @param object Object to update
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectNotFoundException The object to update was not found
*/
public void storeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
adapter.storeObject(getCurrentConnection(), uri, object);
}
/**
* Create a new object.
*
* @param object ObjectNode
* @param uri Uri of the object we want to create
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectAlreadyExistsException An object already exists
* at this Uri
*/
public void createObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectAlreadyExistsException {
adapter.createObject(getCurrentConnection(), uri, object);
}
/**
* Remove an object.
*
* @param object Object to remove
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectNotFoundException The object to remove was not found
*/
public void removeObject(Uri uri, ObjectNode object) throws ServiceAccessException, ObjectNotFoundException {
adapter.removeObject(getCurrentConnection(), uri, object);
}
// ------------------------------------------- SecurityStore Implementation
/**
* Grant a new permission.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public void grantPermission(Uri uri, NodePermission permission) throws ServiceAccessException {
adapter.grantPermission(getCurrentConnection(), uri, permission);
}
/**
* Revoke a permission.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public void revokePermission(Uri uri, NodePermission permission) throws ServiceAccessException {
adapter.revokePermission(getCurrentConnection(), uri, permission);
}
/**
* Revoke all the permissions on an object.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public void revokePermissions(Uri uri) throws ServiceAccessException {
adapter.revokePermissions(getCurrentConnection(), uri);
}
/**
* Enumerate permissions on an object.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public Enumeration enumeratePermissions(Uri uri) throws ServiceAccessException {
if (getCurrentlyActiveTransactionalResource() == null) {
Connection connection = null;
try {
connection = getNewConnection();
return adapter.enumeratePermissions(connection, uri);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
} else {
return adapter.enumeratePermissions(getCurrentConnection(), uri);
}
}
// ----------------------------------------------- LockStore Implementation
/**
* Create a new lock.
*
* @param lock Lock token
* @exception ServiceAccessException Service access error
*/
public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException {
adapter.putLock(getCurrentConnection(), uri, lock);
}
/**
* Refresh a lock.
*
* @param lock the lock to renew
* @exception ServiceAccessException Service access error
* @exception LockTokenNotFoundException Lock token was not found
*/
public void renewLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
adapter.renewLock(getCurrentConnection(), uri, lock);
}
/**
* Unlock.
*
* @param lock Token to remove
* @exception ServiceAccessException Service access error
* @exception LockTokenNotFoundException Lock token was not found
*/
public void removeLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
adapter.removeLock(getCurrentConnection(), uri, lock);
}
/**
* Kill a lock.
*
* @param lock Token to remove
* @exception ServiceAccessException Service access error
* @exception LockTokenNotFoundException Lock token was not found
*/
public void killLock(Uri uri, NodeLock lock) throws ServiceAccessException, LockTokenNotFoundException {
adapter.killLock(getCurrentConnection(), uri, lock);
}
/**
* Enumerate locks on an object.
*
* @param subject Subject
* @return Enumeration List of locks which have been put on the subject
* @exception ServiceAccessException Service access error
*/
public Enumeration enumerateLocks(Uri uri) throws ServiceAccessException {
if (getCurrentlyActiveTransactionalResource() == null) {
Connection connection = null;
try {
connection = getNewConnection();
return adapter.enumerateLocks(connection, uri);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
} else {
return adapter.enumerateLocks(getCurrentConnection(), uri);
}
}
// -------------------------------- RevisionDescriptorsStore Implementation
/**
* Retrieve the revisions informations of an object.
*
* @param uri Uri
* @exception ServiceAccessException Service access error
* @exception RevisionDescriptorNotFoundException Revision descriptor
* was not found
*/
public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
if (getCurrentlyActiveTransactionalResource() == null) {
Connection connection = null;
try {
connection = getNewConnection();
return adapter.retrieveRevisionDescriptors(connection, uri);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
} else {
return adapter.retrieveRevisionDescriptors(getCurrentConnection(), uri);
}
}
/**
* Create a new revision information object.
*
* @param uri Uri
* @param revisionDescriptors Node revision descriptors
* @exception ServiceAccessException Service access error
*/
public void createRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException {
adapter.createRevisionDescriptors(getCurrentConnection(), uri, revisionDescriptors);
}
/**
* Update revision information.
*
* @param uri Uri
* @param revisionDescriptors Node revision descriptors
* @exception ServiceAccessException Service access error
* @exception RevisionDescriptorNotFoundException Revision descriptor
* was not found
*/
public void storeRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
adapter.storeRevisionDescriptors(getCurrentConnection(), uri, revisionDescriptors);
}
/**
* Remove revision information.
*
* @param uri Uri
* @exception ServiceAccessException Service access error
*/
public void removeRevisionDescriptors(Uri uri) throws ServiceAccessException {
adapter.removeRevisionDescriptors(getCurrentConnection(), uri);
}
// --------------------------------- RevisionDescriptorStore Implementation
/**
* Retrieve an individual object's revision descriptor.
*
* @param Uri uri
* @param revisionNumber Node revision number
*/
public NodeRevisionDescriptor retrieveRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
if (getCurrentlyActiveTransactionalResource() == null) {
Connection connection = null;
try {
connection = getNewConnection();
return adapter.retrieveRevisionDescriptor(connection, uri, revisionNumber);
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
if (connection != null) {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new ServiceAccessException(this, e);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
}
} else {
return adapter.retrieveRevisionDescriptor(getCurrentConnection(), uri, revisionNumber);
}
}
/**
* Create a new revision descriptor.
*
* @param uri Uri
* @param revisionDescriptor Node revision descriptor
* @exception ServiceAccessException Service access error
*/
public void createRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
adapter.createRevisionDescriptor(getCurrentConnection(), uri, revisionDescriptor);
}
/**
* Update a revision descriptor.
*
* @param uri Uri
* @param revisionDescriptors Node revision descriptor
* @exception ServiceAccessException Service access error
* @exception RevisionDescriptorNotFoundException Revision descriptor
* was not found
*/
public void storeRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
adapter.storeRevisionDescriptor(getCurrentConnection(), uri, revisionDescriptor);
}
/**
* Remove a revision descriptor.
*
* @param uri Uri
* @param revisionNumber Revision number
* @exception ServiceAccessException Service access error
*/
public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber) throws ServiceAccessException {
adapter.removeRevisionDescriptor(getCurrentConnection(), uri, revisionNumber);
}
// -------------------------------------------- ContentStore Implementation
/**
* Retrieve revision content.
*
* @param uri Uri
* @param revisionNumber Node revision number
*/
public NodeRevisionContent retrieveRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionNotFoundException {
if (getCurrentlyActiveTransactionalResource() == null) {
Connection connection = null;
try {
connection = getNewConnection();
return adapter.retrieveRevisionContent(connection, uri, revisionDescriptor, true);
} catch (SQLException e) {
// only close connection in case of error as standard closing
// will be done in adapter or upon closing of stream
if (connection != null) {
try {
if (!tmCommits) {
connection.rollback();
}
} catch (SQLException e2) {
throw new ServiceAccessException(this, e2);
} finally {
try {
connection.close();
} catch (SQLException e2) {
getLogger().log(e2, LOG_CHANNEL, Logger.WARNING);
}
}
}
throw new ServiceAccessException(this, e);
}
} else {
return adapter.retrieveRevisionContent(getCurrentConnection(), uri, revisionDescriptor, false);
}
}
/**
* Create a new revision
*
* @param uri Uri
* @param revisionDescriptor Node revision descriptor
* @param revisionContent Node revision content
*/
public void createRevisionContent(
Uri uri,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionAlreadyExistException {
adapter.createRevisionContent(getCurrentConnection(), uri, revisionDescriptor, revisionContent);
}
/**
* Modify the latest revision of an object.
*
* @param uri Uri
* @param revisionDescriptor Node revision descriptor
* @param revisionContent Node revision content
*/
public void storeRevisionContent(
Uri uri,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionNotFoundException {
adapter.storeRevisionContent(getCurrentConnection(), uri, revisionDescriptor, revisionContent);
}
/**
* Remove revision.
*
* @param uri Uri
* @param revisionNumber Node revision number
*/
public void removeRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
adapter.removeRevisionContent(getCurrentConnection(), uri, revisionDescriptor);
}
// ------------------------------------------------------ Protected Methods
// XXX just for visibility in RDBMSComparableResourcesPool
protected TransactionalResource getCurrentlyActiveTransactionalResource() {
return super.getCurrentlyActiveTransactionalResource();
}
/**
* Get the Connection object associated with the current transaction.
*/
protected Connection getCurrentConnection() throws ServiceAccessException {
getLogger().log("Getting current connection for thread " + Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId) getCurrentlyActiveTransactionalResource();
if (id == null) {
getLogger().log("No id for current thread - called outside transaction?", LOG_CHANNEL, Logger.DEBUG);
return null;
}
return id.connection;
}
abstract protected Connection getNewConnection() throws SQLException;
protected TransactionalResource createTransactionResource(Xid xid) throws SQLException {
return new TransactionId(xid);
}
private class TransactionId extends AbstractTransactionalResource {
Xid xid;
int status;
Connection connection;
TransactionId(Xid xid) throws SQLException {
super(xid);
status = STATUS_ACTIVE;
connection = getNewConnection();
}
public void commit() throws XAException {
try {
if (!tmCommits) {
connection.commit();
}
} catch (SQLException e) {
throw new XAException(XAException.XA_RBCOMMFAIL);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
public void rollback() throws XAException {
try {
if (!tmCommits) {
connection.rollback();
}
} catch (SQLException e) {
throw new XAException(XAException.XA_RBCOMMFAIL);
} finally {
try {
connection.close();
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
}
public int prepare() throws XAException {
// no check possible
return XA_OK;
}
public void begin() throws XAException {
}
public void suspend() throws XAException {
}
public void resume() throws XAException {
}
}
}