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