001/* 002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others. 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 * Contributors: 017 * Alexandre Russel 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.annotations.repository.service; 023 024import java.net.URI; 025import java.util.ArrayList; 026import java.util.List; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.ecm.core.api.DocumentModel; 031import org.nuxeo.ecm.core.api.DocumentRef; 032import org.nuxeo.ecm.core.api.NuxeoPrincipal; 033import org.nuxeo.ecm.core.api.event.DocumentEventTypes; 034import org.nuxeo.ecm.core.api.facet.VersioningDocument; 035import org.nuxeo.ecm.core.event.Event; 036import org.nuxeo.ecm.core.event.EventContext; 037import org.nuxeo.ecm.platform.annotations.api.Annotation; 038import org.nuxeo.ecm.platform.annotations.api.AnnotationsConstants; 039import org.nuxeo.ecm.platform.annotations.api.AnnotationsService; 040import org.nuxeo.ecm.platform.annotations.repository.URNDocumentViewTranslator; 041import org.nuxeo.ecm.platform.relations.api.Graph; 042import org.nuxeo.ecm.platform.relations.api.Resource; 043import org.nuxeo.ecm.platform.relations.api.Statement; 044import org.nuxeo.ecm.platform.relations.api.impl.ResourceImpl; 045import org.nuxeo.ecm.platform.relations.api.impl.StatementImpl; 046import org.nuxeo.runtime.api.Framework; 047 048/** 049 * @author <a href="mailto:[email protected]">Alexandre Russel</a> 050 */ 051public class DocumentVersionnedGraphManager implements GraphManagerEventListener { 052 053 private static final Log log = LogFactory.getLog(DocumentVersionnedGraphManager.class); 054 055 private URNDocumentViewTranslator translator; 056 057 @Override 058 public void manage(Event event) { 059 if (translator == null) { 060 translator = new URNDocumentViewTranslator(); 061 } 062 EventContext context = event.getContext(); 063 NuxeoPrincipal user = context.getPrincipal(); 064 DocumentModel docModel = (DocumentModel) context.getArguments()[0]; 065 String docId = docModel.getId(); 066 String repo = docModel.getRepositoryName(); 067 068 if (DocumentEventTypes.DOCUMENT_CHECKEDIN.equals(event.getName())) { 069 DocumentRef versionRef = (DocumentRef) context.getProperty("checkedInVersionRef"); 070 copyGraphFor(repo, docId, versionRef.toString(), user); 071 } else if (DocumentEventTypes.DOCUMENT_REMOVED.equals(event.getName()) 072 || DocumentEventTypes.VERSION_REMOVED.equals(event.getName())) { 073 removeGraphFor(repo, docId, user); 074 } else if (DocumentEventTypes.DOCUMENT_RESTORED.equals(event.getName())) { 075 String versionUUID = (String) context.getProperty(VersioningDocument.RESTORED_VERSION_UUID_KEY); 076 restoreGraphFor(repo, versionUUID, docId, user); 077 } 078 } 079 080 private void copyGraphFor(String repositoryName, String fromId, String toId, NuxeoPrincipal principal) { 081 copyGraphFor(translator.getNuxeoUrn(repositoryName, fromId), translator.getNuxeoUrn(repositoryName, toId), 082 principal); 083 } 084 085 private static void copyGraphFor(URI current, URI copied, NuxeoPrincipal user) { 086 List<Statement> newStatements = new ArrayList<Statement>(); 087 AnnotationsService service = Framework.getService(AnnotationsService.class); 088 List<Annotation> annotations = service.queryAnnotations(current, user); 089 log.debug("Copying annotations graph from " + current + " to " + copied + " for " + annotations.size() 090 + " annotations."); 091 for (Annotation annotation : annotations) { 092 List<Statement> statements = annotation.getStatements(); 093 for (Statement statement : statements) { 094 if (statement.getPredicate().equals(AnnotationsConstants.a_annotates)) { 095 Resource resource = (Resource) statement.getObject(); 096 if (current.toString().equals(resource.getUri())) { 097 // copy only the statements associated to the current 098 // URI 099 Statement newStatement = new StatementImpl(statement.getSubject(), statement.getPredicate(), 100 new ResourceImpl(copied.toString())); 101 newStatements.add(newStatement); 102 } 103 } 104 } 105 } 106 Graph graph = service.getAnnotationGraph(); 107 graph.add(newStatements); 108 } 109 110 private void removeGraphFor(String repositoryName, String id, NuxeoPrincipal principal) { 111 removeGraphFor(translator.getNuxeoUrn(repositoryName, id), principal); 112 } 113 114 private static void removeGraphFor(URI uri, NuxeoPrincipal user) { 115 log.debug("Removing annotations graph for " + uri); 116 AnnotationsService service = Framework.getService(AnnotationsService.class); 117 List<Annotation> annotations = service.queryAnnotations(uri, user); 118 for (Annotation annotation : annotations) { 119 service.deleteAnnotationFor(uri, annotation, user); 120 } 121 } 122 123 private void restoreGraphFor(String repositoryName, String versionId, String docId, NuxeoPrincipal principal) { 124 log.debug("Restoring annotations graph for docId:" + docId + " and versionId:" + versionId); 125 removeGraphFor(translator.getNuxeoUrn(repositoryName, docId), principal); 126 copyGraphFor(repositoryName, versionId, docId, principal); 127 } 128 129}