Merged V2.2 to HEAD

7575: Permission changes for AVM.
   7577: Incorporated most of the feedback provided by Kevin C earlier today
   7578: Removed directory not removed by patch
   7579: EmailServer bug fixes
         AR-1902:  Double posts when emailing to a document
         AR-1904:  Attachments via email should be allowed on forum posts
         AR-1903:  (Partial Fix) Text attachments should be treated the same way as other attachments 
   7583: Fixed WCM-961 & WCM-962: Added confirm dialog for 'Delete All Deployment Reports' and 'Release Server' actions


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8434 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-03-06 14:43:55 +00:00
parent a9fac10b45
commit a49bfd311d
89 changed files with 21301 additions and 11139 deletions

View File

@@ -39,6 +39,8 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.email.EmailMessage;
import org.alfresco.service.cmr.email.EmailMessagePart;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
@@ -47,6 +49,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -255,4 +258,113 @@ public abstract class AbstractEmailMessageHandler implements EmailMessageHandler
log.debug("Emailed aspect has been added.");
}
}
/**
* Add new node into Alfresco repository with specified parameters. Node content isn't added.
*
* @param nodeService Alfresco Node Service
* @param parent Parent node
* @param name Name of the new node
* @param assocType Association type that should be set between parent node and the new one.
* @return Reference to created node
*/
protected NodeRef addContentNode(NodeService nodeService, NodeRef parent, String name, QName assocType)
{
NodeRef childNodeRef = nodeService.getChildByName(parent, assocType, name);
if (childNodeRef != null)
{
// The node is present already. Make sure the name csae is correct
nodeService.setProperty(childNodeRef, ContentModel.PROP_NAME, name);
}
else
{
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
contentProps.put(ContentModel.PROP_NAME, name);
ChildAssociationRef associationRef = nodeService.createNode(
parent,
assocType,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
ContentModel.TYPE_CONTENT,
contentProps);
childNodeRef = associationRef.getChildRef();
}
return childNodeRef;
}
/**
* Add new node into Alfresco repository with specified parameters.
* Node content isn't added. New node will be created with ContentModel.ASSOC_CONTAINS association with parent.
*
* @param nodeService Alfresco Node Service
* @param parent Parent node
* @param name Name of the new node
* @return Reference to created node
*/
protected NodeRef addContentNode(NodeService nodeService, NodeRef parent, String name)
{
return addContentNode(nodeService, parent, name, ContentModel.ASSOC_CONTAINS);
}
/**
* Adds new node into Alfresco repository and mark its as an attachment.
*
* @param nodeService Alfresco Node Service.
* @param folder Space/Folder to add.
* @param mainContentNode Main content node. Any mail is added into Alfresco as one main content node and several its attachments. Each attachment related with its main node.
* @param fileName File name for the attachment.
* @return Reference to created node.
*/
protected NodeRef addAttachment(NodeService nodeService, NodeRef folder, NodeRef mainContentNode, String fileName)
{
if (log.isDebugEnabled())
{
log.debug("Adding attachment node (name=" + fileName + ").");
}
NodeRef attachmentNode = addContentNode(nodeService, folder, fileName);
// Remove 'attached' aspect so that we work with the document in its clean form
if (nodeService.hasAspect(attachmentNode, EmailServerModel.ASPECT_ATTACHED))
{
nodeService.removeAspect(attachmentNode, EmailServerModel.ASPECT_ATTACHED);
}
// Add attached aspect
nodeService.addAspect(attachmentNode, EmailServerModel.ASPECT_ATTACHED, null);
// Recreate the association
nodeService.createAssociation(attachmentNode, mainContentNode, EmailServerModel.ASSOC_ATTACHMENT);
if (log.isDebugEnabled())
{
log.debug("Attachment has been added.");
}
return attachmentNode;
}
/**
* Extracts the attachments from the given message and adds them to the space. All attachments
* are linked back to the original node that they are attached to.
*
* @param spaceNodeRef the space to add the documents into
* @param nodeRef the node to which the documents will be attached
* @param message the email message
*/
protected void addAttachments(NodeRef spaceNodeRef, NodeRef nodeRef, EmailMessage message)
{
// Add attachments
EmailMessagePart[] attachments = message.getAttachments();
for (EmailMessagePart attachment : attachments)
{
String fileName = attachment.getFileName();
InputStream contentIs = attachment.getContent();
MimetypeService mimetypeService = getMimetypeService();
String mimetype = mimetypeService.guessMimetype(fileName);
String encoding = attachment.getEncoding();
NodeRef attachmentNode = addAttachment(getNodeService(), spaceNodeRef, nodeRef, fileName);
writeContent(attachmentNode, contentIs, mimetype, encoding);
}
}
}

