com.sun.enterprise.resource.ResourceHandle Maven / Gradle / Ivy
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.enterprise.resource;
import static java.util.logging.Level.FINEST;
import java.util.logging.Logger;
import javax.security.auth.Subject;
import javax.transaction.xa.XAResource;
import com.sun.appserv.connectors.internal.api.PoolingException;
import com.sun.enterprise.connectors.ConnectorRuntime;
import com.sun.enterprise.resource.allocator.LocalTxConnectorAllocator;
import com.sun.enterprise.resource.allocator.ResourceAllocator;
import com.sun.enterprise.transaction.spi.TransactionalResource;
import com.sun.logging.LogDomains;
import jakarta.resource.spi.ConnectionEventListener;
import jakarta.transaction.Transaction;
/**
* ResourceHandle encapsulates a resource connection. Equality on the handle is based on the id field
*
* @author Tony Ng
*/
public class ResourceHandle implements com.sun.appserv.connectors.internal.api.ResourceHandle, TransactionalResource {
private static Logger logger = LogDomains.getLogger(ResourceHandle.class, LogDomains.RSR_LOGGER);
// unique ID for resource handles
static private long idSequence;
private long id;
private ClientSecurityInfo info;
private Object resource; // represents MC
private ResourceSpec spec;
private XAResource xares;
private Object userConnection; // represents connection-handle to user
private ResourceAllocator resourceAllocator;
private Object instance; // the component instance holding this resource
private int shareCount; // sharing within a component (XA only)
private boolean supportsXAResource;
private volatile boolean busy;
private Subject subject;
private ResourceState state;
private ConnectionEventListener listener;
private boolean enlistmentSuspended;
private boolean supportsLazyEnlistment_;
private boolean supportsLazyAssoc_;
public final Object lock = new Object();
private long lastValidated; // holds the latest time at which the connection was validated.
private int usageCount; // holds the no. of times the handle(connection) is used so far.
private int partition;
private boolean isDestroyByLeakTimeOut;
private boolean connectionErrorOccurred;
static private long getNextId() {
synchronized (ResourceHandle.class) {
idSequence++;
return idSequence;
}
}
private boolean markedReclaim;
public ResourceHandle(Object resource, ResourceSpec spec, ResourceAllocator alloc, ClientSecurityInfo info) {
this.id = getNextId();
this.spec = spec;
this.info = info;
this.resource = resource;
this.resourceAllocator = alloc;
if (alloc instanceof LocalTxConnectorAllocator) {
supportsXAResource = false;
} else {
supportsXAResource = true;
}
if (resource instanceof jakarta.resource.spi.LazyEnlistableManagedConnection) {
supportsLazyEnlistment_ = true;
}
if (resource instanceof jakarta.resource.spi.DissociatableManagedConnection) {
supportsLazyAssoc_ = true;
}
}
/**
* Does this resource need enlistment to transaction manager?
*/
@Override
public boolean isTransactional() {
return resourceAllocator.isTransactional();
}
/**
* To check whether lazy enlistment is suspended or not.
* If true, TM will not do enlist/lazy enlist.
*
* @return boolean
*/
@Override
public boolean isEnlistmentSuspended() {
return enlistmentSuspended;
}
@Override
public void setEnlistmentSuspended(boolean enlistmentSuspended) {
this.enlistmentSuspended = enlistmentSuspended;
}
public void markForReclaim(boolean reclaim) {
this.markedReclaim = reclaim;
}
/**
* To check if the resourceHandle is marked for leak reclaim or not.
*
* @return boolean
*/
public boolean isMarkedForReclaim() {
return markedReclaim;
}
@Override
public boolean supportsXA() {
return supportsXAResource;
}
public ResourceAllocator getResourceAllocator() {
return resourceAllocator;
}
public Object getResource() {
return resource;
}
public ClientSecurityInfo getClientSecurityInfo() {
return info;
}
public void setResourceSpec(ResourceSpec spec) {
this.spec = spec;
}
public ResourceSpec getResourceSpec() {
return spec;
}
@Override
public XAResource getXAResource() {
return xares;
}
public Object getUserConnection() {
return userConnection;
}
@Override
public void setComponentInstance(Object instance) {
this.instance = instance;
}
@Override
public void closeUserConnection() throws PoolingException {
getResourceAllocator().closeUserConnection(this);
}
@Override
public Object getComponentInstance() {
return instance;
}
public long getId() {
return id;
}
public void fillInResourceObjects(Object userConnection, XAResource xaRes) {
if (userConnection != null) {
this.userConnection = userConnection;
}
if (xaRes != null) {
if (logger.isLoggable(FINEST)) {
// When Log level is Finest, XAResourceWrapper is used to log
// all XA interactions - Don't wrap XAResourceWrapper if it is
// already wrapped
if ((xaRes instanceof XAResourceWrapper) || (xaRes instanceof ConnectorXAResource)) {
this.xares = xaRes;
} else {
this.xares = new XAResourceWrapper(xaRes);
}
} else {
this.xares = xaRes;
}
}
}
// For XA-capable connections, multiple connections within a
// component are collapsed into one. shareCount keeps track of
// the number of additional shared connections
public void incrementCount() {
shareCount++;
}
public void decrementCount() {
if (shareCount == 0) {
throw new IllegalStateException("shareCount cannot be negative");
}
shareCount--;
}
public int getShareCount() {
return shareCount;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
public Subject getSubject() {
return subject;
}
@Override
public boolean equals(Object other) {
if (other == null) {
return false;
}
if (other instanceof ResourceHandle) {
return this.id == (((ResourceHandle) other).id);
}
return false;
}
@Override
public int hashCode() {
return Long.valueOf(id).hashCode();
}
@Override
public String toString() {
return String.valueOf(id);
}
public void setConnectionErrorOccurred() {
connectionErrorOccurred = true;
}
public boolean hasConnectionErrorOccurred() {
return connectionErrorOccurred;
}
public void setResourceState(ResourceState state) {
this.state = state;
}
public ResourceState getResourceState() {
return state;
}
public void setListener(ConnectionEventListener l) {
this.listener = l;
}
public ConnectionEventListener getListener() {
return listener;
}
@Override
public boolean isShareable() {
return resourceAllocator.shareableWithinComponent();
}
@Override
public void destroyResource() {
throw new UnsupportedOperationException("Transaction is not supported yet");
}
@Override
public boolean isEnlisted() {
return state != null && state.isEnlisted();
}
public long getLastValidated() {
return lastValidated;
}
public void setLastValidated(long lastValidated) {
this.lastValidated = lastValidated;
}
public int getUsageCount() {
return usageCount;
}
public void incrementUsageCount() {
usageCount++;
}
public int getPartition() {
return partition;
}
public void setPartition(int partition) {
this.partition = partition;
}
@Override
public String getName() {
return spec.getResourceId();
}
public boolean supportsLazyEnlistment() {
return supportsLazyEnlistment_;
}
public boolean supportsLazyAssociation() {
return supportsLazyAssoc_;
}
@Override
public void enlistedInTransaction(Transaction transaction) throws IllegalStateException {
ConnectorRuntime.getRuntime().getPoolManager().resourceEnlisted(transaction, this);
}
public void setBusy(boolean isBusy) {
busy = isBusy;
}
public boolean isBusy() {
return busy;
}
public boolean getDestroyByLeakTimeOut() {
return isDestroyByLeakTimeOut;
}
public void setDestroyByLeakTimeOut(boolean isDestroyByLeakTimeOut) {
this.isDestroyByLeakTimeOut = isDestroyByLeakTimeOut;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy