From 913fd94807964f88d1c1af3b29eaad539b09dd29 Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Wed, 13 Jun 2012 19:48:38 +0000 Subject: [PATCH] Merged V4.0-BUG-FIX to HEAD 37623: ALF-14183: Additional NP check for transition-id when building model 37626: ALF-13888: Merged V3.4-BUG-FIX to V4.0-BUG-FIX (missed merge) 33425: Merged DEV to V3.4-BUG-FIX 33359: ALF-12071: Windows 7 cannot open files stored on Alfresco mounted as a webdav network drive if the filename contains + (plus) character For Windows 7 we SHOULD decode the file name gotten from GET request taking into account that "+" is not encoded as "%2B" for GET request. 37630: Process queued responses at the end of the thread request run, before re-enabling socket read events. ALF-14179, ALF-14180. 37636: REVERSE Merge to V4.0-BUG-FIX (4.0.3) << Now that ALF-13933 allows startup of OpenOffice/LibreOffice and JOD transformers from Java (even on Mac), this hack is no longer required. >> << The hack started up OpenOffice from the cmd line so OpenOffice transformer would be working but not JOD. >> << The bitrock alfresco.sh and openoffice.xml fiels are now identical between V3.4-BUG-FIX and V4.0-BUG-FIX >> 32952: ALF-7944: OSX OOo started by script not by subsystem now 37647: RECORD ONLY Merge V4.0 (4.0.2) to V4.0-BUG-FIX (4.0.3) 37646: Merge to V4.0-BUG-FIX (4.0.3) to V4.0 (4.0.2) 37636: REVERSE Merge to V4.0-BUG-FIX (4.0.3) << Now that ALF-13933 allows startup of OpenOffice/LibreOffice and JOD transformers from Java (even on Mac), this hack is no longer required. >> << The hack started up OpenOffice from the cmd line so OpenOffice transformer would be working but not JOD. >> << The bitrock alfresco.sh and openoffice.xml fiels are now identical between V3.4-BUG-FIX and V4.0-BUG-FIX >> 32952: ALF-7944: OSX OOo started by script not by subsystem now 37657: Websphere libraries.xml has regressed due to ALF-12477 37667: ALF-14307: Upgraded Activiti lib, preventing diagram-generation on process-definition query when initial deploy-time generation failed 37676: Fix for ALF-14489 - Link with special charaters (i.e. &) in Site Activities doesn't work properly Note: 4.0 fix is different to 3.4 fix as wiki webscripts have all been converted to Java backed webscripts) Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX 37673: *Record only* Fix for ALF-14489 - Link with special charaters (i.e. &) in Site Activities doesn't work properly 37708: Increase version to 4.0.4 (4.0.3 being now dedicated to Cloud Sync) 37722: RECORD ONLY Merge V4.0 (4.0.2) to V4.0-BUG-FIX (4.0.3) 37679: ALF-14469: Reversed the reverse merge 37656, therefore reinstating ALF-13013 as it was actually a QA configuration problem! 37664: ALF-14053: Merged V4.0-BUG-FIX (4.0.3) to V4.0 (4.0.2) Missing commits that removed $DYLD_LIBRARY_PATH from the environment. Had thought they were already in V4.0. 37353: Merged V3.4-BUG-FIX (3.4.10) to V4.0-BUG-FIX (4.0.3) 37352: ALF-13452, ALF-13933 Alfresco needs to be able to support LibreOffice for transformations - Build test failure 37326: ALF-13933 Alfresco needs to be able to support LibreOffice for transformations ALF-13452 Open office startup from Java not working on OSX - Added code to start LibreOffice 3.5 on Mac (requires different options to the command and ure-link is a directory rather than a file on mac) - Removes $DYLD_LIBRARY_PATH from the environment when starting either openoffice or libreoffice on mac so does not need to rely on the installer moving the soffice.bin process to .soffice.bin and then creating a soffice.bin shell script that removed $DYLD_LIBRARY_PATH - Indent TransformerDebug a bit more now we have fail over transformers at the top and lower levels (saves N.N.N.N.N.N getting mixed up with text) 37656: Reverse merged 34391 and fix to ALF-13013 because it causes regression ALF-14469 on Websphere 37746: Merged V3.4-BUG-FIX to V4.0-BUG-FIX (RECORD ONLY) 37742: ALF-12486: Share - Calendar does not save past events - Fix reviewed by David We 37743: ALF-14340: Merged HEAD to V3.4-BUG-FIX 35582: ALF-8601: Alfresco installs different ImageMagick versions on different stacks - Now 6.5.6 is installed on all platforms 37748: Merged V3.4-BUG-FIX to V4.0-BUG-FIX 37655: ALF-14465: Bitrock installer: Advanced installation (apply AMP) finishes with error - added -force option to installer bundles - added warning (regardless of verbose flag) when files will be overwritten - added -help option (requested by product management) - removed replicated png from RM - reorganised code to differentiate between an install failure and command line parse failure. 37658: ALF-13063: Trailing spaces after the DB2 JDBC class name, causing me hours of puzzlement - Improved the URL so you get error messages out of the database 37663: ALF-13499: Share - Permissions page in the repository shows the groupid instead of displayname 37666: Fixed ALF-10790: DMDeploymentTargetTest consistently failing on SQL Server - Text match for 'fk_alf_cass_' in error message, which covers all FK violations but excludes the unique constraint - This is also a refix for ALF-10581, which should probably be retested 37697: ALF-11911 - Share: unable to externalise the raw role name 37712: Improvements to Forms runtime to handle empty json response when AccessDeniedException is thrown from the repository. Noticed during ALF-9861 investigation. 37744: ALF-14340: Patch from Bitrock to include Ghostscript with Windows-installed ImageMagick (already included with Unix versions) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@37750 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco-global.properties.sample | 4 +- config/alfresco/version.properties | 2 +- .../repo/domain/node/AbstractNodeDAOImpl.java | 27 ++-- .../module/tool/ModuleManagementTool.java | 138 ++++++++++++------ 4 files changed, 108 insertions(+), 63 deletions(-) diff --git a/config/alfresco-global.properties.sample b/config/alfresco-global.properties.sample index 2d71726f19..b48660f160 100644 --- a/config/alfresco-global.properties.sample +++ b/config/alfresco-global.properties.sample @@ -65,8 +65,8 @@ # # DB2 connection # -#db.driver=com.ibm.db2.jcc.DB2Driver -#db.url=jdbc:db2://host:50000/ALFRESCO +#db.driver=com.ibm.db2.jcc.DB2Driver +#db.url=jdbc:db2://localhost:50000/alfresco:retrieveMessagesFromServerOnGetMessage=true; # # Index Recovery Mode diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 4169d3b41d..4589071a8b 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -5,7 +5,7 @@ # Version label version.major=4 -version.minor=1 +version.minor=2 version.revision=0 version.label= diff --git a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java index 7e1a2e9993..b7dc502aed 100644 --- a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java @@ -1377,6 +1377,14 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO catch (Throwable e) { controlDAO.rollbackToSavepoint(savepoint); + // DuplicateChildNodeNameException implements DoNotRetryException. + // There are some cases - FK violations, specifically - where we DO actually want to retry. + // Detecting this is done by looking for the related FK names, 'fk_alf_cass_*' in the error message + String lowerMsg = e.getMessage().toLowerCase(); + if (lowerMsg.contains("fk_alf_cass_")) + { + throw new ConcurrencyFailureException("FK violation updating primary parent association for " + childNodeId, e); + } // We assume that this is from the child cm:name constraint violation throw new DuplicateChildNodeNameException( newParentNode.getNodeRef(), @@ -2869,21 +2877,14 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO catch (Throwable e) { controlDAO.rollbackToSavepoint(savepoint); + // DuplicateChildNodeNameException implements DoNotRetryException. - // SQL Server retry - if (e.getMessage().contains("Snapshot isolation transaction aborted")) + // There are some cases - FK violations, specifically - where we DO actually want to retry. + // Detecting this is done by looking for the related FK names, 'fk_alf_cass_*' in the error message + String lowerMsg = e.getMessage().toLowerCase(); + if (lowerMsg.contains("fk_alf_cass_")) { - logger.warn("insertChildAssoc: SQL Server snapshot isolation retry: "+assoc); - throw new ConcurrencyFailureException("SQL Server snapshot isolation retry...", e); - } - - // FK conflict retry, eg. - // SQL Server - The INSERT statement conflicted with the FOREIGN KEY constraint - // MySQL - Cannot add or update a child row: a foreign key constraint fails - if (e.getMessage().toUpperCase().contains("FOREIGN KEY")) - { - logger.warn("insertChildAssoc: FK conflict retry: "+assoc); - throw new ConcurrencyFailureException("FK conflict retry...", e); + throw new ConcurrencyFailureException("FK violation updating primary parent association:" + assoc, e); } // We assume that this is from the child cm:name constraint violation diff --git a/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java b/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java index 5fb2441938..21d8d4b7fe 100644 --- a/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java +++ b/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java @@ -78,6 +78,7 @@ public class ModuleManagementTool implements LogOutput private static final String OPTION_NOBACKUP = "-nobackup"; private static final String OPTION_DIRECTORY = "-directory"; private static final String OPTION_PURGE = "-purge"; + private static final String OPTION_HELP = "-help"; private static final int ERROR_EXIT_CODE = 1; private static final int SUCCESS_EXIT_CODE = 0; @@ -197,7 +198,7 @@ public class ModuleManagementTool implements LogOutput * @param warFileLocation the location of the WAR file into which the AMP file is to be installed. * @param preview indicates whether this should be a preview install. This means that the process of * installation will be followed and reported, but the WAR file will not be modified. - * @param forceInstall indicates whether the installed files will be replaces regardless of the currently installed + * @param forceInstall indicates whether the installed files will be replaced regardless of the currently installed * version of the AMP. Generally used during development of the AMP. * @param backupWAR indicates whether we should backup the war we are modifying or not */ @@ -205,7 +206,7 @@ public class ModuleManagementTool implements LogOutput { try { - outputMessage("Installing AMP '" + ampFileLocation + "' into WAR '" + warFileLocation + "'"); + outputVerboseMessage("Installing AMP '" + ampFileLocation + "' into WAR '" + warFileLocation + "'"); java.io.File theWar = new File(warFileLocation, DETECTOR_AMP_AND_WAR); if (!theWar.exists()) @@ -243,7 +244,7 @@ public class ModuleManagementTool implements LogOutput uninstallIfNecessary(warFileLocation, installedModuleDetails, preview, forceInstall, installingVersion); - outputMessage("Adding files relating to version '" + installingVersion + "' of module '" + installingId + "'"); + outputVerboseMessage("Adding files relating to version '" + installingVersion + "' of module '" + installingId + "'"); InstalledFiles installedFiles = new InstalledFiles(warFileLocation, installingId); Properties directoryChanges = calculateChanges(ampFileLocation, warFileLocation, preview, forceInstall, installedFiles); @@ -313,7 +314,7 @@ public class ModuleManagementTool implements LogOutput if (compareValue > 0) { // Trying to install an earlier version of the extension - outputMessage("WARNING: A later version of this module is already installed in the WAR. Installation skipped. "+ + outputVerboseMessage("WARNING: A later version of this module is already installed in the WAR. Installation skipped. "+ "You could force the installation by passing the -force option.",false); return; } @@ -321,20 +322,20 @@ public class ModuleManagementTool implements LogOutput if (forceInstall == true) { // Warn of forced install - outputMessage("WARNING: The installation of this module is being forced. All files will be removed and replaced regardless of exiting versions present.",false); + outputVerboseMessage("WARNING: The installation of this module is being forced. All files will be removed and replaced regardless of exiting versions present.",false); } if (compareValue == 0) { // Trying to install the same extension version again - outputMessage("WARNING: This version of this module is already installed in the WAR..upgrading.",false); + outputVerboseMessage("WARNING: This version of this module is already installed in the WAR..upgrading.",false); } if (forceInstall == true || compareValue <= 0) { // Trying to update the extension, old files need to cleaned before we proceed - outputMessage("Clearing out files relating to version '" + installedVersion + "' of module '" + installedId + "'",false); + outputVerboseMessage("Clearing out files relating to version '" + installedVersion + "' of module '" + installedId + "'",false); uninstallModule(installedId, warFileLocation, preview, true); } } @@ -426,7 +427,7 @@ public class ModuleManagementTool implements LogOutput throw new ModuleManagementToolException("An IO error was encountered when backing up the WAR", exception); } - outputMessage("WAR has been backed up to '" + backupLocation + "'"); + outputVerboseMessage("WAR has been backed up to '" + backupLocation + "'"); } } @@ -496,7 +497,7 @@ public class ModuleManagementTool implements LogOutput backup.delete(); } - outputMessage("Recovering file '" + update.getKey() + "' from backup '" + update.getValue() + "'", true); + outputVerboseMessage("Recovering file '" + update.getKey() + "' from backup '" + update.getValue() + "'", true); } // Now remove the installed files list String installedFilesPathInWar = installedFiles.getFilePathInWar(); @@ -518,7 +519,7 @@ public class ModuleManagementTool implements LogOutput File removeFile = new File(warLocation + filePath, DETECTOR_AMP_AND_WAR); if (removeFile.exists() == true) { - outputMessage("Removing file '" + filePath + "' from war", true); + outputVerboseMessage("Removing file '" + filePath + "' from war", true); if (preview == false) { removeFile.delete(); @@ -526,7 +527,7 @@ public class ModuleManagementTool implements LogOutput } else { - outputMessage("The file '" + filePath + "' was expected for removal but was not present in the war", true); + outputVerboseMessage("The file '" + filePath + "' was expected for removal but was not present in the war", true); } } @@ -607,12 +608,12 @@ public class ModuleManagementTool implements LogOutput if (createFile == true) { installedFiles.addAdd(destinationDir + "/" + sourceChild.getName()); - this.outputMessage("File '" + destinationDir + "/" + sourceChild.getName() + "' added to war from amp", true); + this.outputVerboseMessage("File '" + destinationDir + "/" + sourceChild.getName() + "' added to war from amp", true); } else { installedFiles.addUpdate(destinationDir + "/" + sourceChild.getName(), backupLocation); - this.outputMessage("WARNING: The file '" + destinationDir + "/" + sourceChild.getName() + "' is being updated by this module and has been backed-up to '" + backupLocation + "'", true); + this.outputMessage("WARNING: The file '" + destinationDir + "/" + sourceChild.getName() + "' is being overwritten by this module. The original has been backed-up to '" + backupLocation + "'", true); } } else @@ -628,7 +629,7 @@ public class ModuleManagementTool implements LogOutput if (mkdir == true) { installedFiles.addMkdir(destinationDir + "/" + sourceChild.getName()); - this.outputMessage("Directory '" + destinationDir + "/" + sourceChild.getName() + "' added to war", true); + this.outputVerboseMessage("Directory '" + destinationDir + "/" + sourceChild.getName() + "' added to war", true); } } } @@ -668,7 +669,7 @@ public class ModuleManagementTool implements LogOutput File moduleDir = new File(warLocation + WarHelper.MODULE_NAMESPACE_DIR, DETECTOR_AMP_AND_WAR); if (moduleDir.exists() == false) { - outputMessage("No modules are installed in this WAR file"); + outputVerboseMessage("No modules are installed in this WAR file"); } java.io.File[] dirs = moduleDir.listFiles(); @@ -692,22 +693,22 @@ public class ModuleManagementTool implements LogOutput throw new ModuleManagementToolException("Unable to open module properties file '" + moduleProperties.getPath() + "'", exception); } - outputMessage("Module '" + moduleDetails.getId() + "' installed in '" + warLocation + "'"); - outputMessage(" Title: " + moduleDetails.getTitle(), true); - outputMessage(" Version: " + moduleDetails.getVersion(), true); - outputMessage(" Install Date: " + moduleDetails.getInstallDate(), true); - outputMessage(" Description: " + moduleDetails.getDescription(), true); + outputVerboseMessage("Module '" + moduleDetails.getId() + "' installed in '" + warLocation + "'"); + outputVerboseMessage(" Title: " + moduleDetails.getTitle(), true); + outputVerboseMessage(" Version: " + moduleDetails.getVersion(), true); + outputVerboseMessage(" Install Date: " + moduleDetails.getInstallDate(), true); + outputVerboseMessage(" Description: " + moduleDetails.getDescription(), true); } } } } else { - outputMessage("No modules are installed in this WAR file"); + outputVerboseMessage("No modules are installed in this WAR file"); } if (!moduleFound) { - outputMessage("No modules were found in this WAR file"); + outputVerboseMessage("No modules were found in this WAR file"); } } @@ -722,9 +723,9 @@ public class ModuleManagementTool implements LogOutput * * @param message the message to output */ - private void outputMessage(String message) + private void outputVerboseMessage(String message) { - outputMessage(message, false, false); + outputMessage(message, false, false, false); } /** @@ -734,7 +735,7 @@ public class ModuleManagementTool implements LogOutput */ private void outputErrorMessage(String message) { - outputMessage(message, false, true); + outputMessage(message, false, true, false); } /** @@ -743,9 +744,20 @@ public class ModuleManagementTool implements LogOutput * @param message the message to output * @param indent indicates that the message should be formated with an indent */ + private void outputVerboseMessage(String message, boolean indent) + { + outputMessage(message, indent, false, false); + } + + /** + * Outputs a message to the console regardless of the verbose setting. + * + * @param message the message to output + * @param indent indicates that the message should be formated with an indent + */ private void outputMessage(String message, boolean indent) { - outputMessage(message, indent, false); + outputMessage(message, indent, false, true); } /** @@ -754,8 +766,9 @@ public class ModuleManagementTool implements LogOutput * @param message the message to output * @param indent indicates that the message should be formated with an indent * @param error indicates that the message is an error. + * @param stdout indicates that the message should output to the console regardless of verbose setting */ - private void outputMessage(String message, boolean indent, boolean error) + private void outputMessage(String message, boolean indent, boolean error, boolean stdout) { if (indent == true) { @@ -765,7 +778,7 @@ public class ModuleManagementTool implements LogOutput { System.err.println(message); } - else if (this.verbose == true) + else if (this.verbose == true || stdout == true) { System.out.println(message); } @@ -788,8 +801,17 @@ public class ModuleManagementTool implements LogOutput String operation = args[0]; try { - if (operation.equals(OP_INSTALL) == true && args.length >= 3) - { + if (operation.equals(OPTION_HELP) == true) + { + outputUsage(); + System.exit(SUCCESS_EXIT_CODE); + } + else if (operation.equals(OP_INSTALL) == true) + { + if (args.length < 3) + { + throw new UsageException(OP_INSTALL + " requires at least 3 arguments."); + } String aepFileLocation = args[1]; String warFileLocation = args[2]; boolean forceInstall = false; @@ -826,28 +848,36 @@ public class ModuleManagementTool implements LogOutput } } - if (directory == false) - { - // Install the module - manager.installModule(aepFileLocation, warFileLocation, previewInstall, forceInstall, backup); - } - else - { - // Install the modules from the directory - manager.installModules(aepFileLocation, warFileLocation, previewInstall, forceInstall, backup); - } - System.exit(SUCCESS_EXIT_CODE); + if (directory == false) + { + // Install the module + manager.installModule(aepFileLocation, warFileLocation, previewInstall, forceInstall, backup); + } + else + { + // Install the modules from the directory + manager.installModules(aepFileLocation, warFileLocation, previewInstall, forceInstall, backup); + } + System.exit(SUCCESS_EXIT_CODE); } - else if (OP_LIST.equals(operation) == true && args.length == 2) + else if (OP_LIST.equals(operation) == true) { + if (args.length != 2) + { + throw new UsageException(OP_LIST + " requires 2 arguments."); + } // List the installed modules String warFileLocation = args[1]; manager.listModules(warFileLocation); System.exit(SUCCESS_EXIT_CODE); } - else if (OP_UNINSTALL.equals(operation) == true && args.length >= 3) + else if (OP_UNINSTALL.equals(operation) == true) { + if (args.length < 3) + { + throw new UsageException(OP_UNINSTALL + " requires at least 3 arguments."); + } String moduleId = args[1]; String warLocation = args[2]; boolean purge = false; @@ -875,16 +905,20 @@ public class ModuleManagementTool implements LogOutput } else { - outputUsage(); - System.exit(SUCCESS_EXIT_CODE); + throw new UsageException("Unknown operation " + operation + "."); } } + catch (UsageException e) + { + manager.outputErrorMessage("Usage error: " + e.getMessage()); + outputUsage(); + System.exit(ERROR_EXIT_CODE); + } catch (ModuleManagementToolException e) { // These are user-friendly manager.outputErrorMessage(e.getMessage()); - outputUsage(); System.exit(ERROR_EXIT_CODE); } } @@ -956,6 +990,16 @@ public class ModuleManagementTool implements LogOutput @Override public void info(Object message) { - outputMessage(String.valueOf(message)); + outputVerboseMessage(String.valueOf(message)); } + + private static class UsageException extends Exception + { + private static final long serialVersionUID = 1L; + + public UsageException(String message) { + super(message); + } + } + }