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