IMAP configuration changes including support for IMAP home definition

- Added generic RepositoryFolderConfigBean for referencing folders in repo
 - Redefined default and properties used by IMAP


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15064 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-07-02 14:55:22 +00:00
parent 0146cb2f3b
commit 2902b0e6d8
13 changed files with 560 additions and 379 deletions

View File

@@ -417,11 +417,11 @@
</property> </property>
<property name="compositePropertyTypes"> <property name="compositePropertyTypes">
<map> <map>
<entry key="imap.server.mountPoints"> <entry key="imap.config.server.mountPoints">
<value>org.alfresco.repo.imap.config.ImapConfigMountPointsBean</value> <value>org.alfresco.repo.imap.config.ImapConfigMountPointsBean</value>
</entry> </entry>
<entry key="imap.ignore.extraction"> <entry key="imap.config.ignore.extraction">
<value>org.alfresco.repo.imap.config.ImapConfigBean</value> <value>org.alfresco.util.config.RepositoryPathConfigBean</value>
</entry> </entry>
</map> </map>
</property> </property>

View File

@@ -342,18 +342,16 @@ imap.server.host=localhost
imap.server.attachments.extraction.enabled=true imap.server.attachments.extraction.enabled=true
# Default IMAP mount points # Default IMAP mount points
imap.server.mountPoints=Repository_virtual,Repository_archive,Repository_mixed imap.config.home.store=${spaces.store}
imap.server.mountPoints.default.store=${spaces.store} imap.config.home.rootPath=/${spaces.company_home.childname}
imap.server.mountPoints.default.rootPath=/${spaces.company_home.childname} imap.config.home.folderPath=Imap Home
imap.server.mountPoints.default.mode=virtual imap.config.server.mountPoints=AlfrescoIMAP
imap.server.mountPoints.value.Repository_virtual.mode=virtual imap.config.server.mountPoints.default.mountPointName=IMAP
imap.server.mountPoints.value.Repository_archive.mode=archive imap.config.server.mountPoints.default.modeName=ARCHIVE
imap.server.mountPoints.value.Repository_mixed.mode=mixed imap.config.server.mountPoints.default.store=${spaces.store}
imap.config.server.mountPoints.default.rootPath=/${spaces.company_home.childname}
# Folders that will be excluded from the automatic extraction capability imap.config.server.mountPoints.value.AlfrescoIMAP.mountPointName=Alfresco IMAP
#imap.ignore.extraction=adminInbox imap.config.server.mountPoints.value.AlfrescoIMAP.modeName=MIXED
#imap.ignore.extraction.value.adminInbox.store=${spaces.store}
#imap.ignore.extraction.value.adminInbox.rootPath=/${spaces.company_home.childname}/imap:imap_home/cm:admin/cm:INBOX
# Activity feed max size and max age (eg. 44640 mins = 31 days) # Activity feed max size and max age (eg. 44640 mins = 31 days)
activities.feed.max.size=100 activities.feed.max.size=100

View File

