001/* 002 * Copyright 2020 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.workspaces.tasks.jcr; 017 018import java.time.LocalDate; 019import java.time.ZonedDateTime; 020import java.util.Arrays; 021import java.util.List; 022import java.util.Set; 023import java.util.stream.Collectors; 024 025import javax.jcr.Node; 026import javax.jcr.RepositoryException; 027 028import org.ametys.cms.data.Binary; 029import org.ametys.cms.data.holder.ModifiableIndexableDataHolder; 030import org.ametys.cms.data.holder.impl.DefaultModifiableModelAwareDataHolder; 031import org.ametys.cms.repository.comment.Comment; 032import org.ametys.core.user.UserIdentity; 033import org.ametys.plugins.repository.AmetysRepositoryException; 034import org.ametys.plugins.repository.data.holder.ModifiableModelLessDataHolder; 035import org.ametys.plugins.repository.data.holder.group.ModifiableModelAwareRepeater; 036import org.ametys.plugins.repository.data.holder.group.ModifiableModelAwareRepeaterEntry; 037import org.ametys.plugins.repository.data.holder.impl.DefaultModifiableModelLessDataHolder; 038import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData; 039import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData; 040import org.ametys.plugins.repository.jcr.DefaultAmetysObject; 041import org.ametys.plugins.repository.tag.TaggableAmetysObjectHelper; 042import org.ametys.plugins.workspaces.tasks.Task; 043 044/** 045 * JCR implementation of a task 046 */ 047public class JCRTask extends DefaultAmetysObject<JCRTaskFactory> implements Task 048{ 049 /** Attribute Taskid */ 050 public static final String ATTRIBUTE_TASK_ID = "id"; 051 /** Attribute Taskid */ 052 public static final String ATTRIBUTE_TASKSLISTID = "tasksListId"; 053 /** Attribute Taskid */ 054 public static final String ATTRIBUTE_TASKSLISTPOSITION = "tasksListPosition"; 055 /** Attribute Label */ 056 public static final String ATTRIBUTE_LABEL = "label"; 057 /** Attribute Description */ 058 public static final String ATTRIBUTE_DESCRIPTION = "description"; 059 /** Attribute Startdate */ 060 public static final String ATTRIBUTE_STARTDATE = "startDate"; 061 /** Attribute DueDate */ 062 public static final String ATTRIBUTE_DUEDATE = "dueDate"; 063 /** Attribute IsClosed */ 064 public static final String ATTRIBUTE_ISCLOSED = "isClosed"; 065 /** Attribute CloseDate */ 066 public static final String ATTRIBUTE_CLOSEDATE = "closeDate"; 067 /** Attribute CloseAuthor */ 068 public static final String ATTRIBUTE_CLOSEAUTHOR = "closeAuthor"; 069 /** Attribute Author */ 070 public static final String ATTRIBUTE_AUTHOR = "author"; 071 /** Attribute Assignments */ 072 public static final String ATTRIBUTE_ASSIGNMENTS = "assignments"; 073 /** Attribute Creationdate */ 074 public static final String ATTRIBUTE_CREATIONDATE = "creationDate"; 075 /** Attribute Lastmodified */ 076 public static final String ATTRIBUTE_LASTMODIFIED = "lastModified"; 077 /** Attribute Attachments */ 078 public static final String ATTRIBUTE_ATTACHMENTS = "attachments"; 079 /** Attribute CheckList */ 080 public static final String ATTRIBUTE_CHECKLIST = "checkList"; 081 /** Attribute Label for checkList */ 082 public static final String ATTRIBUTE_CHECKLIST_LABEL = "label"; 083 /** Attribute IsChecked for checkList */ 084 public static final String ATTRIBUTE_CHECKLIST_ISCHECKED = "isChecked"; 085 086 /** 087 * Default constructor for the JCRTask 088 * @param node The task node 089 * @param parentPath The parent path 090 * @param factory The factory 091 */ 092 public JCRTask(Node node, String parentPath, JCRTaskFactory factory) 093 { 094 super(node, parentPath, factory); 095 } 096 097 public String getTaskListId() 098 { 099 return getValue(ATTRIBUTE_TASKSLISTID); 100 } 101 102 public void setTasksListId(String taskListId) 103 { 104 setValue(ATTRIBUTE_TASKSLISTID, taskListId); 105 } 106 107 public Long getPosition() 108 { 109 return getValue(ATTRIBUTE_TASKSLISTPOSITION); 110 } 111 112 public void setPosition(Long position) 113 { 114 setValue(ATTRIBUTE_TASKSLISTPOSITION, position); 115 } 116 117 public String getLabel() 118 { 119 return getValue(ATTRIBUTE_LABEL); 120 } 121 122 public void setLabel(String label) 123 { 124 setValue(ATTRIBUTE_LABEL, label); 125 } 126 127 public String getDescription() 128 { 129 return getValue(ATTRIBUTE_DESCRIPTION); 130 } 131 132 public void setDescription(String description) 133 { 134 setValue(ATTRIBUTE_DESCRIPTION, description); 135 } 136 137 public LocalDate getStartDate() 138 { 139 return getValue(ATTRIBUTE_STARTDATE); 140 } 141 142 public void setStartDate(LocalDate startDate) 143 { 144 setValue(ATTRIBUTE_STARTDATE, startDate); 145 } 146 147 public LocalDate getDueDate() 148 { 149 return getValue(ATTRIBUTE_DUEDATE); 150 } 151 152 public void setDueDate(LocalDate dueDate) 153 { 154 setValue(ATTRIBUTE_DUEDATE, dueDate); 155 } 156 157 public boolean isClosed() 158 { 159 return getValue(ATTRIBUTE_ISCLOSED, false, false); 160 } 161 162 public void close(boolean isClosed) 163 { 164 setValue(ATTRIBUTE_ISCLOSED, isClosed); 165 } 166 167 public UserIdentity getCloseAuthor() 168 { 169 return getValue(ATTRIBUTE_CLOSEAUTHOR); 170 } 171 172 public void setCloseAuthor(UserIdentity author) 173 { 174 setValue(ATTRIBUTE_CLOSEAUTHOR, author); 175 } 176 177 public LocalDate getCloseDate() 178 { 179 return getValue(ATTRIBUTE_CLOSEDATE); 180 } 181 182 public void setCloseDate(LocalDate closedDate) 183 { 184 setValue(ATTRIBUTE_CLOSEDATE, closedDate); 185 } 186 187 public UserIdentity getAuthor() 188 { 189 return getValue(ATTRIBUTE_AUTHOR); 190 } 191 192 public void setAuthor(UserIdentity author) 193 { 194 setValue(ATTRIBUTE_AUTHOR, author); 195 } 196 197 public List<UserIdentity> getAssignments() 198 { 199 UserIdentity[] users = getValue(ATTRIBUTE_ASSIGNMENTS, false, new UserIdentity[0]); 200 return Arrays.asList(users); 201 } 202 203 public void setAssignments(List<UserIdentity> assignments) 204 { 205 setValue(ATTRIBUTE_ASSIGNMENTS, assignments.toArray(new UserIdentity[assignments.size()])); 206 } 207 208 public ZonedDateTime getCreationDate() 209 { 210 return getValue(ATTRIBUTE_CREATIONDATE); 211 } 212 213 public void setCreationDate(ZonedDateTime creationDate) 214 { 215 setValue(ATTRIBUTE_CREATIONDATE, creationDate); 216 } 217 218 public ZonedDateTime getLastModified() 219 { 220 return getValue(ATTRIBUTE_LASTMODIFIED); 221 } 222 223 public void setLastModified(ZonedDateTime lastModifiedDate) 224 { 225 setValue(ATTRIBUTE_LASTMODIFIED, lastModifiedDate); 226 } 227 228 public List<Binary> getAttachments() 229 { 230 Binary[] attachements = getValue(ATTRIBUTE_ATTACHMENTS, false, new Binary[0]); 231 return Arrays.asList(attachements); 232 } 233 234 public void setAttachments(List<Binary> attachments) 235 { 236 setValue(ATTRIBUTE_ATTACHMENTS, attachments.toArray(new Binary[attachments.size()])); 237 } 238 239 public void tag(String tag) throws AmetysRepositoryException 240 { 241 TaggableAmetysObjectHelper.tag(this, tag); 242 } 243 244 public void untag(String tag) throws AmetysRepositoryException 245 { 246 TaggableAmetysObjectHelper.untag(this, tag); 247 } 248 249 public Set<String> getTags() throws AmetysRepositoryException 250 { 251 return TaggableAmetysObjectHelper.getTags(this); 252 } 253 254 public List<CheckItem> getCheckList() 255 { 256 ModifiableModelAwareRepeater repeater = getRepeater(ATTRIBUTE_CHECKLIST, true); 257 return repeater.getEntries() 258 .stream() 259 .map(e -> new CheckItem(e.getValue(ATTRIBUTE_CHECKLIST_LABEL), e.getValue(ATTRIBUTE_CHECKLIST_ISCHECKED, false, false))) 260 .collect(Collectors.toList()); 261 } 262 263 public void setCheckListItem(List<CheckItem> checkItems) 264 { 265 ModifiableModelAwareRepeater repeater = getRepeater(ATTRIBUTE_CHECKLIST, true); 266 for (ModifiableModelAwareRepeaterEntry entry : repeater.getEntries()) 267 { 268 repeater.removeEntry(entry.getPosition()); 269 } 270 271 for (CheckItem checkItem : checkItems) 272 { 273 ModifiableModelAwareRepeaterEntry entry = repeater.addEntry(); 274 275 entry.setValue(ATTRIBUTE_CHECKLIST_LABEL, checkItem.getLabel()); 276 entry.setValue(ATTRIBUTE_CHECKLIST_ISCHECKED, checkItem.isChecked()); 277 } 278 } 279 280 private ModifiableModelLessDataHolder _getCommentDataHolder() 281 { 282 try 283 { 284 Node baseNode = getBaseNode(); 285 if (!baseNode.hasNode("ametys:comments")) 286 { 287 baseNode.addNode("ametys:comments", "ametys:compositeMetadata"); 288 } 289 baseNode.getSession().save(); 290 ModifiableRepositoryData repositoryData = new JCRRepositoryData(baseNode.getNode("ametys:comments")); 291 return new DefaultModifiableModelLessDataHolder(_getFactory().getUnversionedDataTypeExtensionPoint(), repositoryData); 292 } 293 catch (RepositoryException e) 294 { 295 throw new AmetysRepositoryException(e); 296 } 297 } 298 299 public Comment createComment() 300 { 301 302 return new Comment(_getCommentDataHolder()); 303 } 304 305 public Comment createComment(String commentId, ZonedDateTime creationDate) 306 { 307 return new Comment(_getCommentDataHolder(), commentId, creationDate); 308 } 309 310 public Comment getComment(String commentId) throws AmetysRepositoryException 311 { 312 return Comment.getComment(_getCommentDataHolder(), commentId); 313 } 314 315 public List<Comment> getComments(boolean includeNotValidatedComments, boolean includeValidatedComments) throws AmetysRepositoryException 316 { 317 return Comment.getComments(_getCommentDataHolder(), includeNotValidatedComments, includeValidatedComments); 318 } 319 320 public ModifiableIndexableDataHolder getDataHolder() 321 { 322 ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode()); 323 return new DefaultModifiableModelAwareDataHolder(repositoryData, _getFactory().getTaskModel()); 324 } 325}