001/*
002 *  Copyright 2014 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.explorer.threads.jcr;
017
018import java.util.Date;
019
020import javax.jcr.Node;
021import javax.jcr.RepositoryException;
022
023import org.ametys.core.user.UserIdentity;
024import org.ametys.plugins.explorer.ExplorerNode;
025import org.ametys.plugins.explorer.threads.ModifiableThread;
026import org.ametys.plugins.repository.AmetysObject;
027import org.ametys.plugins.repository.AmetysRepositoryException;
028import org.ametys.plugins.repository.RepositoryConstants;
029import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject;
030import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata;
031import org.ametys.plugins.repository.metadata.UnknownMetadataException;
032
033/**
034 * Default implementation of an {@link Thread}, backed by a JCR node.<br>
035 */
036public class JCRThread extends DefaultTraversableAmetysObject<JCRThreadFactory> implements ModifiableThread
037{
038    /** application id for resources collections. */
039    public static final String APPLICATION_ID = "Ametys.plugins.explorer.applications.Thread";
040
041    private static final String METADATA_TITLE = "label";
042    private static final String METADATA_DESCRIPTION = "description";
043    private static final String METADATA_AUTHOR = "author";
044    private static final String METADATA_CREATIONDATE = "creationDate";
045    
046    /**
047     * Constructor
048     * @param node The jcr node
049     * @param parentPath The parent path
050     * @param factory The factory
051     */
052    public JCRThread(Node node, String parentPath, JCRThreadFactory factory)
053    {
054        super(node, parentPath, factory);
055    }
056    
057    @Override
058    public String getApplicationId()
059    {
060        return APPLICATION_ID;
061    }
062    
063    @Override
064    public String getTitle ()
065    {
066        return getMetadataHolder().getString(METADATA_TITLE);
067    }
068    
069    @Override
070    public void setTitle(String title)
071    {
072        getMetadataHolder().setMetadata(METADATA_TITLE, title);
073    }
074    
075    @Override
076    public String getDescription ()
077    {
078        return getMetadataHolder().getString(METADATA_DESCRIPTION);
079    }
080    
081    @Override
082    public void setDescription (String description)
083    {
084        getMetadataHolder().setMetadata(METADATA_DESCRIPTION, description);
085    }
086    
087    @Override
088    public UserIdentity getAuthor ()
089    {
090        try
091        {
092            Node authorNode = getNode().getNode(RepositoryConstants.NAMESPACE_PREFIX + ":" + METADATA_AUTHOR);
093            return new UserIdentity(authorNode.getProperty("ametys:login").getString(), authorNode.getProperty("ametys:population").getString());
094        }
095        catch (RepositoryException e)
096        {
097            throw new AmetysRepositoryException("Error while getting author property.", e);
098        }
099    }
100    
101    @Override
102    public void setAuthor(UserIdentity author)
103    {
104        try
105        {
106            Node authorNode = null;
107            if (getNode().hasNode(RepositoryConstants.NAMESPACE_PREFIX + ":" + METADATA_AUTHOR))
108            {
109                authorNode = getNode().getNode(RepositoryConstants.NAMESPACE_PREFIX + ":" + METADATA_AUTHOR);
110            }
111            else
112            {
113                authorNode = getNode().addNode(RepositoryConstants.NAMESPACE_PREFIX + ":" + METADATA_AUTHOR, RepositoryConstants.USER_NODETYPE);
114            }
115            
116            authorNode.setProperty("ametys:login", author.getLogin());
117            authorNode.setProperty("ametys:population", author.getPopulationId());
118        }
119        catch (RepositoryException e)
120        {
121            throw new AmetysRepositoryException("Error setting the author property.", e);
122        }
123    }
124    
125    @Override
126    public Date getCreationDate()
127    {
128        return getMetadataHolder().getDate(METADATA_CREATIONDATE);
129    }
130    
131    @Override
132    public void setCreationDate(Date creationDate)
133    {
134        getMetadataHolder().setMetadata(METADATA_CREATIONDATE, creationDate);
135    }
136    
137
138    @Override
139    public String getIconCls()
140    {
141        return "thread";
142    }
143    
144    
145    @Override
146    public String getExplorerPath()
147    {
148        AmetysObject parent = getParent();
149        
150        if (parent instanceof ExplorerNode)
151        {
152            return ((ExplorerNode) parent).getExplorerPath() + "/" + getName();
153        }
154        else
155        {
156            return "";
157        }
158    }
159    
160    @Override
161    public boolean hasChildExplorerNodes() throws AmetysRepositoryException
162    {
163        for (AmetysObject child : getChildren())
164        {
165            if (child instanceof ExplorerNode)
166            {
167                return true;
168            }
169        }
170
171        return false;
172    }
173    
174    @Override
175    public long getUnreadPosts(UserIdentity user)
176    {
177        if (user == null)
178        {
179            return 0;
180        }
181        
182        Date readDate = null;
183        try
184        {
185            readDate = getMetadataHolder().getCompositeMetadata("populations").getCompositeMetadata(user.getPopulationId()).getCompositeMetadata(user.getLogin()).getDate("read-date");
186        }
187        catch (UnknownMetadataException e)
188        {
189            // no read date, consider all posts as unread
190        }
191        
192        long unreadCount = 0;
193        for (AmetysObject child : getChildren())
194        {
195            if (child instanceof JCRPost && (readDate == null || ((JCRPost) child).getCreationDate().after(readDate)))
196            {
197                unreadCount++;
198            }
199        }
200        
201        return unreadCount;
202    }
203    
204    @Override
205    public void markAsRead(UserIdentity user)
206    {
207        ModifiableCompositeMetadata userMetadata = getMetadataHolder().getCompositeMetadata("populations", true).getCompositeMetadata(user.getPopulationId(), true).getCompositeMetadata(user.getLogin(), true);
208        userMetadata.setMetadata("read-date", new Date());
209    }
210}