001/*
002 * (C) Copyright 2006-2009 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.filemanager.core.listener;
021
022import java.io.Serializable;
023import java.security.Principal;
024import java.util.HashMap;
025import java.util.Iterator;
026import java.util.List;
027import java.util.Map;
028
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031import org.nuxeo.ecm.core.api.Blob;
032import org.nuxeo.ecm.core.api.CoreSession;
033import org.nuxeo.ecm.core.api.DocumentLocation;
034import org.nuxeo.ecm.core.api.DocumentModel;
035import org.nuxeo.ecm.core.api.event.DocumentEventCategories;
036import org.nuxeo.ecm.core.api.model.PropertyNotFoundException;
037import org.nuxeo.ecm.core.event.Event;
038import org.nuxeo.ecm.core.event.EventProducer;
039import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
040import org.nuxeo.ecm.platform.filemanager.api.FileManager;
041import org.nuxeo.runtime.api.Framework;
042
043public abstract class AbstractUnicityChecker {
044
045    private static final Log log = LogFactory.getLog(AbstractUnicityChecker.class);
046
047    protected FileManager fileManager;
048
049    protected static Boolean unicityCheckEnabled;
050
051    protected static final String DUPLICATED_FILE = "duplicatedFile";
052
053    protected void doUnicityCheck(DocumentModel doc2Check, CoreSession session, Event event) {
054
055        List<String> xpathFields = getFileManagerService().getFields();
056
057        if (xpathFields == null || xpathFields.isEmpty()) {
058            unicityCheckEnabled = false;
059            log.info("Unicity check has been automatically disabled");
060            return;
061        }
062
063        for (String field : xpathFields) {
064            Blob blob;
065            try {
066                blob = (Blob) doc2Check.getPropertyValue(field);
067            } catch (PropertyNotFoundException pnfe) {
068                continue;
069            }
070            if (blob == null) {
071                log.debug("No blob retrieved");
072                continue;
073            }
074
075            String digest = blob.getDigest();
076            if (digest == null) {
077                log.debug("Blob has no digest, can not check for unicity");
078                continue;
079            }
080
081            List<DocumentLocation> existingDocuments = null;
082            existingDocuments = fileManager.findExistingDocumentWithFile(session, doc2Check.getPathAsString(), digest,
083                    session.getPrincipal());
084
085            if (!existingDocuments.isEmpty()) {
086                Iterator<DocumentLocation> existingDocumentsIterator = existingDocuments.iterator();
087                while (existingDocumentsIterator.hasNext()) {
088                    if (existingDocumentsIterator.next().getDocRef() == doc2Check.getRef()) {
089                        existingDocumentsIterator.remove();
090                    }
091                }
092                log.debug("Existing Documents[" + existingDocuments.size() + "]");
093
094                onDuplicatedDoc(session, session.getPrincipal(), doc2Check, existingDocuments, event);
095            }
096        }
097    }
098
099    protected abstract void onDuplicatedDoc(CoreSession session, Principal principal, DocumentModel newDoc,
100            List<DocumentLocation> existingDocs, Event event);
101
102    protected void raiseDuplicatedFileEvent(CoreSession session, Principal principal, DocumentModel newDoc,
103            List<DocumentLocation> existingDocs) {
104
105        DocumentEventContext ctx = new DocumentEventContext(session, principal, newDoc);
106
107        Map<String, Serializable> props = new HashMap<String, Serializable>();
108
109        props.put("category", DocumentEventCategories.EVENT_CLIENT_NOTIF_CATEGORY);
110        props.put("duplicatedDocLocation", (Serializable) existingDocs);
111
112        Event event = ctx.newEvent(DUPLICATED_FILE);
113        EventProducer producer = Framework.getService(EventProducer.class);
114        producer.fireEvent(event);
115    }
116
117    protected boolean isUnicityCheckEnabled() {
118        if (unicityCheckEnabled == null) {
119            unicityCheckEnabled = getFileManagerService().isUnicityEnabled();
120        }
121        return unicityCheckEnabled;
122    }
123
124    private FileManager getFileManagerService() {
125        if (fileManager == null) {
126            fileManager = Framework.getRuntime().getService(FileManager.class);
127        }
128        return fileManager;
129    }
130
131}