Merge V1.3 to HEAD (2976:3004)

svn merge svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@2976 svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@3004 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3335 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-07-18 14:50:00 +00:00
parent d1acea9b24
commit d8b6213ee9
20 changed files with 2295 additions and 624 deletions

View File

@@ -19,6 +19,19 @@ package org.alfresco.filesys.ftp;
import java.net.*;
import java.io.*;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.filesys.AccessMode;
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
import org.alfresco.filesys.server.filesys.DiskInterface;
import org.alfresco.filesys.server.filesys.FileAction;
import org.alfresco.filesys.server.filesys.FileOpenParams;
import org.alfresco.filesys.server.filesys.FileStatus;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.filesys.NotifyChange;
import org.alfresco.filesys.server.filesys.TreeConnection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* FTP Data Session Class
* <p>
@@ -30,9 +43,16 @@ import java.io.*;
*
* @author GKSpencer
*/
public class FTPDataSession implements Runnable
public class FTPDataSession extends SrvSession implements Runnable
{
// Debug logging
private static final Log logger = LogFactory.getLog("org.alfresco.ftp.protocol");
// Data session command types
public enum DataCommand { StoreFile, ReturnFile };
// FTP session that this data connection is associated with
private FTPSrvSession m_cmdSess;
@@ -54,10 +74,6 @@ public class FTPDataSession implements Runnable
private ServerSocket m_passiveSock;
// Adapter to bind the passive socket to
private InetAddress m_bindAddr;
// Transfer in progress and abort file transfer flags
private boolean m_transfer;
@@ -66,7 +82,27 @@ public class FTPDataSession implements Runnable
// Send/receive data byte count
private long m_bytCount;
// Data command type
private DataCommand m_dataCmd;
// Requested file name
private String m_reqFileName;
// Path to the local file
private FTPPath m_ftpPath;
// Restart position
private long m_restartPos;
// Thread that runs the data command
private Thread m_dataThread;
/**
* Class constructor
* <p>
@@ -77,7 +113,10 @@ public class FTPDataSession implements Runnable
*/
protected FTPDataSession(FTPSrvSession sess) throws IOException
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
m_cmdSess = sess;
@@ -100,6 +139,9 @@ public class FTPDataSession implements Runnable
*/
protected FTPDataSession(FTPSrvSession sess, int localPort, InetAddress bindAddr) throws IOException
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
@@ -124,6 +166,9 @@ public class FTPDataSession implements Runnable
*/
protected FTPDataSession(FTPSrvSession sess, InetAddress bindAddr) throws IOException
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
@@ -146,6 +191,9 @@ public class FTPDataSession implements Runnable
*/
protected FTPDataSession(FTPSrvSession sess, InetAddress addr, int port)
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
@@ -171,6 +219,9 @@ public class FTPDataSession implements Runnable
*/
protected FTPDataSession(FTPSrvSession sess, int localPort, InetAddress addr, int port)
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
@@ -271,6 +322,16 @@ public class FTPDataSession implements Runnable
return m_transfer;
}
/**
* Determine if the transfer has been aborted
*
* @return boolean
*/
public final boolean isTransferAborted()
{
return m_abort;
}
/**
* Abort an in progress file transfer
*/
@@ -358,12 +419,520 @@ public class FTPDataSession implements Runnable
}
m_passiveSock = null;
}
// Commit, or rollback, any active user transaction
try
{
// Commit or rollback the transaction
endTransaction();
}
catch ( Exception ex)
{
// Debug
if ( logger.isDebugEnabled())
logger.debug("Error committing transaction", ex);
}
}
/**
* Store a file using a seperate thread to receive the data and write the file
*
* @param ftpPath FTPPath
*/
public final void doStoreFile( FTPPath ftpPath, long restartPos, String reqFileName)
{
// Set the transfer details
m_dataCmd = DataCommand.StoreFile;
m_ftpPath = ftpPath;
m_restartPos = restartPos;
m_reqFileName = reqFileName;
// Run the transfer in a seperate thread
m_dataThread = new Thread(this);
m_dataThread.setName(m_cmdSess.getUniqueId() + "_DATA_STORE");
m_dataThread.start();
}
/**
* Return a file using a seperate thread to read the file and send the data
*
* @param ftpPath FTPPath
*/
public final void doReturnFile( FTPPath ftpPath, long restartPos, String reqFileName)
{
// Set the transfer details
m_dataCmd = DataCommand.ReturnFile;
m_ftpPath = ftpPath;
m_restartPos = restartPos;
m_reqFileName = reqFileName;
// Run the transfer in a seperate thread
m_dataThread = new Thread(this);
m_dataThread.setName(m_cmdSess.getUniqueId() + "_DATA_RETURN");
m_dataThread.start();
}
/**
* Run a file send/receive in a seperate thread
*/
public void run()
{
// Setup the authentication context as we are running in a seperate thread from the main FTP session
try
{
// Setup the authentication context for the thread
m_cmdSess.authenticateDataSession();
// Run the required data command
switch ( m_dataCmd)
{
// Store a file
case StoreFile:
runStoreFile();
break;
// Return a file
case ReturnFile:
runReturnFile();
break;
}
}
catch ( org.alfresco.repo.security.authentication.AuthenticationException ex)
{
if ( logger.isErrorEnabled())
logger.error("Failed to authenticate FTP data session", ex);
// Close the data connection to the client
m_cmdSess.getFTPServer().releaseDataSession(this);
closeSession();
}
}
/**
* Return a file to the client
*/
private final void runReturnFile()
{
// Send the file to the client
OutputStream os = null;
DiskInterface disk = null;
TreeConnection tree = null;
NetworkFile netFile = null;
Socket dataSock = null;
try
{
// Open an output stream to the client
dataSock = getSocket();
os = dataSock.getOutputStream();
// Create a temporary tree connection
tree = m_cmdSess.getTreeConnection(m_ftpPath.getSharedDevice());
// Check if the file exists and it is a file, if so then open the
// file
disk = (DiskInterface) m_ftpPath.getSharedDevice().getInterface();
// Create the file open parameters
FileOpenParams params = new FileOpenParams(m_ftpPath.getSharePath(), FileAction.OpenIfExists,
AccessMode.ReadOnly, 0);
// Check if the file exists and it is a file
int sts = disk.fileExists( this, tree, m_ftpPath.getSharePath());
if (sts == FileStatus.FileExists)
{
// Open the file
netFile = disk.openFile( this, tree, params);
}
// Check if the file has been opened
if (netFile == null)
{
m_cmdSess.sendFTPResponse(550, "File " + m_reqFileName + " not available");
return;
}
// Allocate the buffer for the file data
byte[] buf = new byte[FTPSrvSession.DEFAULT_BUFFERSIZE];
long filePos = m_restartPos;
int len = -1;
while (filePos < netFile.getFileSize())
{
// Read another block of data from the file
len = disk.readFile( this, tree, netFile, buf, 0, buf.length, filePos);
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Write len=" + len + " bytes");
// Write the current data block to the client, update the file position
if (len > 0)
{
// Write the data to the client
os.write(buf, 0, len);
// Update the file position
filePos += len;
// Update the transfer byte count
m_bytCount += len;
}
// Check if the transfer has been aborted
if ( isTransferAborted())
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILE))
logger.debug(" Transfer aborted (RETR)");
// Send a status to the client
sendFTPResponse( 226, "Aborted data connection");
// Finally block will cleanup
return;
}
}
// Close the output stream to the client
os.close();
os = null;
// Indicate that the file has been transmitted
sendFTPResponse(226, "Closing data connection");
// Close the data session
m_cmdSess.getFTPServer().releaseDataSession(this);
// Close the network file
disk.closeFile( this, tree, netFile);
netFile = null;
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Transfer complete, file closed");
}
catch (SocketException ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file
// data
sendFTPResponse(426, "Data connection closed by client");
}
catch (Exception ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file
// data
sendFTPResponse(426, "Error during transmission");
}
finally
{
try
{
// Close the network file
if (netFile != null && disk != null && tree != null)
disk.closeFile(m_cmdSess, tree, netFile);
// Close the output stream to the client
if (os != null)
os.close();
// Close the data connection to the client
m_cmdSess.getFTPServer().releaseDataSession( this);
closeSession();
}
catch (Exception ex)
{
if ( logger.isErrorEnabled())
logger.error( "Error during FTP data session close", ex);
}
}
}
/**
* Store a file received from the client
*/
private final void runStoreFile()
{
// Store the file from the client
InputStream is = null;
DiskInterface disk = null;
TreeConnection tree = null;
NetworkFile netFile = null;
Socket dataSock = null;
try
{
// Create a temporary tree connection
tree = m_cmdSess.getTreeConnection(m_ftpPath.getSharedDevice());
// Check if the session has the required access to the filesystem
if (tree == null || tree.hasWriteAccess() == false)
{
// Session does not have write access to the filesystem
sendFTPResponse(550, "Access denied");
return;
}
// Check if the file exists
disk = (DiskInterface) m_ftpPath.getSharedDevice().getInterface();
int sts = disk.fileExists(this, tree, m_ftpPath.getSharePath());
if (sts == FileStatus.DirectoryExists)
{
// Return an error status
sendFTPResponse(500, "Invalid path (existing directory)");
return;
}
// Create the file open parameters
FileOpenParams params = new FileOpenParams(m_ftpPath.getSharePath(),
sts == FileStatus.FileExists ? FileAction.TruncateExisting : FileAction.CreateNotExist,
AccessMode.ReadWrite, 0);
// Create a new file to receive the data
if (sts == FileStatus.FileExists)
{
// Overwrite the existing file
netFile = disk.openFile(this, tree, params);
}
else
{
// Create a new file
netFile = disk.createFile(this, tree, params);
}
// Notify change listeners that a new file has been created
DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext();
if (diskCtx.hasChangeHandler())
diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, m_ftpPath.getSharePath());
// Send the intermediate response
sendFTPResponse(150, "File status okay, about to open data connection");
// Get the data connection socket
try
{
dataSock = getSocket();
}
catch (Exception ex)
{
}
if (dataSock == null)
{
sendFTPResponse(426, "Connection closed; transfer aborted");
return;
}
// Open an input stream from the client
is = dataSock.getInputStream();
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILE))
logger.debug("Storing ftp="
+ m_ftpPath.getFTPPath() + ", share=" + m_ftpPath.getShareName() + ", path="
+ m_ftpPath.getSharePath());
// Allocate the buffer for the file data
byte[] buf = new byte[FTPSrvSession.DEFAULT_BUFFERSIZE];
long filePos = 0;
int len = is.read(buf, 0, buf.length);
while (len > 0)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Receive len=" + len + " bytes");
// Write the current data block to the file, update the file
// position
disk.writeFile(this, tree, netFile, buf, 0, len, filePos);
filePos += len;
// Read another block of data from the client
len = is.read(buf, 0, buf.length);
}
// Close the input stream from the client
is.close();
is = null;
// Close the network file
disk.closeFile(this, tree, netFile);
netFile = null;
// Indicate that the file has been received
sendFTPResponse(226, "Closing data connection");
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Transfer complete, file closed");
}
catch (SocketException ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file data
sendFTPResponse(426, "Data connection closed by client");
}
catch (Exception ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file
// data
sendFTPResponse(426, "Error during transmission");
}
finally
{
try
{
// Close the network file
if (netFile != null && disk != null && tree != null)
disk.closeFile( this, tree, netFile);
// Close the input stream to the client
if (is != null)
is.close();
// Close the data connection to the client
m_cmdSess.getFTPServer().releaseDataSession(this);
closeSession();
}
catch (Exception ex)
{
if ( logger.isErrorEnabled())
logger.error( "Error during FTP data session close", ex);
}
}
}
/**
* Send an FTP response to the client via the command session
*
* @param stsCode int
* @param msg String
*/
protected final void sendFTPResponse(int stsCode, String msg)
{
try
{
m_cmdSess.sendFTPResponse( stsCode, msg);
}
catch (Exception ex)
{
}
}
/**
* Return the client address
*
* @return InetAddress
*/
public InetAddress getRemoteAddress() {
return m_cmdSess.getRemoteAddress();
}
}

