001/*
002 * (C) Copyright 2006-2011 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 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.opencmis.impl.client;
020
021import java.io.OutputStream;
022import java.math.BigInteger;
023import java.util.ArrayList;
024import java.util.List;
025import java.util.Map;
026
027import org.apache.chemistry.opencmis.client.api.Document;
028import org.apache.chemistry.opencmis.client.api.DocumentType;
029import org.apache.chemistry.opencmis.client.api.ObjectId;
030import org.apache.chemistry.opencmis.client.api.ObjectType;
031import org.apache.chemistry.opencmis.client.api.OperationContext;
032import org.apache.chemistry.opencmis.client.api.Policy;
033import org.apache.chemistry.opencmis.client.api.SecondaryType;
034import org.apache.chemistry.opencmis.client.runtime.util.AppendOutputStream;
035import org.apache.chemistry.opencmis.commons.PropertyIds;
036import org.apache.chemistry.opencmis.commons.data.Ace;
037import org.apache.chemistry.opencmis.commons.data.ContentStream;
038import org.apache.chemistry.opencmis.commons.data.ContentStreamHash;
039import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
040import org.apache.chemistry.opencmis.commons.enums.VersioningState;
041import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
042import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
043import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
044import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamHashImpl;
045import org.apache.chemistry.opencmis.commons.spi.Holder;
046import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData;
047
048/**
049 * Live local CMIS Document, which is backed by a Nuxeo document.
050 */
051public class NuxeoDocument extends NuxeoFileableObject implements Document {
052
053    public NuxeoDocument(NuxeoSession session, NuxeoObjectData data, ObjectType type,
054            List<SecondaryType> secondaryTypes) {
055        super(session, data, type, secondaryTypes);
056    }
057
058    @Override
059    public DocumentType getDocumentType() {
060        ObjectType objectType = getType();
061        if (objectType instanceof DocumentType) {
062            return (DocumentType) objectType;
063        } else {
064            throw new ClassCastException("Object type is not a document type.");
065        }
066    }
067
068    @Override
069    public void cancelCheckOut() {
070        service.cancelCheckOut(getRepositoryId(), getId(), null);
071    }
072
073    @Override
074    public ObjectId checkIn(boolean major, Map<String, ?> properties, ContentStream contentStream, String checkinComment) {
075        return checkIn(major, properties, contentStream, checkinComment, null, null, null);
076    }
077
078    @Override
079    public ObjectId checkIn(boolean major, Map<String, ?> properties, ContentStream contentStream,
080            String checkinComment, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) {
081        Holder<String> idHolder = new Holder<>(getId());
082        service.checkIn(getRepositoryId(), idHolder, Boolean.valueOf(major),
083                objectFactory.convertProperties(properties, type, null, UPDATABILITY_READWRITE),
084                objectFactory.convertContentStream(contentStream), checkinComment,
085                objectFactory.convertPolicies(policies), objectFactory.convertAces(addAces),
086                objectFactory.convertAces(removeAces), null);
087        return session.createObjectId(idHolder.getValue());
088    }
089
090    @Override
091    public ObjectId checkOut() {
092        Holder<String> idHolder = new Holder<>(getId());
093        service.checkOut(getRepositoryId(), idHolder, null, null);
094        return session.createObjectId(idHolder.getValue());
095    }
096
097    @Override
098    public NuxeoDocument copy(ObjectId target) {
099        return copy(target, null, null, null, null, null, session.getDefaultContext());
100    }
101
102    @Override
103    public NuxeoDocument copy(ObjectId target, Map<String, ?> properties, VersioningState versioningState,
104            List<Policy> policies, List<Ace> addACEs, List<Ace> removeACEs, OperationContext context) {
105        if (target == null || target.getId() == null) {
106            throw new CmisInvalidArgumentException("Invalid target: " + target);
107        }
108        if (context == null) {
109            context = session.getDefaultContext();
110        }
111        NuxeoObjectData newData = nuxeoCmisService.copy(getId(), target.getId(), properties, type, versioningState,
112                policies, addACEs, removeACEs, context);
113        return (NuxeoDocument) session.getObjectFactory().convertObject(newData, context);
114    }
115
116    @Override
117    public void deleteAllVersions() {
118        // TODO Auto-generated method stub
119        throw new UnsupportedOperationException();
120    }
121
122    @Override
123    public NuxeoDocument deleteContentStream() {
124        ObjectId objectId = deleteContentStream(true);
125        return (NuxeoDocument) session.getObject(objectId);
126    }
127
128    @Override
129    public ObjectId deleteContentStream(boolean refresh) {
130        Holder<String> objectIdHolder = new Holder<String>(getId());
131        String changeToken = getPropertyValue(PropertyIds.CHANGE_TOKEN);
132        Holder<String> changeTokenHolder = new Holder<String>(changeToken);
133
134        service.deleteContentStream(getRepositoryId(), objectIdHolder, changeTokenHolder, null);
135
136        String objectId = objectIdHolder.getValue(); // never null
137        return session.createObjectId(objectId);
138    }
139
140    @Override
141    public List<Document> getAllVersions() {
142        // TODO Auto-generated method stub
143        throw new UnsupportedOperationException();
144    }
145
146    @Override
147    public List<Document> getAllVersions(OperationContext context) {
148        // TODO Auto-generated method stub
149        throw new UnsupportedOperationException();
150    }
151
152    @Override
153    public String getCheckinComment() {
154        return getPropertyValue(PropertyIds.CHECKIN_COMMENT);
155    }
156
157    @Override
158    public ContentStream getContentStream() {
159        return getContentStream(null, null, null);
160    }
161
162    @Override
163    public ContentStream getContentStream(String streamId) {
164        return getContentStream(streamId, null, null);
165    }
166
167    @Override
168    public ContentStream getContentStream(BigInteger offset, BigInteger length) {
169        return getContentStream(null, offset, length);
170    }
171
172    @Override
173    public ContentStream getContentStream(String streamId, BigInteger offset, BigInteger length) {
174        try {
175            return service.getContentStream(getRepositoryId(), getId(), streamId, offset, length, null);
176        } catch (CmisConstraintException e) {
177            return null;
178        }
179    }
180
181    @Override
182    public String getContentStreamFileName() {
183        return getPropertyValue(PropertyIds.CONTENT_STREAM_FILE_NAME);
184    }
185
186    @Override
187    public String getContentStreamId() {
188        return getPropertyValue(PropertyIds.CONTENT_STREAM_ID);
189    }
190
191    @Override
192    public long getContentStreamLength() {
193        Long length = getPropertyValue(PropertyIds.CONTENT_STREAM_LENGTH);
194        return length == null ? -1 : length.longValue();
195    }
196
197    @Override
198    public String getContentStreamMimeType() {
199        return getPropertyValue(PropertyIds.CONTENT_STREAM_MIME_TYPE);
200    }
201
202    @Override
203    public Document getObjectOfLatestVersion(boolean major) {
204        // TODO Auto-generated method stub
205        throw new UnsupportedOperationException();
206    }
207
208    @Override
209    public Document getObjectOfLatestVersion(boolean major, OperationContext context) {
210        // TODO Auto-generated method stub
211        throw new UnsupportedOperationException();
212    }
213
214    @Override
215    public String getVersionLabel() {
216        return getPropertyValue(PropertyIds.VERSION_LABEL);
217    }
218
219    @Override
220    public String getVersionSeriesCheckedOutBy() {
221        return getPropertyValue(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY);
222    }
223
224    @Override
225    public String getVersionSeriesCheckedOutId() {
226        return getPropertyValue(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID);
227    }
228
229    @Override
230    public String getVersionSeriesId() {
231        return getPropertyValue(PropertyIds.VERSION_SERIES_ID);
232    }
233
234    @Override
235    public Boolean isImmutable() {
236        return getPropertyValue(PropertyIds.IS_IMMUTABLE);
237    }
238
239    @Override
240    public boolean isVersionable() {
241        return data.doc.isVersionable();
242    }
243
244    @Override
245    public Boolean isLatestMajorVersion() {
246        return getPropertyValue(PropertyIds.IS_LATEST_MAJOR_VERSION);
247    }
248
249    @Override
250    public Boolean isLatestVersion() {
251        return getPropertyValue(PropertyIds.IS_LATEST_VERSION);
252    }
253
254    @Override
255    public Boolean isMajorVersion() {
256        return getPropertyValue(PropertyIds.IS_MAJOR_VERSION);
257    }
258
259    @Override
260    public Boolean isVersionSeriesCheckedOut() {
261        return getPropertyValue(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT);
262    }
263
264    @Override
265    public Boolean isPrivateWorkingCopy() {
266        return getPropertyValue(PropertyIds.IS_PRIVATE_WORKING_COPY);
267    }
268
269    @Override
270    public String getLatestAccessibleStateId() {
271        return getPropertyValue(PropertyIds.LATEST_ACCESSIBLE_STATE_ID);
272    }
273
274    @Override
275    public Document setContentStream(ContentStream contentStream, boolean overwrite) {
276        ObjectId objectId = setContentStream(contentStream, overwrite, true);
277        return (Document) session.getObject(objectId);
278    }
279
280    @Override
281    public ObjectId setContentStream(ContentStream contentStream, boolean overwrite, boolean refresh) {
282        Holder<String> objectIdHolder = new Holder<String>(getId());
283        String changeToken = getPropertyValue(PropertyIds.CHANGE_TOKEN);
284        Holder<String> changeTokenHolder = new Holder<String>(changeToken);
285
286        service.setContentStream(getRepositoryId(), objectIdHolder, Boolean.valueOf(overwrite), changeTokenHolder,
287                contentStream, null);
288
289        String objectId = objectIdHolder.getValue(); // never null
290        return session.createObjectId(objectId);
291    }
292
293    @Override
294    public Document appendContentStream(ContentStream contentStream, boolean isLastChunk) {
295        ObjectId objectId = appendContentStream(contentStream, isLastChunk, true);
296        return (Document) session.getObject(objectId);
297    }
298
299    @Override
300    public ObjectId appendContentStream(ContentStream contentStream, boolean isLastChunk, boolean refresh) {
301        throw new CmisNotSupportedException();
302    }
303
304    @Override
305    public List<ContentStreamHash> getContentStreamHashes() {
306        List<String> hashes = getPropertyValue(PropertyIds.CONTENT_STREAM_HASH);
307        if (hashes == null || hashes.size() == 0) {
308            return null;
309        }
310
311        List<ContentStreamHash> result = new ArrayList<ContentStreamHash>(hashes.size());
312        for (String hash : hashes) {
313            result.add(new ContentStreamHashImpl(hash));
314        }
315
316        return result;
317    }
318
319    @Override
320    public String getContentUrl() {
321        throw new UnsupportedOperationException();
322    }
323
324    @Override
325    public String getContentUrl(String streamId) {
326        throw new UnsupportedOperationException();
327    }
328
329    @Override
330    public OutputStream createOverwriteOutputStream(String filename, String mimeType) {
331        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
332            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
333        }
334        return new AppendOutputStream(session, this, true, filename, mimeType);
335    }
336
337    @Override
338    public OutputStream createOverwriteOutputStream(String filename, String mimeType, int bufferSize) {
339        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
340            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
341        }
342        return new AppendOutputStream(session, this, true, filename, mimeType, bufferSize);
343    }
344
345    @Override
346    public OutputStream createAppendOutputStream() {
347        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
348            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
349        }
350        return new AppendOutputStream(session, this, false, null, null);
351    }
352
353    @Override
354    public OutputStream createAppendOutputStream(int bufferSize) {
355        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
356            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
357        }
358        return new AppendOutputStream(session, this, false, null, null, bufferSize);
359    }
360
361}