@@ -38,49 +38,36 @@
</property> </property>
</bean> </bean>
<!--The configurable list of mount points - actually a post-processed composite property! --> <!--The configurable list of mount points -->
<bean id="imap.server.mountPoints" class="org.springframework.beans.factory.config.ListFactoryBean"> <bean id="imap.config.server.mountPoints" class="org.springframework.beans.factory.config.ListFactoryBean" >
<property name="sourceList"> <!-- Uses ImapConfigMountPointsBean with:
<list> mountPointName (e.g. Repository_virtual')
<bean id="Repository_virtual" class="org.alfresco.repo.imap.config.ImapConfigMountPointsBean"> modeName (e.g. 'VIRTUAL', 'ARCHIVE' or 'MIXED')
<property name="mode"> store (e.g. '${spaces.store}')
<value>virtual</value> rootPath (e.g. '/${spaces.company_home.childname})
</property> folderPath (optional e.g. Projects/T1)
<property name="store"> -->
<value>${spaces.store}</value>
</property>
<property name="rootPath">
<value>/${spaces.company_home.childname}</value>
</property>
</bean>
<bean id="Repository_archive" class="org.alfresco.repo.imap.config.ImapConfigMountPointsBean">
<property name="mode">
<value>archive</value>
</property>
<property name="store">
<value>${spaces.store}</value>
</property>
<property name="rootPath">
<value>/${spaces.company_home.childname}</value>
</property>
</bean>
</list>
</property>
</bean> </bean>
<!--The configurable list of folders that ignore attachment extraction - actually a post-processed composite property! --> <!--The configurable list of folders that ignore attachment extraction -->
<bean id="imap.ignore.extraction" class="org.springframework.beans.factory.config.ListFactoryBean"> <bean id="imap.config.ignore.extraction" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList"> <!-- Uses RepositoryPathConfigBean with:
<list> store (e.g. '${spaces.store}')
<bean id="ignored" class="org.alfresco.repo.imap.config.ImapConfigBean"> rootPath (e.g. '/${spaces.company_home.childname})
folderPath (optional e.g. Projects/T1)
-->
</bean>
<!-- The IMAP home, which has to be a sub-folder -->
<bean id="imap.config.home" class="org.alfresco.util.config.RepositoryFolderConfigBean">
<property name="store"> <property name="store">
<value>${spaces.store}</value> <value>${imap.config.home.store}</value>
</property> </property>
<property name="rootPath"> <property name="rootPath">
<value>/${spaces.company_home.childname}</value> <value>${imap.config.home.rootPath}</value>
</property> </property>
</bean> <property name="folderPath">
</list> <value>${imap.config.home.folderPath}</value>
</property> </property>
</bean> </bean>
@@ -111,14 +98,14 @@
<ref bean="ServiceRegistry"/> <ref bean="ServiceRegistry"/>
</property> </property>
<property name="imapConfigMountPointsBeans"> <property name="imapConfigMountPoints">
<ref bean="imap.server.mountPoints" /> <ref bean="imap.config.server.mountPoints" />
</property> </property>
<property name="ignoreExtractionFolders"> <property name="ignoreExtractionFolders">
<ref bean="imap.ignore.extraction" /> <ref bean="imap.config.ignore.extraction" />
</property> </property>
<property name="imapRoot"> <property name="imapHome">
<value>${spaces.store}/${spaces.company_home.childname}</value> <ref bean="imap.config.home" />
</property> </property>
<property name="defaultFromAddress"> <property name="defaultFromAddress">
<value>${mail.from.default}</value> <value>${mail.from.default}</value>

View File

@@ -2,4 +2,8 @@ imap.server.enabled=false
imap.server.host=localhost imap.server.host=localhost
imap.server.port=143 imap.server.port=143
imap.config.home.store=${spaces.store}
imap.config.home.rootPath=/${spaces.company_home.childname}
imap.config.home.folderPath=Imap Home
#imap.server.web.application.context.url=http://localhost:8080/alfresco #imap.server.web.application.context.url=http://localhost:8080/alfresco

View File

@@ -26,9 +26,29 @@ package org.alfresco.repo.imap;
/** /**
* @author Mike Shavnev * @author Mike Shavnev
* @since 3.2
*/ */
public interface AlfrescoImapConst public interface AlfrescoImapConst
{ {
/**
* @author Derek Hulley
* @since 3.2
*/
public static enum ImapViewMode
{
/**
* Defines {@link AlfrescoImapFolder} view mode as virtual mode. Used for IMAP Virtualised View.
*/
VIRTUAL,
/**
* Defines {@link AlfrescoImapFolder} view mode as mixed mode. Used for IMAP Mixed View.
*/
MIXED,
/**
* Defines {@link AlfrescoImapFolder} view mode as archive mode. Used for Email Archive View.
*/
ARCHIVE
}
public static final char HIERARCHY_DELIMITER = '/'; public static final char HIERARCHY_DELIMITER = '/';
public static final String NAMESPACE_PREFIX = "#"; public static final String NAMESPACE_PREFIX = "#";
@@ -42,20 +62,6 @@ public interface AlfrescoImapConst
// Separator for user enties in flag and subscribe properties // Separator for user enties in flag and subscribe properties
public static final String USER_SEPARATOR = ";"; public static final String USER_SEPARATOR = ";";
/**
* Defines {@link AlfrescoImapFolder} view mode as archive mode. Used for Email Archive View.
*/
public static final String MODE_ARCHIVE = "archive";
/**
* Defines {@link AlfrescoImapFolder} view mode as virtual mode. Used for IMAP Virtualised View.
*/
public static final String MODE_VIRTUAL = "virtual";
/**
* Defines {@link AlfrescoImapFolder} view mode as mixed mode. Used for IMAP Mixed View.
*/
public static final String MODE_MIXED = "mixed";
// Default content model email message templates // Default content model email message templates
public static final String CLASSPATH_TEXT_PLAIN_TEMPLATE = "/alfresco/templates/imap/imap_message_text_plain.ftl"; public static final String CLASSPATH_TEXT_PLAIN_TEMPLATE = "/alfresco/templates/imap/imap_message_text_plain.ftl";
public static final String CLASSPATH_TEXT_HTML_TEMPLATE = "/alfresco/templates/imap/imap_message_text_html.ftl"; public static final String CLASSPATH_TEXT_HTML_TEMPLATE = "/alfresco/templates/imap/imap_message_text_html.ftl";

View File

@@ -48,6 +48,7 @@ import javax.mail.internet.MimeUtility;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.ImapModel; import org.alfresco.model.ImapModel;
import org.alfresco.repo.imap.AlfrescoImapConst.ImapViewMode;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileFolderService;
@@ -104,9 +105,9 @@ public class AlfrescoImapFolder extends AbstractImapFolder
private String folderName; private String folderName;
/** /**
* Defines view mode. Can be one of the following: {@link AlfrescoImapConst#MODE_ARCHIVE} or {@link AlfrescoImapConst#MODE_VIRTUAL}. * Defines view mode.
*/ */
private String viewMode; private ImapViewMode viewMode;
/** /**
* Name of the mount point. * Name of the mount point.
@@ -168,7 +169,7 @@ public class AlfrescoImapFolder extends AbstractImapFolder
String qualifiedMailboxName, String qualifiedMailboxName,
FileInfo folderInfo, FileInfo folderInfo,
String folderName, String folderName,
String viewMode, ImapViewMode viewMode,
NodeRef rootNodeRef, NodeRef rootNodeRef,
String mountPointName, String mountPointName,
boolean extractAttachmentsEnabled, boolean extractAttachmentsEnabled,
@@ -193,7 +194,7 @@ public class AlfrescoImapFolder extends AbstractImapFolder
String qualifiedMailboxName, String qualifiedMailboxName,
FileInfo folderInfo, FileInfo folderInfo,
String folderName, String folderName,
String viewMode, ImapViewMode viewMode,
NodeRef rootNodeRef, NodeRef rootNodeRef,
String mountPointName, String mountPointName,
ServiceRegistry serviceRegistry, ServiceRegistry serviceRegistry,
@@ -205,7 +206,7 @@ public class AlfrescoImapFolder extends AbstractImapFolder
this.folderInfo = folderInfo; this.folderInfo = folderInfo;
this.rootNodeRef = rootNodeRef; this.rootNodeRef = rootNodeRef;
this.folderName = folderName != null ? folderName : (folderInfo != null ? folderInfo.getName() : null); this.folderName = folderName != null ? folderName : (folderInfo != null ? folderInfo.getName() : null);
this.viewMode = viewMode != null ? viewMode : AlfrescoImapConst.MODE_ARCHIVE; this.viewMode = viewMode != null ? viewMode : ImapViewMode.ARCHIVE;
this.mountPointName = mountPointName; this.mountPointName = mountPointName;
this.extractAttachmentsEnabled = extractAttachmentsEnabled; this.extractAttachmentsEnabled = extractAttachmentsEnabled;
@@ -838,7 +839,7 @@ public class AlfrescoImapFolder extends AbstractImapFolder
this.folderName = folderName; this.folderName = folderName;
} }
public void setViewMode(String viewMode) public void setViewMode(ImapViewMode viewMode)
{ {
this.viewMode = viewMode; this.viewMode = viewMode;
} }
@@ -889,7 +890,7 @@ public class AlfrescoImapFolder extends AbstractImapFolder
return readOnly; return readOnly;
} }
public String getViewMode() public ImapViewMode getViewMode()
{ {
return viewMode; return viewMode;
} }

View File

@@ -29,6 +29,7 @@ import java.util.List;
import javax.mail.Flags; import javax.mail.Flags;
import javax.mail.Flags.Flag; import javax.mail.Flags.Flag;
import org.alfresco.repo.imap.AlfrescoImapConst.ImapViewMode;
import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -142,7 +143,7 @@ public interface ImapService
* @param viewMode (ARCHIVE, MIXED or VIRTUAL) * @param viewMode (ARCHIVE, MIXED or VIRTUAL)
* @return list of mailboxes that are visible from specified view * @return list of mailboxes that are visible from specified view
*/ */
public List<FileInfo> searchFolders(NodeRef contextNodeRef, String namePattern, boolean includeSubFolders, String viewMode); public List<FileInfo> searchFolders(NodeRef contextNodeRef, String namePattern, boolean includeSubFolders, ImapViewMode viewMode);
/** /**
* Search for emails in specified folder depend on view mode. * Search for emails in specified folder depend on view mode.
@@ -153,7 +154,7 @@ public interface ImapService
* @param includeSubFolders includeSubFolders * @param includeSubFolders includeSubFolders
* @return list of emails that context folder contains. * @return list of emails that context folder contains.
*/ */
public List<FileInfo> searchMails(NodeRef contextNodeRef, String namePattern, String viewMode, boolean includeSubFolders); public List<FileInfo> searchMails(NodeRef contextNodeRef, String namePattern, ImapViewMode viewMode, boolean includeSubFolders);
/** /**
* Return flags that belong to the specified imap folder. * Return flags that belong to the specified imap folder.

View File

@@ -26,7 +26,6 @@ package org.alfresco.repo.imap;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@@ -42,7 +41,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.i18n.I18NUtil; import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.ImapModel; import org.alfresco.model.ImapModel;
import org.alfresco.repo.imap.config.ImapConfigBean; import org.alfresco.repo.imap.AlfrescoImapConst.ImapViewMode;
import org.alfresco.repo.imap.config.ImapConfigMountPointsBean; import org.alfresco.repo.imap.config.ImapConfigMountPointsBean;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
@@ -51,8 +50,6 @@ import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.preference.PreferenceService; import org.alfresco.service.cmr.preference.PreferenceService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; 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.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
@@ -62,6 +59,7 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.util.AbstractLifecycleBean; import org.alfresco.util.AbstractLifecycleBean;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.alfresco.util.Utf7; import org.alfresco.util.Utf7;
import org.alfresco.util.config.RepositoryFolderConfigBean;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
@@ -84,18 +82,18 @@ public class ImapServiceImpl implements ImapService
private NodeService nodeService; private NodeService nodeService;
private ServiceRegistry serviceRegistry; private ServiceRegistry serviceRegistry;
private Map<String, ImapConfigMountPointsBean> imapConfigMountPointsBeans = Collections.emptyMap(); private Map<String, ImapConfigMountPointsBean> imapConfigMountPoints;
ImapConfigBean[] ignoreExtractionFoldersBeans = new ImapConfigBean[0]; private RepositoryFolderConfigBean[] ignoreExtractionFoldersBeans;
private Set<NodeRef> ignoreExtractionFolders = Collections.emptySet(); private RepositoryFolderConfigBean imapHomeConfigBean;
private NodeRef imapHomeNodeRef;
private Set<NodeRef> ignoreExtractionFolders;
private String imapRoot;
private String defaultFromAddress; private String defaultFromAddress;
private String webApplicationContextUrl = "http://localhost:8080/alfresco"; private String webApplicationContextUrl = "http://localhost:8080/alfresco";
private String repositoryTemplatePath; private String repositoryTemplatePath;
private boolean extractAttachmentsEnabled = true; private boolean extractAttachmentsEnabled = true;
private NodeRef imapRootNodeRef;
private final static Map<QName, Flags.Flag> qNameToFlag; private final static Map<QName, Flags.Flag> qNameToFlag;
private final static Map<Flags.Flag, QName> flagToQname; private final static Map<Flags.Flag, QName> flagToQname;
@@ -188,14 +186,9 @@ public class ImapServiceImpl implements ImapService
this.serviceRegistry = serviceRegistry; this.serviceRegistry = serviceRegistry;
} }
public String getImapRoot() public void setImapHome(RepositoryFolderConfigBean imapHomeConfigBean)
{ {
return imapRoot; this.imapHomeConfigBean = imapHomeConfigBean;
}
public void setImapRoot(String imapRoot)
{
this.imapRoot = imapRoot;
} }
public String getDefaultFromAddress() public String getDefaultFromAddress()
@@ -228,35 +221,20 @@ public class ImapServiceImpl implements ImapService
this.repositoryTemplatePath = repositoryTemplatePath; this.repositoryTemplatePath = repositoryTemplatePath;
} }
public void setImapConfigMountPointsBeans(ImapConfigMountPointsBean[] imapConfigMountPointsBeans) public void setImapConfigMountPoints(ImapConfigMountPointsBean[] imapConfigMountPointsBeans)
{ {
this.imapConfigMountPointsBeans = new LinkedHashMap<String, ImapConfigMountPointsBean>(imapConfigMountPointsBeans.length * 2); this.imapConfigMountPoints = new LinkedHashMap<String, ImapConfigMountPointsBean>(imapConfigMountPointsBeans.length * 2);
for (ImapConfigMountPointsBean bean : imapConfigMountPointsBeans) for (ImapConfigMountPointsBean bean : imapConfigMountPointsBeans)
{ {
this.imapConfigMountPointsBeans.put(bean.getName(), bean); this.imapConfigMountPoints.put(bean.getMountPointName(), bean);
} }
} }
/** public void setIgnoreExtractionFolders(final RepositoryFolderConfigBean[] ignoreExtractionFolders)
* Return map of imap configs. Name of config == key in the map
*
* @return map of imap configs.
*/
public Map<String, ImapConfigMountPointsBean> getImapConfigMountPoints()
{
return this.imapConfigMountPointsBeans;
}
public void setIgnoreExtractionFolders(final ImapConfigBean[] ignoreExtractionFolders)
{ {
this.ignoreExtractionFoldersBeans = ignoreExtractionFolders; this.ignoreExtractionFoldersBeans = ignoreExtractionFolders;
} }
public boolean getExtractAttachmentsEnabled()
{
return extractAttachmentsEnabled;
}
public void setExtractAttachmentsEnabled(boolean extractAttachmentsEnabled) public void setExtractAttachmentsEnabled(boolean extractAttachmentsEnabled)
{ {
this.extractAttachmentsEnabled = extractAttachmentsEnabled; this.extractAttachmentsEnabled = extractAttachmentsEnabled;
@@ -264,8 +242,34 @@ public class ImapServiceImpl implements ImapService
// ---------------------- Lifecycle Methods ------------------------------ // ---------------------- Lifecycle Methods ------------------------------
public void init()
{
PropertyCheck.mandatory(this, "imapConfigMountPoints", imapConfigMountPoints);
PropertyCheck.mandatory(this, "ignoreExtractionFoldersBeans", ignoreExtractionFoldersBeans);
PropertyCheck.mandatory(this, "imapHome", imapHomeConfigBean);
PropertyCheck.mandatory(this, "fileFolderService", fileFolderService);
PropertyCheck.mandatory(this, "nodeService", nodeService);
PropertyCheck.mandatory(this, "serviceRegistry", serviceRegistry);
PropertyCheck.mandatory(this, "defaultFromAddress", defaultFromAddress);
PropertyCheck.mandatory(this, "repositoryTemplatePath", repositoryTemplatePath);
}
public void startup() public void startup()
{ {
final NamespaceService namespaceService = serviceRegistry.getNamespaceService();
final SearchService searchService = serviceRegistry.getSearchService();
// Hit the mount points for early failure
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>()
{
public Void doWork() throws Exception
{
getMountPoints();
return null;
}
}, AuthenticationUtil.getSystemUserName());
// Get NodeRefs for folders to ignore // Get NodeRefs for folders to ignore
this.ignoreExtractionFolders = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Set<NodeRef>>() this.ignoreExtractionFolders = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Set<NodeRef>>()
{ {
@@ -273,95 +277,30 @@ public class ImapServiceImpl implements ImapService
{ {
Set<NodeRef> result = new HashSet<NodeRef>(ignoreExtractionFoldersBeans.length * 2); Set<NodeRef> result = new HashSet<NodeRef>(ignoreExtractionFoldersBeans.length * 2);
for (ImapConfigBean bean : ignoreExtractionFoldersBeans) for (RepositoryFolderConfigBean ignoreExtractionFoldersBean : ignoreExtractionFoldersBeans)
{ {
StoreRef storeRef = new StoreRef(bean.getStore()); NodeRef nodeRef = ignoreExtractionFoldersBean.getFolderPath(
namespaceService, nodeService, searchService, fileFolderService);
if (nodeService.exists(storeRef) == false) if (!result.add(nodeRef))
{ {
throw new RuntimeException("No store for path: " + storeRef); // It was already in the set
throw new AlfrescoRuntimeException(
"The folder extraction path has been referenced already: \n" +
" Folder: " + ignoreExtractionFoldersBean);
} }
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
NamespaceService namespaceService = serviceRegistry.getNamespaceService();
String rootPathInStore = bean.getRootPath();
List<NodeRef> nodeRefs = serviceRegistry.getSearchService().selectNodes(storeRootNodeRef, rootPathInStore, null, namespaceService, false);
if (nodeRefs.size() > 1)
{
throw new RuntimeException(
"Multiple possible roots for : \n" +
" root path: " + rootPathInStore + "\n" +
" results: " + nodeRefs);
}
else if (nodeRefs.size() == 0)
{
throw new RuntimeException(
"No root found for : \n" +
" root path: " + rootPathInStore);
}
result.add(nodeRefs.get(0));
} }
return result; return result;
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
// Locate IMAP root folder
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>() // Locate or create IMAP home
imapHomeNodeRef = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
{ {
public Void doWork() throws Exception public NodeRef doWork() throws Exception
{ {
int indexOfStoreDelim = imapRoot.indexOf(StoreRef.URI_FILLER); return imapHomeConfigBean.getOrCreateFolderPath(namespaceService, nodeService, searchService, fileFolderService);
if (indexOfStoreDelim == -1)
{
throw new RuntimeException("Bad path format, " + StoreRef.URI_FILLER + " not found");
}
indexOfStoreDelim += StoreRef.URI_FILLER.length();
int indexOfPathDelim = imapRoot.indexOf("/", indexOfStoreDelim);
if (indexOfPathDelim == -1)
{
throw new RuntimeException("Bad path format, / not found");
}
String storePath = imapRoot.substring(0, indexOfPathDelim);
String rootPathInStore = imapRoot.substring(indexOfPathDelim);
StoreRef storeRef = new StoreRef(storePath);
if (nodeService.exists(storeRef) == false)
{
throw new RuntimeException("No store for path: " + storeRef);
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
SearchService searchService = serviceRegistry.getSearchService();
NamespaceService namespaceService = serviceRegistry.getNamespaceService();
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, rootPathInStore, null, namespaceService, false);
if (nodeRefs.size() > 1)
{
throw new RuntimeException(
"Multiple possible roots for : \n" +
" root path: " + rootPathInStore +
"\n" + " results: " + nodeRefs);
}
else if (nodeRefs.size() == 0)
{
throw new RuntimeException(
"No root found for : \n" +
" root path: " + rootPathInStore);
}
imapRootNodeRef = nodeRefs.get(0);
return null;
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
} }
@@ -370,16 +309,6 @@ public class ImapServiceImpl implements ImapService
{ {
} }
public void init()
{
PropertyCheck.mandatory(this, "fileFolderService", fileFolderService);
PropertyCheck.mandatory(this, "nodeService", nodeService);
PropertyCheck.mandatory(this, "serviceRegistry", serviceRegistry);
PropertyCheck.mandatory(this, "imapRoot", imapRoot);
PropertyCheck.mandatory(this, "defaultFromAddress", defaultFromAddress);
PropertyCheck.mandatory(this, "repositoryTemplatePath", repositoryTemplatePath);
}
// ---------------------- Service Methods -------------------------------- // ---------------------- Service Methods --------------------------------
public List<AlfrescoImapFolder> listSubscribedMailboxes(AlfrescoImapUser user, String mailboxPattern) public List<AlfrescoImapFolder> listSubscribedMailboxes(AlfrescoImapUser user, String mailboxPattern)
@@ -430,7 +359,7 @@ public class ImapServiceImpl implements ImapService
NodeRef parentNodeRef = root; // it is used for hierarhy deep search. NodeRef parentNodeRef = root; // it is used for hierarhy deep search.
for (String folderName : getMailPathInRepo(mailboxName).split(String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER))) for (String folderName : getMailPathInRepo(mailboxName).split(String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER)))
{ {
List<FileInfo> folders = searchFolders(parentNodeRef, folderName, false, AlfrescoImapConst.MODE_MIXED); List<FileInfo> folders = searchFolders(parentNodeRef, folderName, false, ImapViewMode.MIXED);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("Trying to create folder '" + folderName + "'"); logger.debug("Trying to create folder '" + folderName + "'");
@@ -615,7 +544,7 @@ public class ImapServiceImpl implements ImapService
NodeRef root = getMailboxRootRef(mailboxName, user.getLogin()); NodeRef root = getMailboxRootRef(mailboxName, user.getLogin());
String mountPointName = getMountPointName(mailboxName); String mountPointName = getMountPointName(mailboxName);
NodeRef nodeRef = root; // initial top folder NodeRef nodeRef = root; // initial top folder
String viewMode = getViewMode(mailboxName); ImapViewMode viewMode = getViewMode(mailboxName);
String[] folderNames = getMailPathInRepo(mailboxName).split(String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER)); String[] folderNames = getMailPathInRepo(mailboxName).split(String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER));
@@ -661,10 +590,10 @@ public class ImapServiceImpl implements ImapService
* @param isVirtualView is folder in "Virtual" View * @param isVirtualView is folder in "Virtual" View
* @return list of mailboxes * @return list of mailboxes
*/ */
public List<FileInfo> searchFolders(NodeRef contextNodeRef, String namePattern, boolean includeSubFolders, String viewMode) public List<FileInfo> searchFolders(NodeRef contextNodeRef, String namePattern, boolean includeSubFolders, ImapViewMode viewMode)
{ {
List<FileInfo> result = fileFolderService.search(contextNodeRef, namePattern, false, true, includeSubFolders); List<FileInfo> result = fileFolderService.search(contextNodeRef, namePattern, false, true, includeSubFolders);
if (viewMode.equals(AlfrescoImapConst.MODE_VIRTUAL) || viewMode.equals(AlfrescoImapConst.MODE_MIXED)) if (viewMode == ImapViewMode.VIRTUAL || viewMode == ImapViewMode.MIXED)
{ {
List<SiteInfo> nonFavSites = getNonFavouriteSites(getCurrentUser()); List<SiteInfo> nonFavSites = getNonFavouriteSites(getCurrentUser());
for (SiteInfo siteInfo : nonFavSites) for (SiteInfo siteInfo : nonFavSites)
@@ -715,37 +644,33 @@ public class ImapServiceImpl implements ImapService
* @param includeSubFolders includeSubFolders * @param includeSubFolders includeSubFolders
* @return list of emails that context folder contains. * @return list of emails that context folder contains.
*/ */
public List<FileInfo> searchMails(NodeRef contextNodeRef, String namePattern, String viewMode, boolean includeSubFolders) public List<FileInfo> searchMails(NodeRef contextNodeRef, String namePattern, ImapViewMode viewMode, boolean includeSubFolders)
{ {
List<FileInfo> result = new LinkedList<FileInfo>(); List<FileInfo> result = new LinkedList<FileInfo>();
List<FileInfo> searchResult = fileFolderService.search(contextNodeRef, namePattern, true, false, includeSubFolders); List<FileInfo> searchResult = fileFolderService.search(contextNodeRef, namePattern, true, false, includeSubFolders);
if (viewMode.equals(AlfrescoImapConst.MODE_MIXED)) switch (viewMode)
{
return searchResult;
}
else if (viewMode.equals(AlfrescoImapConst.MODE_ARCHIVE))
{ {
case MIXED:
result = searchResult;
break;
case ARCHIVE:
for (FileInfo fileInfo : searchResult) for (FileInfo fileInfo : searchResult)
{ {
if (nodeService.hasAspect(fileInfo.getNodeRef(), ImapModel.ASPECT_IMAP_CONTENT)) if (nodeService.hasAspect(fileInfo.getNodeRef(), ImapModel.ASPECT_IMAP_CONTENT))
{ {
result.add(fileInfo); result.add(fileInfo);
} }
} }
} break;
else if (viewMode.equals(AlfrescoImapConst.MODE_VIRTUAL)) case VIRTUAL:
{
for (FileInfo fileInfo : searchResult) for (FileInfo fileInfo : searchResult)
{ {
if (!nodeService.hasAspect(fileInfo.getNodeRef(), ImapModel.ASPECT_IMAP_CONTENT)) if (!nodeService.hasAspect(fileInfo.getNodeRef(), ImapModel.ASPECT_IMAP_CONTENT))
{ {
result.add(fileInfo); result.add(fileInfo);
} }
} }
break;
} }
return result; return result;
@@ -831,7 +756,6 @@ public class ImapServiceImpl implements ImapService
List<AlfrescoImapFolder> result = new LinkedList<AlfrescoImapFolder>(); List<AlfrescoImapFolder> result = new LinkedList<AlfrescoImapFolder>();
Map<String, NodeRef> mountPoints = getMountPoints(); Map<String, NodeRef> mountPoints = getMountPoints();
Map<String, ImapConfigMountPointsBean> imapConfigs = getImapConfigMountPoints();
NodeRef mountPoint; NodeRef mountPoint;
@@ -842,7 +766,7 @@ public class ImapServiceImpl implements ImapService
mountPoint = mountPoints.get(mountPointName); mountPoint = mountPoints.get(mountPointName);
FileInfo mountPointFileInfo = fileFolderService.getFileInfo(mountPoint); FileInfo mountPointFileInfo = fileFolderService.getFileInfo(mountPoint);
NodeRef mountParent = nodeService.getParentAssocs(mountPoint).get(0).getParentRef(); NodeRef mountParent = nodeService.getParentAssocs(mountPoint).get(0).getParentRef();
String viewMode = imapConfigs.get(mountPointName).getMode(); ImapViewMode viewMode = imapConfigMountPoints.get(mountPointName).getMode();
if (!mailboxPattern.equals("*")) if (!mailboxPattern.equals("*"))
{ {
@@ -899,14 +823,14 @@ public class ImapServiceImpl implements ImapService
// List mailboxes that are in user IMAP Home // List mailboxes that are in user IMAP Home
NodeRef root = getUserImapHomeRef(user.getLogin()); NodeRef root = getUserImapHomeRef(user.getLogin());
List<AlfrescoImapFolder> imapFolders = listFolder(root, root, user, mailboxPattern, listSubscribed, AlfrescoImapConst.MODE_ARCHIVE); List<AlfrescoImapFolder> imapFolders = listFolder(root, root, user, mailboxPattern, listSubscribed, ImapViewMode.ARCHIVE);
if (imapFolders != null) if (imapFolders != null)
{ {
for (AlfrescoImapFolder mailFolder : imapFolders) for (AlfrescoImapFolder mailFolder : imapFolders)
{ {
AlfrescoImapFolder folder = (AlfrescoImapFolder) mailFolder; AlfrescoImapFolder folder = (AlfrescoImapFolder) mailFolder;
folder.setViewMode(AlfrescoImapConst.MODE_ARCHIVE); folder.setViewMode(ImapViewMode.ARCHIVE);
folder.setMountParent(root); folder.setMountParent(root);
} }
result.addAll(imapFolders); result.addAll(imapFolders);
@@ -916,7 +840,13 @@ public class ImapServiceImpl implements ImapService
} }
private List<AlfrescoImapFolder> listFolder(NodeRef mailboxRoot, NodeRef root, AlfrescoImapUser user, String mailboxPattern, boolean listSubscribed, String viewMode) private List<AlfrescoImapFolder> listFolder(
NodeRef mailboxRoot,
NodeRef root,
AlfrescoImapUser user,
String mailboxPattern,
boolean listSubscribed,
ImapViewMode viewMode)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
@@ -1111,8 +1041,7 @@ public class ImapServiceImpl implements ImapService
{ {
rootFolder = mailPath; rootFolder = mailPath;
} }
Map<String, ImapConfigMountPointsBean> imapConfigs = getImapConfigMountPoints(); if (imapConfigMountPoints.keySet().contains(rootFolder))
if (imapConfigs.keySet().contains(rootFolder))
{ {
Map<String, NodeRef> mountPoints = getMountPoints(); Map<String, NodeRef> mountPoints = getMountPoints();
NodeRef rootRef = mountPoints.get(rootFolder); NodeRef rootRef = mountPoints.get(rootFolder);
@@ -1144,8 +1073,7 @@ public class ImapServiceImpl implements ImapService
{ {
rootFolder = mailboxName; rootFolder = mailboxName;
} }
Map<String, ImapConfigMountPointsBean> imapConfigs = getImapConfigMountPoints(); if (imapConfigMountPoints.keySet().contains(rootFolder))
if (imapConfigs.keySet().contains(rootFolder))
{ {
return rootFolder; return rootFolder;
} }
@@ -1163,24 +1091,23 @@ public class ImapServiceImpl implements ImapService
*/ */
private Map<String, NodeRef> getMountPoints() private Map<String, NodeRef> getMountPoints()
{ {
Map<String, ImapConfigMountPointsBean> imapConfigs = getImapConfigMountPoints(); Set<NodeRef> mountPointNodeRefs = new HashSet<NodeRef>(5);
Map<String, NodeRef> mountPoints = new HashMap<String, NodeRef>(); Map<String, NodeRef> mountPoints = new HashMap<String, NodeRef>();
NamespaceService namespaceService = serviceRegistry.getNamespaceService();
SearchService searchService = serviceRegistry.getSearchService(); SearchService searchService = serviceRegistry.getSearchService();
for (ImapConfigMountPointsBean config : imapConfigs.values()) for (ImapConfigMountPointsBean config : imapConfigMountPoints.values())
{ {
// Get node reference // Get node reference
StoreRef store = new StoreRef(config.getStore()); NodeRef nodeRef = config.getFolderPath(namespaceService, nodeService, searchService, fileFolderService);
ResultSet rs = searchService.query(store, SearchService.LANGUAGE_XPATH, config.getRootPath());
if (rs.length() == 0) if (!mountPointNodeRefs.add(nodeRef))
{ {
logger.warn("Didn't find " + config.getName()); throw new IllegalArgumentException(
"A mount point has been defined twice: \n" +
" Mount point: " + config);
} }
else mountPoints.put(config.getMountPointName(), nodeRef);
{
NodeRef nodeRef = rs.getNodeRef(0);
mountPoints.put(config.getName(), nodeRef);
}
rs.close();
} }
return mountPoints; return mountPoints;
} }
@@ -1205,7 +1132,7 @@ public class ImapServiceImpl implements ImapService
rootFolder = mailboxName; rootFolder = mailboxName;
} }
Map<String, ImapConfigMountPointsBean> imapConfigs = getImapConfigMountPoints(); Map<String, ImapConfigMountPointsBean> imapConfigs = imapConfigMountPoints;
if (imapConfigs.keySet().contains(rootFolder)) if (imapConfigs.keySet().contains(rootFolder))
{ {
Map<String, NodeRef> mountPoints = getMountPoints(); Map<String, NodeRef> mountPoints = getMountPoints();
@@ -1224,7 +1151,7 @@ public class ImapServiceImpl implements ImapService
*/ */
private NodeRef getUserImapHomeRef(final String userName) private NodeRef getUserImapHomeRef(final String userName)
{ {
NodeRef userHome = fileFolderService.searchSimple(imapRootNodeRef, userName); NodeRef userHome = fileFolderService.searchSimple(imapHomeNodeRef, userName);
if (userHome == null) if (userHome == null)
{ {
// create user home // create user home
@@ -1232,7 +1159,7 @@ public class ImapServiceImpl implements ImapService
{ {
public NodeRef doWork() throws Exception public NodeRef doWork() throws Exception
{ {
NodeRef result = fileFolderService.create(imapRootNodeRef, userName, ContentModel.TYPE_FOLDER).getNodeRef(); NodeRef result = fileFolderService.create(imapHomeNodeRef, userName, ContentModel.TYPE_FOLDER).getNodeRef();
nodeService.setProperty(result, ContentModel.PROP_DESCRIPTION, userName); nodeService.setProperty(result, ContentModel.PROP_DESCRIPTION, userName);
// create inbox // create inbox
fileFolderService.create(result, AlfrescoImapConst.INBOX_NAME, ContentModel.TYPE_FOLDER); fileFolderService.create(result, AlfrescoImapConst.INBOX_NAME, ContentModel.TYPE_FOLDER);
@@ -1276,7 +1203,7 @@ public class ImapServiceImpl implements ImapService
return result; return result;
} }
private boolean hasSubscribedChild(FileInfo parent, String userName, String viewMode) private boolean hasSubscribedChild(FileInfo parent, String userName, ImapViewMode viewMode)
{ {
List<FileInfo> list = searchFolders(parent.getNodeRef(), "*", true, viewMode); List<FileInfo> list = searchFolders(parent.getNodeRef(), "*", true, viewMode);
@@ -1320,7 +1247,7 @@ public class ImapServiceImpl implements ImapService
* @param mailboxName name of the mailbox in IMAP client. * @param mailboxName name of the mailbox in IMAP client.
* @return view mode of the specified mailbox. * @return view mode of the specified mailbox.
*/ */
private String getViewMode(String mailboxName) private ImapViewMode getViewMode(String mailboxName)
{ {
String rootFolder; String rootFolder;
int index = mailboxName.indexOf(AlfrescoImapConst.HIERARCHY_DELIMITER); int index = mailboxName.indexOf(AlfrescoImapConst.HIERARCHY_DELIMITER);
@@ -1332,14 +1259,13 @@ public class ImapServiceImpl implements ImapService
{ {
rootFolder = mailboxName; rootFolder = mailboxName;
} }
Map<String, ImapConfigMountPointsBean> imapConfigs = getImapConfigMountPoints(); if (imapConfigMountPoints.keySet().contains(rootFolder))
if (imapConfigs.keySet().contains(rootFolder))
{ {
return imapConfigs.get(rootFolder).getMode(); return imapConfigMountPoints.get(rootFolder).getMode();
} }
else else
{ {
return AlfrescoImapConst.MODE_ARCHIVE; return ImapViewMode.ARCHIVE;
} }
} }

View File

@@ -14,6 +14,7 @@ import junit.framework.TestCase;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.ImapModel; import org.alfresco.model.ImapModel;
import org.alfresco.repo.imap.AlfrescoImapConst.ImapViewMode;
import org.alfresco.repo.importer.ACPImportPackageHandler; import org.alfresco.repo.importer.ACPImportPackageHandler;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory; import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl; import org.alfresco.repo.model.filefolder.FileFolderServiceImpl;
@@ -36,6 +37,7 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.PropertyMap; import org.alfresco.util.PropertyMap;
import org.alfresco.util.config.RepositoryFolderConfigBean;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
@@ -142,8 +144,11 @@ public class ImapServiceImplTest extends TestCase
FileFolderServiceImpl.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER); FileFolderServiceImpl.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);
// Setting IMAP root // Setting IMAP root
String imapRoot = storePath + companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + TEST_IMAP_FOLDER_NAME; RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
imapServiceImpl.setImapRoot(imapRoot); imapHome.setStore(storePath);
imapHome.setRootPath(companyHomePathInStore);
imapHome.setFolderPath(TEST_IMAP_FOLDER_NAME);
imapServiceImpl.setImapHome(imapHome);
// Starting IMAP // Starting IMAP
imapServiceImpl.startup(); imapServiceImpl.startup();
@@ -304,33 +309,33 @@ public class ImapServiceImplTest extends TestCase
public void testSearchFoldersInArchive() throws Exception public void testSearchFoldersInArchive() throws Exception
{ {
List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, AlfrescoImapConst.MODE_ARCHIVE); List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, ImapViewMode.ARCHIVE);
assertNotNull("Can't find folders in Archive Mode", fi); assertNotNull("Can't find folders in Archive Mode", fi);
assertEquals("Can't find folders in Archive Mode", fi.size(), 2); assertEquals("Can't find folders in Archive Mode", fi.size(), 2);
fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, AlfrescoImapConst.MODE_ARCHIVE); fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, ImapViewMode.ARCHIVE);
assertNotNull("Can't find folders in Archive Mode", fi); assertNotNull("Can't find folders in Archive Mode", fi);
assertEquals("Can't find folders in Archive Mode", fi.size(), 1); assertEquals("Can't find folders in Archive Mode", fi.size(), 1);
} }
public void testSearchFoldersInVirtual() throws Exception public void testSearchFoldersInVirtual() throws Exception
{ {
List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, AlfrescoImapConst.MODE_VIRTUAL); List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, ImapViewMode.VIRTUAL);
assertNotNull("Can't find folders in Virtual Mode", fi); assertNotNull("Can't find folders in Virtual Mode", fi);
assertEquals("Can't find folders in Virtual Mode", fi.size(), 2); assertEquals("Can't find folders in Virtual Mode", fi.size(), 2);
fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, AlfrescoImapConst.MODE_VIRTUAL); fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, ImapViewMode.VIRTUAL);
assertNotNull("Can't find folders in Virtual Mode", fi); assertNotNull("Can't find folders in Virtual Mode", fi);
assertEquals("Can't find folders in Virtual Mode", fi.size(), 1); assertEquals("Can't find folders in Virtual Mode", fi.size(), 1);
} }
public void testSearchFoldersInMixed() throws Exception public void testSearchFoldersInMixed() throws Exception
{ {
List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, AlfrescoImapConst.MODE_MIXED); List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, ImapViewMode.MIXED);
assertNotNull("Can't find folders in Mixed Mode", fi); assertNotNull("Can't find folders in Mixed Mode", fi);
assertEquals("Can't find folders in Mixed Mode", fi.size(), 2); assertEquals("Can't find folders in Mixed Mode", fi.size(), 2);
fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, AlfrescoImapConst.MODE_MIXED); fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, ImapViewMode.MIXED);
assertNotNull("Can't find folders in Mixed Mode", fi); assertNotNull("Can't find folders in Mixed Mode", fi);
assertEquals("Can't find folders in Mixed Mode", fi.size(), 1); assertEquals("Can't find folders in Mixed Mode", fi.size(), 1);
} }
@@ -344,7 +349,7 @@ public class ImapServiceImplTest extends TestCase
public void testSearchMails() throws Exception public void testSearchMails() throws Exception
{ {
List<FileInfo> fi = imapService.searchMails(testImapFolderNodeRef, "*", AlfrescoImapConst.MODE_MIXED, true); List<FileInfo> fi = imapService.searchMails(testImapFolderNodeRef, "*", ImapViewMode.MIXED, true);
assertNotNull(fi); assertNotNull(fi);
assertTrue(fi.size() > 0); assertTrue(fi.size() > 0);
} }
@@ -379,7 +384,7 @@ public class ImapServiceImplTest extends TestCase
public void testSetFlags() throws Exception public void testSetFlags() throws Exception
{ {
List<FileInfo> fis = imapService.searchMails(testImapFolderNodeRef, "*", AlfrescoImapConst.MODE_ARCHIVE, true); List<FileInfo> fis = imapService.searchMails(testImapFolderNodeRef, "*", ImapViewMode.ARCHIVE, true);
if (fis != null && fis.size() > 0) if (fis != null && fis.size() > 0)
{ {
FileInfo messageFileInfo = fis.get(0); FileInfo messageFileInfo = fis.get(0);
@@ -412,7 +417,7 @@ public class ImapServiceImplTest extends TestCase
public void testSetFlag() throws Exception public void testSetFlag() throws Exception
{ {
List<FileInfo> fis = imapService.searchMails(testImapFolderNodeRef, "*", AlfrescoImapConst.MODE_ARCHIVE, true); List<FileInfo> fis = imapService.searchMails(testImapFolderNodeRef, "*", ImapViewMode.ARCHIVE, true);
if (fis != null && fis.size() > 0) if (fis != null && fis.size() > 0)
{ {
FileInfo messageFileInfo = fis.get(0); FileInfo messageFileInfo = fis.get(0);
@@ -432,7 +437,7 @@ public class ImapServiceImplTest extends TestCase
public void testGetFlags() throws Exception public void testGetFlags() throws Exception
{ {
List<FileInfo> fis = imapService.searchMails(testImapFolderNodeRef, "*", AlfrescoImapConst.MODE_ARCHIVE, true); List<FileInfo> fis = imapService.searchMails(testImapFolderNodeRef, "*", ImapViewMode.ARCHIVE, true);
if (fis != null && fis.size() > 0) if (fis != null && fis.size() > 0)
{ {
FileInfo messageFileInfo = fis.get(0); FileInfo messageFileInfo = fis.get(0);

View File

@@ -1,105 +0,0 @@
/*
* Copyright (C) 2005-2009 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 received 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.imap.config;
import org.springframework.beans.factory.BeanNameAware;
/**
* Standard ImapConfig bean.
*/
public class ImapConfigBean implements BeanNameAware
{
/** The IMAP folder name. */
private String name;
/** The Alfresco store name. */
private String store;
/** The path within the store to the root node. */
private String rootPath;
/**
* Gets the IMAP folder name.
*
* @return the IMAP folder name
*/
public String getName()
{
return this.name;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
*/
public void setBeanName(String name)
{
this.name = name;
}
/**
* Gets the Alfresco store name.
*
* @return the Alfresco store name
*/
public String getStore()
{
return this.store;
}
/**
* Sets the Alfresco store name.
*
* @param store
* the Alfresco store name
*/
public void setStore(String store)
{
this.store = store;
}
/**
* Gets the path within the store to the root node.
*
* @return the path within the store to the root node
*/
public String getRootPath()
{
return this.rootPath;
}
/**
* Sets the path within the store to the root node.
*
* @param rootPath
* the path within the store to the root node
*/
public void setRootPath(String rootPath)
{
this.rootPath = rootPath;
}
}

View File

@@ -24,36 +24,65 @@
*/ */
package org.alfresco.repo.imap.config; package org.alfresco.repo.imap.config;
import org.alfresco.repo.imap.AlfrescoImapConst.ImapViewMode;
import org.alfresco.util.config.RepositoryFolderConfigBean;
/** /**
* Provides the parameters for an IMAP mount point (a mapping from an Alfresco node path to an IMAP folder name). * Provides the parameters for an IMAP mount point (a mapping from an Alfresco node path to an IMAP folder name).
*
* @since 3.2
*/ */
public class ImapConfigMountPointsBean extends ImapConfigBean public class ImapConfigMountPointsBean extends RepositoryFolderConfigBean
{ {
private String mountPointName;
private ImapViewMode mode;
/**
* Gets the IMAP mount-point name.
*
* @return the IMAP folder name
*/
public String getMountPointName()
{
return this.mountPointName;
}
/** The mode (virtual, archive or mixed). */ /**
private String mode; * @param folderName the name of the IMAP folder
*/
public void setMountPointName(String folderName)
{
this.mountPointName = folderName;
}
/** /**
* Gets the mode. * Gets the mode.
* *
* @return the mode (virtual or archive) * @return the mode (virtual, mixed or archive)
*/ */
public String getMode() public ImapViewMode getMode()
{ {
return this.mode; return this.mode;
} }
/**
* @return Returns the string value of the mode
*/
public String getModeName()
{
return mode == null ? null : mode.toString();
}
/** /**
* Sets the mode. * Sets the mode.
* *
* @param mode * @param mode
* the new mode (virtual or archive) * the new mode (virtual or archive)
* @see MountPointMode
*/ */
public void setMode(String mode) public void setModeName(String mode)
{ {
this.mode = mode; this.mode = ImapViewMode.valueOf(mode);
} }
} }

View File

@@ -0,0 +1,203 @@
/*
* Copyright (C) 2005-2009 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 received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.util.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.PropertyCheck;
/**
* Composite property bean to identify a folder in the repository. This uses the
* {@link RepositoryPathConfigBean#getPath() path} to identify a root and then a
* {@link #getFolderNames() folder-name path} to identify a folder.
*
* @author Derek Hulley
* @since 3.2
*/
public class RepositoryFolderConfigBean extends RepositoryPathConfigBean
{
private List<String> folderPath;
public RepositoryFolderConfigBean()
{
folderPath = Collections.emptyList();
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(128);
sb.append("Folder Path: ").append(super.getStoreRef()).append(super.getRootPath());
for (String folder : folderPath)
{
sb.append("/").append(folder);
}
return sb.toString();
}
/**
* Get the folder name path
*/
public List<String> getFolderNames()
{
return folderPath;
}
/**
*
* @return Returns the string representation of the folder path
*/
public String getFolderPath()
{
StringBuilder sb = new StringBuilder(56);
for (String pathElement : folderPath)
{
sb.append("/").append(pathElement);
}
return sb.toString();
}
/**
* Set the folder name path <b>relative to the {@link RepositoryPathConfigBean#getPath() path}</b>.
*
* @param folderPath a folder-name path using the '<b>/</b>' path separator e.g. '<b>IMAP HOME/MAIL-1</b>'
*/
public void setFolderPath(String folderPath)
{
if (!PropertyCheck.isValidPropertyString(folderPath))
{
folderPath = "";
}
this.folderPath = new ArrayList<String>(5);
StringTokenizer tokenizer = new StringTokenizer(folderPath, "/");
while (tokenizer.hasMoreTokens())
{
String folderName = tokenizer.nextToken();
if (folderName.length() == 0)
{
throw new IllegalArgumentException("Invalid folder name path for property 'folderPath': " + folderPath);
}
this.folderPath.add(folderName);
}
}
/**
* Helper method to find the folder path referenced by this bean.
* The {@link #getPath() path} to the start of the {@link #getFolderNames() folder path}
* must exist.
* <p>
* Authentication and transactions are the client's responsibility.
*
* @return Returns an existing folder reference or null
*/
public NodeRef getFolderPath(
NamespaceService namespaceService,
NodeService nodeService,
SearchService searchService,
FileFolderService fileFolderService)
{
NodeRef pathStartNodeRef = super.resolveNodePath(namespaceService, nodeService, searchService);
if (pathStartNodeRef == null)
{
throw new AlfrescoRuntimeException(
"Folder path resolution requires an existing base path. \n" +
" Base path: " + getRootPath());
}
// Just choose the root path if the folder path is empty
if (folderPath.size() == 0)
{
return pathStartNodeRef;
}
else
{
try
{
FileInfo folderInfo = fileFolderService.resolveNamePath(pathStartNodeRef, folderPath);
if (!folderInfo.isFolder())
{
throw new AlfrescoRuntimeException("Not a folder: " + this);
}
return folderInfo.getNodeRef();
}
catch (FileNotFoundException e)
{
throw new AlfrescoRuntimeException("Folder not found: " + this);
}
}
// Done
}
/**
* Helper method to find or create the folder path referenced by this bean.
* The {@link #getPath() path} to the start of the {@link #getFolderNames() folder path}
* must exist. The folder path will be created, if required.
* <p>
* Authentication and transactions are the client's responsibility.
*
* @return Returns an existing or new folder reference
*/
public NodeRef getOrCreateFolderPath(
NamespaceService namespaceService,
NodeService nodeService,
SearchService searchService,
FileFolderService fileFolderService)
{
NodeRef pathStartNodeRef = super.resolveNodePath(namespaceService, nodeService, searchService);
if (pathStartNodeRef == null)
{
throw new AlfrescoRuntimeException(
"Folder path resolution requires an existing base path. \n" +
" Base path: " + getRootPath());
}
// Just choose the root path if the folder path is empty
if (folderPath.size() == 0)
{
return pathStartNodeRef;
}
else
{
FileInfo folderInfo = FileFolderServiceImpl.makeFolders(
fileFolderService,
pathStartNodeRef,
folderPath,
ContentModel.TYPE_FOLDER);
return folderInfo.getNodeRef();
}
// Done
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2005-2009 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 received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.util.config;
import java.util.List;
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.namespace.NamespaceService;
import org.alfresco.util.ParameterCheck;
import org.alfresco.util.PropertyCheck;
/**
* Composite property bean to identify a repository path.
*
* @author Derek Hulley
* @since 3.2
*/
public class RepositoryPathConfigBean
{
/** The Alfresco store reference */
private StoreRef store;
/** The path within the store to the root node. */
private String rootPath;
/**
* Gets the Alfresco store reference
*
* @return the Alfresco store reference
*/
public StoreRef getStoreRef()
{
return this.store;
}
/**
* @return Returns the string representation of the store reference
*/
public String getStore()
{
return store == null ? null : store.toString();
}
/**
* Sets the Alfresco store name.
*
* @param store
* the Alfresco store name
*/
public void setStore(String storeRef)
{
PropertyCheck.mandatory(this, "store", storeRef);
this.store = new StoreRef(storeRef);
}
/**
* Gets the path within the store
*/
public String getRootPath()
{
return this.rootPath;
}
/**
* Sets the path within the store. This must start with <b>/</b> at least.
*
* @param path
* the path within the store
*/
public void setRootPath(String path)
{
PropertyCheck.mandatory(this, "path", path);
ParameterCheck.mandatoryString("path", path);
if (!path.startsWith("/"))
{
throw new IllegalArgumentException("Propety 'path' must start with '/' - it is a path relative to the store root.");
}
this.rootPath = path;
}
/**
* Helper method to resolve the path represented by this configuration bean.
* <p>
* Authentication and transactions are the client's responsibility.
*
* @return Returns the node reference (first one found) or <tt>null</tt>
*/
public NodeRef resolveNodePath(NamespaceService namespaceService, NodeService nodeService, SearchService searchService)
{
NodeRef rootNodeRef = nodeService.getRootNode(store);
List<NodeRef> nodeRefs = searchService.selectNodes(rootNodeRef, rootPath, null, namespaceService, true);
if (nodeRefs.size() == 0)
{
return null;
}
else
{
return nodeRefs.get(0);
}
}
}