简体   繁体   中英

How do I get a valid Alfresco application context to create folders?

I'm modifying InboundSMTP to create folders for the new messages. It appears that requires fileFolderService.create, with parameters for a folder content type. Working back from that I need a ServiceRegistry, which in turn needs ApplicationContext.

Here's what I'm attempting to do:

ApplicationContext appContext = new ClassPathXmlApplicationContext("alfresco/application-context.xml");
ServiceRegistry serviceRegistry = (ServiceRegistry) appContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
FileFolderService fileFolderService=serviceRegistry.getFileFolderService();
FileInfo object = fileFolderService.create(nodeRef, messageSubject, ContentModel.TYPE_FOLDER);

However, this causes the inbound e-mails to be rejected. I can comment out the last 3 lines and it still fails the same way, so something is wrong with my ApplicationContext call. With even just that call in place, I get the following error (which makes no sense to me):

ERROR [org.springframework.extensions.surf.util.AbstractLifecycleBean] [org.subethamail.smtp.server.Session-/2001:470:c27d:18:0:0:0:17:62204] 06300186 Email message processing failed
org.alfresco.error.AlfrescoRuntimeException: 06300186 Email message processing failed
    at org.alfresco.email.server.EmailServiceImpl.processMessage(EmailServiceImpl.java:324)
    at org.alfresco.email.server.EmailServiceImpl.importMessage(EmailServiceImpl.java:180)
    at org.alfresco.email.server.impl.subetha.SubethaEmailServer$Handler.processDelivery(SubethaEmailServer.java:223)
    at org.alfresco.email.server.impl.subetha.SubethaEmailServer$Handler.data(SubethaEmailServer.java:184)
    at org.subethamail.smtp.command.DataCommand.execute(DataCommand.java:61)
    at org.subethamail.smtp.server.RequireTLSCommandWrapper.execute(RequireTLSCommandWrapper.java:27)
    at org.subethamail.smtp.server.CommandHandler.handleCommand(CommandHandler.java:98)
    at org.subethamail.smtp.server.Session.runCommandLoop(Session.java:222)
    at org.subethamail.smtp.server.Session.run(Session.java:125)
Caused by: org.alfresco.error.AlfrescoRuntimeException: 06300185 Not all patches could be applied
    at org.alfresco.repo.admin.patch.PatchExecuter.applyOutstandingPatches(PatchExecuter.java:111)
    at org.alfresco.repo.admin.patch.PatchExecuter$1.doWork(PatchExecuter.java:124)
    at org.alfresco.repo.admin.patch.PatchExecuter$1.doWork(PatchExecuter.java:120)
    at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:548)
    at org.alfresco.repo.admin.patch.PatchExecuter.onBootstrap(PatchExecuter.java:128)
    at org.springframework.extensions.surf.util.AbstractLifecycleBean.onApplicationEvent(AbstractLifecycleBean.java:56)
    at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEventInternal(SafeApplicationEventMulticaster.java:209)
    at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEvent(SafeApplicationEventMulticaster.java:180)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:303)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:911)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:428)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.sscorp.CustomFolderEmailMessageHandler.addAlfrescoContent(CustomFolderEmailMessageHandler.java:132)
    at com.sscorp.CustomFolderEmailMessageHandler.processMessage(CustomFolderEmailMessageHandler.java:94)
    at org.alfresco.email.server.EmailServiceImpl$3.execute(EmailServiceImpl.java:296)
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:454)
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:342)
    at org.alfresco.email.server.EmailServiceImpl$4.doWork(EmailServiceImpl.java:304)
    at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:548)
    at org.alfresco.email.server.EmailServiceImpl.processMessage(EmailServiceImpl.java:307)
    ... 8 more

What am I doing wrong while trying to get ApplicationContext? Or, should I try another approach/is there a better way to create folders programmatically in Alfresco?

In this case you should not need to inject the application context.

Best practice for making modifications to email handling involves creating a custom handler. The following is the important code for defining this:

public class CustomFolderEmailMessageHandler extends AbstractEmailMessageHandler {

    public void processMessage(NodeRef nodeRef, EmailMessage message) {
        NodeService nodeService = getNodeService();
    }

}

The abstract class has a getNodeService() method which gives you the node service. This is the verbose version of the FileFolderService.

You should use the FolderEmailMessageHandler as a guide: https://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD/root/projects/repository/source/java/org/alfresco/email/server/handler/FolderEmailMessageHandler.java

In order to register your message handler you need override the emailService bean: https://wiki.alfresco.com/wiki/Inbound_SMTP_Email_Server_Configuration#Implementing_A_Custom_Node_Handler

You almost certainly don't want to get the Application Context for what you need to do!

If you want "all the common services", don't get the context. Instead, ask Spring to give you the Alfresco ServiceRegistry . That is available as a bean with the ID ServiceRegistry , and has handy getters for the main services you might want

In your case though, if you know you want the FileFolderService , ask spring for it for your bean! If you're overriding the documentEmailMessageHandler bean (for example), you'd want a bean like:

<bean id="documentEmailMessageHandler"
      parent="emailMessageHandlerBase"
      class="com.something.else.DocumentEmailMessageHandler">
   <property name="fileFolderService" ref="FileFolderService"/>
</bean>

Then in your custom implementation, provide a method setFileFolderService(FileFolderService fileFolderService) which saves the service for later use. Follow any standard spring tutorial if this is news to you!

If you really really do need the Spring Application Context, then follow the normal Spring pattern and have your bean class implement the ApplicationContextAware interface , and spring will set you the context during initialisation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM