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