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