001/*
002 * (C) Copyright 2006-2012 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 *     Thomas Roger <troger@nuxeo.com>
018 */
019
020package org.nuxeo.ecm.quota;
021
022import static org.nuxeo.ecm.core.api.LifeCycleConstants.DELETE_TRANSITION;
023import static org.nuxeo.ecm.core.api.LifeCycleConstants.TRANSITION_EVENT;
024import static org.nuxeo.ecm.core.api.LifeCycleConstants.TRANSTION_EVENT_OPTION_TRANSITION;
025import static org.nuxeo.ecm.core.api.LifeCycleConstants.UNDELETE_TRANSITION;
026import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.ABOUT_TO_REMOVE;
027import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.ABOUT_TO_REMOVE_VERSION;
028import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.BEFORE_DOC_RESTORE;
029import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.BEFORE_DOC_UPDATE;
030import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_CHECKEDIN;
031import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_CHECKEDOUT;
032import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_CREATED;
033import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_CREATED_BY_COPY;
034import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_MOVED;
035import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_RESTORED;
036import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_UPDATED;
037import static org.nuxeo.ecm.core.trash.TrashService.DOCUMENT_TRASHED;
038import static org.nuxeo.ecm.core.trash.TrashService.DOCUMENT_UNTRASHED;
039
040import java.util.ArrayList;
041import java.util.List;
042
043import org.apache.commons.logging.Log;
044import org.apache.commons.logging.LogFactory;
045import org.nuxeo.ecm.core.api.CoreSession;
046import org.nuxeo.ecm.core.api.DocumentModel;
047import org.nuxeo.ecm.core.api.DocumentRef;
048import org.nuxeo.ecm.core.api.event.CoreEventConstants;
049import org.nuxeo.ecm.core.event.Event;
050import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
051import org.nuxeo.ecm.quota.size.QuotaExceededException;
052
053/**
054 * Abstract class implementing {@code QuotaStatsUpdater} to handle common cases.
055 * <p>
056 * Provides abstract methods to override for common events.
057 *
058 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
059 * @since 5.5
060 */
061public abstract class AbstractQuotaStatsUpdater implements QuotaStatsUpdater {
062
063    protected String name;
064
065    protected String label;
066
067    protected String descriptionLabel;
068
069    protected static Log log = LogFactory.getLog(AbstractQuotaStatsUpdater.class);
070
071    @Override
072    public void setName(String name) {
073        this.name = name;
074    }
075
076    @Override
077    public String getName() {
078        return name;
079    }
080
081    @Override
082    public void setLabel(String label) {
083        this.label = label;
084    }
085
086    @Override
087    public String getLabel() {
088        return label;
089    }
090
091    @Override
092    public void setDescriptionLabel(String descriptionLabel) {
093        this.descriptionLabel = descriptionLabel;
094    }
095
096    @Override
097    public String getDescriptionLabel() {
098        return descriptionLabel;
099    }
100
101    @Override
102    public void updateStatistics(CoreSession session, DocumentEventContext docCtx, Event event) {
103        DocumentModel doc = docCtx.getSourceDocument();
104        if (!needToProcessEventOnDocument(event, doc)) {
105            log.debug("Exit Listener !!!!");
106            return;
107        }
108        try {
109            switch (event.getName()) {
110            case DOCUMENT_CREATED:
111                processDocumentCreated(session, doc);
112                break;
113            case ABOUT_TO_REMOVE:
114            case ABOUT_TO_REMOVE_VERSION:
115                processDocumentAboutToBeRemoved(session, doc);
116                break;
117            case DOCUMENT_CREATED_BY_COPY:
118                processDocumentCopied(session, doc);
119                break;
120            case DOCUMENT_MOVED:
121                DocumentRef sourceParentRef = (DocumentRef) docCtx.getProperty(CoreEventConstants.PARENT_PATH);
122                DocumentRef destinationRef = (DocumentRef) docCtx.getProperty(CoreEventConstants.DESTINATION_REF);
123                DocumentModel sourceParent = sourceParentRef == null ? null : session.getDocument(sourceParentRef);
124                DocumentModel parent = destinationRef == null ? null : session.getDocument(destinationRef);
125                if (sourceParent == null && parent == null
126                        || sourceParent != null && parent != null && sourceParent.getId().equals(parent.getId())) {
127                    // rename
128                    break;
129                }
130                processDocumentMoved(session, doc, sourceParent);
131                break;
132            case DOCUMENT_UPDATED:
133                processDocumentUpdated(session, doc);
134                break;
135            case BEFORE_DOC_UPDATE:
136                processDocumentBeforeUpdate(session, doc);
137                break;
138            case TRANSITION_EVENT:
139                String transition = (String) docCtx.getProperty(TRANSTION_EVENT_OPTION_TRANSITION);
140                if (!DELETE_TRANSITION.equals(transition) && !UNDELETE_TRANSITION.equals(transition)) {
141                    break;
142                }
143                processDocumentTrashOp(session, doc, DELETE_TRANSITION.equals(transition));
144                break;
145            case DOCUMENT_CHECKEDIN:
146                processDocumentCheckedIn(session, doc);
147                break;
148            case DOCUMENT_CHECKEDOUT:
149                processDocumentCheckedOut(session, doc);
150                break;
151            case BEFORE_DOC_RESTORE:
152                processDocumentBeforeRestore(session, doc);
153                break;
154            case DOCUMENT_RESTORED:
155                processDocumentRestored(session, doc);
156                break;
157            case DOCUMENT_TRASHED:
158                processDocumentTrashOp(session, doc, true);
159                break;
160            case DOCUMENT_UNTRASHED:
161                processDocumentTrashOp(session, doc, false);
162                break;
163            }
164        } catch (QuotaExceededException e) {
165            handleQuotaExceeded(e, event);
166            throw e;
167        }
168    }
169
170    /** Gets all the ancestors of the document, including the root. */
171    protected List<DocumentModel> getAncestors(CoreSession session, DocumentModel doc) {
172        List<DocumentModel> ancestors = new ArrayList<>();
173        for (DocumentRef documentRef : session.getParentDocumentRefs(doc.getRef())) {
174            ancestors.add(session.getDocument(documentRef));
175        }
176        return ancestors;
177    }
178
179    protected abstract void handleQuotaExceeded(QuotaExceededException e, Event event);
180
181    protected abstract boolean needToProcessEventOnDocument(Event event, DocumentModel doc);
182
183    protected abstract void processDocumentCreated(CoreSession session, DocumentModel doc);
184
185    protected abstract void processDocumentCopied(CoreSession session, DocumentModel doc);
186
187    protected abstract void processDocumentCheckedIn(CoreSession session, DocumentModel doc);
188
189    protected abstract void processDocumentCheckedOut(CoreSession session, DocumentModel doc);
190
191    protected abstract void processDocumentUpdated(CoreSession session, DocumentModel doc);
192
193    protected abstract void processDocumentMoved(CoreSession session, DocumentModel doc, DocumentModel sourceParent);
194
195    protected abstract void processDocumentAboutToBeRemoved(CoreSession session, DocumentModel doc);
196
197    protected abstract void processDocumentBeforeUpdate(CoreSession session, DocumentModel doc);
198
199    protected abstract void processDocumentTrashOp(CoreSession session, DocumentModel doc, boolean isTrashed);
200
201    protected abstract void processDocumentRestored(CoreSession session, DocumentModel doc);
202
203    protected abstract void processDocumentBeforeRestore(CoreSession session, DocumentModel doc);
204
205}