mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged 1.4 to HEAD
svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4364 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4379 . git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4658 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -45,6 +45,7 @@ import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.mail.javamail.MimeMessagePreparator;
|
||||
@@ -54,7 +55,8 @@ import org.springframework.mail.javamail.MimeMessagePreparator;
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class MailActionExecuter extends ActionExecuterAbstractBase
|
||||
public class MailActionExecuter extends ActionExecuterAbstractBase
|
||||
implements InitializingBean
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(MailActionExecuter.class);
|
||||
|
||||
@@ -72,7 +74,7 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
||||
/**
|
||||
* From address
|
||||
*/
|
||||
public static final String FROM_ADDRESS = "alfresco_repository@alfresco.org";
|
||||
private static final String FROM_ADDRESS = "alfresco@alfresco.org";
|
||||
|
||||
/**
|
||||
* The java mail sender
|
||||
@@ -114,6 +116,11 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
||||
*/
|
||||
private String headerEncoding = null;
|
||||
|
||||
/**
|
||||
* Default from address
|
||||
*/
|
||||
private String fromAddress = null;
|
||||
|
||||
/**
|
||||
* @param javaMailSender the java mail sender
|
||||
*/
|
||||
@@ -178,6 +185,25 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
||||
this.headerEncoding = headerEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fromAddress The default mail address.
|
||||
*/
|
||||
public void setFromAddress(String fromAddress)
|
||||
{
|
||||
this.fromAddress = fromAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise bean
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
if (fromAddress == null || fromAddress.length() == 0)
|
||||
{
|
||||
fromAddress = FROM_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the rule action
|
||||
*/
|
||||
@@ -274,13 +300,13 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
||||
|
||||
// set the from address - use the default if not set
|
||||
String from = (String)ruleAction.getParameterValue(PARAM_FROM);
|
||||
if (from != null)
|
||||
if (from == null || from.length() == 0)
|
||||
{
|
||||
message.setFrom(from);
|
||||
message.setFrom(fromAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
message.setFrom(FROM_ADDRESS);
|
||||
message.setFrom(from);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -336,4 +362,5 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
||||
paramList.add(new ParameterDefinitionImpl(PARAM_FROM, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_FROM)));
|
||||
paramList.add(new ParameterDefinitionImpl(PARAM_TEMPLATE, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_TEMPLATE)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -224,6 +224,26 @@
|
||||
assoc.id = :childAssocId
|
||||
</query>
|
||||
|
||||
<query name="node.GetPrimaryChildNodeStatuses">
|
||||
select
|
||||
status
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.NodeStatusImpl as status
|
||||
join status.node as node
|
||||
where
|
||||
node.id in
|
||||
(
|
||||
select
|
||||
child.id
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc
|
||||
join assoc.child as child
|
||||
where
|
||||
assoc.parent.id = :parentId and
|
||||
assoc.isPrimary = 1
|
||||
)
|
||||
</query>
|
||||
|
||||
<query name="node.GetChildAssocs">
|
||||
select
|
||||
assoc
|
||||
|
83
source/java/org/alfresco/repo/jscript/People.java
Normal file
83
source/java/org/alfresco/repo/jscript/People.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.repo.jscript;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ActionDefinition;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.mozilla.javascript.Wrapper;
|
||||
|
||||
/**
|
||||
* Scripted People service for describing and executing actions against People & Groups.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public final class People extends BaseScriptImplementation implements Scopeable
|
||||
{
|
||||
/** Repository Service Registry */
|
||||
private ServiceRegistry services;
|
||||
|
||||
/** Root scope for this object */
|
||||
private Scriptable scope;
|
||||
|
||||
/**
|
||||
* Set the service registry
|
||||
*
|
||||
* @param serviceRegistry the service registry
|
||||
*/
|
||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
this.services = serviceRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
|
||||
*/
|
||||
public void setScope(Scriptable scope)
|
||||
{
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Person given the username
|
||||
*
|
||||
* @return the person node (type cm:person) or null if no such person exists
|
||||
*/
|
||||
public Node getPerson(String username)
|
||||
{
|
||||
Node person = null;
|
||||
PersonService personService = services.getPersonService();
|
||||
if (personService.personExists(username))
|
||||
{
|
||||
NodeRef personRef = personService.getPerson(username);
|
||||
person = new Node(personRef, services, null, scope);
|
||||
}
|
||||
return person;
|
||||
}
|
||||
|
||||
}
|
@@ -123,6 +123,22 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
return unchecked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node status for a live node.
|
||||
* @param nodeRef the node reference
|
||||
* @return Returns the node status, which will not be <tt>null</tt> and will have a live node attached.
|
||||
* @throws InvalidNodeRefException if the node is deleted or never existed
|
||||
*/
|
||||
public NodeStatus getNodeStatusNotNull(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
NodeStatus nodeStatus = nodeDaoService.getNodeStatus(nodeRef, false);
|
||||
if (nodeStatus == null || nodeStatus.getNode() == null)
|
||||
{
|
||||
throw new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef);
|
||||
}
|
||||
return nodeStatus;
|
||||
}
|
||||
|
||||
public boolean exists(StoreRef storeRef)
|
||||
{
|
||||
Store store = nodeDaoService.getStore(storeRef.getProtocol(), storeRef.getIdentifier());
|
||||
@@ -1411,7 +1427,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
private void archiveNode(NodeRef nodeRef, StoreRef archiveStoreRef)
|
||||
{
|
||||
Node node = getNodeNotNull(nodeRef);
|
||||
NodeStatus nodeStatus = nodeDaoService.getNodeStatus(nodeRef, false);
|
||||
Node node = nodeStatus.getNode();
|
||||
ChildAssoc primaryParentAssoc = nodeDaoService.getPrimaryParentAssoc(node);
|
||||
|
||||
// add the aspect
|
||||
@@ -1454,17 +1471,24 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedItem"));
|
||||
|
||||
// get the IDs of all the node's primary children, including its own
|
||||
Map<Long, Node> nodesById = getNodeHierarchy(node, null);
|
||||
|
||||
// Archive all the associations between the archived nodes and non-archived nodes
|
||||
for (Node nodeToArchive : nodesById.values())
|
||||
{
|
||||
archiveAssocs(nodeToArchive, nodesById);
|
||||
}
|
||||
|
||||
// the node reference has changed due to the store move
|
||||
nodeRef = node.getNodeRef();
|
||||
// as has the node status
|
||||
nodeStatus = nodeDaoService.getNodeStatus(nodeRef, true);
|
||||
|
||||
// get the IDs of all the node's primary children, including its own
|
||||
Map<Long, NodeStatus> nodeStatusesById = getNodeHierarchy(nodeStatus, null);
|
||||
|
||||
// Archive all the associations between the archived nodes and non-archived nodes
|
||||
for (NodeStatus nodeStatusToArchive : nodeStatusesById.values())
|
||||
{
|
||||
Node nodeToArchive = nodeStatusToArchive.getNode();
|
||||
if (nodeToArchive == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
archiveAssocs(nodeToArchive, nodeStatusesById);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1477,22 +1501,25 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
*/
|
||||
private void moveNodeToStore(Node node, Store store)
|
||||
{
|
||||
NodeRef nodeRef = node.getNodeRef();
|
||||
NodeStatus nodeStatus = nodeDaoService.getNodeStatus(nodeRef, true);
|
||||
// get the IDs of all the node's primary children, including its own
|
||||
Map<Long, Node> nodesById = getNodeHierarchy(node, null);
|
||||
Map<Long, NodeStatus> nodeStatusesById = getNodeHierarchy(nodeStatus, null);
|
||||
|
||||
// move each node into the archive store
|
||||
for (Node nodeToMove : nodesById.values())
|
||||
for (NodeStatus oldNodeStatus : nodeStatusesById.values())
|
||||
{
|
||||
NodeRef oldNodeRef = nodeToMove.getNodeRef();
|
||||
Node nodeToMove = oldNodeStatus.getNode();
|
||||
nodeToMove.setStore(store);
|
||||
NodeRef newNodeRef = nodeToMove.getNodeRef();
|
||||
|
||||
// update old status
|
||||
NodeStatus oldNodeStatus = nodeDaoService.getNodeStatus(oldNodeRef, true);
|
||||
oldNodeStatus.setNode(null);
|
||||
// create the new status
|
||||
NodeStatus newNodeStatus = nodeDaoService.getNodeStatus(newNodeRef, true);
|
||||
newNodeStatus.setNode(nodeToMove);
|
||||
|
||||
invokeOnUpdateNode(newNodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1501,38 +1528,42 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
* The given node will be added to the map and the method is recursive
|
||||
* to all primary children.
|
||||
*
|
||||
* @param node the start of the hierarchy
|
||||
* @param nodesById a map of nodes that will be reused as the return value
|
||||
* @param nodeStatus the status of the node at the top of the hierarchy
|
||||
* @param nodeStatusesById a map of node statuses that will be reused as the return value
|
||||
* @return Returns a map of nodes in the hierarchy keyed by their IDs
|
||||
*/
|
||||
private Map<Long, Node> getNodeHierarchy(Node node, Map<Long, Node> nodesById)
|
||||
private Map<Long, NodeStatus> getNodeHierarchy(NodeStatus nodeStatus, Map<Long, NodeStatus> nodeStatusesById)
|
||||
{
|
||||
if (nodesById == null)
|
||||
if (nodeStatusesById == null)
|
||||
{
|
||||
nodesById = new HashMap<Long, Node>(23);
|
||||
nodeStatusesById = new HashMap<Long, NodeStatus>(23);
|
||||
// this is the entry into the hierarchy - flush to ensure we are not stale
|
||||
nodeDaoService.flush();
|
||||
}
|
||||
|
||||
Long id = node.getId();
|
||||
if (nodesById.containsKey(id))
|
||||
Node node = nodeStatus.getNode();
|
||||
if (node == null)
|
||||
{
|
||||
// the node has already been deleted
|
||||
return nodeStatusesById;
|
||||
}
|
||||
Long nodeId = node.getId();
|
||||
if (nodeStatusesById.containsKey(nodeId))
|
||||
{
|
||||
// this ID was already added - circular reference
|
||||
logger.warn("Circular hierarchy found including node " + id);
|
||||
return nodesById;
|
||||
logger.warn("Circular hierarchy found including node " + nodeId);
|
||||
return nodeStatusesById;
|
||||
}
|
||||
// add the node to the map
|
||||
nodesById.put(id, node);
|
||||
nodeStatusesById.put(nodeId, nodeStatus);
|
||||
// recurse into the primary children
|
||||
Collection<ChildAssoc> childAssocs = nodeDaoService.getChildAssocs(node);
|
||||
for (ChildAssoc childAssoc : childAssocs)
|
||||
Collection<NodeStatus> primaryChildNodeStatuses = nodeDaoService.getPrimaryChildNodeStatuses(node);
|
||||
for (NodeStatus primaryChildNodeStatus : primaryChildNodeStatuses)
|
||||
{
|
||||
// cascade into primary associations
|
||||
if (childAssoc.getIsPrimary())
|
||||
{
|
||||
Node primaryChild = childAssoc.getChild();
|
||||
nodesById = getNodeHierarchy(primaryChild, nodesById);
|
||||
}
|
||||
nodeStatusesById = getNodeHierarchy(primaryChildNodeStatus, nodeStatusesById);
|
||||
}
|
||||
return nodesById;
|
||||
return nodeStatusesById;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1544,7 +1575,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
* @param node the node whose associations must be archived
|
||||
* @param nodesById a map of nodes partaking in the archival process
|
||||
*/
|
||||
private void archiveAssocs(Node node, Map<Long, Node> nodesById)
|
||||
private void archiveAssocs(Node node, Map<Long, NodeStatus> nodeStatusesById)
|
||||
{
|
||||
List<ChildAssoc> childAssocsToDelete = new ArrayList<ChildAssoc>(5);
|
||||
// child associations
|
||||
@@ -1553,7 +1584,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
for (ChildAssoc assoc : childAssocs)
|
||||
{
|
||||
Long relatedNodeId = assoc.getChild().getId();
|
||||
if (nodesById.containsKey(relatedNodeId))
|
||||
if (nodeStatusesById.containsKey(relatedNodeId))
|
||||
{
|
||||
// a sibling in the archive process
|
||||
continue;
|
||||
@@ -1566,7 +1597,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
for (ChildAssoc assoc : node.getParentAssocs())
|
||||
{
|
||||
Long relatedNodeId = assoc.getParent().getId();
|
||||
if (nodesById.containsKey(relatedNodeId))
|
||||
if (nodeStatusesById.containsKey(relatedNodeId))
|
||||
{
|
||||
// a sibling in the archive process
|
||||
continue;
|
||||
@@ -1586,7 +1617,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
for (NodeAssoc assoc : nodeDaoService.getSourceNodeAssocs(node))
|
||||
{
|
||||
Long relatedNodeId = assoc.getSource().getId();
|
||||
if (nodesById.containsKey(relatedNodeId))
|
||||
if (nodeStatusesById.containsKey(relatedNodeId))
|
||||
{
|
||||
// a sibling in the archive process
|
||||
continue;
|
||||
@@ -1599,7 +1630,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
for (NodeAssoc assoc : nodeDaoService.getTargetNodeAssocs(node))
|
||||
{
|
||||
Long relatedNodeId = assoc.getTarget().getId();
|
||||
if (nodesById.containsKey(relatedNodeId))
|
||||
if (nodeStatusesById.containsKey(relatedNodeId))
|
||||
{
|
||||
// a sibling in the archive process
|
||||
continue;
|
||||
@@ -1665,7 +1696,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
public NodeRef restoreNode(NodeRef archivedNodeRef, NodeRef destinationParentNodeRef, QName assocTypeQName, QName assocQName)
|
||||
{
|
||||
Node archivedNode = getNodeNotNull(archivedNodeRef);
|
||||
NodeStatus archivedNodeStatus = getNodeStatusNotNull(archivedNodeRef);
|
||||
Node archivedNode = archivedNodeStatus.getNode();
|
||||
Set<QName> aspects = archivedNode.getAspects();
|
||||
Map<QName, PropertyValue> properties = archivedNode.getProperties();
|
||||
// the node must be a top-level archive node
|
||||
@@ -1707,18 +1739,21 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
// move the node to the target parent, which may or may not be the original parent
|
||||
moveNode(
|
||||
ChildAssociationRef newChildAssocRef = moveNode(
|
||||
archivedNodeRef,
|
||||
destinationParentNodeRef,
|
||||
assocTypeQName,
|
||||
assocQName);
|
||||
archivedNodeRef = newChildAssocRef.getChildRef();
|
||||
archivedNodeStatus = nodeDaoService.getNodeStatus(archivedNodeRef, false);
|
||||
|
||||
// get the IDs of all the node's primary children, including its own
|
||||
Map<Long, Node> restoredNodesById = getNodeHierarchy(archivedNode, null);
|
||||
Map<Long, NodeStatus> restoreNodeStatusesById = getNodeHierarchy(archivedNodeStatus, null);
|
||||
// Restore the archived associations, if required
|
||||
for (Node restoredNode : restoredNodesById.values())
|
||||
for (NodeStatus restoreNodeStatus : restoreNodeStatusesById.values())
|
||||
{
|
||||
restoreAssocs(restoredNode);
|
||||
Node restoreNode = restoreNodeStatus.getNode();
|
||||
restoreAssocs(restoreNode);
|
||||
}
|
||||
|
||||
// the node reference has changed due to the store move
|
||||
|
@@ -143,6 +143,11 @@ public interface NodeDaoService
|
||||
*/
|
||||
public void setChildNameUnique(ChildAssoc childAssoc, String childName);
|
||||
|
||||
/**
|
||||
* Get the statuses of all the child primary child nodes of the given parent
|
||||
*/
|
||||
public Collection<NodeStatus> getPrimaryChildNodeStatuses(final Node parentNode);
|
||||
|
||||
/**
|
||||
* Get all child associations for a given node
|
||||
*
|
||||
|
@@ -63,6 +63,7 @@ import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.ObjectDeletedException;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.ScrollMode;
|
||||
@@ -82,6 +83,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
{
|
||||
private static final String QUERY_GET_ALL_STORES = "store.GetAllStores";
|
||||
private static final String UPDATE_SET_CHILD_ASSOC_NAME = "node.updateChildAssocName";
|
||||
private static final String QUERY_GET_PRIMARY_CHILD_NODE_STATUSES = "node.GetPrimaryChildNodeStatuses";
|
||||
private static final String QUERY_GET_CHILD_ASSOCS = "node.GetChildAssocs";
|
||||
private static final String QUERY_GET_CHILD_ASSOC_BY_TYPE_AND_NAME = "node.GetChildAssocByTypeAndName";
|
||||
private static final String QUERY_GET_CHILD_ASSOC_REFS = "node.GetChildAssocRefs";
|
||||
@@ -647,6 +649,24 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<NodeStatus> getPrimaryChildNodeStatuses(final Node parentNode)
|
||||
{
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session
|
||||
.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_PRIMARY_CHILD_NODE_STATUSES)
|
||||
.setLong("parentId", parentNode.getId())
|
||||
.setFlushMode(FlushMode.NEVER);
|
||||
return query.list();
|
||||
}
|
||||
};
|
||||
List<NodeStatus> queryResults = (List<NodeStatus>) getHibernateTemplate().execute(callback);
|
||||
return queryResults;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<ChildAssoc> getChildAssocs(final Node parentNode)
|
||||
{
|
||||
|
Reference in New Issue
Block a user