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 *     <a href="mailto:tdelprat@nuxeo.com">Tiry</a>
018 */
019
020package org.nuxeo.ecm.quota.size;
021
022import java.io.Serializable;
023import java.util.Collections;
024import java.util.List;
025
026import org.nuxeo.ecm.core.api.CoreSession;
027import org.nuxeo.ecm.core.api.DocumentModel;
028import org.nuxeo.ecm.core.event.Event;
029import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
030import org.nuxeo.ecm.quota.QuotaStatsService;
031
032/**
033 * Custom EventContext used to propage info between the synchronous listener that is run by the
034 * {@link QuotaStatsService} synchronously and the Asynchrous listener ( {@link QuotaComputerProcessor} that actually
035 * does the work.
036 *
037 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a>
038 * @since 5.6
039 */
040public class SizeUpdateEventContext extends DocumentEventContext {
041
042    public static final String QUOTA_UPDATE_NEEDED = "quotaUpdateNeeded";
043
044    public static final String DOCUMENT_UPDATE_INITIAL_STATISTICS = "documentUpdateInitialStats";
045
046    private static final long serialVersionUID = 1L;
047
048    public static final String BLOB_SIZE_PROPERTY_KEY = "blobSize";
049
050    public static final String BLOB_DELTA_PROPERTY_KEY = "blobDelta";
051
052    // holds the total size for all versions of a given doc
053    // used when permanently deleting a doc and for the initial computation;
054    // ( and restore)
055    public static final String VERSIONS_SIZE_PROPERTY_KEY = "versionsSize";
056
057    // used for the initial computation and restore
058    // versions size to be added on the total size , differs from the versions
059    // size if the doc is checked in
060    public static final String VERSIONS_SIZE_ON_TOTAL_PROPERTY_KEY = "versionsSizeOnTotal";
061
062    public static final String PARENT_UUIDS_PROPERTY_KEY = "parentUUIDs";
063
064    public static final String SOURCE_EVENT_PROPERTY_KEY = "sourceEvent";
065
066    public static final String MARKER_KEY = "contextType";
067
068    public static final String MARKER_VALUE = "SizeUpdateEventContext";
069
070    // mark that an update trash is needed
071    // used when permanently deleting a doc and in the initial computation
072    // if the doc is in trash
073    public static final String _UPDATE_TRASH_SIZE = "_UPDATE_TRASH";
074
075    protected SizeUpdateEventContext(CoreSession session, DocumentEventContext evtCtx) {
076        super(session, evtCtx.getPrincipal(), evtCtx.getSourceDocument(), evtCtx.getDestination());
077        setProperty(MARKER_KEY, MARKER_VALUE);
078    }
079
080    public SizeUpdateEventContext(CoreSession session, DocumentEventContext evtCtx, DocumentModel sourceDocument,
081            BlobSizeInfo bsi, String sourceEvent) {
082        super(session, evtCtx.getPrincipal(), sourceDocument, evtCtx.getDestination());
083        setBlobSize(bsi.getBlobSize());
084        setBlobDelta(bsi.getBlobSizeDelta());
085        setProperty(SOURCE_EVENT_PROPERTY_KEY, sourceEvent);
086        setProperty(MARKER_KEY, MARKER_VALUE);
087    }
088
089    public SizeUpdateEventContext(CoreSession session, BlobSizeInfo bsi, String sourceEvent,
090            DocumentModel sourceDocument) {
091        super(session, session.getPrincipal(), sourceDocument, null);
092        setBlobSize(bsi.getBlobSize());
093        setBlobDelta(bsi.getBlobSizeDelta());
094        setProperty(SOURCE_EVENT_PROPERTY_KEY, sourceEvent);
095        setProperty(MARKER_KEY, MARKER_VALUE);
096    }
097
098    public SizeUpdateEventContext(CoreSession session, DocumentEventContext evtCtx, BlobSizeInfo bsi, String sourceEvent) {
099        super(session, evtCtx.getPrincipal(), evtCtx.getSourceDocument(), evtCtx.getDestination());
100        setBlobSize(bsi.getBlobSize());
101        setBlobDelta(bsi.getBlobSizeDelta());
102        setProperty(SOURCE_EVENT_PROPERTY_KEY, sourceEvent);
103        setProperty(MARKER_KEY, MARKER_VALUE);
104    }
105
106    public SizeUpdateEventContext(CoreSession session, DocumentEventContext evtCtx, long totalSize, String sourceEvent) {
107        super(session, evtCtx.getPrincipal(), evtCtx.getSourceDocument(), evtCtx.getDestination());
108        setBlobSize(totalSize);
109        setBlobDelta(-totalSize);
110        setProperty(SOURCE_EVENT_PROPERTY_KEY, sourceEvent);
111        setProperty(MARKER_KEY, MARKER_VALUE);
112    }
113
114    public static SizeUpdateEventContext unwrap(DocumentEventContext docCtx) {
115        if (MARKER_VALUE.equals(docCtx.getProperty(MARKER_KEY))) {
116            SizeUpdateEventContext ctx = new SizeUpdateEventContext(docCtx.getCoreSession(), docCtx);
117            ctx.setProperties(docCtx.getProperties());
118            return ctx;
119        }
120        return null;
121    }
122
123    public long getBlobSize() {
124        return (Long) getProperty(BLOB_SIZE_PROPERTY_KEY);
125    }
126
127    public void setBlobSize(long blobSize) {
128        setProperty(BLOB_SIZE_PROPERTY_KEY, new Long(blobSize));
129    }
130
131    public void setVersionsSize(long versionsSize) {
132        setProperty(VERSIONS_SIZE_PROPERTY_KEY, new Long(versionsSize));
133    }
134
135    public long getVersionsSize() {
136        if (getProperty(VERSIONS_SIZE_PROPERTY_KEY) != null) {
137            return (Long) getProperty(VERSIONS_SIZE_PROPERTY_KEY);
138        }
139        return 0L;
140    }
141
142    /**
143     * @since 5.7
144     */
145    public void setVersionsSizeOnTotal(long blobSize) {
146        setProperty(VERSIONS_SIZE_ON_TOTAL_PROPERTY_KEY, blobSize);
147    }
148
149    /**
150     * @since 5.7
151     */
152    public long getVersionsSizeOnTotal() {
153        if (getProperty(VERSIONS_SIZE_ON_TOTAL_PROPERTY_KEY) != null) {
154            return (Long) getProperty(VERSIONS_SIZE_ON_TOTAL_PROPERTY_KEY);
155        }
156        return 0L;
157    }
158
159    public long getBlobDelta() {
160        return (Long) getProperty(BLOB_DELTA_PROPERTY_KEY);
161    }
162
163    public void setBlobDelta(long blobDelta) {
164        setProperty(BLOB_DELTA_PROPERTY_KEY, new Long(blobDelta));
165    }
166
167    @SuppressWarnings("unchecked")
168    public List<String> getParentUUIds() {
169        return (List<String>) getProperty(PARENT_UUIDS_PROPERTY_KEY);
170    }
171
172    public void setParentUUIds(List<String> parentUUIds) {
173        parentUUIds.removeAll(Collections.singleton(null));
174        setProperty(PARENT_UUIDS_PROPERTY_KEY, (Serializable) parentUUIds);
175    }
176
177    public String getSourceEvent() {
178        return (String) getProperty(SOURCE_EVENT_PROPERTY_KEY);
179    }
180
181    /**
182     * @since 5.7
183     */
184    public long getTrashSize() {
185        if (getProperty(_UPDATE_TRASH_SIZE) != null && (Boolean) getProperty(_UPDATE_TRASH_SIZE)) {
186            return getBlobSize();
187        }
188        return 0;
189    }
190
191    @Override
192    public String toString() {
193        StringBuffer sb = new StringBuffer();
194        sb.append("\nsourceDocument " + getSourceDocument().getId() + " " + getSourceDocument().getPathAsString());
195        sb.append("\nprops " + getProperties().toString());
196        return sb.toString();
197    }
198
199    public Event newQuotaUpdateEvent() {
200        return newEvent(SizeUpdateEventContext.QUOTA_UPDATE_NEEDED);
201    }
202}