AnsweredAssumed Answered

Adding custom aspects during an upload using Java

Question asked by yuhuayang on Aug 26, 2013
Latest reply on Aug 27, 2013 by yuhuayang
Hi All

I really would appreciate some help on this.

I am currently trying to create my own Inbound email handler similar to this tutorial: http://www.whiteboardcoder.com/2012/11/alfresco-4-customize-inbound-email.html

The difference is that I am also attempting to extract information from the body of the email and use that data as values for custom aspect properties. Because the custom aspects are not attached to the document yet, I need the custom email handler to also add aspects to the document and then set the values to be the ones I extracted from the body of the email.

I have created my custom aspects and properties and have verified it working. I can add the custom aspects to my documents in Alfresco. Here is model xml just for reference:

<?xml version="1.0" encoding="UTF-8"?>
<model name="contracts:contractsModel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
    <description>Contract Metadata</description>
    <author>yangy</author>
    <version>1.0</version>
    <imports>
        <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
        <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
    </imports>
    <namespaces>
        <namespace uri="contracts.model" prefix="contracts"/>
    </namespaces>
    <aspects>
        <aspect name="contracts:metadata">
            <title>Contracts Metadata</title>
            <properties>
                <property name="contracts:masterID">
                    <title>Master ID</title>
                    <type>d:text</type>
                </property>
                <property name="contracts:companyName">
                    <title>Company Name</title>
                    <type>d:text</type>
                </property>
            </properties>
        </aspect>
    </aspects>
</model>


However my problem is in the Java code. I am getting this error:
Caused by: org.alfresco.service.cmr.dictionary.InvalidAspectException: 07260056 The aspect is invalid: {contracts.model.}metadata 


Even though I followed the NodeRef cookbook to add aspects (http://wiki.alfresco.com/wiki/NodeRef_cookbook#Adding_an_aspect_to_a_node) Is this wiki completely outdated and wrong to follow? It did mislead me about the services I needed to start which I don't think were right. I don't understand why official wiki from Alfresco leads people down the wrong path sometimes.

The following is my Java code, specifically the parts attempting to add aspects:

package com._10x13.alfresco.email;

import org.alfresco.email.server.handler.FolderEmailMessageHandler;
import org.apache.log4j.Logger;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.email.EmailMessage;
import org.alfresco.service.cmr.email.EmailMessagePart;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;

import javax.xml.parsers.*;
import org.xml.sax.InputSource;
import org.w3c.dom.*;
import java.io.*;
import java.util.*;

public class CustomFolderEmailMessageHandler
                                            extends FolderEmailMessageHandler {
    private Logger log = Logger.getLogger("com._10x13");
    private ListableBeanFactory beanFactory;
   
    private NodeService nodeService;
  
    public void setNodeService(NodeService nodeService)
    {
        //  System.out.println(" dist ");
        this.nodeService = nodeService;
    }

    public void processMessage(NodeRef folderNodeRef, EmailMessage message){
       
        //ServiceRegistry serviceRegistry = (ServiceRegistry) beanFactory.getBean(ServiceRegistry.SERVICE_REGISTRY);
        //NodeService nodeService = serviceRegistry.getNodeService();
       
        String toAddress = message.getTo();
        String fromAddress = message.getFrom();
        String subject = message.getSubject();
        MimetypeService mimetypeService = getMimetypeService();
        InputStream contentIs;
        InputStream bodyContent;
        NodeRef contentNodeRef;
        String mimeType;

        log.info("An Email was sent to: " + toAddress);
        log.info("An Email was sent from: " + fromAddress);
        log.info("An Email was sent with the subject line of: " + subject);
       
        //here we extract the body of the email and the meta data
        EmailMessagePart mailBody = message.getBody();
        bodyContent = mailBody.getContent();
       
        String metaData = fromStream(bodyContent);
       
        //get the metadata
        String masterID = parseXMLString(metaData, "MasterID");
        String companyName = parseXMLString(metaData, "CompanyName");
       

        for(EmailMessagePart attachment: message.getAttachments()) {
            //Skip saving the email as an html file
            if(!attachment.getFileName().startsWith(subject)){
                log.info("attached file is named: " + attachment.getFileName()
                           + "And Has a size of: " + attachment.getSize() + " Bytes");

                contentIs = attachment.getContent();
                mimeType = mimetypeService.guessMimetype(attachment.getFileName());
               
                //here the document is added as a node, returned nodeRef
                contentNodeRef = addContentNode(nodeService,
                                                folderNodeRef, attachment.getFileName(), true);

                writeContent(contentNodeRef, contentIs, mimeType, attachment.getEncoding());
               
                log.info("the file has been written to node: " + contentNodeRef.toString());
               
                //add the metadata
                Map<QName,Serializable> aspectValues = new HashMap<QName,Serializable>();
               
                QName CUSTOM_ASPECT_QNAME = QName.createQName("contracts.model", "metadata");
                QName PROP_QNAME_MY_PROPERTY = QName.createQName("contracts.model", "masterID");
                aspectValues.put(PROP_QNAME_MY_PROPERTY, masterID);
                nodeService.addAspect(contentNodeRef, CUSTOM_ASPECT_QNAME, aspectValues);
               
                //clear aspectValues
                aspectValues.clear();
               
                PROP_QNAME_MY_PROPERTY = QName.createQName("contracts.model", "companyName");
                aspectValues.put(PROP_QNAME_MY_PROPERTY, companyName);
                nodeService.addAspect(contentNodeRef, CUSTOM_ASPECT_QNAME, aspectValues);
               
            }
        }
    }
    public static String parseXMLString(String s, String tag) {
       
        String result = "";
       
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(s));
           
            Document doc = db.parse(is);
            NodeList node = doc.getElementsByTagName(tag);
            Element line = (Element) node.item(0);
           
            result = getCharacterDataFromElement(line);
           
        }
        catch (Exception e) {
            e.printStackTrace();
        }
       
        return result;
    }
    public static String getCharacterDataFromElement(Element e) {
        Node child = e.getFirstChild();
        if (child instanceof CharacterData) {
            CharacterData cd = (CharacterData) child;
            return cd.getData();
        }
        return "?";
    }
    public static String fromStream(InputStream is) {
       
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
       
        String line;
        try {
           
            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
           
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
       
        return sb.toString();
       
    }
                           
}

Outcomes