cancel
Showing results for 
Search instead for 
Did you mean: 

subscribe aspect

xerox
Champ in-the-making
Champ in-the-making
I made a link by every document(in de browse page) with subscribe.
the meaning of this is, that a person can subscribe himself on a document.
If you click on that link, it calls browsebean.subscribe.

code of browsebean.subscribe

public void Subscribe()
   {
      UserTransaction tx = null;
     
      try
      {
         tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
         tx.begin();
        
         // add the versionable aspect to the node
         this.nodeService.addAspect(getDocument().getNodeRef(), ContentModel.ASPECT_SUBSCRIBABLE, null);
        
         // commit the transaction
         tx.commit();
        
         // reset the state of the current document
         getDocument().reset();
      }
      catch (Throwable e)
      {
         // rollback the transaction
         try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
         Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
               FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_SUBSCRIBE), e.getMessage()), e);
      }
   }
But this doesn't work.
Does someone know how to deal with the subscribe aspect?
12 REPLIES 12

xerox
Champ in-the-making
Champ in-the-making
I've solved the error.
Now I want to implement the class I've got from another alfresco user(Ryan Berg)

This is the class:

package org.alfresco.repo.subscribable;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.ContentServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.transaction.TransactionListenerAdapter;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;

import java.util.ArrayList;
import java.util.List;

/**
* Aspect that enables a content item to be subscribed to.
* Upon update of the content item, all subscribers will be notified.
*
* @author Ryan Berg ([email protected])
* @version 1.0
*/
public class SubscribableAspect extends TransactionListenerAdapter implements ContentServicePolicies.OnContentUpdatePolicy
{
    //  Logger
    private static final Log logger = LogFactory.getLog(SubscribableAspect.class);

    private static final String SUBSCRIBERS_ADDRESSES = "SubscribableAspect.subscribersAddresses";
    private static final String NOTIFICATION_INFO = "SubscribableAspect.notificationInfo";

    // Unknown user, for when authentication has not occured
    private static final String USERNAME_UNKNOWN = "unknown";

    // Dependencies
    private NodeService nodeService;
    private AuthenticationService authenticationService;
    private PolicyComponent policyComponent;
    private JavaMailSender mailSender;


    /**
     * @param nodeService the node service to use for audit property maintenance
     */
    public void setNodeService(NodeService nodeService)
    {
        this.nodeService = nodeService;
    }

    /**
     * @param policyComponent the policy component
     */
    public void setPolicyComponent(PolicyComponent policyComponent)
    {
        this.policyComponent = policyComponent;
    }

    /**
     * @param authenticationService the authentication service
     */
    public void setAuthenticationService(AuthenticationService authenticationService)
    {
        this.authenticationService = authenticationService;
    }

    /**
     * @param mailSender The JavaMailSender to set.
     */
    public void setMailSender(JavaMailSender mailSender)
    {
        this.mailSender = mailSender;
    }

    /**
     * Initialise the Auditable Aspect
     */
    public void init()
    {
        // Bind Behaviours
        this.policyComponent.bindClassBehaviour(
                ContentServicePolicies.ON_CONTENT_UPDATE,
                ContentModel.ASPECT_SUBSCRIBABLE,
                new JavaBehaviour(this, "onContentUpdate"));
    }

    /**
     * Maintain audit properties on update of node
     *
     * @param nodeRef the updated node
     */
    public void onContentUpdate(NodeRef nodeRef, boolean isNew)
    {
        AlfrescoTransactionSupport.bindListener(this);

        List<AssociationRef> subscribers = nodeService.getTargetAssocs(nodeRef, ContentModel.ASSOC_SUBSCRIBEDBY);
        String modifier = getUsername();

        NotificationInfo info = new NotificationInfo(modifier, nodeRef);
        AlfrescoTransactionSupport.bindResource(NOTIFICATION_INFO, info);

        List<String> emailAddresses = getAddressList();

        for (AssociationRef ar : subscribers)
        {
            NodeRef subscriber = ar.getTargetRef();
            String emailAddress = (String) nodeService.getProperty(subscriber, ContentModel.PROP_EMAIL);
            emailAddresses.add(emailAddress);
        }

        if (logger.isDebugEnabled())
            logger.debug("Subscribeable node " + nodeRef + " updated [notified=" + subscribers + "]");
    }

