Merged V4.1-BUG-FIX to HEAD

42118: ALF-15878 ALF-15741: generate doc and src zip for web-framework-commons and jlan
   42134: ALF-15741: Fix build failing when creating jlan src jar
   42142: Added ignore for dev-log4j.properties
   42143: In-memory bridge table for ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups
   42156: Merged V3.4-BUG-FIX to V4.1-BUG-FIX
      41336: TransformerDebug: Use debug rather than trace when there are transformers but they are all unavailable.
      41589: GERMAN: Translation updates based on EN rev41571
      41590: SPANISH: Translation updates based on EN rev41571
      41592: FRENCH: Translation updates based on EN rev41571
      41593: ITALIAN: Translation updates based on EN rev41571
      41594: JAPANESE: Translation updates based on EN rev41571
      41726: Merge DEV to V3.4-BUG-FIX (3.4.11)
        41582: ALF-5285: Workflow: Setting default value to data type <default>0</default>, value is not retained.
           Used a hashMap (initialized in constructor), containing the properties to be "ignored" and they used this for checking
      41769: GERMAN: Translation updates based on EN rev41571
      41770: FRENCH: Translation updates based on EN rev41571
      41771: SPANISH: Translation updates based on EN rev41571
      41772: ITALIAN: Translation updates based on EN rev41571
      41773: JAPANESE: Translation updates based on EN rev41571
      41776: Fixes: ALF-12999: Filters labels not showing correctly in RSS feed.
      41917: ALF-14892: Merged DEV to V3.4-BUG-FIX
         41668: Excessive number of unused transactions created with WQS publishing failure
      42002: ALF-4742: webscript person.lib.ftl does not include all attributes for users out of the box.
      42016: ALF-13282: When moving a hierarchy of nodes to a different store (e.g. on archiving) fire ALL beforeDelete() policies on the hierarchy BEFORE commencing the moving to save confusion
      42040: ALF-13282: Fix unit test failures
      42144: Fixes: ALF-11124 - removes country specific suffix from Sharepoint properties files.
      42150: ALF-16125: DTD error in web.xml
      42152: Merged V3.4 to V3.4-BUG-FIX (RECORD ONLY)
         42149: Merged V3.4-BUG-FIX to V3.4 (3.4.11)
         42151: Merged V3.4-BUG-FIX to V3.4
            42150: ALF-16125: DTD error in web.xml
   42161: Merged V3.4-BUG-FIX to V4.1-BUG-FIX (RECORD ONLY)
      41586: ALF-15951: Merged V4.1-BUG-FIX to V3.4-BUG-FIX
         40490: ALF-15455: Pass through windows specific environment variables (will not be set on unix) to make ImageMagick work on Windows with Bitrock layout
         40535: ALF-15455: Another attempt
         - Properly escape global variables so bitrock doesn't try to expand them
         - Force backslash paths on windows
         40539: ALF-15455: ImageMagick still not working on Windows because env variable setting was losing the system PATH
         - Did it ever work before?
         - Now, if variables are specified, the PATH is propagated from the parent environment. If a PATH is specified, it is prepended to the parent PATH.
      41749: BACKPORT from 4 <<< DO NOT MERGE TO V4.1-BUG-FIX >>>
         - ALF-9946 Need a supported solution for switching off content indexing (FTS) 
      41774: DO NOT MERGE TO 4.x (I have already refactored the code)
      Merged BRANCHES/DEV/BELARUS/V3.4-BUG-FIX-2012_04_05 to BRANCHES/DEV/V3.4-BUG-FIX:
         35195: ALF-13623: Event info dissappears after choosing doc folder
      41775: DO NOT MERGE TO v4.x
      Fixes: ALF-13295: removes incorrect background colour.
      41844: ALF-16102: Merged HEAD to V3.4-BUG-FIX
         30913: ALF-1966 - Inbound email supports STARTTLS by default - however this requires Java + SSL configuration to be done to work
            Updated to latest SubEtha lib and added three new configuration properties.
         30952: ALF-1878 : Duplicate incoming email Subjects over-write each other
           new configuration property email.handler.folder.overwriteDuplicates added, defaults to true so existing behaviour is maintained.
         31269: ALF-10775 - Thumbnail is not created created for duplicate files uploaded via email
         31795: Added new test for Email Server to check configuration for EVERYONE group works.
         32731: ALF-11837 - now will authenticate via both from fields - also a refactor in anticipation of implemeting multiple recipeints and authentication.
         32732: File missed from last check in.
      Merged V4.1-BUG-FIX to V3.4-BUG-FIX
         41539: ALF-15899: Inbound email does not support multiple recipient folders
            - Fix by Dmitry Vaserin
      41854: Rollback of: BACKPORT from 4 <<< DO NOT MERGE TO V4.1-BUG-FIX >>>
         - ALF-9946 Need a supported solution for switching off content indexing (FTS)
      41901: BACKPORT from 4 <<< DO NOT MERGE TO V4.1-BUG-FIX >>>
         - ALF-9946 Need a supported solution for switching off content indexing (FTS) 
      42159: Merged V3.4 to V3.4-BUG-FIX
         42158: ALF-13282: Correction to invokeBeforeDeleteChildAssociation sequencing in moveNode().
   42162: Merged V4.1 to V4.1-BUG-FIX
      42048: ALF-16005 Could not transform file size of 0 kb
         - Turns out that it was only doc ppt and xls zero byte files that had the problem.
         - Reverting part of revision 6473 (release 2.1 2007) AR-1251 (Version error when saving new content via CIFS)
           Dave W tells me that this is no longer an issue due to other changes
      42051: Merged DEV to V4.1 (4.1.1)
         42035: ALF-15983: SPP: Meeting space: all-day event is displayed on the day before specified during creation
         -   Removing of time zone has been modified to cover the case, when UTC time zone is already configured for Java.
             This case leads to conversion of date to UTC time zone in both cases: using 'new Date(Date, DateTimeZone)' and 'new Date(Date)'
      42116: ALF-9300, ALF-16074: Add the aria plugins to our strange YUI variant to make AWE work on non-IE browsers


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@42163 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2012-09-28 16:00:23 +00:00
parent 642d332d24
commit 148df71e9e
3 changed files with 137 additions and 124 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -26,6 +26,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -2560,7 +2561,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
Pair<Long, NodeRef> parentNodePair = getNodePairNotNull(newParentRef);
Long nodeToMoveId = nodeToMovePair.getFirst();
QName nodeToMoveTypeQName = nodeDAO.getNodeType(nodeToMoveId);
NodeRef oldNodeToMoveRef = nodeToMovePair.getSecond();
Long parentNodeId = parentNodePair.getFirst();
NodeRef parentNodeRef = parentNodePair.getSecond();
@@ -2576,64 +2576,123 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
}
ChildAssociationRef oldParentAssocRef = oldParentAssocPair.getSecond();
// Get the aspects for later use
Set<QName> nodeToMoveAspectQNames = nodeDAO.getNodeAspects(nodeToMoveId);
boolean movingStore = !oldStoreRef.equals(newStoreRef);
// Invoke "Before"policy behaviour
if (movingStore)
{
invokeBeforeDeleteNode(nodeToMoveRef);
invokeBeforeCreateNode(newParentRef, assocTypeQName, assocQName, nodeToMoveTypeQName);
}
else
{
invokeBeforeMoveNode(oldParentAssocRef, newParentRef);
invokeBeforeDeleteChildAssociation(oldParentAssocRef);
}
// Move node under the new parent
Pair<Pair<Long, ChildAssociationRef>, Pair<Long, NodeRef>> moveNodeResult = nodeDAO.moveNode(
nodeToMoveId,
parentNodeId,
assocTypeQName,
assocQName);
Pair<Long, ChildAssociationRef> newParentAssocPair = moveNodeResult.getFirst();
Pair<Long, NodeRef> newNodeToMovePair = moveNodeResult.getSecond();
ChildAssociationRef newParentAssocRef = newParentAssocPair.getSecond();
// Handle indexing differently if it is a store move
if (movingStore)
{
// The association existed before and the node is moving to a new store
// Recursively find primary children of the node to move
// TODO: Use NodeHierarchyWalker
List<ChildAssociationRef> childAssocs = new LinkedList<ChildAssociationRef>();
Map<NodeRef, Long> oldChildNodeIds = new HashMap<NodeRef, Long>(97);
findNodeChildrenToMove(nodeToMoveId, newStoreRef, childAssocs, oldChildNodeIds);
// Invoke "Before Delete" policy behaviour
invokeBeforeDeleteNode(nodeToMoveRef);
// do the same to the children, preserving parents, types and qnames
for (ChildAssociationRef oldChildAssoc : childAssocs)
{
// Fire before delete policy. Before create policy needs the new parent ref to exist, so will be fired later
invokeBeforeDeleteNode(oldChildAssoc.getChildRef());
}
// Now do the moving and remaining policy firing
Map<NodeRef, Pair<Long, NodeRef>> movedNodePairs = new HashMap<NodeRef, Pair<Long,NodeRef>>(childAssocs.size() * 2 + 2);
QName childNodeTypeQName = nodeDAO.getNodeType(nodeToMoveId);
Set<QName> childNodeAspectQNames = nodeDAO.getNodeAspects(nodeToMoveId);
// Fire before create immediately before moving with all parents in place
invokeBeforeCreateNode(newParentRef, assocTypeQName, assocQName, childNodeTypeQName);
// Move node under the new parent
Pair<Pair<Long, ChildAssociationRef>, Pair<Long, NodeRef>> moveNodeResult = nodeDAO.moveNode(
nodeToMoveId,
parentNodeId,
assocTypeQName,
assocQName);
Pair<Long, ChildAssociationRef> newParentAssocPair = moveNodeResult.getFirst();
movedNodePairs.put(nodeToMoveRef, moveNodeResult.getSecond());
ChildAssociationRef newParentAssocRef = newParentAssocPair.getSecond();
// Index
nodeIndexer.indexDeleteNode(oldParentAssocRef);
nodeIndexer.indexCreateNode(newParentAssocRef);
}
else
{
// The node is in the same store and is just having it's child association modified
nodeIndexer.indexUpdateChildAssociation(oldParentAssocRef, newParentAssocRef);
}
// Call behaviours
// TODO: Use NodeHierarchyWalker
if (movingStore)
{
// Propagate timestamps
propagateTimeStamps(oldParentAssocRef);
propagateTimeStamps(newParentAssocRef);
// The Node changes NodeRefs, so this is really the deletion of the old node and creation
// of a node in a new store as far as the clients are concerned.
invokeOnDeleteNode(oldParentAssocRef, nodeToMoveTypeQName, nodeToMoveAspectQNames, true);
invokeOnDeleteNode(oldParentAssocRef, childNodeTypeQName, childNodeAspectQNames, true);
invokeOnCreateNode(newParentAssocRef);
// Pull children to the new store
pullNodeChildrenToSameStore(newNodeToMovePair);
// do the same to the children, preserving parents, types and qnames
for (ChildAssociationRef oldChildAssoc : childAssocs)
{
NodeRef oldChildNodeRef = oldChildAssoc.getChildRef();
Long oldChildNodeId = oldChildNodeIds.get(oldChildNodeRef);
NodeRef oldParentNodeRef = oldChildAssoc.getParentRef();
Pair<Long, NodeRef> newParentNodePair = movedNodePairs.get(oldParentNodeRef);
Long newParentNodeId = newParentNodePair.getFirst();
childNodeTypeQName = nodeDAO.getNodeType(oldChildNodeId);
childNodeAspectQNames = nodeDAO.getNodeAspects(oldChildNodeId);
// Now that the new parent ref exists, invoke the before create policy
invokeBeforeCreateNode(
newParentNodePair.getSecond(),
oldChildAssoc.getTypeQName(),
oldChildAssoc.getQName(),
childNodeTypeQName);
// Move the node as this gives back the primary parent association
try
{
moveNodeResult = nodeDAO.moveNode(oldChildNodeId, newParentNodeId, null,null);
}
catch (NodeExistsException e)
{
deleteNode(e.getNodePair().getSecond());
moveNodeResult = nodeDAO.moveNode(oldChildNodeId, newParentNodeId, null,null);
}
// Move the node as this gives back the primary parent association
newParentAssocPair = moveNodeResult.getFirst();
movedNodePairs.put(oldChildNodeRef, moveNodeResult.getSecond());
ChildAssociationRef newChildAssoc = newParentAssocPair.getSecond();
// Index
nodeIndexer.indexDeleteNode(oldChildAssoc);
nodeIndexer.indexCreateNode(newChildAssoc);
// Propagate timestamps
propagateTimeStamps(newChildAssoc);
// Fire node policies. This ensures that each node in the hierarchy gets a notification fired.
invokeOnDeleteNode(oldChildAssoc, childNodeTypeQName, childNodeAspectQNames, true);
invokeOnCreateNode(newChildAssoc);
}
return newParentAssocRef;
}
else
{
invokeBeforeMoveNode(oldParentAssocRef, newParentRef);
invokeBeforeDeleteChildAssociation(oldParentAssocRef);
// Move node under the new parent
Pair<Pair<Long, ChildAssociationRef>, Pair<Long, NodeRef>> moveNodeResult = nodeDAO.moveNode(
nodeToMoveId,
parentNodeId,
assocTypeQName,
assocQName);
Pair<Long, ChildAssociationRef> newParentAssocPair = moveNodeResult.getFirst();
ChildAssociationRef newParentAssocRef = newParentAssocPair.getSecond();
// The node is in the same store and is just having its child association modified
nodeIndexer.indexUpdateChildAssociation(oldParentAssocRef, newParentAssocRef);
// Propagate timestamps (watch out for moves within the same folder)
if (!oldParentAssocRef.getParentRef().equals(newParentAssocRef.getParentRef()))
{
@@ -2648,22 +2707,18 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
invokeOnCreateChildAssociation(newParentAssocRef, false);
invokeOnDeleteChildAssociation(oldParentAssocRef);
invokeOnMoveNode(oldParentAssocRef, newParentAssocRef);
invokeOnMoveNode(oldParentAssocRef, newParentAssocRef);
// Done
return newParentAssocRef;
}
// Done
return newParentAssocRef;
}
/**
* This process is less invasive than the <b>move</b> method as the child associations
* do not need to be remade.
*/
private void pullNodeChildrenToSameStore(Pair<Long, NodeRef> nodePair)
private void findNodeChildrenToMove(Long nodeId, final StoreRef storeRef,
final List<ChildAssociationRef> childAssocsToMove, final Map<NodeRef, Long> nodeIds)
{
Long nodeId = nodePair.getFirst();
// Get the node's children, but only one's that aren't in the same store
final List<Pair<Long, NodeRef>> childNodePairs = new ArrayList<Pair<Long, NodeRef>>(5);
final List<ChildAssociationRef> childAssocs = new LinkedList<ChildAssociationRef>();
NodeDAO.ChildAssocRefQueryCallback callback = new NodeDAO.ChildAssocRefQueryCallback()
{
public boolean preLoadNodes()
@@ -2683,8 +2738,13 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
Pair<Long, NodeRef> childNodePair
)
{
// Add it
childNodePairs.add(childNodePair);
// Add it if it's not in the target store
NodeRef childNodeRef = childNodePair.getSecond();
if (!childNodeRef.getStoreRef().equals(storeRef))
{
childAssocs.add(childAssocPair.getSecond());
nodeIds.put(childNodeRef, childNodePair.getFirst());
}
// More results
return true;
}
@@ -2693,58 +2753,23 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
{
}
};
// We only need to move child nodes that are not already in the same store
nodeDAO.getChildAssocs(nodeId, null, null, null, Boolean.TRUE, Boolean.FALSE, callback);
// We need to get all primary children and do the store filtering ourselves
nodeDAO.getChildAssocs(nodeId, null, null, null, Boolean.TRUE, null, callback);
// Each child must be moved to the same store as the parent
for (Pair<Long, NodeRef> oldChildNodePair : childNodePairs)
for (ChildAssociationRef oldChildAssoc : childAssocs)
{
Long childNodeId = oldChildNodePair.getFirst();
NodeRef childNodeRef = oldChildNodePair.getSecond();
NodeRef childNodeRef = oldChildAssoc.getChildRef();
Long childNodeId = nodeIds.get(childNodeRef);
NodeRef.Status childNodeStatus = nodeDAO.getNodeRefStatus(childNodeRef);
if (childNodeStatus == null || childNodeStatus.isDeleted())
{
// Node has already been deleted.
continue;
}
QName childNodeTypeQName = nodeDAO.getNodeType(childNodeId);
Set<QName> childNodeAspectQNames = nodeDAO.getNodeAspects(childNodeId);
Pair<Long, ChildAssociationRef> oldParentAssocPair = nodeDAO.getPrimaryParentAssoc(childNodeId);
ChildAssociationRef oldParentAssocRef = oldParentAssocPair.getSecond();
// Fire node policies. This ensures that each node in the hierarchy gets a notification fired.
invokeBeforeDeleteNode(childNodeRef);
invokeBeforeCreateNode(
oldParentAssocPair.getSecond().getParentRef(),
oldParentAssocPair.getSecond().getTypeQName(),
oldParentAssocPair.getSecond().getQName(),
childNodeTypeQName);
// Move the node as this gives back the primary parent association
Pair<Pair<Long, ChildAssociationRef>, Pair<Long, NodeRef>> moveResult;
try
{
moveResult = nodeDAO.moveNode(childNodeId, nodeId, null,null);
}
catch (NodeExistsException e)
{
deleteNode(e.getNodePair().getSecond());
moveResult = nodeDAO.moveNode(childNodeId, nodeId, null,null);
}
// Move the node as this gives back the primary parent association
Pair<Long, ChildAssociationRef> newParentAssocPair = moveResult.getFirst();
Pair<Long, NodeRef> newChildNodePair = moveResult.getSecond();
ChildAssociationRef newParentAssocRef = newParentAssocPair.getSecond();
// Index
nodeIndexer.indexDeleteNode(oldParentAssocPair.getSecond());
nodeIndexer.indexCreateNode(newParentAssocPair.getSecond());
// Propagate timestamps
propagateTimeStamps(oldParentAssocRef);
propagateTimeStamps(newParentAssocRef);
// Fire node policies. This ensures that each node in the hierarchy gets a notification fired.
invokeOnDeleteNode(oldParentAssocRef, childNodeTypeQName, childNodeAspectQNames, true);
invokeOnCreateNode(newParentAssocRef);
childAssocsToMove.add(oldChildAssoc);
// Cascade
pullNodeChildrenToSameStore(newChildNodePair);
findNodeChildrenToMove(childNodeId, storeRef, childAssocsToMove, nodeIds);
}
}