View File

@@ -98,10 +98,10 @@ public class FTPDate
buf.append(hr);
buf.append(":");
int sec = cal.get(Calendar.SECOND);
if (sec < 10)
int min = cal.get(Calendar.MINUTE);
if (min < 10)
buf.append("0");
buf.append(sec);
buf.append(min);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -460,8 +460,6 @@ public class ServerConfiguration implements ApplicationListener
throw new AlfrescoRuntimeException("Property 'configService' not set");
}
initialised = false;
// Create the configuration context
ConfigLookupContext configCtx = new ConfigLookupContext(ConfigArea);
@@ -470,59 +468,106 @@ public class ServerConfiguration implements ApplicationListener
determinePlatformType();
// Initialize the filesystems
boolean filesysInitOK = false;
Config config = null;
try
{
// Process the CIFS server configuration
Config config = configService.getConfig(ConfigCIFS, configCtx);
processCIFSServerConfig(config);
// Process the FTP server configuration
config = configService.getConfig(ConfigFTP, configCtx);
processFTPServerConfig(config);
// Process the security configuration
config = configService.getConfig(ConfigSecurity, configCtx);
processSecurityConfig(config);
// Process the filesystems configuration
config = configService.getConfig(ConfigFilesystems, configCtx);
processFilesystemsConfig(config);
// Successful initialisation
initialised = true;
// Indicate that the filesystems were initialized
filesysInitOK = true;
}
catch (UnsatisfiedLinkError ex)
{
// Error accessing the Win32NetBIOS DLL code
logger.error("Error accessing Win32 NetBIOS, check DLL is on the path");
// Disable the CIFS server
setNetBIOSSMB(false);
setTcpipSMB(false);
setWin32NetBIOS(false);
setSMBServerEnabled(false);
}
catch (Throwable ex)
catch (Exception ex)
{
// Configuration error
logger.error("File server configuration error, " + ex.getMessage(), ex);
}
// Disable the CIFS server
// Initialize the CIFS and FTP servers, if the filesystem(s) initialized successfully
if ( filesysInitOK == true)
{
// Initialize the CIFS server
setNetBIOSSMB(false);
setTcpipSMB(false);
setWin32NetBIOS(false);
try
{
// Process the CIFS server configuration
config = configService.getConfig(ConfigCIFS, configCtx);
processCIFSServerConfig(config);
// Process the security configuration
config = configService.getConfig(ConfigSecurity, configCtx);
processSecurityConfig(config);
// Log the successful startup
logger.info("CIFS server started");
}
catch (UnsatisfiedLinkError ex)
{
// Error accessing the Win32NetBIOS DLL code
logger.error("Error accessing Win32 NetBIOS, check DLL is on the path");
// Disable the CIFS server
setNetBIOSSMB(false);
setTcpipSMB(false);
setWin32NetBIOS(false);
setSMBServerEnabled(false);
}
catch (Throwable ex)
{
// Configuration error
logger.error("CIFS server configuration error, " + ex.getMessage(), ex);
// Disable the CIFS server
setNetBIOSSMB(false);
setTcpipSMB(false);
setWin32NetBIOS(false);
setSMBServerEnabled(false);
}
setSMBServerEnabled(false);
// Initialize the FTP server
try
{
// Process the FTP server configuration
config = configService.getConfig(ConfigFTP, configCtx);
processFTPServerConfig(config);
// Log the successful startup
logger.info("FTP server started");
}
catch (Exception ex)
{
// Configuration error
logger.error("FTP server configuration error, " + ex.getMessage(), ex);
}
}
else
{
// Log the error
logger.error("CIFS and FTP servers not started due to filesystem initialization error");
}
}