    private List<String> getAddressList()
    {
        List<String> addresses = (List<String>)AlfrescoTransactionSupport.getResource(SUBSCRIBERS_ADDRESSES);

        if(addresses == null)
        {
            addresses = new ArrayList<String>();
            AlfrescoTransactionSupport.bindResource(SUBSCRIBERS_ADDRESSES, addresses);
        }

        return addresses;
    }

    /**
     * @return the current username (or unknown, if unknown)
     */
    private String getUsername()
    {
        String currentUserName = authenticationService.getCurrentUserName();
        if (currentUserName != null)
        {
            return currentUserName;
        }
        return USERNAME_UNKNOWN;
    }

    /**
     * Send an e-mail to a subscriber
     *
     * @param subscriber - email address of subscriber
     * @param info       - notification information
     */
    private void notifySubscriber(String subscriber, NotificationInfo info)
    {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setTo(subscriber);
        simpleMailMessage.setSubject("*** Alfresco Subscription Alert: " + info.getName());

        StringBuilder buf = new StringBuilder(256);

        buf.append("An item you are subscribed to has been modified.\r\n\r\n");
        buf.append("PATH:        " + info.getPath() + "/" + info.getName() + "\r\n");
        buf.append("MODIFIED BY: " + info.getModifier() + "\r\n");

        simpleMailMessage.setText(buf.toString());
        simpleMailMessage.setFrom("[email protected]");

        try
        {
            // Send the message
            this.mailSender.send(simpleMailMessage);
        }
        catch (Throwable e)
        {
            // don't stop the action but let admins know email is not getting sent
            logger.error("Failed to send subscription alert email to " + subscriber, e);
        }
    }

    public void afterCommit()
    {
        List<String> addresses = (List<String>)AlfrescoTransactionSupport.getResource(SUBSCRIBERS_ADDRESSES);
        NotificationInfo info = (NotificationInfo)AlfrescoTransactionSupport.getResource(NOTIFICATION_INFO);

        for (String emailAddress : addresses)
        {
            notifySubscriber(emailAddress, info);
        }
    }


    /**
     * Simple class which contains the notification information.
     * Data member values are initialized by passing the node reference
     * into the constructor.
     */
    private class NotificationInfo
    {
        private String modifier;
        private String name;
        private String path;

        public NotificationInfo(String modifier, NodeRef nodeRef)
        {
            setModifier(modifier);
            setName((String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME));
            setPath((String) nodeService.getPath(nodeRef).toDisplayPath(nodeService));
        }

        private void setModifier(String modifier)
        {
            this.modifier = modifier;
        }

        public String getModifier()
        {
            return modifier;
        }

        private void setName(String name)
        {
            this.name = name;
        }

        public String getName()
        {
            return name;
        }

        private void setPath(String path)
        {
            this.path = path;
        }

        public String getPath()
        {
            return path;
        }
    }
}

but I don't know how I can 'bind' this class, so it will send these mails when content is updated.
Can anyone help me?
Nick

xerox
Champ in-the-making
Champ in-the-making
I've made subscribe.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>

    <!– Action Service –>

    <bean id="Subscribe" class="org.alfresco.repo.subscribable.Subscribe" init-method="init">
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>       
        <property name="policyComponent">
        <ref bean="policyComponent"/>
        </property>       
        <property name="authenticationService">
            <ref bean="authenticationService" />
        </property>
       <property name="mailService">
            <ref bean="mailService" />
        </property>
    </bean>
   
   
</beans>
and placed a link in application-context.xml
<import resource="classpath:alfresco/subscribe.xml" />

but still this isn't working. the system doens't send mails when content is updated.
Do I need to programm something ele?

Nick

xerox
Champ in-the-making
Champ in-the-making
never mind, it worksSmiley Happy
but only is I update something with the updatebutton.
with the checkinbutton, it doesn't work.