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}