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}