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