001/*
002 *  Copyright 2011 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.blog.posts;
017
018import java.io.IOException;
019import java.util.HashMap;
020import java.util.Map;
021
022import javax.jcr.Node;
023import javax.jcr.NodeIterator;
024import javax.jcr.Repository;
025import javax.jcr.RepositoryException;
026import javax.jcr.Session;
027import javax.jcr.query.Query;
028
029import org.apache.avalon.framework.service.ServiceException;
030import org.apache.avalon.framework.service.ServiceManager;
031import org.apache.cocoon.ProcessingException;
032import org.apache.cocoon.environment.ObjectModelHelper;
033import org.apache.cocoon.environment.Request;
034import org.apache.cocoon.generation.ServiceableGenerator;
035import org.apache.cocoon.xml.AttributesImpl;
036import org.apache.cocoon.xml.XMLUtils;
037import org.joda.time.DateTime;
038import org.joda.time.format.ISODateTimeFormat;
039import org.xml.sax.SAXException;
040
041import org.ametys.cms.repository.Content;
042import org.ametys.cms.repository.comment.Comment;
043import org.ametys.plugins.repository.AmetysObjectResolver;
044import org.ametys.plugins.repository.AmetysRepositoryException;
045import org.ametys.plugins.repository.RepositoryConstants;
046import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata;
047import org.ametys.plugins.repository.metadata.jcr.JCRCompositeMetadata;
048import org.ametys.plugins.repository.provider.AbstractRepository;
049import org.ametys.web.repository.content.jcr.DefaultWebContent;
050
051/**
052 * Generate the latest comments.
053 */
054public class CommentsGenerator extends ServiceableGenerator
055{
056    
057    /** RSS max number of comments. */
058    public static final int RSS_MAX_COMMENTS = 20;
059    
060    /** The ametys object resolver. */
061    protected AmetysObjectResolver _resolver;
062    
063    /** The repository. */
064    protected Repository _repository;
065    
066    @Override
067    public void service(ServiceManager serviceManager) throws ServiceException
068    {
069        super.service(serviceManager);
070        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
071        _repository = (Repository) serviceManager.lookup(AbstractRepository.ROLE);
072    }
073    
074    @Override
075    public void generate() throws IOException, SAXException, ProcessingException
076    {
077        Request request = ObjectModelHelper.getRequest(objectModel);
078        
079        String siteName = parameters.getParameter("siteName", (String) request.getAttribute("site"));
080        
081        Map<Comment, Content> comments = getComments(siteName, RSS_MAX_COMMENTS);
082        
083        AttributesImpl attrs = new AttributesImpl();
084        attrs.addCDATAAttribute("site", siteName);
085        attrs.addCDATAAttribute("now", ISODateTimeFormat.dateTime().print(new DateTime()));
086        
087        contentHandler.startDocument();
088        XMLUtils.startElement(contentHandler, "comments", attrs);
089        
090        for (Comment comment : comments.keySet())
091        {
092            Content content = comments.get(comment);
093            
094            AttributesImpl cmtAttrs = new AttributesImpl();
095            
096            cmtAttrs.addCDATAAttribute("id", comment.getId());
097            cmtAttrs.addCDATAAttribute("date", ISODateTimeFormat.dateTime().print(new DateTime(comment.getCreationDate())));
098            cmtAttrs.addCDATAAttribute("sortDate", Long.toString(comment.getCreationDate().getTime()));
099            cmtAttrs.addCDATAAttribute("authorName", comment.getAuthorName());
100            cmtAttrs.addCDATAAttribute("contentId", content.getId());
101            cmtAttrs.addCDATAAttribute("contentName", content.getName());
102            cmtAttrs.addCDATAAttribute("contentTitle", content.getTitle());
103            
104            XMLUtils.startElement(contentHandler, "comment", cmtAttrs);
105            XMLUtils.valueOf(contentHandler, comment.getContent());
106            XMLUtils.endElement(contentHandler, "comment");
107        }
108        
109        XMLUtils.endElement(contentHandler, "comments");
110        contentHandler.endDocument();
111    }
112    
113    /**
114     * Get a site's latest comments.
115     * @param siteName the site name.
116     * @param max the maximum number of comments.
117     * @return the comments.
118     */
119    @SuppressWarnings("deprecation")
120    protected Map<Comment, Content> getComments(String siteName, int max)
121    {
122        Map<Comment, Content> comments = new HashMap<>();
123        
124        // element(*, ametys:content)[(@ametys:site = 'siteName')]/ametys-internal:unversioned/@ametys:comments/element(*, ametys:compositeMetadata)
125        String jcrQuery = "//element(*, ametys:content)[@" + RepositoryConstants.NAMESPACE_PREFIX + ":" + DefaultWebContent.METADATA_SITE + " = '" + siteName + "']/"
126            + RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":unversioned/"
127            + RepositoryConstants.NAMESPACE_PREFIX + ":" + Comment.METADATA_COMMENTS
128            + "/element(*, ametys:compositeMetadata)[@ametys:validated = true()]"
129            + " order by @ametys:creation descending";
130        
131        Session session = null;
132        try
133        {
134            session = _repository.login();
135            
136            Query query = session.getWorkspace().getQueryManager().createQuery(jcrQuery, Query.XPATH);
137            
138            NodeIterator nodes = query.execute().getNodes();
139            int processed = 0;
140            while (nodes.hasNext() && processed < max)
141            {
142                Node commentNode = nodes.nextNode();
143                
144                Node unversionedNode = commentNode.getParent().getParent();
145                Node contentNode = unversionedNode.getParent();
146                
147                String nodeName = commentNode.getName();
148                String commentId = nodeName.substring(RepositoryConstants.NAMESPACE_PREFIX.length() + 1);
149                ModifiableCompositeMetadata unversionedMeta = new JCRCompositeMetadata(unversionedNode, _resolver);
150                
151                Comment comment = new Comment(unversionedMeta, commentId);
152                
153                Content content = _resolver.resolve(contentNode, false);
154                
155                comments.put(comment, content);
156                
157                processed++;
158            }
159        }
160        catch (RepositoryException ex)
161        {
162            if (session != null)
163            {
164                session.logout();
165            }
166
167            throw new AmetysRepositoryException("An error occurred executing the JCR query : " + jcrQuery, ex);
168        }
169        
170        return comments;
171//        return commentedContents;
172    }
173
174}