001/* 002 * Copyright 2012 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.cms.repository; 017 018import java.time.ZonedDateTime; 019import java.util.Collection; 020import java.util.Date; 021import java.util.List; 022import java.util.Locale; 023import java.util.Map; 024 025import javax.jcr.Node; 026 027import org.ametys.cms.content.references.OutgoingReferences; 028import org.ametys.cms.contenttype.ContentType; 029import org.ametys.cms.repository.comment.Comment; 030import org.ametys.cms.repository.comment.CommentableContent; 031import org.ametys.cms.repository.comment.contributor.ContributorCommentableContent; 032import org.ametys.core.user.UserIdentity; 033import org.ametys.plugins.repository.AmetysRepositoryException; 034import org.ametys.plugins.repository.data.extractor.xml.XMLValuesExtractorAdditionalDataGetter; 035import org.ametys.plugins.repository.data.holder.ModifiableModelLessDataHolder; 036import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData; 037import org.ametys.plugins.repository.jcr.DublinCoreHelper; 038import org.ametys.plugins.repository.lock.LockableAmetysObject; 039import org.ametys.plugins.repository.tag.TaggableAmetysObjectHelper; 040 041/** 042 * Default implementation of a {@link Content}, also versionable, lockable and workflow-aware. 043 * @param <F> the actual type of factory. 044 */ 045public class ModifiableDefaultContent<F extends ModifiableContentFactory> extends DefaultContent<F> implements CommentableContent, ContributorCommentableContent, LockableAmetysObject, ModifiableWorkflowAwareContent/*, AnnotableContent*/ //, CopiableAmetysObject 046{ 047 private boolean _lockAlreadyChecked; 048 049 /** 050 * Creates a JCR-based Content. 051 * @param node the JCR Node backing this Content. 052 * @param parentPath the parent path in the Ametys hierarchy. 053 * @param factory the corresponding {@link ContentFactory}. 054 */ 055 public ModifiableDefaultContent(Node node, String parentPath, F factory) 056 { 057 super(node, parentPath, factory); 058 } 059 060 public void setTitle(String title, Locale locale) throws AmetysRepositoryException 061 { 062 _getFactory()._getModifiableContentHelper().setTitle(this, title, locale); 063 } 064 065 public void setTitle(String title) throws AmetysRepositoryException 066 { 067 _getFactory()._getModifiableContentHelper().setTitle(this, title); 068 } 069 070 public void setCreator(UserIdentity user) throws AmetysRepositoryException 071 { 072 _getFactory()._getModifiableContentHelper().setCreator(this, user); 073 } 074 075 public void setCreationDate(ZonedDateTime creationDate) throws AmetysRepositoryException 076 { 077 _getFactory()._getModifiableContentHelper().setCreationDate(this, creationDate); 078 } 079 080 public void setLastContributor(UserIdentity user) 081 { 082 _getFactory()._getModifiableContentHelper().setLastContributor(this, user); 083 } 084 085 public void setLastModified(ZonedDateTime lastModified) throws AmetysRepositoryException 086 { 087 _getFactory()._getModifiableContentHelper().setLastModified(this, lastModified); 088 } 089 090 public void setFirstValidator(UserIdentity user) throws AmetysRepositoryException 091 { 092 _getFactory()._getModifiableContentHelper().setFirstValidator(this, user); 093 } 094 095 @Override 096 public void setFirstValidationDate(ZonedDateTime validationDate) throws AmetysRepositoryException 097 { 098 _getFactory()._getModifiableContentHelper().setFirstValidationDate(this, validationDate); 099 } 100 101 public void setLastValidator(UserIdentity user) throws AmetysRepositoryException 102 { 103 _getFactory()._getModifiableContentHelper().setLastValidator(this, user); 104 } 105 106 @Override 107 public void setLastValidationDate(ZonedDateTime validationDate) throws AmetysRepositoryException 108 { 109 _getFactory()._getModifiableContentHelper().setLastValidationDate(this, validationDate); 110 } 111 112 public void setLastMajorValidator(UserIdentity user) throws AmetysRepositoryException 113 { 114 _getFactory()._getModifiableContentHelper().setLastMajorValidator(this, user); 115 } 116 117 @Override 118 public void setLastMajorValidationDate(ZonedDateTime validationDate) throws AmetysRepositoryException 119 { 120 _getFactory()._getModifiableContentHelper().setLastMajorValidationDate(this, validationDate); 121 } 122 123 @Override 124 public void setOutgoingReferences(Map<String, OutgoingReferences> references) throws AmetysRepositoryException 125 { 126 _getFactory()._getModifiableContentHelper().setOutgoingReferences(this, references); 127 _outgoingReferences = references; 128 } 129 130 // ------------------- Tags management -------------------- // 131 @Override 132 public void tag(String tag) throws AmetysRepositoryException 133 { 134 TaggableAmetysObjectHelper.tag(this, tag); 135 } 136 137 @Override 138 public void untag(String tag) throws AmetysRepositoryException 139 { 140 TaggableAmetysObjectHelper.untag(this, tag); 141 } 142 143 // ------------------- Workflow management -------------------- // 144 @Override 145 public long getWorkflowId() throws AmetysRepositoryException 146 { 147 return WorkflowAwareContentHelper.getWorkflowId(this); 148 } 149 150 @Override 151 public void setWorkflowId(long workflowId) throws AmetysRepositoryException 152 { 153 WorkflowAwareContentHelper.setWorkflowId(this, workflowId); 154 } 155 156 @Override 157 public long getCurrentStepId() throws AmetysRepositoryException 158 { 159 return WorkflowAwareContentHelper.getCurrentStepId(this); 160 } 161 162 @Override 163 public void setCurrentStepId (long stepId) throws AmetysRepositoryException 164 { 165 WorkflowAwareContentHelper.setCurrentStepId(this, stepId); 166 } 167 168 @Override 169 public ZonedDateTime getProposalDate() throws AmetysRepositoryException 170 { 171 return WorkflowAwareContentHelper.getProposalDate(this); 172 } 173 174 @Override 175 public void setProposalDate(ZonedDateTime proposalDate) throws AmetysRepositoryException 176 { 177 WorkflowAwareContentHelper.setProposalDate(this, proposalDate); 178 } 179 180 // --------------------- Lock management ----------------------- // 181 @Override 182 public void lock() throws AmetysRepositoryException 183 { 184 _getFactory().getLockComponent().lock(this); 185 186 // the lock component immediately detached the lock token, so we have to check it again at next usage 187 _lockAlreadyChecked = false; 188 } 189 190 @Override 191 public void unlock() throws AmetysRepositoryException 192 { 193 _getFactory().getLockComponent().unlock(this); 194 195 // the lock component removed the lock token on unlock 196 _lockAlreadyChecked = true; 197 } 198 199 @Override 200 public void setLockInfoOnCurrentContext() throws AmetysRepositoryException 201 { 202 if (!_lockAlreadyChecked) 203 { 204 _getFactory().getLockComponent().setLockTokenOnCurrentSession(this); 205 _lockAlreadyChecked = true; 206 } 207 } 208 209 @Override 210 public boolean isLocked() throws AmetysRepositoryException 211 { 212 return _getFactory().getLockComponent().isLocked(this); 213 } 214 215 @Override 216 public UserIdentity getLockOwner() throws AmetysRepositoryException 217 { 218 return _getFactory().getLockComponent().getLockOwner(this); 219 } 220 221 // -------------------------- DUBLIN CORE ---------------------------- // 222 @Override 223 public void setDCTitle(String title) throws AmetysRepositoryException 224 { 225 DublinCoreHelper.setDCTitle(this, title); 226 } 227 228 @Override 229 public void setDCCreator(String creator) throws AmetysRepositoryException 230 { 231 DublinCoreHelper.setDCCreator(this, creator); 232 } 233 234 @Override 235 public void setDCSubject(String[] subject) throws AmetysRepositoryException 236 { 237 DublinCoreHelper.setDCSubject(this, subject); 238 } 239 240 @Override 241 public void setDCDescription(String description) throws AmetysRepositoryException 242 { 243 DublinCoreHelper.setDCDescription(this, description); 244 } 245 246 @Override 247 public void setDCPublisher(String publisher) throws AmetysRepositoryException 248 { 249 DublinCoreHelper.setDCPublisher(this, publisher); 250 } 251 252 @Override 253 public void setDCContributor(String contributor) throws AmetysRepositoryException 254 { 255 DublinCoreHelper.setDCContributor(this, contributor); 256 } 257 258 @Override 259 public void setDCDate(Date date) throws AmetysRepositoryException 260 { 261 DublinCoreHelper.setDCDate(this, date); 262 } 263 264 @Override 265 public void setDCType(String type) throws AmetysRepositoryException 266 { 267 DublinCoreHelper.setDCType(this, type); 268 } 269 270 @Override 271 public void setDCFormat(String format) throws AmetysRepositoryException 272 { 273 DublinCoreHelper.setDCFormat(this, format); 274 } 275 276 @Override 277 public void setDCIdentifier(String identifier) throws AmetysRepositoryException 278 { 279 DublinCoreHelper.setDCIdentifier(this, identifier); 280 } 281 282 @Override 283 public void setDCSource(String source) throws AmetysRepositoryException 284 { 285 DublinCoreHelper.setDCSource(this, source); 286 } 287 288 @Override 289 public void setDCLanguage(String language) throws AmetysRepositoryException 290 { 291 DublinCoreHelper.setDCLanguage(this, language); 292 } 293 294 @Override 295 public void setDCRelation(String relation) throws AmetysRepositoryException 296 { 297 DublinCoreHelper.setDCRelation(this, relation); 298 } 299 300 @Override 301 public void setDCCoverage(String coverage) throws AmetysRepositoryException 302 { 303 DublinCoreHelper.setDCCoverage(this, coverage); 304 } 305 306 @Override 307 public void setDCRights(String rights) throws AmetysRepositoryException 308 { 309 DublinCoreHelper.setDCRights(this, rights); 310 } 311 312 // ---------------------------- COMMENTS ------------------------------ // 313 @Override 314 public Comment createComment() 315 { 316 return new Comment(_getFactory()._getModifiableContentHelper().getCommentsDataHolder(this, true)); 317 } 318 319 public Comment createComment(String commentId, ZonedDateTime creationDate) 320 { 321 return new Comment(_getFactory()._getModifiableContentHelper().getCommentsDataHolder(this, true), commentId, creationDate); 322 } 323 324 @Override 325 public Comment getComment(String commentId) throws AmetysRepositoryException 326 { 327 ModifiableModelLessDataHolder commentsDataHolder = _getFactory()._getModifiableContentHelper().getCommentsDataHolder(this, false); 328 return commentsDataHolder != null ? Comment.getComment(commentsDataHolder, commentId) : null; 329 } 330 331 @Override 332 public List<Comment> getComments(boolean includeNotValidatedComments, boolean includeValidatedComments) throws AmetysRepositoryException 333 { 334 ModifiableModelLessDataHolder commentsDataHolder = _getFactory()._getModifiableContentHelper().getCommentsDataHolder(this, false); 335 return commentsDataHolder != null ? Comment.getComments(commentsDataHolder, includeNotValidatedComments, includeValidatedComments) : List.of(); 336 } 337 338 // ---------------------------- CONTRIBUTOR COMMENTS ------------------------------ // 339 @Override 340 public Comment createContributorComment() 341 { 342 return new Comment(_getFactory()._getModifiableContentHelper().getContributorCommentsDataHolder(this, true)); 343 } 344 345 public Comment createContributorComment(String commentId, ZonedDateTime creationDate) 346 { 347 return new Comment(_getFactory()._getModifiableContentHelper().getContributorCommentsDataHolder(this, true), commentId, creationDate); 348 } 349 350 @Override 351 public Comment getContributorComment(String commentId) throws AmetysRepositoryException 352 { 353 ModifiableModelLessDataHolder commentsDataHolder = _getFactory()._getModifiableContentHelper().getContributorCommentsDataHolder(this, false); 354 return commentsDataHolder != null ? Comment.getComment(commentsDataHolder, commentId) : null; 355 } 356 357 @Override 358 public List<Comment> getContributorComments() throws AmetysRepositoryException 359 { 360 ModifiableModelLessDataHolder commentsDataHolder = _getFactory()._getModifiableContentHelper().getContributorCommentsDataHolder(this, false); 361 return commentsDataHolder != null ? Comment.getComments(commentsDataHolder, false, true) : List.of(); 362 } 363 364 // ---------------------------- DATA HOLDER --------------------------- // 365 @Override 366 public ModifiableContentDataHolder getDataHolder() 367 { 368 // It is necessary to instantiate the repository data because of locks: 369 // when the content is locked, the lock token is released to be taken by anyone 370 // in repository data there is a lock checked boolean that need to be reset in order to take the token 371 // this boolean is only reset at instantiation 372 Collection<ContentType> contentTypes = _getFactory().getContentHelper().getContentTypes(this); 373 return new ModifiableContentDataHolder(this, _getFactory().getContentDataHelper(), new JCRRepositoryData(getNode()), contentTypes); 374 } 375 376 public void fillContent(org.w3c.dom.Node node, XMLValuesExtractorAdditionalDataGetter additionalDataGetter) throws Exception 377 { 378 _getFactory().getContentExtractor().fillContent(this, node, additionalDataGetter); 379 } 380}