View File

@@ -54,10 +54,11 @@ public abstract class AbstractForumEmailMessageHandler extends AbstractEmailMess
/**
* Posts content
*
* @param nodeRef Reference to node
* @param parser Mail parser
* @param nodeRef Reference to node
* @param parser Mail parser
* @return Returns the new post node
*/
protected void addPostNode(NodeRef nodeRef, EmailMessage message)
protected NodeRef addPostNode(NodeRef nodeRef, EmailMessage message)
{
NodeService nodeService = getNodeService();
Date now = new Date();
@@ -66,8 +67,8 @@ public abstract class AbstractForumEmailMessageHandler extends AbstractEmailMess
PropertyMap properties = new PropertyMap(3);
properties.put(ContentModel.PROP_NAME, nodeName);
NodeRef postNode = nodeService.getChildByName(nodeRef, ContentModel.ASSOC_CONTAINS, nodeName);
if (postNode == null)
NodeRef postNodeRef = nodeService.getChildByName(nodeRef, ContentModel.ASSOC_CONTAINS, nodeName);
if (postNodeRef == null)
{
ChildAssociationRef childAssoc = nodeService.createNode(
nodeRef,
@@ -75,27 +76,34 @@ public abstract class AbstractForumEmailMessageHandler extends AbstractEmailMess
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, nodeName),
ForumModel.TYPE_POST,
properties);
postNode = childAssoc.getChildRef();
postNodeRef = childAssoc.getChildRef();
}
// Add necessary aspects
properties.clear();
properties.put(ContentModel.PROP_TITLE, nodeName);
nodeService.addAspect(postNode, ContentModel.ASPECT_TITLED, properties);
nodeService.addAspect(postNodeRef, ContentModel.ASPECT_TITLED, properties);
properties.clear();
properties.put(ApplicationModel.PROP_EDITINLINE, true);
nodeService.addAspect(postNode, ApplicationModel.ASPECT_INLINEEDITABLE, properties);
nodeService.addAspect(postNodeRef, ApplicationModel.ASPECT_INLINEEDITABLE, properties);
// Write content
if (message.getBody() != null)
{
writeContent(postNode, message.getBody().getContent(), message.getBody().getContentType(), message.getBody().getEncoding());
writeContent(
postNodeRef,
message.getBody().getContent(),
message.getBody().getContentType(),
message.getBody().getEncoding());
}
else
{
writeContent(postNode, "<The message was empty>");
writeContent(postNodeRef, "<The message was empty>");
}
addEmailedAspect(postNode, message);
addEmailedAspect(postNodeRef, message);
// Done
return postNodeRef;
}
/**

View File

@@ -51,7 +51,7 @@ public class DocumentEmailMessageHandler extends AbstractForumEmailMessageHandle
{
private static final String forumNodeName = "EmailForum";
public void processMessage(NodeRef nodeRef, EmailMessage message)
public void processMessage(NodeRef contentNodeRef, EmailMessage message)
{
String messageSubject;
@@ -64,27 +64,34 @@ public class DocumentEmailMessageHandler extends AbstractForumEmailMessageHandle
messageSubject = "EMPTY_SUBJECT_" + System.currentTimeMillis();
}
QName nodeTypeQName = getNodeService().getType(nodeRef);
QName nodeTypeQName = getNodeService().getType(contentNodeRef);
DictionaryService dictionaryService = getDictionaryService();
if (dictionaryService.isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT))
{
NodeRef forumNode = getForumNode(nodeRef);
// Find where the content resides
NodeRef spaceNodeRef = getNodeService().getPrimaryParent(contentNodeRef).getParentRef();
NodeRef forumNode = getForumNode(contentNodeRef);
if (forumNode == null)
{
forumNode = addForumNode(nodeRef);
forumNode = addForumNode(contentNodeRef);
}
// Try to find existed node
NodeRef topicNode = getTopicNode(forumNode, messageSubject);
NodeRef topicNodeRef = getTopicNode(forumNode, messageSubject);
if (topicNode == null)
if (topicNodeRef == null)
{
topicNode = addTopicNode(forumNode, messageSubject);
topicNodeRef = addTopicNode(forumNode, messageSubject);
}
addPostNode(topicNode, message);
// Create the post
NodeRef postNodeRef = addPostNode(topicNodeRef, message);
// Add attachments
addAttachments(spaceNodeRef, postNodeRef, message);
}
else
{

View File

@@ -34,19 +34,14 @@ import java.util.Map;
import javax.mail.MessagingException;
import org.alfresco.email.server.EmailServerModel;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.email.EmailMessage;
import org.alfresco.service.cmr.email.EmailMessageException;
import org.alfresco.service.cmr.email.EmailMessagePart;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -140,101 +135,7 @@ public class FolderEmailMessageHandler extends AbstractEmailMessageHandler
}
// Add attachments
EmailMessagePart[] attachments = message.getAttachments();
for (EmailMessagePart attachment : attachments)
{
String fileName = attachment.getFileName();
InputStream contentIs = attachment.getContent();
MimetypeService mimetypeService = getMimetypeService();
String mimetype = mimetypeService.guessMimetype(fileName);
String encoding = attachment.getEncoding();
NodeRef attachmentNode = addAttachment(getNodeService(), spaceNodeRef, contentNodeRef, fileName);
writeContent(attachmentNode, contentIs, mimetype, encoding);
}
}
/**
* Add new node into Alfresco repository with specified parameters. Node content isn't added. New node will be created with ContentModel.ASSOC_CONTAINS association with parent.
*
* @param nodeService Alfresco Node Service
* @param parent Parent node
* @param name Name of the new node
* @return Reference to created node
*/
private NodeRef addContentNode(NodeService nodeService, NodeRef parent, String name)
{
return addContentNode(nodeService, parent, name, ContentModel.ASSOC_CONTAINS);
}
/**
* Add new node into Alfresco repository with specified parameters. Node content isn't added.
*
* @param nodeService Alfresco Node Service
* @param parent Parent node
* @param name Name of the new node
* @param assocType Association type that should be set between parent node and the new one.
* @return Reference to created node
*/
private NodeRef addContentNode(NodeService nodeService, NodeRef parent, String name, QName assocType)
{
NodeRef childNodeRef = nodeService.getChildByName(parent, assocType, name);
if (childNodeRef != null)
{
// The node is present already. Make sure the name csae is correct
nodeService.setProperty(childNodeRef, ContentModel.PROP_NAME, name);
}
else
{
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
contentProps.put(ContentModel.PROP_NAME, name);
ChildAssociationRef associationRef = nodeService.createNode(
parent,
assocType,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
ContentModel.TYPE_CONTENT,
contentProps);
childNodeRef = associationRef.getChildRef();
}
return childNodeRef;
}
/**
* Adds new node into Alfresco repository and mark its as an attachment.
*
* @param nodeService Alfresco Node Service.
* @param folder Space/Folder to add.
* @param mainContentNode Main content node. Any mail is added into Alfresco as one main content node and several its attachments. Each attachment related with its main node.
* @param fileName File name for the attachment.
* @return Reference to created node.
*/
private NodeRef addAttachment(NodeService nodeService, NodeRef folder, NodeRef mainContentNode, String fileName)
{
if (log.isDebugEnabled())
{
log.debug("Adding attachment node (name=" + fileName + ").");
}
NodeRef attachmentNode = addContentNode(nodeService, folder, fileName);
// Remove 'attached' aspect so that we work with the document in its clean form
if (nodeService.hasAspect(attachmentNode, EmailServerModel.ASPECT_ATTACHED))
{
nodeService.removeAspect(attachmentNode, EmailServerModel.ASPECT_ATTACHED);
}
// Add attached aspect
nodeService.addAspect(attachmentNode, EmailServerModel.ASPECT_ATTACHED, null);
// Recreate the association
nodeService.createAssociation(attachmentNode, mainContentNode, EmailServerModel.ASSOC_ATTACHMENT);
if (log.isDebugEnabled())
{
log.debug("Attachment has been added.");
}
return attachmentNode;
addAttachments(spaceNodeRef, contentNodeRef, message);
}
/**

View File

@@ -32,6 +32,7 @@ import java.util.LinkedList;
import java.util.List;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
@@ -176,13 +177,13 @@ public class SubethaEmailMessage implements EmailMessage
sentDate = new Date(); // Just anti-null stub :)
}
parseMesagePart(mimeMessage);
parseMessagePart(mimeMessage);
attachments = new EmailMessagePart[attachmentList.size()];
attachmentList.toArray(attachments);
attachmentList = null;
}
private void parseMesagePart(Part messagePart)
private void parseMessagePart(Part messagePart)
{
try
{
@@ -231,7 +232,18 @@ public class SubethaEmailMessage implements EmailMessage
}
for (int i = 0; i < count; i++)
{
parseMesagePart(mp.getBodyPart(i));
BodyPart bp = mp.getBodyPart(i);
String disposition = bp.getDisposition();
if (i > 0)
{
// It's an attachment. Recurse.
parseMessagePart(bp);
}
else
{
// It's the body
addBody(messagePart);
}
}
if (log.isDebugEnabled())
@@ -248,7 +260,7 @@ public class SubethaEmailMessage implements EmailMessage
log.debug("MIME_RFC822 part found. Processing inside part...");
}
parseMesagePart((Part) messagePart.getContent());
parseMessagePart((Part) messagePart.getContent());
if (log.isDebugEnabled())
{
@@ -281,27 +293,15 @@ public class SubethaEmailMessage implements EmailMessage
{
if (body != null)
{
if (!MIME_PLAIN_TEXT.equals(body.getContentType()) && messagePart.isMimeType(MIME_PLAIN_TEXT))
attachmentList.add(new SubethaEmailMessagePart(messagePart, getPartFileName(getSubject() + " (part " + ++bodyNumber + ")", messagePart)));
if (log.isInfoEnabled())
{
attachmentList.add(body);
body = new SubethaEmailMessagePart(messagePart);
if (log.isDebugEnabled())
{
log.debug("Body has been changed to the new one.");
}
}
else
{
attachmentList.add(new SubethaEmailMessagePart(messagePart, getPartFileName(getSubject() + " (part " + ++bodyNumber + ")", messagePart)));
if (log.isInfoEnabled())
{
log.info(String.format("Attachment \"%s\" has been added.", attachmentList.get(attachmentList.size() - 1).getFileName()));
}
log.info(String.format("Attachment \"%s\" has been added.", attachmentList.get(attachmentList.size() - 1).getFileName()));
}
}
else
{
body = new SubethaEmailMessagePart(messagePart, getPartFileName(getSubject() + " (part " + ++bodyNumber + ")", messagePart));
body = new SubethaEmailMessagePart(messagePart, getPartFileName(getSubject(), messagePart));
if (log.isDebugEnabled())
{
log.debug("Boby has been added.");
@@ -319,7 +319,7 @@ public class SubethaEmailMessage implements EmailMessage
*/
private void addAttachment(Part messagePart) throws MessagingException
{
String fileName = getPartFileName(FILENAME_ATTACHMENT_PREFIX + ++attachmentNumber, messagePart);
String fileName = getPartFileName(FILENAME_ATTACHMENT_PREFIX + attachmentNumber, messagePart);
attachmentList.add(new SubethaEmailMessagePart(messagePart, fileName));
if (log.isDebugEnabled())
{

View File

@@ -126,39 +126,46 @@ public class SubethaEmailServer extends EmailServer
public void data(InputStream data) throws TooMuchDataException, IOException, RejectException
{
if (deliveries.size() == 1)
if (deliveries.size() > 0)
{
Delivery delivery = deliveries.get(0);
processDelivery(delivery, data);
}
else if (deliveries.size() > 1)
{
DeferredFileOutputStream dfos = null;
try
{
dfos = new DeferredFileOutputStream(DEFAULT_DATA_DEFERRED_SIZE);
byte[] bytes = new byte[1024 * 8];
for (int len = -1; (len = data.read(bytes)) != -1;)
{
dfos.write(bytes, 0, len);
}
for (Delivery delivery : deliveries)
{
processDelivery(delivery, dfos.getInputStream());
}
}
finally
{
try
{
dfos.close();
}
catch (Exception e)
{
}
}
}
// Duplicate messages coming in
// http://www.subethamail.org/se/archive_msg.jsp?msgId=20938
// if (deliveries.size() == 1)
// {
// Delivery delivery = deliveries.get(0);
// processDelivery(delivery, data);
// }
// else if (deliveries.size() > 1)
// {
// DeferredFileOutputStream dfos = null;
// try
// {
// dfos = new DeferredFileOutputStream(DEFAULT_DATA_DEFERRED_SIZE);
//
// byte[] bytes = new byte[1024 * 8];
// for (int len = -1; (len = data.read(bytes)) != -1;)
// {
// dfos.write(bytes, 0, len);
// }
// for (Delivery delivery : deliveries)
// {
// processDelivery(delivery, dfos.getInputStream());
// }
// }
// finally
// {
// try
// {
// dfos.close();
// }
// catch (Exception e)
// {
// }
// }
// }
}
private void processDelivery(Delivery delivery, InputStream data) throws RejectException