org.modeshape.jca.JcrManagedConnection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modeshape-jca Show documentation
Show all versions of modeshape-jca Show documentation
JCA Resource adapter implementation
The newest version!
/*
* ModeShape (http://www.modeshape.org)
*
* 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.modeshape.jca;
import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.resource.ResourceException;
import javax.resource.spi.ConnectionEvent;
import javax.resource.spi.ConnectionEventListener;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.LocalTransaction;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionMetaData;
import javax.security.auth.Subject;
import javax.transaction.xa.XAResource;
import org.modeshape.common.logging.Logger;
import org.modeshape.jcr.JcrSession;
import org.modeshape.jcr.txn.Transactions;
/**
* JcrManagedConnection
*
* @author kulikov
*/
public class JcrManagedConnection implements ManagedConnection {
private static final Logger LOGGER = Logger.getLogger(JcrManagedConnection.class);
/**
* The logwriter
*/
private PrintWriter logwriter;
/**
* ManagedConnectionFactory
*/
private final JcrManagedConnectionFactory mcf;
/**
* Listeners
*/
private final List listeners = new CopyOnWriteArrayList();
private final JcrConnectionRequestInfo cri;
private JcrSession session;
private Transactions transactions;
// Handles.
private final List handles = new CopyOnWriteArrayList();
/**
* Creates new instance of the managed connection.
*
* @param mcf Managed Connection Factory instance
* @param cri Connection request info
* @throws ResourceException if there is an error opening the session
*/
public JcrManagedConnection( JcrManagedConnectionFactory mcf,
JcrConnectionRequestInfo cri ) throws ResourceException {
this.mcf = mcf;
this.cri = cri;
this.logwriter = null;
// init repository and open session
this.session = openSession();
this.transactions = session.getRepository().transactions();
}
/**
* Gets the managed connection factory.
*
* @return Managed connection factory object.
*/
public JcrManagedConnectionFactory getManagedConnectionFactory() {
return mcf;
}
/**
* Gets the connection request info.
*
* @return Connection request info object.
*/
public JcrConnectionRequestInfo getConnectionRequestInfo() {
return cri;
}
/**
* Add a session handle.
*
* @param handle the session handle object to add
*/
private void addHandle( JcrSessionHandle handle ) {
handles.add(handle);
}
/**
* Remove a session handle.
*
* @param handle session handle to remove.
*/
private void removeHandle( JcrSessionHandle handle ) {
handles.remove(handle);
}
/**
* Create a new session.
*
* @return new JCR session handle object.
* @throws ResourceException if there is an error opening the session
*/
private JcrSession openSession() throws ResourceException {
try {
Repository repo = mcf.getRepository();
Session s = repo.login(cri.getCredentials(), cri.getWorkspace());
return (JcrSession) s;
} catch (RepositoryException e) {
throw new ResourceException("Failed to create session: " + e.getMessage(), e);
}
}
/**
* Creates a new connection handle for the underlying physical connection represented by the ManagedConnection instance.
*
* @param subject Security context as JAAS subject
* @param cxRequestInfo ConnectionRequestInfo instance
* @return generic Object instance representing the connection handle.
* @throws ResourceException generic exception if operation fails
*/
@Override
public Object getConnection( Subject subject,
ConnectionRequestInfo cxRequestInfo ) throws ResourceException {
JcrSessionHandle handle = new JcrSessionHandle(this);
addHandle(handle);
return handle;
}
/**
* Used by the container to change the association of an application-level connection handle with a ManagedConneciton
* instance.
*
* @param connection Application-level connection handle
* @throws ResourceException generic exception if operation fails
*/
@Override
public void associateConnection( Object connection ) throws ResourceException {
JcrSessionHandle handle = (JcrSessionHandle)connection;
if (handle.getManagedConnection() != this) {
handle.getManagedConnection().removeHandle(handle);
handle.setManagedConnection(this);
addHandle(handle);
}
}
/**
* Application server calls this method to force any cleanup on the ManagedConnection instance.
*
* @throws ResourceException generic exception if operation fails
*/
@Override
public void cleanup() throws ResourceException {
this.session.logout();
this.session = openSession();
this.transactions = session.getRepository().transactions();
this.handles.clear();
}
/**
* Destroys the physical connection to the underlying resource manager.
*
* @throws ResourceException generic exception if operation fails
*/
@Override
public void destroy() throws ResourceException {
LOGGER.debug("Shutting down connection to repo '{0}'", mcf.getRepositoryURL());
this.session.logout();
this.handles.clear();
}
/**
* Adds a connection event listener to the ManagedConnection instance.
*
* @param listener A new ConnectionEventListener to be registered
*/
@Override
public void addConnectionEventListener( ConnectionEventListener listener ) {
if (listener == null) {
throw new IllegalArgumentException("Listener is null");
}
listeners.add(listener);
}
/**
* Removes an already registered connection event listener from the ManagedConnection instance.
*
* @param listener already registered connection event listener to be removed
*/
@Override
public void removeConnectionEventListener( ConnectionEventListener listener ) {
if (listener == null) {
throw new IllegalArgumentException("Listener is null");
}
listeners.remove(listener);
}
/**
* Close handle
*
* @param handle The handle
*/
protected void closeHandle( JcrSessionHandle handle ) {
ConnectionEvent event = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
event.setConnectionHandle(handle);
for (ConnectionEventListener cel : listeners) {
cel.connectionClosed(event);
}
}
/**
* Gets the log writer for this ManagedConnection instance.
*
* @return Character output stream associated with this Managed-Connection instance
* @throws ResourceException generic exception if operation fails
*/
@Override
public PrintWriter getLogWriter() throws ResourceException {
return logwriter;
}
/**
* Sets the log writer for this ManagedConnection instance.
*
* @param out Character Output stream to be associated
* @throws ResourceException generic exception if operation fails
*/
@Override
public void setLogWriter( PrintWriter out ) throws ResourceException {
logwriter = out;
}
/**
* Returns an javax.resource.spi.LocalTransaction
instance.
*
* @return LocalTransaction instance
* @throws ResourceException generic exception if operation fails
*/
@Override
public LocalTransaction getLocalTransaction() throws ResourceException {
return new JcrLocalTransaction(transactions);
}
/**
* Returns an javax.transaction.xa.XAresource
instance.
*
* @return XAResource instance
* @throws ResourceException generic exception if operation fails
*/
@Override
public XAResource getXAResource() throws ResourceException {
throw new UnsupportedOperationException("ModeShape 5 does not support XA");
}
/**
* Gets the metadata information for this connection's underlying EIS resource manager instance.
*
* @return ManagedConnectionMetaData instance
* @throws ResourceException generic exception if operation fails
*/
@Override
public ManagedConnectionMetaData getMetaData() throws ResourceException {
try {
return new JcrManagedConnectionMetaData(mcf.getRepository(), session);
} catch (Exception e) {
throw new ResourceException(e);
}
}
/**
* Searches session object using handle.
*
* @param handle the session handle
* @return session related to specified handle.
*/
public Session getSession( JcrSessionHandle handle ) {
if ((handles.size() > 0) && (handles.get(0) == handle)) {
return session;
}
throw new java.lang.IllegalStateException("Inactive logical session handle called");
}
}