001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Thierry Delprat 011 */ 012package org.nuxeo.ecm.core.versioning; 013 014import java.util.Collection; 015import java.util.List; 016 017import org.apache.commons.logging.Log; 018import org.apache.commons.logging.LogFactory; 019import org.nuxeo.ecm.core.CoreService; 020import org.nuxeo.ecm.core.api.CoreSession; 021import org.nuxeo.ecm.core.api.DocumentModel; 022import org.nuxeo.ecm.core.api.IdRef; 023import org.nuxeo.ecm.core.event.Event; 024import org.nuxeo.ecm.core.event.EventBundle; 025import org.nuxeo.ecm.core.event.EventContext; 026import org.nuxeo.ecm.core.event.PostCommitEventListener; 027import org.nuxeo.ecm.core.event.impl.ShallowDocumentModel; 028import org.nuxeo.runtime.api.Framework; 029 030/** 031 * Async listener that is in charge to delete the versions. Before running the delete operation on the versions passed 032 * as argument of the event, it will call the registred {@link OrphanVersionRemovalFilter} to allow them to mark some of 033 * the orphan versions to be kept. 034 * 035 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a> 036 */ 037public class OrphanVersionRemoverListener implements PostCommitEventListener { 038 039 protected static final Log log = LogFactory.getLog(OrphanVersionRemoverListener.class); 040 041 @Override 042 public void handleEvent(EventBundle events) { 043 if (events.containsEventName(DefaultVersionRemovalPolicy.ORPHAN_VERSION_REMOVE)) { 044 for (Event event : events) { 045 if (!event.getName().equals(DefaultVersionRemovalPolicy.ORPHAN_VERSION_REMOVE)) { 046 continue; 047 } 048 EventContext ctx = event.getContext(); 049 CoreSession session = ctx.getCoreSession(); 050 Object[] args = ctx.getArguments(); 051 if (args.length == 2) { 052 DocumentModel doc = (DocumentModel) args[0]; 053 ShallowDocumentModel deletedLiveDoc = null; 054 if (doc instanceof ShallowDocumentModel) { 055 deletedLiveDoc = (ShallowDocumentModel) doc; 056 } else { 057 // cluster node has still no fetched invalidation 058 // so ShallowDocumentModel has been reconnected via the cache ! 059 deletedLiveDoc = new ShallowDocumentModel(doc); 060 } 061 List<String> versionUUIDs = (List<String>) args[1]; 062 removeIfPossible(session, deletedLiveDoc, versionUUIDs); 063 } 064 } 065 } 066 } 067 068 protected Collection<OrphanVersionRemovalFilter> getFilters() { 069 return Framework.getLocalService(CoreService.class).getOrphanVersionRemovalFilters(); 070 } 071 072 protected void removeIfPossible(CoreSession session, ShallowDocumentModel deletedLiveDoc, List<String> versionUUIDs) 073 { 074 session.save(); // receive invalidations if no tx 075 076 for (OrphanVersionRemovalFilter filter : getFilters()) { 077 versionUUIDs = filter.getRemovableVersionIds(session, deletedLiveDoc, versionUUIDs); 078 if (versionUUIDs.size() == 0) { 079 break; 080 } 081 } 082 083 for (String id : versionUUIDs) { 084 IdRef idRef = new IdRef(id); 085 if (session.exists(idRef)) { 086 log.debug("Removing version: " + id); 087 session.removeDocument(idRef); 088 } 089 } 090 091 session.save(); // send invalidations if no tx 092 } 093 094}