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<>(getId());
131        String changeToken = getPropertyValue(PropertyIds.CHANGE_TOKEN);
132        Holder<String> changeTokenHolder = new Holder<>(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 isVersionSeriesPrivateWorkingCopy() {
246        return Boolean.valueOf(data.doc.isVersionSeriesCheckedOut());
247    }
248
249    @Override
250    public Boolean isLatestMajorVersion() {
251        return getPropertyValue(PropertyIds.IS_LATEST_MAJOR_VERSION);
252    }
253
254    @Override
255    public Boolean isLatestVersion() {
256        return getPropertyValue(PropertyIds.IS_LATEST_VERSION);
257    }
258
259    @Override
260    public Boolean isMajorVersion() {
261        return getPropertyValue(PropertyIds.IS_MAJOR_VERSION);
262    }
263
264    @Override
265    public Boolean isVersionSeriesCheckedOut() {
266        return getPropertyValue(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT);
267    }
268
269    @Override
270    public Boolean isPrivateWorkingCopy() {
271        return getPropertyValue(PropertyIds.IS_PRIVATE_WORKING_COPY);
272    }
273
274    @Override
275    public String getLatestAccessibleStateId() {
276        return getPropertyValue(PropertyIds.LATEST_ACCESSIBLE_STATE_ID);
277    }
278
279    @Override
280    public Document setContentStream(ContentStream contentStream, boolean overwrite) {
281        ObjectId objectId = setContentStream(contentStream, overwrite, true);
282        return (Document) session.getObject(objectId);
283    }
284
285    @Override
286    public ObjectId setContentStream(ContentStream contentStream, boolean overwrite, boolean refresh) {
287        Holder<String> objectIdHolder = new Holder<>(getId());
288        String changeToken = getPropertyValue(PropertyIds.CHANGE_TOKEN);
289        Holder<String> changeTokenHolder = new Holder<>(changeToken);
290
291        service.setContentStream(getRepositoryId(), objectIdHolder, Boolean.valueOf(overwrite), changeTokenHolder,
292                contentStream, null);
293
294        String objectId = objectIdHolder.getValue(); // never null
295        return session.createObjectId(objectId);
296    }
297
298    @Override
299    public Document appendContentStream(ContentStream contentStream, boolean isLastChunk) {
300        ObjectId objectId = appendContentStream(contentStream, isLastChunk, true);
301        return (Document) session.getObject(objectId);
302    }
303
304    @Override
305    public ObjectId appendContentStream(ContentStream contentStream, boolean isLastChunk, boolean refresh) {
306        throw new CmisNotSupportedException();
307    }
308
309    @Override
310    public List<ContentStreamHash> getContentStreamHashes() {
311        List<String> hashes = getPropertyValue(PropertyIds.CONTENT_STREAM_HASH);
312        if (hashes == null || hashes.size() == 0) {
313            return null;
314        }
315
316        List<ContentStreamHash> result = new ArrayList<>(hashes.size());
317        for (String hash : hashes) {
318            result.add(new ContentStreamHashImpl(hash));
319        }
320
321        return result;
322    }
323
324    @Override
325    public String getContentUrl() {
326        throw new UnsupportedOperationException();
327    }
328
329    @Override
330    public String getContentUrl(String streamId) {
331        throw new UnsupportedOperationException();
332    }
333
334    @Override
335    public OutputStream createOverwriteOutputStream(String filename, String mimeType) {
336        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
337            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
338        }
339        return new AppendOutputStream(session, this, true, filename, mimeType);
340    }
341
342    @Override
343    public OutputStream createOverwriteOutputStream(String filename, String mimeType, int bufferSize) {
344        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
345            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
346        }
347        return new AppendOutputStream(session, this, true, filename, mimeType, bufferSize);
348    }
349
350    @Override
351    public OutputStream createAppendOutputStream() {
352        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
353            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
354        }
355        return new AppendOutputStream(session, this, false, null, null);
356    }
357
358    @Override
359    public OutputStream createAppendOutputStream(int bufferSize) {
360        if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
361            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0 repositories");
362        }
363        return new AppendOutputStream(session, this, false, null, null, bufferSize);
364    }
365
366}