Derek Hulley 0c10d61a48 Merged V2.0 to HEAD
svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V2.0@5141 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V2.0@51352 .
      - FLOSS
      - Some files will need a follow-up
         -root/projects/repository/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java (not yet on HEAD: 5094)
         -root/projects/repository/source/java/org/alfresco/filesys/server/state/FileStateLockManager.java (not yet on HEAD: 5093)
         -onContentUpdateRecord (not on HEAD)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5167 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2007-02-16 06:44:46 +00:00

679 lines
17 KiB
Java

/*
* Copyright (C) 2005-2006 Alfresco, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.server;
import java.net.InetAddress;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.auth.AuthContext;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.core.SharedDevice;
import org.alfresco.filesys.server.core.SharedDeviceList;
import org.alfresco.filesys.server.filesys.FilesysTransaction;
import org.alfresco.service.transaction.TransactionService;
/**
* Server Session Base Class
* <p>
* Base class for server session implementations for different protocols.
*/
public abstract class SrvSession
{
// Network server this session is associated with
private NetworkServer m_server;
// Session id/slot number
private int m_sessId;
// Unique session id string
private String m_uniqueId;
// Process id
private int m_processId = -1;
// Session/user is logged on/validated
private boolean m_loggedOn;
// Client details
private ClientInfo m_clientInfo;
// Debug flags for this session
private int m_debug;
// Session shutdown flag
private boolean m_shutdown;
// Protocol type
private String m_protocol;
// Remote client/host name
private String m_remoteName;
// Authentication token, used during logon
private Object m_authToken;
// Authentication context, used during the initial session setup phase
private AuthContext m_authContext;
// List of dynamic/temporary shares created for this session
private SharedDeviceList m_dynamicShares;
// Active transaction and read/write flag
private ThreadLocal<FilesysTransaction> m_tx = new ThreadLocal<FilesysTransaction>();
// UserTransaction m_transaction;
// private boolean m_readOnlyTrans;
// Request and transaction counts
protected int m_reqCount;
protected int m_transCount;
protected int m_transConvCount;
/**
* Class constructor
*
* @param sessId int
* @param srv NetworkServer
* @param proto String
* @param remName String
*/
public SrvSession(int sessId, NetworkServer srv, String proto, String remName)
{
m_sessId = sessId;
m_server = srv;
setProtocolName(proto);
setRemoteName(remName);
}
/**
* Add a dynamic share to the list of shares created for this session
*
* @param shrDev SharedDevice
*/
public final void addDynamicShare(SharedDevice shrDev) {
// Check if the dynamic share list must be allocated
if ( m_dynamicShares == null)
m_dynamicShares = new SharedDeviceList();
// Add the new share to the list
m_dynamicShares.addShare(shrDev);
}
/**
* Return the authentication token
*
* @return Object
*/
public final Object getAuthenticationToken()
{
return m_authToken;
}
/**
* Determine if the authentication token is set
*
* @return boolean
*/
public final boolean hasAuthenticationToken()
{
return m_authToken != null ? true : false;
}
/**
* Return the process id
*
* @return int
*/
public final int getProcessId()
{
return m_processId;
}
/**
* Return the remote client network address
*
* @return InetAddress
*/
public abstract InetAddress getRemoteAddress();
/**
* Return the session id for this session.
*
* @return int
*/
public final int getSessionId()
{
return m_sessId;
}
/**
* Return the server this session is associated with
*
* @return NetworkServer
*/
public final NetworkServer getServer()
{
return m_server;
}
/**
* Check if the session has valid client information
*
* @return boolean
*/
public final boolean hasClientInformation()
{
return m_clientInfo != null ? true : false;
}
/**
* Return the client information
*
* @return ClientInfo
*/
public final ClientInfo getClientInformation()
{
return m_clientInfo;
}
/**
* Check if the session has an authentication context
*
* @return boolean
*/
public final boolean hasAuthenticationContext()
{
return m_authContext != null ? true : false;
}
/**
* Return the authentication context for this sesion
*
* @return AuthContext
*/
public final AuthContext getAuthenticationContext()
{
return m_authContext;
}
/**
* Determine if the session has any dynamic shares
*
* @return boolean
*/
public final boolean hasDynamicShares() {
return m_dynamicShares != null ? true : false;
}
/**
* Return the list of dynamic shares created for this session
*
* @return SharedDeviceList
*/
public final SharedDeviceList getDynamicShareList() {
return m_dynamicShares;
}
/**
* Determine if the protocol type has been set
*
* @return boolean
*/
public final boolean hasProtocolName()
{
return m_protocol != null ? true : false;
}
/**
* Return the protocol name
*
* @return String
*/
public final String getProtocolName()
{
return m_protocol;
}
/**
* Determine if the remote client name has been set
*
* @return boolean
*/
public final boolean hasRemoteName()
{
return m_remoteName != null ? true : false;
}
/**
* Return the remote client name
*
* @return String
*/
public final String getRemoteName()
{
return m_remoteName;
}
/**
* Determine if the session is logged on/validated
*
* @return boolean
*/
public final boolean isLoggedOn()
{
return m_loggedOn;
}
/**
* Determine if the session has been shut down
*
* @return boolean
*/
public final boolean isShutdown()
{
return m_shutdown;
}
/**
* Return the unique session id
*
* @return String
*/
public final String getUniqueId()
{
return m_uniqueId;
}
/**
* Determine if the specified debug flag is enabled.
*
* @return boolean
* @param dbg int
*/
public final boolean hasDebug(int dbgFlag)
{
if ((m_debug & dbgFlag) != 0)
return true;
return false;
}
/**
* Set the authentication token
*
* @param authToken Object
*/
public final void setAuthenticationToken(Object authToken)
{
m_authToken = authToken;
}
/**
* Set the authentication context, used during the initial session setup phase
*
* @param ctx AuthContext
*/
public final void setAuthenticationContext( AuthContext ctx)
{
m_authContext = ctx;
}
/**
* Set the client information
*
* @param client ClientInfo
*/
public final void setClientInformation(ClientInfo client)
{
m_clientInfo = client;
}
/**
* Set the debug output interface.
*
* @param flgs int
*/
public final void setDebug(int flgs)
{
m_debug = flgs;
}
/**
* Set the logged on/validated status for the session
*
* @param loggedOn boolean
*/
public final void setLoggedOn(boolean loggedOn)
{
m_loggedOn = loggedOn;
}
/**
* Set the process id
*
* @param id int
*/
public final void setProcessId(int id)
{
m_processId = id;
}
/**
* Set the protocol name
*
* @param name String
*/
public final void setProtocolName(String name)
{
m_protocol = name;
}
/**
* Set the remote client name
*
* @param name String
*/
public final void setRemoteName(String name)
{
m_remoteName = name;
}
/**
* Set the session id for this session.
*
* @param id int
*/
public final void setSessionId(int id)
{
m_sessId = id;
}
/**
* Set the unique session id
*
* @param unid String
*/
public final void setUniqueId(String unid)
{
m_uniqueId = unid;
}
/**
* Set the shutdown flag
*
* @param flg boolean
*/
protected final void setShutdown(boolean flg)
{
m_shutdown = flg;
}
/**
* Close the network session
*/
public void closeSession()
{
// Release any dynamic shares owned by this session
if ( hasDynamicShares()) {
// Close the dynamic shares
getServer().getShareMapper().deleteShares(this);
}
}
/**
* Create a read transaction, if not already active
*
* @param transService TransactionService
* @return boolean
* @exception AlfrescoRuntimeException
*/
public final boolean beginReadTransaction( TransactionService transService)
throws AlfrescoRuntimeException
{
return beginTransaction(transService, true);
}
/**
* Create a write transaction, if not already active
*
* @param transService TransactionService
* @return boolean
* @exception AlfrescoRuntimeException
*/
public final boolean beginWriteTransaction( TransactionService transService)
throws AlfrescoRuntimeException
{
return beginTransaction(transService, false);
}
/**
* Create and start a transaction, if not already active
*
* @param transService TransactionService
* @param readOnly boolean
* @return boolean
* @exception AlfrescoRuntimeException
*/
private final boolean beginTransaction(TransactionService transService, boolean readOnly)
throws AlfrescoRuntimeException
{
boolean created = false;
// Get the filesystem transaction
FilesysTransaction filesysTx = m_tx.get();
if ( filesysTx == null)
{
filesysTx = new FilesysTransaction();
m_tx.set( filesysTx);
}
// If there is an active transaction check that it is the required type
if ( filesysTx.hasTransaction())
{
// Get the active transaction
UserTransaction tx = filesysTx.getTransaction();
// Check if the current transaction is marked for rollback
try
{
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK ||
tx.getStatus() == Status.STATUS_ROLLEDBACK ||
tx.getStatus() == Status.STATUS_ROLLING_BACK)
{
// Rollback the current transaction
tx.rollback();
}
}
catch ( Exception ex)
{
}
// Check if the transaction is a write transaction, if write has been requested
if ( readOnly == false && filesysTx.isReadOnly() == true)
{
// Commit the read-only transaction
try
{
tx.commit();
m_transConvCount++;
}
catch ( Exception ex)
{
throw new AlfrescoRuntimeException("Failed to commit read-only transaction, " + ex.getMessage());
}
finally
{
// Clear the active transaction
filesysTx.clearTransaction();
}
}
}
// Create the transaction
if ( filesysTx.hasTransaction() == false)
{
try
{
UserTransaction userTrans = transService.getUserTransaction(readOnly);
userTrans.begin();
created = true;
// Store the transaction
filesysTx.setTransaction( userTrans, readOnly);
m_transCount++;
}
catch (Exception ex)
{
throw new AlfrescoRuntimeException("Failed to create transaction, " + ex.getMessage());
}
}
return created;
}
/**
* End a transaction by either committing or rolling back
*
* @exception AlfrescoRuntimeException
*/
public final void endTransaction()
throws AlfrescoRuntimeException
{
// Get the filesystem transaction
FilesysTransaction filesysTx = m_tx.get();
// Check if there is an active transaction
if ( filesysTx != null && filesysTx.hasTransaction())
{
// Get the active transaction
UserTransaction tx = filesysTx.getTransaction();
try
{
// Commit or rollback the transaction
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
{
// Transaction is marked for rollback
tx.rollback();
}
else
{
// Commit the transaction
tx.commit();
}
}
catch ( Exception ex)
{
throw new AlfrescoRuntimeException("Failed to end transaction", ex);
}
finally
{
// Clear the current transaction
filesysTx.clearTransaction();
}
}
}
/**
* Determine if the session has an active transaction
*
* @return boolean
*/
public final boolean hasUserTransaction()
{
// Get the filesystem transaction
FilesysTransaction filesysTx = m_tx.get();
if ( filesysTx != null)
return filesysTx.hasTransaction();
return false;
}
/**
* Get the active transaction and clear the stored transaction
*
* @return UserTransaction
*/
public final UserTransaction getUserTransaction()
{
// Get the filesystem transaction
UserTransaction userTrans = null;
FilesysTransaction filesysTx = m_tx.get();
if ( filesysTx != null)
{
userTrans = filesysTx.getTransaction();
filesysTx.clearTransaction();
}
return userTrans;
}
}