
de.tsl2.nano.resource.fs.impl.FsManagedConnection Maven / Gradle / Ivy
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Erwin Guib, Thomas Schneider
* created on: Oct 25, 2009
*
* Copyright: (c) Thomas Schneider, all rights reserved
*/
package de.tsl2.nano.resource.fs.impl;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.resource.NotSupportedException;
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.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.resource.fs.FsConnection;
import de.tsl2.nano.resource.fs.FsConnectionFactory;
/**
* The managed connection (connector internal) behind a FsConnection.
*
* @author Erwin Guib, Thomas Schneider
* @author Thomas Schneider, Thomas Schneider
* @version $Revision$
*/
public class FsManagedConnection implements ManagedConnection, FsConnection {
private static final Log LOG = LogFactory.getLog(FsManagedConnection.class);
private final ArrayList listeners = new ArrayList();
private final Subject subject;
private final FsConnectionRequestInfo info;
private final List connections = new ArrayList();
private File rootDir;
/**
* Constructor.
*
* @param subject the subject (from App-Server)
* @param info the connection info
*/
public FsManagedConnection(Subject subject, FsConnectionRequestInfo info) {
LOG.info("new subject=" + subject + " info=" + info);
this.subject = subject;
this.info = info;
if (!isUseAbsoluteFilePath()) {
rootDir = new File(info.getRootDirPath());
LOG.info("absolute rootDirPath: " + rootDir.getAbsolutePath());
}
}
/**
* Check if this connection is matching for the given parameters (used by
* {@link FsManagedConnectionFactory#matchManagedConnections(java.util.Set, Subject, ConnectionRequestInfo)}
*
* @param subject a subject
* @param info a info
* @return true when matching
*/
public boolean isMatch(Subject subject, ConnectionRequestInfo info) {
return this.info.equals(info);
}
/**
* {@inheritDoc}
*/
@Override
public Object getConnection(Subject subject, ConnectionRequestInfo info) throws ResourceException {
if (!isMatch(subject, info)) {
LOG.error("getConnection called with wrong info=" + info + " internal info=" + this.info);
throw new ResourceException("Info missmatch: parameter 'info'=" + info + " 'internal info'=" + this.info);
}
final FsConnectionImpl con = new FsConnectionImpl();
associateConnection(con);
return con;
}
/**
* {@inheritDoc}
*/
@Override
public void associateConnection(Object connection) throws ResourceException {
LOG.debug("associateConnection con=" + connection);
final FsConnectionImpl fsCon = (FsConnectionImpl) connection;
connections.add(fsCon);
fsCon.setManagedConnection(this);
}
/**
* @param con
*/
protected void detachConnection(FsConnectionImpl con) {
LOG.debug("detachConnection con=" + con);
con.setManagedConnection(null);
connections.remove(con);
final ConnectionEvent event = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
event.setConnectionHandle(con);
fireConnectionEvent(event);
}
/**
* {@inheritDoc}
*/
@Override
public LocalTransaction getLocalTransaction() throws ResourceException {
throw new NotSupportedException();
}
/**
* {@inheritDoc}
*/
@Override
public XAResource getXAResource() throws ResourceException {
throw new NotSupportedException();
}
/**
* {@inheritDoc}
*/
@Override
public ManagedConnectionMetaData getMetaData() throws ResourceException {
return new FsManagedConnectionMetaData(subject);
}
/**
* {@inheritDoc}
*/
@Override
public void cleanup() throws ResourceException {
LOG.info("cleanup");
// Attention: detachConnection will remove the connection from list =>
// cannot use iterator
while (connections.size() > 0) {
final FsConnectionImpl con = connections.get(0);
detachConnection(con);
}
}
/**
* {@inheritDoc}
*/
@Override
public void destroy() throws ResourceException {
// nothing to do
LOG.info("destroy");
}
/**
* {@inheritDoc}
*/
@Override
public void addConnectionEventListener(ConnectionEventListener listener) {
listeners.add(listener);
}
/**
* {@inheritDoc}
*/
@Override
public void removeConnectionEventListener(ConnectionEventListener listener) {
listeners.remove(listener);
}
/**
* Fire an event.
*
* @param event the event
*/
protected void fireConnectionEvent(ConnectionEvent event) {
for (final ConnectionEventListener l : listeners) {
switch (event.getId()) {
case ConnectionEvent.CONNECTION_CLOSED:
l.connectionClosed(event);
break;
case ConnectionEvent.CONNECTION_ERROR_OCCURRED:
l.connectionErrorOccurred(event);
break;
case ConnectionEvent.LOCAL_TRANSACTION_COMMITTED:
l.localTransactionCommitted(event);
break;
case ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK:
l.localTransactionRolledback(event);
break;
case ConnectionEvent.LOCAL_TRANSACTION_STARTED:
l.localTransactionStarted(event);
break;
default:
LOG.error("unknown event id=" + event.getId());
}
}
}
/**
* {@inheritDoc}
*/
@Override
public PrintWriter getLogWriter() throws ResourceException {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public void setLogWriter(PrintWriter writer) throws ResourceException {
}
/**
* {@inheritDoc}
*/
@Override
public void close() {
// nothing to do
throw new IllegalStateException("this method must never be called");
}
/**
* {@inheritDoc}
*/
@Override
public void delete(String fileName) throws IOException {
final File f = getFile(fileName);
if (f.isDirectory()) {
try {
FileUtils.deleteDirectory(f);
} catch (final IOException e) {
LOG.error("Error deleting directory: " + fileName, e);
throw e;
}
} else {
f.delete();
}
}
/**
* {@inheritDoc}
*/
@Override
public void rename(String sourceName, String destinationName) {
File file = getFile(sourceName);
file.renameTo(getFile(destinationName));
}
/**
* {@inheritDoc}
*/
@Override
public void writeFile(String destFileName, InputStream data, boolean overwrite) throws IOException {
final File f = getFile(destFileName);
final FileOutputStream out = new FileOutputStream(f);
if (!overwrite && f.exists()) {
final String msg = "Error writing file (already exists):" + destFileName;
LOG.error(msg);
throw new IOException(msg);
}
final File parentDir = f.getParentFile();
if (!parentDir.exists() && !parentDir.mkdirs()) {
final String msg = "failed to create parent dir=" + parentDir;
LOG.error(msg);
throw new IOException(msg);
}
try {
IOUtils.copy(data, out);
} catch (final IOException e) {
LOG.error("Error writing file:" + destFileName, e);
throw e;
} finally {
IOUtils.closeQuietly(data);
IOUtils.closeQuietly(out);
}
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getInputStream(String fileName) throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream(getFile(fileName));
} catch (final FileNotFoundException e) {
LOG.error("file not found f=" + fileName, e);
throw e;
}
final BufferedInputStream bis = new BufferedInputStream(fis);
return bis;
}
/**
* @param fileName
* @return absolute file
*/
protected File getFile(String fileName) {
final File f = isUseAbsoluteFilePath() ? new File(fileName) : new File(rootDir, fileName);
LOG.debug("accessing file: " + f.getAbsolutePath());
return f;
}
/**
* {@inheritDoc}
*/
@Override
public boolean exists(String fileName) {
final File f = getFile(fileName);
return f.exists();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isDirectory(String fileName) {
final File f = getFile(fileName);
return f.isDirectory();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isFile(String fileName) {
final File f = getFile(fileName);
return f.isFile();
}
/**
* if rootDir is @link{FsConnectionFactory#MODE_ABSOLUTE_PATH}, the given full file path will be used - rootDir will
* be ignored.
*/
public final boolean isUseAbsoluteFilePath() {
return isUseAbsoluteFilePath(info.getRootDirPath());
}
/**
* if rootDir is @link{FsConnectionFactory#MODE_ABSOLUTE_PATH}, the given full file path will be used - rootDir will
* be ignored.
*/
public static final boolean isUseAbsoluteFilePath(String rootDirPath) {
return rootDirPath.equals(FsConnectionFactory.MODE_ABSOLUTE_PATH);
}
/**
* @see de.tsl2.nano.resource.fs.FsConnection#getDirectoryEntries(java.lang.String)
*/
@Override
public String[] getDirectoryEntries(String dirName) throws IOException {
if (!exists(dirName)) {
throw new IllegalArgumentException(dirName + " does not exist!");
}
if (!isDirectory(dirName)) {
throw new IllegalArgumentException(dirName + " must be of type directory - but is a file!");
}
return getFile(dirName).list();
}
@Override
public boolean isOpen() {
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy