From a4b4ca69ec3b51601a58690e8d67019a1bdc573f Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Tue, 11 Sep 2007 04:18:53 +0000 Subject: [PATCH] Merged V2.1 to HEAD 6636: Temporary hack to fix build. 6637: Better handling of binary string bufs, disable link validation when poll interval is <= 0 6638: Forgotten files for TXT to PDF transformer. 6639: Fix for AWC-1541 6641: Fix for WCM-792. 6642: A little extra PropertyValue support for createNode, too. 6643: Fix for WCM-791 6644: Closure of AR-1528: Check concurrency handling of DuplicateChildNodeNameException 6647: Fix WCM-794 6648: WCM-656 6650: Applied user supplied patch to fix AWC-1546 - Cannot mount AVM using CIFS on new alfresco installation. 6651: Index tidy ups 6654: Various minor updates for passthru authentication debugging and error handling. 6657: Fix for WCM-799 (Some items selected for submission were not present) 6659: Updated installers. 6660: Partial fix to AWC-1524 6661: Fix WCM-803 6664: Including hibernate-3.2.1.jar in $VIRTUAL_TOMCAT_HOME/server/lib/ 6665: adding an automated unit test for output path patterns. 6668: Fixed to add shale-test-1.0.4.jar to Eclipse classpath (PHH oked) 6681: Fixes WCM-811 - Lookup.getIndirectionPath() had a bit of a howler in it. 6684: UncategorizedSQLException with the word 'deadlock' in the message is now cause for retrying a transaction. 6691: Fix for WCM-813 (lock not removed when expiration date set and no workflow on web project) 6696: Imporved SSO filters for SiteMinder etc + test filter 6697: Support for scheduled import 6699: Fix for the compliation target: compile-benchmarkframework 6701: Fix for 1.6 JVMs (1.5 gets by with lucky ordering) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6749 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../linkvalidation-service-context.xml | 3 +- config/alfresco/public-services-context.xml | 2 +- .../alfresco/filesys/avm/AVMDiskDriver.java | 10 +- .../filesys/netbios/NetBIOSPacket.java | 5 +- .../filesys/netbios/NetBIOSSession.java | 94 ++++--- .../server/auth/CifsAuthenticator.java | 14 +- .../auth/EnterpriseCifsAuthenticator.java | 72 +++--- .../auth/passthru/AuthSessionFactory.java | 7 +- .../auth/passthru/PassthruAuthenticator.java | 26 +- .../server/auth/passthru/PassthruServers.java | 4 +- .../org/alfresco/repo/avm/AVMNodeService.java | 48 ++-- .../org/alfresco/repo/avm/AVMServiceImpl.java | 15 +- .../org/alfresco/repo/avm/AVMServiceTest.java | 1 + source/java/org/alfresco/repo/avm/Lookup.java | 6 +- .../repo/content/ContentTestSuite.java | 3 + .../TextToPdfContentTransformer.java | 141 ++++++++++ .../TextToPdfContentTransformerTest.java | 65 +++++ .../copy/CrossRepositoryCopyServiceImpl.java | 62 ++++- .../repo/importer/FileSourceImporter.java | 242 ++++++++++++++++++ .../org/alfresco/repo/jscript/ScriptNode.java | 41 +++ .../FileFolderDuplicateChildTest.java | 226 ++++++++++++++++ .../model/filefolder/FileFolderTestSuite.java | 46 ++++ .../ml/MultilingualContentServiceImpl.java | 13 +- .../search/impl/lucene/index/IndexInfo.java | 97 ++++--- ...nceCountingReadOnlyIndexReaderFactory.java | 7 +- .../repo/template/BaseContentNode.java | 33 ++- .../RetryingTransactionHelper.java | 32 ++- 27 files changed, 1110 insertions(+), 205 deletions(-) create mode 100644 source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformer.java create mode 100644 source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformerTest.java create mode 100644 source/java/org/alfresco/repo/importer/FileSourceImporter.java create mode 100644 source/java/org/alfresco/repo/model/filefolder/FileFolderDuplicateChildTest.java create mode 100644 source/java/org/alfresco/repo/model/filefolder/FileFolderTestSuite.java diff --git a/config/alfresco/linkvalidation-service-context.xml b/config/alfresco/linkvalidation-service-context.xml index 2206b40b2f..da06dbb391 100644 --- a/config/alfresco/linkvalidation-service-context.xml +++ b/config/alfresco/linkvalidation-service-context.xml @@ -252,7 +252,8 @@ - + + diff --git a/config/alfresco/public-services-context.xml b/config/alfresco/public-services-context.xml index 27efcd4982..bbb20b3164 100644 --- a/config/alfresco/public-services-context.xml +++ b/config/alfresco/public-services-context.xml @@ -702,7 +702,7 @@ - + diff --git a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java index c0ab7d1ed3..296678658b 100644 --- a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java +++ b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java @@ -1642,15 +1642,15 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface PseudoFileList searchList = fstate.getPseudoFileList(); + // Check if the pseudo file list is valid + + if (searchList == null) + searchList = new PseudoFileList(); + // Check if this is a single file or wildcard search if (WildCard.containsWildcards(searchPath)) { - // Check if the pseudo file list is valid - - if (searchList == null) - searchList = new PseudoFileList(); - // Create the search context, wildcard filter will take care of secondary filtering of the // folder listing diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSPacket.java b/source/java/org/alfresco/filesys/netbios/NetBIOSPacket.java index 6a1a380e09..d6fdb9123d 100644 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSPacket.java +++ b/source/java/org/alfresco/filesys/netbios/NetBIOSPacket.java @@ -396,7 +396,6 @@ public class NetBIOSPacket if (cnt == 0) return null; - NetBIOSNameList nameList = new NetBIOSNameList(); int pos = NB_DATA; // Skip the initial name @@ -409,9 +408,13 @@ public class NetBIOSPacket // Get the count of data bytes and name count int dataCnt = DataPacker.getShort(m_nbbuf, pos); + if ( dataCnt < 16) + return null; + pos += 2; int nameCnt = (int) (m_nbbuf[pos++] & 0xFF); + NetBIOSNameList nameList = new NetBIOSNameList(); while (nameCnt > 0 && dataCnt > 0) { diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSSession.java b/source/java/org/alfresco/filesys/netbios/NetBIOSSession.java index 5919e86984..2870f7e31a 100644 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSSession.java +++ b/source/java/org/alfresco/filesys/netbios/NetBIOSSession.java @@ -822,6 +822,19 @@ public final class NetBIOSSession implements NetworkSession * @return NetBIOSNameList */ public static NetBIOSNameList FindNamesForAddress(String ipAddr) throws UnknownHostException, SocketException + { + return FindNamesForAddress( ipAddr, 1); + } + + /** + * Get the NetBIOS name list for the specified IP address + * + * @param ipAddr String + * @param retryCnt int + * @return NetBIOSNameList + */ + public static NetBIOSNameList FindNamesForAddress(String ipAddr, int retryCnt) + throws UnknownHostException, SocketException { // Create a datagram socket @@ -836,7 +849,7 @@ public final class NetBIOSSession implements NetworkSession // Set the datagram socket timeout, in milliseconds - m_dgramSock.setSoTimeout(2000); + m_dgramSock.setSoTimeout(5000); // Create a name lookup NetBIOS packet @@ -875,43 +888,48 @@ public final class NetBIOSSession implements NetworkSession try { - - // Send the name query datagram - - m_dgramSock.send(dgram); - - // Receive a datagram packet - - m_dgramSock.receive(rxdgram); - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - { - logger.debug("NetBIOS: Rx Datagram"); - rxpkt.DumpPacket(false); - } - - // Check if this is a valid response datagram - - if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY && rxpkt.getAnswerCount() >= 1) - { - - // Get the received name list - - nameList = rxpkt.getAdapterStatusNameList(); - - // If the name list is valid update the names with the original address that was connected to - - if( nameList != null) - { - for ( int i = 0; i < nameList.numberOfNames(); i++) - { - NetBIOSName nbName = nameList.getName(i); - nbName.addIPAddress(destAddr.getAddress()); - } - } - } + // Loop until we get a valid reply or the retry count is zero + + while ( retryCnt-- > 0 && nameList == null) + { + // Send the name query datagram + + m_dgramSock.send(dgram); + + // Receive a datagram packet + + m_dgramSock.receive(rxdgram); + rxpkt.setLength( rxdgram.getLength()); + + // DEBUG + + if (logger.isDebugEnabled() && m_debug) + { + logger.debug("NetBIOS: Rx Datagram"); + rxpkt.DumpPacket(false); + } + + // Check if this is a valid response datagram + + if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY && rxpkt.getAnswerCount() >= 1) + { + + // Get the received name list + + nameList = rxpkt.getAdapterStatusNameList(); + + // If the name list is valid update the names with the original address that was connected to + + if( nameList != null) + { + for ( int i = 0; i < nameList.numberOfNames(); i++) + { + NetBIOSName nbName = nameList.getName(i); + nbName.addIPAddress(destAddr.getAddress()); + } + } + } + } } catch (java.io.IOException ex) { diff --git a/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java b/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java index cb4b43030a..d5214a3957 100644 --- a/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java +++ b/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java @@ -348,6 +348,8 @@ public abstract class CifsAuthenticator // Pack the negotiate response for NT/LanMan challenge/response authentication NTLanManAuthContext authCtx = (NTLanManAuthContext) getAuthContext( sess); + if ( authCtx == null) + throw new AuthenticatorException("Failed to get authentication context"); // Encryption key and primary domain string should be returned in the byte area @@ -403,7 +405,7 @@ public abstract class CifsAuthenticator if (reqPkt.checkPacketIsValid(13, 0) == false) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // Extract the session details @@ -434,7 +436,7 @@ public abstract class CifsAuthenticator if (user == null) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // Extract the clients primary domain name string @@ -450,7 +452,7 @@ public abstract class CifsAuthenticator if (domain == null) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } } @@ -467,7 +469,7 @@ public abstract class CifsAuthenticator if (clientOS == null) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } } @@ -531,7 +533,7 @@ public abstract class CifsAuthenticator // Invalid user, reject the session setup request - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } else { @@ -562,7 +564,7 @@ public abstract class CifsAuthenticator // Failed to allocate a UID - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) { diff --git a/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java b/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java index 8f4e2a7394..e181ead0f5 100644 --- a/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java +++ b/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java @@ -510,7 +510,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Check that the received packet looks like a valid NT session setup andX request if (reqPkt.checkPacketIsValid(12, 0) == false) - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); // Check if the request is using security blobs or the older hashed password format @@ -557,7 +557,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca domain = reqPkt.unpackString(isUni); if (domain == null) - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // Extract the clients native operating system @@ -571,7 +571,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca clientOS = reqPkt.unpackString(isUni); if (clientOS == null) - throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // DEBUG @@ -751,7 +751,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Failed to allocate a UID - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) { @@ -834,7 +834,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure status - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Check for a type 1 NTLMSSP message @@ -903,7 +903,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Determine if the client sent us NTLMv1 or NTLMv2 @@ -1004,7 +1004,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure status - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Get the second stage NTLMSSP blob @@ -1046,7 +1046,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure status - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Determine the authentication mechanism the client is using and logon @@ -1094,7 +1094,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // No valid authentication mechanism - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1105,7 +1105,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure status - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Generate the NegTokenTarg blob @@ -1127,7 +1127,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Failed to build response blob - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Return the SPNEGO response blob @@ -1202,7 +1202,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure status - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Return the response SPNEGO blob @@ -1231,7 +1231,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Get the type 2 message that contains the challenge sent to the client @@ -1301,7 +1301,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1326,7 +1326,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1337,7 +1337,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1361,7 +1361,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Start a transaction @@ -1437,7 +1437,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1461,7 +1461,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1472,7 +1472,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1552,7 +1552,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1577,7 +1577,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1588,7 +1588,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1599,7 +1599,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1679,7 +1679,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1703,7 +1703,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1714,7 +1714,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1725,7 +1725,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1846,7 +1846,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1871,7 +1871,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } else @@ -1882,7 +1882,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } } @@ -1901,7 +1901,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca if (reqPkt.checkPacketIsValid(13, 0) == false) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // Extract the session details @@ -1932,7 +1932,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca if (user == null) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // Extract the clients primary domain name string @@ -1948,7 +1948,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca if (domain == null) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } } @@ -1965,7 +1965,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca if (clientOS == null) { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } } @@ -2064,7 +2064,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Failed to allocate a UID - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) { diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/AuthSessionFactory.java b/source/java/org/alfresco/filesys/server/auth/passthru/AuthSessionFactory.java index efacda7ec5..93b912749d 100644 --- a/source/java/org/alfresco/filesys/server/auth/passthru/AuthSessionFactory.java +++ b/source/java/org/alfresco/filesys/server/auth/passthru/AuthSessionFactory.java @@ -668,13 +668,13 @@ public final class AuthSessionFactory // Get a list of NetBIOS names from the remote host toAddr = toName; - NetBIOSNameList nameList = NetBIOSSession.FindNamesForAddress(toAddr); + NetBIOSNameList nameList = NetBIOSSession.FindNamesForAddress(toAddr, 3); // Find the server service nbName = nameList.findName(NetBIOSName.FileServer, false); if (nbName == null) - throw new IOException("Server service not running"); + throw new IOException("Failed to convert server address to NetBIOS name"); // Set the remote name @@ -708,8 +708,7 @@ public final class AuthSessionFactory // Get a list of NetBIOS names for the local system - NetBIOSNameList localList = NetBIOSSession.FindNamesForAddress(InetAddress.getLocalHost() - .getHostAddress()); + NetBIOSNameList localList = NetBIOSSession.FindNamesForAddress(InetAddress.getLocalHost().getHostAddress()); if (localList != null) { nbName = localList.findName(toName, NetBIOSName.FileServer, false); diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruAuthenticator.java b/source/java/org/alfresco/filesys/server/auth/passthru/PassthruAuthenticator.java index 7d3c1c5987..37408cd87a 100644 --- a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruAuthenticator.java +++ b/source/java/org/alfresco/filesys/server/auth/passthru/PassthruAuthenticator.java @@ -381,6 +381,9 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL if (logger.isDebugEnabled()) logger.debug("Passthru sessId=" + authSess.getSessionId() + ", auth ctx=" + authCtx); } + else if ( logger.isDebugEnabled()) + logger.debug("No passthru server available for domain, " + domain); + } catch (Exception ex) { @@ -454,7 +457,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL // Check that the received packet looks like a valid NT session setup andX request if (reqPkt.checkPacketIsValid(12, 0) == false) - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); // Check if the request is using security blobs or the older hashed password format @@ -501,7 +504,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL domain = reqPkt.unpackString(isUni); if (domain == null) - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // Extract the clients native operating system @@ -515,7 +518,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL clientOS = reqPkt.unpackString(isUni); if (clientOS == null) - throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } // Store the client maximum buffer size, maximum multiplexed requests count and client capability flags @@ -584,7 +587,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL { // Invalid blob type - throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); } } catch (SMBSrvException ex) @@ -695,7 +698,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL // Failed to allocate a UID - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) { @@ -778,7 +781,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL // Return a logon failure status - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Check for a type 1 NTLMSSP message @@ -844,7 +847,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } // Determine if the client sent us NTLMv1 or NTLMv2 @@ -858,7 +861,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL // Return a logon failure - throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } else { @@ -1021,14 +1024,9 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL } catch (Exception ex) { - - // Debug - - logger.error(ex.getMessage()); - // Indicate logon failure - throw new SMBSrvException( SMBStatus.NTErr, SMBStatus.NTLogonFailure); + throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); } finally { diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServers.java b/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServers.java index 27d0e9c382..1c97472c39 100644 --- a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServers.java +++ b/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServers.java @@ -360,7 +360,7 @@ public class PassthruServers // Debug if ( logger.isDebugEnabled()) - logger.debug("Failed to connect to " + passthruServer + " : " + ex.getMessage()); + logger.debug("Failed to connect to " + passthruServer, ex); // Failed to connect to the current authentication server, mark the server as offline @@ -439,7 +439,7 @@ public class PassthruServers passthruServer = curServer; // Move to the back of the list - + m_onlineList.add( m_onlineList.remove( idx)); } diff --git a/source/java/org/alfresco/repo/avm/AVMNodeService.java b/source/java/org/alfresco/repo/avm/AVMNodeService.java index 2bf6c98db0..57f9eee4ed 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeService.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeService.java @@ -46,7 +46,6 @@ import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.ClassDefinition; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.InvalidAspectException; import org.alfresco.service.cmr.dictionary.InvalidTypeException; import org.alfresco.service.cmr.dictionary.PropertyDefinition; @@ -319,13 +318,17 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi addDefaultPropertyValues(nodeTypeDef, properties); addDefaultAspects(nodeTypeDef, newAVMPath, properties); Map props = new HashMap(); - for (QName qname : properties.keySet()) + for (Map.Entry entry : properties.entrySet()) { - if (isBuiltInProperty(qname)) + QName propertyQName = entry.getKey(); + if (isBuiltInProperty(propertyQName)) { continue; } - props.put(qname, new PropertyValue(null, properties.get(qname))); + Serializable value = entry.getValue(); + PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + props.put(propertyQName, propertyValue); } fAVMService.setNodeProperties(newAVMPath, props); ChildAssociationRef ref = @@ -583,10 +586,15 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi Map props = new HashMap(); for (Map.Entry entry : properties.entrySet()) { - if (!isBuiltInProperty(entry.getKey())) + QName propertyQName = entry.getKey(); + if (isBuiltInProperty(propertyQName)) { - props.put(entry.getKey(), new PropertyValue(null, entry.getValue())); + continue; } + Serializable value = entry.getValue(); + PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + props.put(propertyQName, propertyValue); } if (props.size() != 0) { @@ -1176,12 +1184,14 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi // Map oldProps = getProperties(nodeRef); fAVMService.deleteNodeProperties(avmVersionPath.getSecond()); Map values = new HashMap(); - for (QName qName : properties.keySet()) + for (Map.Entry entry : properties.entrySet()) { + QName propertyQName = entry.getKey(); + Serializable value = entry.getValue(); // For AVM nodes is in place. - if (isBuiltInProperty(qName)) + if (isBuiltInProperty(propertyQName)) { - if (qName.equals(ContentModel.PROP_CONTENT)) + if (propertyQName.equals(ContentModel.PROP_CONTENT)) { AVMNodeDescriptor desc = fAVMService.lookup(-1, avmVersionPath.getSecond()); if (desc == null) @@ -1191,16 +1201,13 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi if (desc.isPlainFile()) { fAVMService.setContentData(avmVersionPath.getSecond(), - (ContentData)properties.get(qName)); + (ContentData)properties.get(propertyQName)); } } } - DataTypeDefinition def = dictionaryService.getDataType(qName); - if (def == null) - { - def = dictionaryService.getDataType(properties.get(qName).getClass()); - } - values.put(qName, new PropertyValue(def.getName(), properties.get(qName))); + PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + values.put(propertyQName, propertyValue); } fAVMService.setNodeProperties(avmVersionPath.getSecond(), values); // Invoke policy behaviors. @@ -1293,12 +1300,9 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi try { // Map propsBefore = getProperties(nodeRef); - DataTypeDefinition def = dictionaryService.getDataType(qname); - if (def == null) - { - def = dictionaryService.getDataType(value.getClass()); - } - fAVMService.setNodeProperty(avmVersionPath.getSecond(), qname, new PropertyValue(def.getName(), value)); + PropertyDefinition propertyDef = dictionaryService.getProperty(qname); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + fAVMService.setNodeProperty(avmVersionPath.getSecond(), qname, propertyValue); // Map propsAfter = getProperties(nodeRef); // Invoke policy behaviors. // invokeOnUpdateNode(nodeRef); diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index 7f097a58f6..82caa7ff02 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -1414,9 +1414,14 @@ public class AVMServiceImpl implements AVMService private void recursiveCopy(int version, AVMNodeDescriptor desc, String path, String name) { String newPath = path + '/' + name; + AVMNodeDescriptor existing = lookup(-1, newPath); if (desc.isFile()) { InputStream in = getFileInputStream(version, desc.getPath()); + if (existing != null) + { + removeNode(newPath); + } createFile(path, name, in); ContentData cd = getContentDataForRead(version, desc.getPath()); setEncoding(newPath, cd.getEncoding()); @@ -1424,7 +1429,15 @@ public class AVMServiceImpl implements AVMService } else // desc is a directory. { - createDirectory(path, name); + if (existing != null && !existing.isDirectory()) + { + removeNode(newPath); + existing = null; + } + if (existing == null) + { + createDirectory(path, name); + } Map listing = getDirectoryListing(desc); for (Map.Entry entry : listing.entrySet()) { diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index 48ee2ca862..4f0fdec11b 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -1721,6 +1721,7 @@ public class AVMServiceTest extends AVMServiceTestBase setupBasicTree(); fService.createStore("layer"); fService.createLayeredDirectory("main:/a", "layer:/", "layer"); + fService.createFile("layer:/layer/b", "figs").close(); assertEquals("main:/a", fService.getIndirectionPath(-1, "layer:/layer")); assertEquals("main:/a/b", fService.getIndirectionPath(-1, "layer:/layer/b")); assertEquals("main:/a/b/c", fService.getIndirectionPath(-1, "layer:/layer/b/c")); diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java index c97b2fd19b..36088d9198 100644 --- a/source/java/org/alfresco/repo/avm/Lookup.java +++ b/source/java/org/alfresco/repo/avm/Lookup.java @@ -395,9 +395,9 @@ class Lookup implements Serializable int pos = fLowestLayerIndex; AVMNode node = fComponents.get(pos).getNode(); LayeredDirectoryNode oNode = null; - while (pos >= fTopLayerIndex && node.getType() != AVMNodeType.LAYERED_DIRECTORY && - ((oNode = (LayeredDirectoryNode)node).getLayerID() != fTopLayer.getLayerID() || - !oNode.getPrimaryIndirection())) + while (pos >= fTopLayerIndex && (node.getType() != AVMNodeType.LAYERED_DIRECTORY || + (oNode = (LayeredDirectoryNode)node).getLayerID() != fTopLayer.getLayerID() || + !oNode.getPrimaryIndirection())) { pos--; node = fComponents.get(pos).getNode(); diff --git a/source/java/org/alfresco/repo/content/ContentTestSuite.java b/source/java/org/alfresco/repo/content/ContentTestSuite.java index 21f6565e39..12f039b254 100644 --- a/source/java/org/alfresco/repo/content/ContentTestSuite.java +++ b/source/java/org/alfresco/repo/content/ContentTestSuite.java @@ -50,6 +50,9 @@ import org.alfresco.repo.content.transform.StringExtractingContentTransformerTes import org.alfresco.repo.content.transform.TextMiningContentTransformerTest; import org.alfresco.repo.content.transform.TextToPdfContentTransformerTest; +// TODO: This class is currently missing +// import org.alfresco.repo.content.transform.TextToPdfContentTransformerTest; + import junit.framework.Test; import junit.framework.TestSuite; diff --git a/source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformer.java b/source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformer.java new file mode 100644 index 0000000000..234bdd4ca8 --- /dev/null +++ b/source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformer.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * 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.repo.content.transform; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.pdfbox.TextToPDF; +import org.pdfbox.pdmodel.PDDocument; +import org.pdfbox.pdmodel.font.PDTrueTypeFont; +import org.pdfbox.pdmodel.font.PDType1Font; + +/** + * Makes use of the {@link http://www.pdfbox.org/ PDFBox} library's TextToPDF utility. + * + * @author Derek Hulley + * @since 2.1.0 + */ +public class TextToPdfContentTransformer extends AbstractContentTransformer +{ + private TextToPDF transformer; + + public TextToPdfContentTransformer() + { + transformer = new TextToPDF(); + } + + public void setStandardFont(String fontName) + { + try + { + transformer.setFont(PDType1Font.getStandardFont(fontName)); + } + catch (Throwable e) + { + throw new AlfrescoRuntimeException("Unable to set Standard Font for PDF generation: " + fontName, e); + } + } + + public void setTrueTypeFont(String fontName) + { + try + { + transformer.setFont(PDTrueTypeFont.loadTTF(null, fontName)); + } + catch (Throwable e) + { + throw new AlfrescoRuntimeException("Unable to set True Type Font for PDF generation: " + fontName, e); + } + } + + public void setFontSize(int fontSize) + { + try + { + transformer.setFontSize(fontSize); + } + catch (Throwable e) + { + throw new AlfrescoRuntimeException("Unable to set Font Size for PDF generation: " + fontSize); + } + } + + /** + * Only supports Text to PDF + */ + public double getReliability(String sourceMimetype, String targetMimetype) + { + if (!MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(sourceMimetype) || + !MimetypeMap.MIMETYPE_PDF.equals(targetMimetype)) + { + // only support Text -> PDF + return 0.0; + } + else + { + return 1.0; + } + } + + protected void transformInternal( + ContentReader reader, + ContentWriter writer, + Map options) throws Exception + { + PDDocument pdf = null; + InputStream is = null; + OutputStream os = null; + try + { + is = reader.getContentInputStream(); + pdf = transformer.createPDFFromText(new InputStreamReader(is)); + // dump it all to the writer + os = writer.getContentOutputStream(); + pdf.save(os); + } + finally + { + if (pdf != null) + { + try { pdf.close(); } catch (Throwable e) {e.printStackTrace(); } + } + if (is != null) + { + try { is.close(); } catch (Throwable e) {e.printStackTrace(); } + } + if (os != null) + { + try { os.close(); } catch (Throwable e) {e.printStackTrace(); } + } + } + } +} diff --git a/source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformerTest.java b/source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformerTest.java new file mode 100644 index 0000000000..7f7b1a13f5 --- /dev/null +++ b/source/java/org/alfresco/repo/content/transform/TextToPdfContentTransformerTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * 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.repo.content.transform; + +import org.alfresco.repo.content.MimetypeMap; + +/** + * @see org.alfresco.repo.content.transform.TextToPdfContentTransformer + * + * @author Derek Hulley + * @since 2.1.0 + */ +public class TextToPdfContentTransformerTest extends AbstractContentTransformerTest +{ + private TextToPdfContentTransformer transformer; + + @Override + public void setUp() throws Exception + { + super.setUp(); + + transformer = new TextToPdfContentTransformer(); + transformer.setStandardFont("Times-Roman"); + transformer.setFontSize(20); + } + + /** + * @return Returns the same transformer regardless - it is allowed + */ + protected ContentTransformer getTransformer(String sourceMimetype, String targetMimetype) + { + return transformer; + } + + public void testReliability() throws Exception + { + double reliability = 0.0; + reliability = transformer.getReliability(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_TEXT_PLAIN); + assertEquals("Mimetype should not be supported", 0.0, reliability); + reliability = transformer.getReliability(MimetypeMap.MIMETYPE_TEXT_PLAIN, MimetypeMap.MIMETYPE_PDF); + assertEquals("Mimetype should be supported", 1.0, reliability); + } +} diff --git a/source/java/org/alfresco/repo/copy/CrossRepositoryCopyServiceImpl.java b/source/java/org/alfresco/repo/copy/CrossRepositoryCopyServiceImpl.java index 4e4d7af674..5a61fb115c 100644 --- a/source/java/org/alfresco/repo/copy/CrossRepositoryCopyServiceImpl.java +++ b/source/java/org/alfresco/repo/copy/CrossRepositoryCopyServiceImpl.java @@ -15,7 +15,6 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.content.MimetypeMap; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.dictionary.DictionaryService; @@ -180,10 +179,23 @@ public class CrossRepositoryCopyServiceImpl implements CrossRepositoryCopyServic { Pair versionPath = AVMNodeConverter.ToAVMVersionPath(src); AVMNodeDescriptor desc = fAVMService.lookup(versionPath.getFirst(), versionPath.getSecond()); + NodeRef existing = fFileFolderService.searchSimple(dst, name); if (desc.isFile()) { - FileInfo newChild = fFileFolderService.create(dst, name, ContentModel.TYPE_CONTENT); - NodeRef childRef = newChild.getNodeRef(); + if (existing != null && !fNodeService.getType(existing).equals(ContentModel.TYPE_CONTENT)) + { + fFileFolderService.delete(existing); + existing = null; + } + NodeRef childRef = null; + if (existing == null) + { + childRef = fFileFolderService.create(dst, name, ContentModel.TYPE_CONTENT).getNodeRef(); + } + else + { + childRef = existing; + } InputStream in = fAVMService.getFileInputStream(desc); ContentData cd = fAVMService.getContentDataForRead(desc.getVersionID(), desc.getPath()); ContentWriter writer = fContentService.getWriter(childRef, ContentModel.PROP_CONTENT, true); @@ -195,8 +207,20 @@ public class CrossRepositoryCopyServiceImpl implements CrossRepositoryCopyServic } else { - FileInfo newChild = fFileFolderService.create(dst, name, ContentModel.TYPE_FOLDER); - NodeRef childRef = newChild.getNodeRef(); + if (existing != null && !fNodeService.getType(existing).equals(ContentModel.TYPE_FOLDER)) + { + fFileFolderService.delete(existing); + existing = null; + } + NodeRef childRef = null; + if (existing == null) + { + childRef = fFileFolderService.create(dst, name, ContentModel.TYPE_FOLDER).getNodeRef(); + } + else + { + childRef = existing; + } copyPropsAndAspectsAVMToRepo(src, childRef); Map listing = fAVMService.getDirectoryListing(desc); for (Map.Entry entry : listing.entrySet()) @@ -256,13 +280,22 @@ public class CrossRepositoryCopyServiceImpl implements CrossRepositoryCopyServic { ContentReader reader = fContentService.getReader(src, ContentModel.PROP_CONTENT); InputStream in = reader.getContentInputStream(); - try + AVMNodeDescriptor desc = fAVMService.lookup(-1, childPath); + if (desc != null && !desc.isFile()) { - fAVMService.createFile(versionPath.getSecond(), name).close(); + fAVMService.removeNode(childPath); + desc = null; } - catch (IOException e) + if (desc == null) { - throw new AlfrescoRuntimeException("I/O Error.", e); + try + { + fAVMService.createFile(versionPath.getSecond(), name).close(); + } + catch (IOException e) + { + throw new AlfrescoRuntimeException("I/O Error.", e); + } } ContentWriter writer = fAVMService.getContentWriter(childPath); writer.setEncoding(reader.getEncoding()); @@ -274,7 +307,16 @@ public class CrossRepositoryCopyServiceImpl implements CrossRepositoryCopyServic } if (fDictionaryService.isSubClass(srcType, ContentModel.TYPE_FOLDER)) { - fAVMService.createDirectory(versionPath.getSecond(), name); + AVMNodeDescriptor desc = fAVMService.lookup(-1, childPath); + if (desc != null && !desc.isDirectory()) + { + fAVMService.removeNode(childPath); + desc = null; + } + if (desc == null) + { + fAVMService.createDirectory(versionPath.getSecond(), name); + } copyPropsAndAspectsRepoToAVM(src, childNodeRef, childPath); List listing = fFileFolderService.list(src); for (FileInfo info : listing) diff --git a/source/java/org/alfresco/repo/importer/FileSourceImporter.java b/source/java/org/alfresco/repo/importer/FileSourceImporter.java new file mode 100644 index 0000000000..11cdd2228a --- /dev/null +++ b/source/java/org/alfresco/repo/importer/FileSourceImporter.java @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * 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.repo.importer; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.Reader; +import java.util.List; +import java.util.Set; + +import javax.transaction.UserTransaction; + +import org.alfresco.repo.cache.SimpleCache; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.security.authentication.ldap.LDAPGroupExportSource; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +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.cmr.view.ImporterBinding; +import org.alfresco.service.cmr.view.ImporterService; +import org.alfresco.service.cmr.view.Location; +import org.alfresco.service.namespace.NamespacePrefixResolver; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.transaction.TransactionService; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class FileSourceImporter implements ImporterJobSPI +{ + private static Log s_logger = LogFactory.getLog(FileSourceImporter.class); + + private ImporterService importerService; + + private String fileLocation; + + private AuthenticationComponent authenticationComponent; + + private StoreRef storeRef; + + private String path; + + private boolean clearAllChildren; + + private NodeService nodeService; + + private SearchService searchService; + + private NamespacePrefixResolver namespacePrefixResolver; + + private TransactionService transactionService; + + private Set caches; + + public FileSourceImporter() + { + super(); + } + + public void setImporterService(ImporterService importerService) + { + this.importerService = importerService; + } + + public void setFileLocation(String fileLocation) + { + this.fileLocation = fileLocation; + } + + public void setClearAllChildren(boolean clearAllChildren) + { + this.clearAllChildren = clearAllChildren; + } + + public void setPath(String path) + { + this.path = path; + } + + public void setStoreRef(String storeRef) + { + this.storeRef = new StoreRef(storeRef); + } + + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } + + public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver) + { + this.namespacePrefixResolver = namespacePrefixResolver; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setCaches(Set caches) + { + this.caches = caches; + } + + public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) + { + this.authenticationComponent = authenticationComponent; + } + + public void setSearchService(SearchService searchService) + { + this.searchService = searchService; + } + + @SuppressWarnings("unchecked") + public void doImport() + { + UserTransaction userTransaction = null; + try + { + long start = System.nanoTime(); + userTransaction = transactionService.getUserTransaction(); + userTransaction.begin(); + authenticationComponent.setSystemUserAsCurrentUser(); + if (clearAllChildren) + { + List refs = searchService.selectNodes(nodeService.getRootNode(storeRef), path, null, + namespacePrefixResolver, false); + for (NodeRef ref : refs) + { + for (ChildAssociationRef car : nodeService.getChildAssocs(ref)) + { + nodeService.deleteNode(car.getChildRef()); + } + } + } + + if (caches != null) + { + for (SimpleCache cache : caches) + { + + cache.clear(); + } + } + + Reader reader = new BufferedReader(new FileReader(fileLocation)); + + Location location = new Location(storeRef); + location.setPath(path); + + importerService.importView(reader, location, REPLACE_BINDING, null); + reader.close(); + + if (caches != null) + { + for (SimpleCache cache : caches) + { + cache.clear(); + } + } + + userTransaction.commit(); + long end = System.nanoTime(); + s_logger.info("Imported "+fileLocation+ " in "+((end-start)/1e9f) + " seconds"); + } + catch (Throwable t) + { + try + { + if (userTransaction != null) + { + userTransaction.rollback(); + } + } + catch (Exception ex) + { + } + try + { + authenticationComponent.clearCurrentSecurityContext(); + } + catch (Exception ex) + { + } + throw new ExportSourceImporterException("Failed to import", t); + } + finally + { + authenticationComponent.clearCurrentSecurityContext(); + } + } + + private static ImporterBinding REPLACE_BINDING = new ImporterBinding() + { + + public UUID_BINDING getUUIDBinding() + { + return UUID_BINDING.UPDATE_EXISTING; + } + + public String getValue(String key) + { + return null; + } + + public boolean allowReferenceWithinTransaction() + { + return false; + } + + public QName[] getExcludedClasses() + { + return null; + } + + }; + +} diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java index fc8bbf6930..13af1c1e35 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptNode.java +++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java @@ -39,6 +39,7 @@ import java.util.Set; import java.util.StringTokenizer; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ApplicationModel; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.executer.TransformActionExecuter; import org.alfresco.repo.content.transform.magick.ImageMagickContentTransformer; @@ -137,6 +138,8 @@ public class ScriptNode implements Serializable, Scopeable private NodeService nodeService = null; private Boolean isDocument = null; private Boolean isContainer = null; + private Boolean isLinkToDocument = null; + private Boolean isLinkToContainer = null; private String displayPath = null; protected TemplateImageResolver imageResolver = null; protected ScriptNode parent = null; @@ -595,6 +598,44 @@ public class ScriptNode implements Serializable, Scopeable return getIsDocument(); } + /** + * @return true if this Node is a Link to a Container (i.e. a folderlink) + */ + public boolean getIsLinkToContainer() + { + if (isLinkToContainer == null) + { + DictionaryService dd = this.services.getDictionaryService(); + isLinkToContainer = Boolean.valueOf(dd.isSubClass(getType(), ApplicationModel.TYPE_FOLDERLINK)); + } + + return isLinkToContainer.booleanValue(); + } + + public boolean jsGet_isLinkToContainer() + { + return getIsLinkToContainer(); + } + + /** + * @return true if this Node is a Link to a Document (i.e. a filelink) + */ + public boolean getIsLinkToDocument() + { + if (isLinkToDocument == null) + { + DictionaryService dd = this.services.getDictionaryService(); + isLinkToDocument = Boolean.valueOf(dd.isSubClass(getType(), ApplicationModel.TYPE_FILELINK)); + } + + return isLinkToDocument.booleanValue(); + } + + public boolean jsGet_isLinkToDocument() + { + return getIsLinkToDocument(); + } + /** * @return true if the Node is a Category */ diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderDuplicateChildTest.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderDuplicateChildTest.java new file mode 100644 index 0000000000..4b1941669a --- /dev/null +++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderDuplicateChildTest.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * 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.repo.model.filefolder; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import junit.framework.TestCase; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.model.FileExistsException; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileInfo; +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.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.util.ApplicationContextHelper; +import org.springframework.context.ApplicationContext; + +/** + * Checks that the duplicate child handling is done correctly. + * + * @see org.alfresco.repo.model.filefolder.FileFolderServiceImpl + * + * @author Derek Hulley + * @since 2.1.0 + */ +public class FileFolderDuplicateChildTest extends TestCase +{ + private static final ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); + + private AuthenticationComponent authenticationComponent; + private TransactionService transactionService; + private RetryingTransactionHelper retryingTransactionHelper; + private NodeService nodeService; + private FileFolderService fileFolderService; + private NodeRef rootNodeRef; + private NodeRef workingRootNodeRef; + + @Override + public void setUp() throws Exception + { + ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry"); + transactionService = serviceRegistry.getTransactionService(); + retryingTransactionHelper = transactionService.getRetryingTransactionHelper(); + nodeService = serviceRegistry.getNodeService(); + fileFolderService = serviceRegistry.getFileFolderService(); + authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); + + RetryingTransactionCallback callback = new RetryingTransactionCallback() + { + public NodeRef execute() throws Throwable + { + // authenticate + authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); + + // create a test store + StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis()); + rootNodeRef = nodeService.getRootNode(storeRef); + + // create a folder to import into + NodeRef nodeRef = nodeService.createNode( + rootNodeRef, + ContentModel.ASSOC_CHILDREN, + QName.createQName(NamespaceService.ALFRESCO_URI, "working root"), + ContentModel.TYPE_FOLDER).getChildRef(); + // Done + return nodeRef; + } + }; + workingRootNodeRef = retryingTransactionHelper.doInTransaction(callback, false, true); + } + + public void tearDown() throws Exception + { + } + + public void testDuplicateChildNameDetection() throws Exception + { + // First create a file name F1 + RetryingTransactionCallback callback = new CreateFileCallback(0); + FileInfo fileInfo = retryingTransactionHelper.doInTransaction(callback, false, true); + // Check that the filename is F0 + assertEquals("Incorrect initial filename", "F0", fileInfo.getName()); + + // Now create a whole lot of threads that attempt file creation + int threadCount = 10; + CountDownLatch endLatch = new CountDownLatch(threadCount); + WorkerThread[] workers = new WorkerThread[threadCount]; + for (int i = 0; i < threadCount; i++) + { + workers[i] = new WorkerThread(endLatch); + workers[i].start(); + } + // Wait at the end gate + endLatch.await(300L, TimeUnit.SECONDS); + + // Analyse + int failureCount = 0; + int didNotCompleteCount = 0; + for (int i = 0; i < threadCount; i++) + { + if (workers[i].error != null) + { + failureCount++; + } + else if (workers[i].success == null) + { + didNotCompleteCount++; + } + } + System.out.println("" + failureCount + " of the " + threadCount + " threads failed and " + didNotCompleteCount + " did not finish."); + assertEquals("Some failures", 0, failureCount); + assertEquals("Some non-finishes", 0, didNotCompleteCount); + } + + /** + * Attempts to create a file "Fn" where n is the number supplied to the constructor. + */ + private class CreateFileCallback implements RetryingTransactionCallback + { + private final int number; + public CreateFileCallback(int number) + { + this.number = number; + } + public FileInfo execute() throws Throwable + { + authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); + return fileFolderService.create( + workingRootNodeRef, + "F" + number, + ContentModel.TYPE_CONTENT); + } + } + + private static ThreadGroup threadGroup = new ThreadGroup("FileFolderDuplicateChildTest"); + private static int threadNumber = -1; + private class WorkerThread extends Thread + { + private CountDownLatch endLatch; + private Throwable error; + private FileInfo success; + + public WorkerThread(CountDownLatch endLatch) + { + super(threadGroup, "Worker " + ++threadNumber); + this.endLatch = endLatch; + } + + public void run() + { + FileInfo fileInfo = null; + // Start the count with a guaranteed failure + int number = 0; + while(true) + { + RetryingTransactionCallback callback = new CreateFileCallback(number); + try + { + System.out.println("Thread " + getName() + " attempting file: " + number); + System.out.flush(); + + fileInfo = retryingTransactionHelper.doInTransaction(callback, false, true); + // It worked + success = fileInfo; + break; + } + catch (FileExistsException e) + { + // Try another number + number++; + } + catch (Throwable e) + { + // Oops + error = e; + break; + } + } + // Done + if (error != null) + { + System.err.println("Thread " + getName() + " failed to create file " + number + ":"); + System.err.flush(); + error.printStackTrace(); + } + else + { + System.out.println("\t\t\tThread " + getName() + " created file: " + success.getName()); + System.out.flush(); + } + // Tick the latch + endLatch.countDown(); + } + } +} diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderTestSuite.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderTestSuite.java new file mode 100644 index 0000000000..7c1e5d31cb --- /dev/null +++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderTestSuite.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * 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.repo.model.filefolder; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Suite for FileFolderService tests. + * + * @author Derek Hulley + */ +public class FileFolderTestSuite extends TestSuite +{ + public static Test suite() + { + TestSuite suite = new TestSuite(); + + suite.addTestSuite(FileFolderServiceImplTest.class); + suite.addTestSuite(FileFolderDuplicateChildTest.class); + + return suite; + } +} diff --git a/source/java/org/alfresco/repo/model/ml/MultilingualContentServiceImpl.java b/source/java/org/alfresco/repo/model/ml/MultilingualContentServiceImpl.java index ea464f1f6b..7b9fea1d1a 100644 --- a/source/java/org/alfresco/repo/model/ml/MultilingualContentServiceImpl.java +++ b/source/java/org/alfresco/repo/model/ml/MultilingualContentServiceImpl.java @@ -401,13 +401,16 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic // remove the translations for(NodeRef translationToRemove : translations.values()) { - // unmake the translation - this.unmakeTranslation(translationToRemove); - - // remove it if(nodeService.exists(translationToRemove)) { - nodeService.deleteNode(translationToRemove); + // unmake the translation + this.unmakeTranslation(translationToRemove); + + // remove it + if(nodeService.exists(translationToRemove)) + { + nodeService.deleteNode(translationToRemove); + } } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java index 7ce7348788..7ac27f9987 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java @@ -1360,7 +1360,14 @@ public class IndexInfo // Do the deletions if ((entry.getDocumentCount() + entry.getDeletions()) == 0) { + registerReferenceCountingIndexReader(id, tl.get()); indexEntries.remove(id); + if (s_logger.isDebugEnabled()) + { + s_logger.debug("Removed commit with no new docs and no deletions"); + } + clearOldReaders(); + cleaner.schedule(); } else { @@ -1429,9 +1436,12 @@ public class IndexInfo private class RolledBackTransition implements Transition { + ThreadLocal tl = new ThreadLocal(); + public void beforeWithReadLock(String id, Set toDelete, Set read) throws IOException { closeDelta(id); + tl.set(buildReferenceCountingIndexReader(id)); } public void transition(String id, Set toDelete, Set read) throws IOException @@ -1446,6 +1456,15 @@ public class IndexInfo { entry.setStatus(TransactionStatus.ROLLEDBACK); writeStatus(); + + registerReferenceCountingIndexReader(id, tl.get()); + indexEntries.remove(id); + if (s_logger.isDebugEnabled()) + { + s_logger.debug("Removed rollback"); + } + clearOldReaders(); + cleaner.schedule(); } else { @@ -1477,9 +1496,9 @@ public class IndexInfo if (TransactionStatus.DELETABLE.follows(entry.getStatus())) { indexEntries.remove(id); - cleaner.schedule(); writeStatus(); clearOldReaders(); + cleaner.schedule(); } else { @@ -2094,62 +2113,34 @@ public class IndexInfo String indexLocation = args[0]; IndexInfo ii = new IndexInfo(new File(indexLocation), null); - while (true) + + ii.readWriteLock.writeLock().lock(); + try { - ii.readWriteLock.writeLock().lock(); - try + System.out.println("Entry List for " + indexLocation); + System.out.println(" Size = " + ii.indexEntries.size()); + int i = 0; + for (IndexEntry entry : ii.indexEntries.values()) { - System.out.println("Entry List for " + indexLocation); - System.out.println(" Size = " + ii.indexEntries.size()); - int i = 0; - for (IndexEntry entry : ii.indexEntries.values()) - { - System.out.println("\t" + (i++) + "\t" + entry.toString()); - } + System.out.println("\t" + (i++) + "\t" + entry.toString()); } - finally - { - ii.releaseWriteLock(); - } - IndexReader reader = ii.getMainIndexReferenceCountingReadOnlyIndexReader(); - TermEnum terms = reader.terms(new Term("@{archiweb.model}instance", "")); - while (terms.next() && terms.term().field().equals("@{archiweb.model}instance")) - { - System.out.println("F = " + terms.term().field() + " V = " + terms.term().text() + " F = " + terms.docFreq()); - } - terms.close(); - long start = System.currentTimeMillis(); - TermDocs termDocs = reader.termDocs(new Term("@{archiweb.model}instance", "tfl")); - while (termDocs.next()) - { - // System.out.println("Doc = " + termDocs.doc()); - Document doc = reader.document(termDocs.doc()); - doc.getField("ID"); - // System.out.println("Ref = "+doc.getField("ID")); - } - termDocs.close(); - System.out.println("Time = " + ((System.currentTimeMillis() - start) / 1000.0f)); - - terms = reader.terms(new Term("TYPE", "")); - while (terms.next() && terms.term().field().equals("TYPE")) - { - System.out.println("F = " + terms.term().field() + " V = " + terms.term().text() + " F = " + terms.docFreq()); - } - terms.close(); - start = System.currentTimeMillis(); - termDocs = reader.termDocs(new Term("TYPE", "{archiweb.model}tfdoc")); - while (termDocs.next()) - { - // System.out.println("Doc = " + termDocs.doc()); - Document doc = reader.document(termDocs.doc()); - doc.getField("ID"); - // System.out.println("Ref = "+doc.getField("ID")); - } - termDocs.close(); - System.out.println("Time = " + ((System.currentTimeMillis() - start) / 1000.0f)); - - // +@\{archiweb.model\}instance:TFL* } + finally + { + ii.releaseWriteLock(); + } + IndexReader reader = ii.getMainIndexReferenceCountingReadOnlyIndexReader(); + TermEnum terms = reader.terms(new Term("@{http://www.alfresco.org/model/user/1.0}members", "")); + while (terms.next() && terms.term().field().equals("@{http://www.alfresco.org/model/user/1.0}members")) + { + System.out.println("F = " + terms.term().field() + " V = " + terms.term().text() + " F = " + terms.docFreq()); + if (terms.term().text().equals("xirmsi")) + { + System.out.println("Matched"); + } + } + terms.close(); + } /** diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/ReferenceCountingReadOnlyIndexReaderFactory.java b/source/java/org/alfresco/repo/search/impl/lucene/index/ReferenceCountingReadOnlyIndexReaderFactory.java index 958793b1ad..64f5f279fa 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/index/ReferenceCountingReadOnlyIndexReaderFactory.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/index/ReferenceCountingReadOnlyIndexReaderFactory.java @@ -66,7 +66,7 @@ public class ReferenceCountingReadOnlyIndexReaderFactory builder .append("Id = " + rc.getId() + " Invalid = " + rc.getReferenceCount() + " invalid = " - + rc.getInvalidForReuse()); + + rc.getInvalidForReuse() + " closed="+rc.getClosed()); return builder.toString(); } @@ -158,6 +158,11 @@ public class ReferenceCountingReadOnlyIndexReaderFactory return invalidForReuse; } + public synchronized boolean getClosed() + { + return closed; + } + public synchronized void setInvalidForReuse() throws IOException { if(closed) diff --git a/source/java/org/alfresco/repo/template/BaseContentNode.java b/source/java/org/alfresco/repo/template/BaseContentNode.java index b905f42774..a09e851459 100644 --- a/source/java/org/alfresco/repo/template/BaseContentNode.java +++ b/source/java/org/alfresco/repo/template/BaseContentNode.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import org.alfresco.model.ApplicationModel; import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.security.permissions.AccessDeniedException; @@ -73,6 +74,8 @@ public abstract class BaseContentNode implements TemplateContent private Boolean isDocument = null; private Boolean isContainer = null; + private Boolean isLinkToDocument = null; + private Boolean isLinkToContainer = null; /** * @return true if this Node is a container (i.e. a folder) @@ -102,7 +105,35 @@ public abstract class BaseContentNode implements TemplateContent return isDocument.booleanValue(); } - + + /** + * @return true if this Node is a Link to a Container (i.e. a folderlink) + */ + public boolean getIsLinkToContainer() + { + if (isLinkToContainer == null) + { + DictionaryService dd = this.services.getDictionaryService(); + isLinkToContainer = Boolean.valueOf(dd.isSubClass(getType(), ApplicationModel.TYPE_FOLDERLINK)); + } + + return isLinkToContainer.booleanValue(); + } + + /** + * @return true if this Node is a Link to a Document (i.e. a filelink) + */ + public boolean getIsLinkToDocument() + { + if (isLinkToDocument == null) + { + DictionaryService dd = this.services.getDictionaryService(); + isLinkToDocument = Boolean.valueOf(dd.isSubClass(getType(), ApplicationModel.TYPE_FILELINK)); + } + + return isLinkToDocument.booleanValue(); + } + /** * Override Object.toString() to provide useful debug output */ diff --git a/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java b/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java index 62a0f3fedd..39d08b880a 100644 --- a/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java +++ b/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java @@ -40,7 +40,9 @@ import org.apache.log4j.Logger; import org.hibernate.StaleObjectStateException; import org.hibernate.exception.LockAcquisitionException; import org.springframework.dao.ConcurrencyFailureException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DeadlockLoserDataAccessException; +import org.springframework.jdbc.UncategorizedSQLException; /** * A helper that runs a unit of work inside a UserTransaction, @@ -65,7 +67,8 @@ public class RetryingTransactionHelper DeadlockLoserDataAccessException.class, StaleObjectStateException.class, LockAcquisitionException.class, - BatchUpdateException.class + BatchUpdateException.class, + DataIntegrityViolationException.class }; } @@ -363,6 +366,33 @@ public class RetryingTransactionHelper return null; } } + else if (retryCause instanceof DataIntegrityViolationException) + { + if (retryCause.getMessage().contains("ChildAssocImpl")) + { + // It is probably the duplicate name violation + return retryCause; + } + else + { + // Something else + return null; + } + } + else if (retryCause instanceof UncategorizedSQLException) + { + // Handle error that slips out of MSSQL + if (retryCause.getMessage().contains("deadlock")) + { + // It is valid + return retryCause; + } + else + { + // Not valid + return null; + } + } else { return retryCause;