001/* 002 * Copyright 2010 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 */ 016 017package org.ametys.web.synchronization; 018 019import java.util.Map; 020 021import javax.jcr.ItemNotFoundException; 022import javax.jcr.Node; 023import javax.jcr.PathNotFoundException; 024import javax.jcr.RepositoryException; 025import javax.jcr.Session; 026 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.commons.collections.PredicateUtils; 030 031import org.ametys.cms.ObservationConstants; 032import org.ametys.cms.repository.Content; 033import org.ametys.cms.repository.comment.Comment; 034import org.ametys.core.observation.Event; 035import org.ametys.plugins.repository.AmetysObjectResolver; 036import org.ametys.plugins.repository.RepositoryConstants; 037import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData; 038import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData; 039import org.ametys.plugins.repository.jcr.JCRAmetysObject; 040 041/** 042 * When a comment (validated) is modifier, synchronize it 043 */ 044public class SynchronizeContentCommentedObserver extends AbstractSynchronizeObserver 045{ 046 private static final String COMMENTS_DATA_PREFIX = RepositoryConstants.NAMESPACE_PREFIX + ":"; 047 048 /** Ametys object resolver. */ 049 protected AmetysObjectResolver _ametysObjectResolver; 050 051 @Override 052 public void service(ServiceManager manager) throws ServiceException 053 { 054 super.service(manager); 055 _ametysObjectResolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 056 } 057 058 @Override 059 public boolean supports(Event event) 060 { 061 return event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_VALIDATED) 062 || event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_UNVALIDATED) 063 || event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_DELETED) 064 || event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_MODIFYING) 065 || event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_REACTION_CHANGED); 066 } 067 068 @Override 069 protected void _internalObserve(Event event, Session liveSession) throws RepositoryException 070 { 071 if (event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_DELETED) || event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_UNVALIDATED)) 072 { 073 _synchronizeDeletedContentComment(event, liveSession); 074 } 075 else 076 { 077 _synchronizeContentComment(event, liveSession); 078 } 079 080 if (liveSession.hasPendingChanges()) 081 { 082 liveSession.save(); 083 } 084 } 085 086 /** 087 * Synchronize deleted content comment 088 * @param event the event 089 * @param liveSession the live session 090 * @throws RepositoryException if an error occurred 091 */ 092 protected void _synchronizeDeletedContentComment(Event event, Session liveSession) throws RepositoryException 093 { 094 try 095 { 096 Map<String, Object> arguments = event.getArguments(); 097 Content content = (Content) arguments.get(ObservationConstants.ARGS_CONTENT); 098 Comment comment = (Comment) arguments.get(ObservationConstants.ARGS_COMMENT); 099 100 String commentId = comment != null ? comment.getId() : (String) arguments.get(ObservationConstants.ARGS_COMMENT_ID); 101 102 Node node = ((JCRAmetysObject) content).getNode(); 103 104 // let's check that content is in live 105 Node liveContentNode = liveSession.getNodeByIdentifier(node.getIdentifier()); 106 Node unversionnedMetadata = liveContentNode.getNode("ametys-internal:unversioned"); 107 Node commentNode = _getCommentNode(unversionnedMetadata, commentId); 108 109 commentNode.remove(); 110 } 111 catch (PathNotFoundException e) 112 { 113 // comment does not exist in the live, do nothing 114 } 115 } 116 117 /** 118 * Synchronize content comment 119 * @param event the event 120 * @param liveSession the live session 121 * @throws RepositoryException if an error occurred 122 */ 123 protected void _synchronizeContentComment(Event event, Session liveSession) throws RepositoryException 124 { 125 Map<String, Object> arguments = event.getArguments(); 126 Content content = (Content) arguments.get(ObservationConstants.ARGS_CONTENT); 127 Comment comment = (Comment) arguments.get(ObservationConstants.ARGS_COMMENT); 128 129 ModifiableRepositoryData repositoryData = comment.getRepositoryData(); 130 131 if (!(content instanceof JCRAmetysObject) || !(repositoryData instanceof JCRRepositoryData)) 132 { 133 return; 134 } 135 136 Node node = ((JCRAmetysObject) content).getNode(); 137 Node initialCommentNode = ((JCRRepositoryData) repositoryData).getNode(); 138 139 try 140 { 141 // let's check that content is in live 142 Node liveContentNode = liveSession.getNodeByIdentifier(node.getIdentifier()); 143 144 try 145 { 146 Node unversionedMetadata = liveContentNode.getNode("ametys-internal:unversioned"); 147 String commentId = comment.getId(); 148 Node commentNode = _getCommentNode(unversionedMetadata, commentId); 149 Node parent = commentNode.getParent(); 150 commentNode.remove(); 151 152 Node clonedNode = _synchronizeComponent.addNodeWithUUID(initialCommentNode, parent, initialCommentNode.getName()); 153 _synchronizeComponent.cloneNodeAndPreserveUUID(initialCommentNode, clonedNode, PredicateUtils.truePredicate(), PredicateUtils.truePredicate()); 154 } 155 catch (PathNotFoundException e) 156 { 157 // comment was not already existing 158 Node clonedParentNode = _synchronizeComponent.cloneAncestorsAndPreserveUUID(initialCommentNode, liveSession); 159 Node clonedNode = _synchronizeComponent.addNodeWithUUID(initialCommentNode, clonedParentNode, initialCommentNode.getName()); 160 _synchronizeComponent.cloneNodeAndPreserveUUID(initialCommentNode, clonedNode, PredicateUtils.truePredicate(), PredicateUtils.truePredicate()); 161 } 162 } 163 catch (ItemNotFoundException e) 164 { 165 // content does not exist in the live workspace 166 } 167 } 168 169 /** 170 * Get the node of the comment id 171 * @param unversionedMetadata the unversioned metadata 172 * @param commentId the comment id 173 * @return the node of the comment id 174 * @throws PathNotFoundException if an error occurred 175 * @throws RepositoryException if an error occurred 176 */ 177 protected Node _getCommentNode(Node unversionedMetadata, String commentId) throws PathNotFoundException, RepositoryException 178 { 179 Node commentsNode = unversionedMetadata.getNode(COMMENTS_DATA_PREFIX + Comment.METADATA_COMMENTS); 180 181 String[] commentIdAsTab = commentId.split(Comment.ID_SEPARATOR); 182 int i = 0; 183 int lastIndex = commentIdAsTab.length - 1; 184 while (i < lastIndex) 185 { 186 Node commentNode = commentsNode.getNode(COMMENTS_DATA_PREFIX + commentIdAsTab[i]); 187 commentsNode = commentNode.getNode(COMMENTS_DATA_PREFIX + Comment.METADATA_COMMENTS); 188 i++; 189 } 190 191 return commentsNode.getNode(COMMENTS_DATA_PREFIX + commentIdAsTab[lastIndex]); 192 } 193}