View File

@@ -120,6 +120,6 @@ public class Win32NetBIOSHostAnnouncer extends HostAnnouncer
int sts = Win32NetBIOS.SendDatagram(getLana(), getNameNumber(), destName, buf, 0, len);
if ( sts != NetBIOS.NRC_GoodRet)
logger.debug("Win32NetBIOS host announce error " + NetBIOS.getErrorString( -sts));
logger.debug("Win32NetBIOS host announce error " + NetBIOS.getErrorString( -sts) + " (LANA " + getLana() + ")");
}
}

View File

@@ -39,7 +39,7 @@ public class Win32NetBIOSLanaMonitor extends Thread
//
// Initial LANA listener array size
private static final int LanaListenerArraySize = 16;
private static final int LanaListenerArraySize = 256;
// Debug logging
@@ -153,24 +153,7 @@ public class Win32NetBIOSLanaMonitor extends Thread
// Check if the listener array has been allocated
if ( m_listeners == null)
{
int len = LanaListenerArraySize;
if ( lana > len)
len = (lana + 3) & 0x00FC;
m_listeners = new LanaListener[len];
}
else if ( lana >= m_listeners.length)
{
// Extend the LANA listener array
LanaListener[] newArray = new LanaListener[(lana + 3) & 0x00FC];
// Copy the existing array to the extended array
System.arraycopy(m_listeners, 0, newArray, 0, m_listeners.length);
m_listeners = newArray;
}
m_listeners = new LanaListener[LanaListenerArraySize];
// Add the LANA listener
@@ -343,6 +326,10 @@ public class Win32NetBIOSLanaMonitor extends Thread
m_lanas.set(lana);
m_lanaSts.set(lana, true);
// Add a listener for the new LANA
addLanaListener( sessHandler.getLANANumber(), sessHandler);
}
}
else

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Alfresco Network License. You may obtain a
* copy of the License at
*
* http://www.alfrescosoftware.com/legal/
*
* Please view the license relevant to your network subscription.
*
* BY CLICKING THE "I UNDERSTAND AND ACCEPT" BOX, OR INSTALLING,
* READING OR USING ALFRESCO'S Network SOFTWARE (THE "SOFTWARE"),
* YOU ARE AGREEING ON BEHALF OF THE ENTITY LICENSING THE SOFTWARE
* ("COMPANY") THAT COMPANY WILL BE BOUND BY AND IS BECOMING A PARTY TO
* THIS ALFRESCO NETWORK AGREEMENT ("AGREEMENT") AND THAT YOU HAVE THE
* AUTHORITY TO BIND COMPANY. IF COMPANY DOES NOT AGREE TO ALL OF THE
* TERMS OF THIS AGREEMENT, DO NOT SELECT THE "I UNDERSTAND AND AGREE"
* BOX AND DO NOT INSTALL THE SOFTWARE OR VIEW THE SOURCE CODE. COMPANY
* HAS NOT BECOME A LICENSEE OF, AND IS NOT AUTHORIZED TO USE THE
* SOFTWARE UNLESS AND UNTIL IT HAS AGREED TO BE BOUND BY THESE LICENSE
* TERMS. THE "EFFECTIVE DATE" FOR THIS AGREEMENT SHALL BE THE DAY YOU
* CHECK THE "I UNDERSTAND AND ACCEPT" BOX.
*/
package org.alfresco.license;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import de.schlichtherle.license.KeyStoreParam;
/**
* Alfresco Public KeyStore Parameters
*
* @author davidc
*/
public class AlfrescoKeyStore implements KeyStoreParam
{
// location of alfresco public keystore
private final static String KEYSTORE = "/org/alfresco/license/alfresco.keystore";
/* (non-Javadoc)
* @see de.schlichtherle.license.KeyStoreParam#getStream()
*/
public InputStream getStream() throws IOException
{
final InputStream in = getClass().getResourceAsStream(KEYSTORE);
if (in == null)
{
throw new FileNotFoundException(KEYSTORE);
}
return in;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.KeyStoreParam#getStorePwd()
*/
public String getStorePwd()
{
return "ocs3rf1a";
}
/* (non-Javadoc)
* @see de.schlichtherle.license.KeyStoreParam#getAlias()
*/
public String getAlias()
{
return "alfresco";
}
/* (non-Javadoc)
* @see de.schlichtherle.license.KeyStoreParam#getKeyPwd()
*/
public String getKeyPwd()
{
// Note: not required for public key
return null;
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Alfresco Network License. You may obtain a
* copy of the License at
*
* http://www.alfrescosoftware.com/legal/
*
* Please view the license relevant to your network subscription.
*
* BY CLICKING THE "I UNDERSTAND AND ACCEPT" BOX, OR INSTALLING,
* READING OR USING ALFRESCO'S Network SOFTWARE (THE "SOFTWARE"),
* YOU ARE AGREEING ON BEHALF OF THE ENTITY LICENSING THE SOFTWARE
* ("COMPANY") THAT COMPANY WILL BE BOUND BY AND IS BECOMING A PARTY TO
* THIS ALFRESCO NETWORK AGREEMENT ("AGREEMENT") AND THAT YOU HAVE THE
* AUTHORITY TO BIND COMPANY. IF COMPANY DOES NOT AGREE TO ALL OF THE
* TERMS OF THIS AGREEMENT, DO NOT SELECT THE "I UNDERSTAND AND AGREE"
* BOX AND DO NOT INSTALL THE SOFTWARE OR VIEW THE SOURCE CODE. COMPANY
* HAS NOT BECOME A LICENSEE OF, AND IS NOT AUTHORIZED TO USE THE
* SOFTWARE UNLESS AND UNTIL IT HAS AGREED TO BE BOUND BY THESE LICENSE
* TERMS. THE "EFFECTIVE DATE" FOR THIS AGREEMENT SHALL BE THE DAY YOU
* CHECK THE "I UNDERSTAND AND ACCEPT" BOX.
*/
package org.alfresco.license;
import java.util.prefs.Preferences;
import javax.security.auth.x500.X500Principal;
import org.alfresco.service.descriptor.DescriptorService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import de.schlichtherle.license.CipherParam;
import de.schlichtherle.license.KeyStoreParam;
import de.schlichtherle.license.LicenseContent;
import de.schlichtherle.license.ftp.LicenseParam;
/**
* Alfresco License Parameters
*
* @author davidc
*/
public class AlfrescoLicenseParam implements LicenseParam
{
private static final Log logger = LogFactory.getLog(DescriptorService.class);
private KeyStoreParam alfrescoStore = new AlfrescoKeyStore();
private KeyStoreParam trialStore = new TrialKeyStore();
private CipherParam cipherParam = new CipherParamImpl();
private boolean createTrialLicense = true;
private int days = 30;
/**
* Construct
*
* @param createTrialLicense allow the creation of trial license
*/
public AlfrescoLicenseParam(boolean createTrialLicense)
{
this.createTrialLicense = createTrialLicense;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.ftp.LicenseParam#getFTPKeyStoreParam()
*/
public KeyStoreParam getFTPKeyStoreParam()
{
return trialStore;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.ftp.LicenseParam#getFTPDays()
*/
public int getFTPDays()
{
return days;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.ftp.LicenseParam#isFTPEligible()
*/
public boolean isFTPEligible()
{
return createTrialLicense;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.ftp.LicenseParam#createFTPLicenseContent()
*/
public LicenseContent createFTPLicenseContent()
{
if (logger.isInfoEnabled())
logger.info("Alfresco license: Creating time limited trial license");
LicenseContent result = new LicenseContent();
X500Principal holder = new X500Principal("O=Trial User");
result.setHolder(holder);
X500Principal issuer = new X500Principal("CN=Unknown, OU=Unknown, O=Alfresco, L=Maidenhead, ST=Berkshire, C=UK");
result.setIssuer(issuer);
result.setConsumerType("System");
result.setConsumerAmount(1);
return result;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.ftp.LicenseParam#removeFTPEligibility()
*/
public void removeFTPEligibility()
{
}
/* (non-Javadoc)
* @see de.schlichtherle.license.ftp.LicenseParam#ftpGranted(de.schlichtherle.license.LicenseContent)
*/
public void ftpGranted(LicenseContent content)
{
}
/* (non-Javadoc)
* @see de.schlichtherle.license.LicenseParam#getSubject()
*/
public String getSubject()
{
return "Enterprise Network";
}
/* (non-Javadoc)
* @see de.schlichtherle.license.LicenseParam#getPreferences()
*/
public Preferences getPreferences()
{
// note: Alfresco license manager does not store licenses in Preferences
return null;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.LicenseParam#getKeyStoreParam()
*/
public KeyStoreParam getKeyStoreParam()
{
return alfrescoStore;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.LicenseParam#getCipherParam()
*/
public CipherParam getCipherParam()
{
return cipherParam;
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Alfresco Network License. You may obtain a
* copy of the License at
*
* http://www.alfrescosoftware.com/legal/
*
* Please view the license relevant to your network subscription.
*
* BY CLICKING THE "I UNDERSTAND AND ACCEPT" BOX, OR INSTALLING,
* READING OR USING ALFRESCO'S Network SOFTWARE (THE "SOFTWARE"),
* YOU ARE AGREEING ON BEHALF OF THE ENTITY LICENSING THE SOFTWARE
* ("COMPANY") THAT COMPANY WILL BE BOUND BY AND IS BECOMING A PARTY TO
* THIS ALFRESCO NETWORK AGREEMENT ("AGREEMENT") AND THAT YOU HAVE THE
* AUTHORITY TO BIND COMPANY. IF COMPANY DOES NOT AGREE TO ALL OF THE
* TERMS OF THIS AGREEMENT, DO NOT SELECT THE "I UNDERSTAND AND AGREE"
* BOX AND DO NOT INSTALL THE SOFTWARE OR VIEW THE SOURCE CODE. COMPANY
* HAS NOT BECOME A LICENSEE OF, AND IS NOT AUTHORIZED TO USE THE
* SOFTWARE UNLESS AND UNTIL IT HAS AGREED TO BE BOUND BY THESE LICENSE
* TERMS. THE "EFFECTIVE DATE" FOR THIS AGREEMENT SHALL BE THE DAY YOU
* CHECK THE "I UNDERSTAND AND ACCEPT" BOX.
*/
package org.alfresco.license;
import de.schlichtherle.license.CipherParam;
/**
* Password used for license encryption
*
* @author davidc
*/
public class CipherParamImpl implements CipherParam
{
/* (non-Javadoc)
* @see de.schlichtherle.license.CipherParam#getKeyPwd()
*/
public String getKeyPwd()
{
return "j3ss13";
};
}

View File

@@ -0,0 +1,493 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Alfresco Network License. You may obtain a
* copy of the License at
*
* http://www.alfrescosoftware.com/legal/
*
* Please view the license relevant to your network subscription.
*
* BY CLICKING THE "I UNDERSTAND AND ACCEPT" BOX, OR INSTALLING,
* READING OR USING ALFRESCO'S Network SOFTWARE (THE "SOFTWARE"),
* YOU ARE AGREEING ON BEHALF OF THE ENTITY LICENSING THE SOFTWARE
* ("COMPANY") THAT COMPANY WILL BE BOUND BY AND IS BECOMING A PARTY TO
* THIS ALFRESCO NETWORK AGREEMENT ("AGREEMENT") AND THAT YOU HAVE THE
* AUTHORITY TO BIND COMPANY. IF COMPANY DOES NOT AGREE TO ALL OF THE
* TERMS OF THIS AGREEMENT, DO NOT SELECT THE "I UNDERSTAND AND AGREE"
* BOX AND DO NOT INSTALL THE SOFTWARE OR VIEW THE SOURCE CODE. COMPANY
* HAS NOT BECOME A LICENSEE OF, AND IS NOT AUTHORIZED TO USE THE
* SOFTWARE UNLESS AND UNTIL IT HAS AGREED TO BE BOUND BY THESE LICENSE
* TERMS. THE "EFFECTIVE DATE" FOR THIS AGREEMENT SHALL BE THE DAY YOU
* CHECK THE "I UNDERSTAND AND ACCEPT" BOX.
*/
package org.alfresco.license;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.PatchDaoService;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.domain.AppliedPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.transaction.TransactionComponent;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.license.LicenseDescriptor;
import org.alfresco.service.license.LicenseException;
import org.alfresco.service.license.LicenseService;
import org.alfresco.service.namespace.NamespaceService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.helpers.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import de.schlichtherle.license.LicenseContent;
import de.schlichtherle.license.ftp.LicenseManager;
import de.schlichtherle.license.ftp.LicenseParam;
/**
* Alfresco Enterprise Network implementation of License Service
*
* @author davidc
*/
public class LicenseComponent implements LicenseService
{
protected AlfrescoLicenseManager licenseManager;
private LicenseDescriptor licenseDescriptor = null;
// dependencies
private TransactionComponent transactionComponent;
private ImporterBootstrap systemBootstrap;
private SearchService searchService;
private NamespaceService namespaceService;
protected NodeService nodeService;
protected ContentService contentService;
private Scheduler verifyScheduler = null;
private boolean failed = false;
// logger
private static final Log logger = LogFactory.getLog(DescriptorService.class);
private static final Log loggerInternal = LogFactory.getLog(LicenseComponent.class);
/**
* Construct
*
* @param context application context
*/
public LicenseComponent(ApplicationContext context)
{
transactionComponent = (TransactionComponent)context.getBean("transactionComponent");
systemBootstrap = (ImporterBootstrap)context.getBean("systemBootstrap");
nodeService = (NodeService)context.getBean("nodeService");
searchService = (SearchService)context.getBean("searchService");
contentService = (ContentService)context.getBean("contentService");
namespaceService = (NamespaceService)context.getBean(ServiceRegistry.NAMESPACE_SERVICE.getLocalName());
// construct license manager
boolean trialEligibility = getTrialEligibility(context);
licenseManager = new AlfrescoLicenseManager(new AlfrescoLicenseParam(trialEligibility));
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseService#verifyLicense()
*/
public void verifyLicense()
{
// check to see if there's a license to install
File licenseFile = getLicenseFile();
if (licenseFile != null)
{
if (logger.isInfoEnabled())
logger.info("Alfresco license: Installing license file " + licenseFile.getName());
try
{
LicenseContent licenseContent = licenseManager.install(licenseFile);
renameLicenseFile(licenseFile);
licenseDescriptor = new LicenseContentDescriptor(licenseContent);
}
catch(Exception e)
{
throw new LicenseException("Failed to install license file " + licenseFile.getName(), e);
}
}
// verify existing license
if (licenseDescriptor == null)
{
verify();
// construct scheduler for period license verify
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
try
{
verifyScheduler = schedulerFactory.getScheduler();
JobDetail jobDetail = new JobDetail("vlj", Scheduler.DEFAULT_GROUP, VerifyLicenseJob.class);
jobDetail.getJobDataMap().put("licenseComponent", this);
Trigger trigger = TriggerUtils.makeHourlyTrigger();
trigger.setStartTime(new Date(System.currentTimeMillis() + (60L * 1000L))); // one minute from now
trigger.setName("vlt");
trigger.setGroup(Scheduler.DEFAULT_GROUP);
verifyScheduler.scheduleJob(jobDetail, trigger);
verifyScheduler.start();
}
catch(SchedulerException e)
{
throw new LicenseException("Failed to initialise License Component");
}
}
}
/**
* Verify License
*/
protected void verify()
{
// note: if a license hasn't been already been installed then install
// a free trial period
TransactionWork<LicenseDescriptor> verifyLicense = new TransactionUtil.TransactionWork<LicenseDescriptor>()
{
public LicenseDescriptor doWork()
{
LicenseDescriptor descriptor = null;
try
{
LicenseContent licenseContent = licenseManager.verify();
descriptor = new LicenseContentDescriptor(licenseContent);
}
catch(Exception e)
{
// handle license failure case
licenseFailed(e);
}
return descriptor;
}
};
licenseDescriptor = TransactionUtil.executeInUserTransaction(transactionComponent, verifyLicense);
}
/**
* Handle case where license is found to be invalid
*/
protected void licenseFailed(Exception e)
throws LicenseException
{
if (!failed)
{
// Mark transactions as read-only
transactionComponent.setAllowWrite(false);
if (logger.isWarnEnabled())
{
logger.warn("Alfresco license: Failed to verify license - Invalid License!");
logger.warn("Alfresco license: Restricted Alfresco Repository to read-only capability");
}
if (loggerInternal.isDebugEnabled())
{
loggerInternal.debug("Alfresco license: Failed due to " + e.toString());
}
failed = true;
}
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseService#getLicense()
*/
public LicenseDescriptor getLicense()
{
return licenseDescriptor;
}
/**
* Determine if a license file is to be installed
*
* @return the license file (or null, if one is not to be installed)
*/
private File getLicenseFile()
{
File licenseFile = null;
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try
{
Resource[] resources = resolver.getResources("classpath*:/alfresco/extension/license/*.lic");
if (resources.length > 1)
{
String resMsg = "";
for (Resource resource : resources)
{
resMsg += "[" + resource.getURL().toExternalForm() + "] ";
}
throw new LicenseException("Found more than one license file to install. The licenses found are: " + resMsg);
}
if (resources.length > 0)
{
licenseFile = resources[0].getFile();
}
}
catch (IOException e)
{
// Note: Ignore: license not found
}
return licenseFile;
}
/**
* Rename installed license file
*
* @param licenseFile license file to rename
*/
private void renameLicenseFile(File licenseFile)
{
File dest = new File(licenseFile.getAbsolutePath() + ".installed");
boolean success = false;
try
{
success = licenseFile.renameTo(dest);
}
catch(Exception e)
{
}
if (!success)
{
if (logger.isWarnEnabled())
logger.warn("Alfresco license: Failed to rename installed license file " + licenseFile.getName() + " to " + dest.getName());
}
}
/**
* Determine if eligible for trial license creation
*
* @param context application context
* @return true => trial license may be created
*/
private boolean getTrialEligibility(ApplicationContext context)
{
// from clean (open)
// from clean (enterprise)
// ==> systemBootstrap == true
// upgrade from 1.2.1 open to 1.2.1 enterprise
// ==> patch = true, schema >= 12, versionEdition = open
// upgrade from 1.2.1 open to 1.3.0 enterprise
// ==> patch = true, schema >= 12, versionEdition = open
// upgrade from 1.2.1 enterprise to 1.3.0 enterprise
// ==> patch = true, schema >= 12, versionEdition = license
// upgrade from 1.2 open to 1.2.1+ enterprise
// ==> patch = false, schema < 12, versionEdition = null
// upgrade from 1.2 enterprise to 1.2.1+ enterprise
// ==> patch = false, schema < 12, versionEdition = null
// first determine if the system store has been bootstrapped in this startup sequence
// if so, a trial license may be created
boolean trialEligibility = systemBootstrap.hasPerformedBootstrap();
if (loggerInternal.isDebugEnabled())
loggerInternal.debug("Alfresco license: System store bootstrapped: " + trialEligibility);
// if not, then this could be a pre-installed repository that has yet to be patched with a license
if (!trialEligibility)
{
NodeRef descriptorRef = getDescriptor();
if (descriptorRef != null)
{
PatchDaoService patchDao = (PatchDaoService)context.getBean("patchDaoComponent");
AppliedPatch patch = patchDao.getAppliedPatch("patch.descriptorUpdate");
// versionEdition = open
// patch = true, schema >= 12
// versionEdition = null
// patch = false, schema < 12
// versionEdition = license
// not eligible
int schema = (Integer)nodeService.getProperty(descriptorRef, ContentModel.PROP_SYS_VERSION_SCHEMA);
Serializable value = nodeService.getProperty(descriptorRef, ContentModel.PROP_SYS_VERSION_EDITION);
if (loggerInternal.isDebugEnabled())
{
loggerInternal.debug("Alfresco license: patch applied: " + (patch != null));
loggerInternal.debug("Alfresco license: schema: " + schema);
loggerInternal.debug("Alfresco license: edition: " + value);
}
if (value == null)
{
trialEligibility = (patch == null) && schema < 12;
}
else if (value instanceof Collection)
{
Collection editions = (Collection)value;
Object editionsValue = (editions.size() > 0) ? editions.iterator().next() : null;
String edition = (editionsValue instanceof String) ? (String)editionsValue : "";
trialEligibility = (patch != null) && schema >=12 && edition.equals("Community Network");
}
}
}
if (loggerInternal.isDebugEnabled())
loggerInternal.debug("Alfresco license: trial eligibility: " + trialEligibility);
return trialEligibility;
}
/**
* Get System Store Descriptor
*
* @return node reference of system store descriptor
*/
protected NodeRef getDescriptor()
{
StoreRef storeRef = systemBootstrap.getStoreRef();
List<NodeRef> nodeRefs = null;
if (nodeService.exists(storeRef))
{
Properties systemProperties = systemBootstrap.getConfiguration();
String path = systemProperties.getProperty("system.descriptor.current.childname");
String searchPath = "/" + path;
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
nodeRefs = searchService.selectNodes(rootNodeRef, searchPath, null, namespaceService, false);
}
return (nodeRefs == null || nodeRefs.size() == 0) ? null : nodeRefs.get(0);
}
/**
* Job for period license verification
*
* @author davidc
*/
public static class VerifyLicenseJob implements Job
{
public void execute(JobExecutionContext context) throws JobExecutionException
{
LicenseComponent license = (LicenseComponent)context.getJobDetail().getJobDataMap().get("licenseComponent");
license.verify();
}
}
/**
* Alfresco implementation of License Manager
*
* Note: Stores verified license files in Alfresco Repository
*
* @author davidc
*/
public class AlfrescoLicenseManager extends LicenseManager
{
/**
* Construct
*
* @param context application context
* @param param license parameters
*/
public AlfrescoLicenseManager(LicenseParam param)
{
super(param);
}
/* (non-Javadoc)
* @see de.schlichtherle.license.LicenseManager#getLicenseKey()
*/
protected byte[] getLicenseKey()
{
byte[] key = null;
try
{
NodeRef descriptorRef = getDescriptor();
if (descriptorRef == null)
{
throw new LicenseException("Failed to find system descriptor");
}
ContentReader reader = contentService.getReader(descriptorRef, ContentModel.PROP_SYS_VERSION_EDITION);
if (reader != null && reader.exists())
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
reader.getContent(os);
key = os.toByteArray();
}
}
catch(Exception e)
{
throw new LicenseException("Failed to load license", e);
}
return key;
}
/* (non-Javadoc)
* @see de.schlichtherle.license.LicenseManager#setLicenseKey(byte[])
*/
protected synchronized void setLicenseKey(final byte[] key)
{
try
{
NodeRef descriptorRef = getDescriptor();
if (descriptorRef == null)
{
throw new LicenseException("Failed to find system descriptor");
}
if (key == null)
{
nodeService.setProperty(descriptorRef, ContentModel.PROP_SYS_VERSION_EDITION, null);
}
else
{
ContentWriter writer = contentService.getWriter(descriptorRef, ContentModel.PROP_SYS_VERSION_EDITION, true);
InputStream is = new ByteArrayInputStream(key);
writer.setMimetype(MimetypeMap.MIMETYPE_BINARY);
writer.putContent(is);
}
}
catch(Exception e)
{
throw new LicenseException("Failed to save license", e);
}
}
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Alfresco Network License. You may obtain a
* copy of the License at
*
* http://www.alfrescosoftware.com/legal/
*
* Please view the license relevant to your network subscription.
*
* BY CLICKING THE "I UNDERSTAND AND ACCEPT" BOX, OR INSTALLING,
* READING OR USING ALFRESCO'S Network SOFTWARE (THE "SOFTWARE"),
* YOU ARE AGREEING ON BEHALF OF THE ENTITY LICENSING THE SOFTWARE
* ("COMPANY") THAT COMPANY WILL BE BOUND BY AND IS BECOMING A PARTY TO
* THIS ALFRESCO NETWORK AGREEMENT ("AGREEMENT") AND THAT YOU HAVE THE
* AUTHORITY TO BIND COMPANY. IF COMPANY DOES NOT AGREE TO ALL OF THE
* TERMS OF THIS AGREEMENT, DO NOT SELECT THE "I UNDERSTAND AND AGREE"
* BOX AND DO NOT INSTALL THE SOFTWARE OR VIEW THE SOURCE CODE. COMPANY
* HAS NOT BECOME A LICENSEE OF, AND IS NOT AUTHORIZED TO USE THE
* SOFTWARE UNLESS AND UNTIL IT HAS AGREED TO BE BOUND BY THESE LICENSE
* TERMS. THE "EFFECTIVE DATE" FOR THIS AGREEMENT SHALL BE THE DAY YOU
* CHECK THE "I UNDERSTAND AND ACCEPT" BOX.
*/
package org.alfresco.license;
import java.security.Principal;
import java.util.Date;
import org.alfresco.service.license.LicenseDescriptor;
import org.joda.time.DateMidnight;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import de.schlichtherle.license.LicenseContent;
/**
* License Descriptor
*
* @author davidc
*/
public class LicenseContentDescriptor implements LicenseDescriptor
{
private LicenseContent licenseContent = null;
/**
* Construct
*
* @param licenseContent
*/
public LicenseContentDescriptor(LicenseContent licenseContent)
{
this.licenseContent = licenseContent;
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseDescriptor#getIssued()
*/
public Date getIssued()
{
return licenseContent.getIssued();
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseDescriptor#getValidUntil()
*/
public Date getValidUntil()
{
return licenseContent.getNotAfter();
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseDescriptor#getSubject()
*/
public String getSubject()
{
return licenseContent.getSubject();
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseDescriptor#getHolder()
*/
public Principal getHolder()
{
return licenseContent.getHolder();
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseDescriptor#getIssuer()
*/
public Principal getIssuer()
{
return licenseContent.getIssuer();
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseDescriptor#getDays()
*/
public Integer getDays()
{
Integer days = null;
Date validUntil = getValidUntil();
if (validUntil != null)
{
Date issued = getIssued();
days = new Integer(calcDays(issued, validUntil));
}
return days;
}
/* (non-Javadoc)
* @see org.alfresco.service.license.LicenseDescriptor#getRemainingDays()
*/
public Integer getRemainingDays()
{
Integer days = null;
Date validUntil = getValidUntil();
if (validUntil != null)
{
Date now = new Date();
days = new Integer(calcDays(now, validUntil));
}
return days;
}
/**
* Calculate number of days between start and end date
*
* @param start start date
* @param end end date
* @return number days between
*/
private int calcDays(Date start, Date end)
{
DateMidnight startMidnight = new DateMidnight(start);
DateMidnight endMidnight = new DateMidnight(end);
int days;
if (endMidnight.isBefore(startMidnight))
{
Interval interval = new Interval(endMidnight, startMidnight);
Period period = interval.toPeriod(PeriodType.days());
days = 0 - period.getDays();
}
else
{
Interval interval = new Interval(startMidnight, endMidnight);
Period period = interval.toPeriod(PeriodType.days());
days = period.getDays();
}
return days;
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Alfresco Network License. You may obtain a
* copy of the License at
*
* http://www.alfrescosoftware.com/legal/
*
* Please view the license relevant to your network subscription.
*
* BY CLICKING THE "I UNDERSTAND AND ACCEPT" BOX, OR INSTALLING,
* READING OR USING ALFRESCO'S Network SOFTWARE (THE "SOFTWARE"),
* YOU ARE AGREEING ON BEHALF OF THE ENTITY LICENSING THE SOFTWARE
* ("COMPANY") THAT COMPANY WILL BE BOUND BY AND IS BECOMING A PARTY TO
* THIS ALFRESCO NETWORK AGREEMENT ("AGREEMENT") AND THAT YOU HAVE THE
* AUTHORITY TO BIND COMPANY. IF COMPANY DOES NOT AGREE TO ALL OF THE
* TERMS OF THIS AGREEMENT, DO NOT SELECT THE "I UNDERSTAND AND AGREE"
* BOX AND DO NOT INSTALL THE SOFTWARE OR VIEW THE SOURCE CODE. COMPANY
* HAS NOT BECOME A LICENSEE OF, AND IS NOT AUTHORIZED TO USE THE
* SOFTWARE UNLESS AND UNTIL IT HAS AGREED TO BE BOUND BY THESE LICENSE
* TERMS. THE "EFFECTIVE DATE" FOR THIS AGREEMENT SHALL BE THE DAY YOU
* CHECK THE "I UNDERSTAND AND ACCEPT" BOX.
*/
package org.alfresco.license;
/**
* Alfresco Trial KeyStore Parameters
*
* @author davidc
*/
public class TrialKeyStore extends AlfrescoKeyStore
{
/* (non-Javadoc)
* @see de.schlichtherle.license.KeyStoreParam#getAlias()
*/
public String getAlias()
{
return "alfrescoTrial";
}
/* (non-Javadoc)
* @see de.schlichtherle.license.KeyStoreParam#getKeyPwd()
*/
public String getKeyPwd()
{
return "la1rtocs3rf1a";
}
}

Binary file not shown.

View File

@@ -18,7 +18,6 @@ package org.alfresco.repo.action.executer;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.service.cmr.action.Action;
@@ -212,58 +211,48 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
destinationAssocQName,
false);
newCopy = true;
}
}
// Get the content reader
ContentReader contentReader = this.contentService.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT);
if (contentReader == null)
{
// for some reason, this action is premature
throw new AlfrescoRuntimeException(
"Attempting to execute content transformation rule " +
"but content has not finished writing, i.e. no URL is available.");
}
String originalMimetype = contentReader.getMimetype();
// get the writer and set it up
ContentWriter contentWriter = this.contentService.getWriter(copyNodeRef, ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype(mimeType); // new mimetype
contentWriter.setEncoding(contentReader.getEncoding()); // original encoding
if (newCopy == true)
{
// Adjust the name of the copy
String originalName = (String)nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_NAME);
String newName = transformName(originalName, originalMimetype, mimeType);
String newName = transformName(originalName, mimeType);
nodeService.setProperty(copyNodeRef, ContentModel.PROP_NAME, newName);
String originalTitle = (String)nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_TITLE);
if (originalTitle != null && originalTitle.length() > 0)
{
String newTitle = transformName(originalTitle, originalMimetype, mimeType);
String newTitle = transformName(originalTitle, mimeType);
nodeService.setProperty(copyNodeRef, ContentModel.PROP_TITLE, newTitle);
}
}
// Try and transform the content
try
// Get the content reader
ContentReader contentReader = this.contentService.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT);
// Only do the transformation if some content is available
if (contentReader != null)
{
doTransform(ruleAction, contentReader, contentWriter);
}
catch(NoTransformerException e)
{
if (logger.isDebugEnabled())
// get the writer and set it up
ContentWriter contentWriter = this.contentService.getWriter(copyNodeRef, ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype(mimeType); // new mimetype
contentWriter.setEncoding(contentReader.getEncoding()); // original encoding
// Try and transform the content
try
{
logger.debug("No transformer found to execute rule: \n" +
" reader: " + contentReader + "\n" +
" writer: " + contentWriter + "\n" +
" action: " + this);
doTransform(ruleAction, contentReader, contentWriter);
}
//if (newCopy == true)
//{
// TODO: Revisit this for alternative solutions
// nodeService.deleteNode(copyNodeRef);
// }
}
catch(NoTransformerException e)
{
if (logger.isDebugEnabled())
{
logger.debug("No transformer found to execute rule: \n" +
" reader: " + contentReader + "\n" +
" writer: " + contentWriter + "\n" +
" action: " + this);
}
}
}
}
protected void doTransform(Action ruleAction, ContentReader contentReader, ContentWriter contentWriter)
@@ -279,7 +268,7 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
* @param newMimetype
* @return
*/
private String transformName(String original, String originalMimetype, String newMimetype)
private String transformName(String original, String newMimetype)
{
// get the current extension
int dotIndex = original.lastIndexOf('.');