/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.chemistry.opencmis.client.runtime;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.Document;
import org.apache.chemistry.opencmis.client.api.ObjectFactory;
import org.apache.chemistry.opencmis.client.api.ObjectId;
import org.apache.chemistry.opencmis.client.api.ObjectType;
import org.apache.chemistry.opencmis.client.api.OperationContext;
import org.apache.chemistry.opencmis.client.api.Policy;
import org.apache.chemistry.opencmis.client.api.TransientCmisObject;
import org.apache.chemistry.opencmis.client.api.TransientDocument;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.Ace;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.data.ObjectData;
import org.apache.chemistry.opencmis.commons.enums.Updatability;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.apache.chemistry.opencmis.commons.spi.Holder;
public class DocumentImpl extends AbstractFilableCmisObject implements Document {
private static final long serialVersionUID = 1L;
/**
* Constructor.
*/
public DocumentImpl(SessionImpl session, ObjectType objectType, ObjectData objectData, OperationContext context) {
initialize(session, objectType, objectData, context);
}
@Override
protected TransientCmisObject createTransientCmisObject() {
TransientDocumentImpl td = new TransientDocumentImpl();
td.initialize(getSession(), this);
return td;
}
public TransientDocument getTransientDocument() {
return (TransientDocument) getTransientObject();
}
// properties
public String getCheckinComment() {
return getPropertyValue(PropertyIds.CHECKIN_COMMENT);
}
public String getVersionLabel() {
return getPropertyValue(PropertyIds.VERSION_LABEL);
}
public String getVersionSeriesId() {
return getPropertyValue(PropertyIds.VERSION_SERIES_ID);
}
public String getVersionSeriesCheckedOutId() {
return getPropertyValue(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID);
}
public String getVersionSeriesCheckedOutBy() {
return getPropertyValue(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY);
}
public Boolean isImmutable() {
return getPropertyValue(PropertyIds.IS_IMMUTABLE);
}
public Boolean isLatestMajorVersion() {
return getPropertyValue(PropertyIds.IS_LATEST_MAJOR_VERSION);
}
public Boolean isLatestVersion() {
return getPropertyValue(PropertyIds.IS_LATEST_VERSION);
}
public Boolean isMajorVersion() {
return getPropertyValue(PropertyIds.IS_MAJOR_VERSION);
}
public Boolean isVersionSeriesCheckedOut() {
return getPropertyValue(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT);
}
public long getContentStreamLength() {
BigInteger bigInt = getPropertyValue(PropertyIds.CONTENT_STREAM_LENGTH);
return (bigInt == null) ? (long) -1 : bigInt.longValue();
}
public String getContentStreamMimeType() {
return getPropertyValue(PropertyIds.CONTENT_STREAM_MIME_TYPE);
}
public String getContentStreamFileName() {
return getPropertyValue(PropertyIds.CONTENT_STREAM_FILE_NAME);
}
public String getContentStreamId() {
return getPropertyValue(PropertyIds.CONTENT_STREAM_ID);
}
// operations
public Document copy(ObjectId targetFolderId, Map<String, ?> properties, VersioningState versioningState,
List<Policy> policies, List<Ace> addAces, List<Ace> removeAces, OperationContext context) {
ObjectId newId = getSession().createDocumentFromSource(this, properties, targetFolderId, versioningState,
policies, addAces, removeAces);
// if no context is provided the object will not be fetched
if (context == null || newId == null) {
return null;
}
// get the new object
CmisObject object = getSession().getObject(newId, context);
if (!(object instanceof Document)) {
throw new CmisRuntimeException("Newly created object is not a document! New id: " + newId);
}
return (Document) object;
}
public Document copy(ObjectId targetFolderId) {
return copy(targetFolderId, null, null, null, null, null, getSession().getDefaultContext());
}
public void deleteAllVersions() {
delete(true);
}
// versioning
public ObjectId checkOut() {
String newObjectId = null;
readLock();
try {
String objectId = getObjectId();
Holder<String> objectIdHolder = new Holder<String>(objectId);
getBinding().getVersioningService().checkOut(getRepositoryId(), objectIdHolder, null, null);
newObjectId = objectIdHolder.getValue();
} finally {
readUnlock();
}
if (newObjectId == null) {
return null;
}
return getSession().createObjectId(newObjectId);
}
public void cancelCheckOut() {
String objectId = getObjectId();
getBinding().getVersioningService().cancelCheckOut(getRepositoryId(), objectId, null);
}
public ObjectId checkIn(boolean major, Map<String, ?> properties, ContentStream contentStream,
String checkinComment, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) {
String newObjectId = null;
readLock();
try {
Holder<String> objectIdHolder = new Holder<String>(getObjectId());
ObjectFactory of = getObjectFactory();
Set<Updatability> updatebility = new HashSet<Updatability>();
updatebility.add(Updatability.READWRITE);
updatebility.add(Updatability.WHENCHECKEDOUT);
getBinding().getVersioningService().checkIn(getRepositoryId(), objectIdHolder, major,
of.convertProperties(properties, getType(), updatebility), of.convertContentStream(contentStream),
checkinComment, of.convertPolicies(policies), of.convertAces(addAces), of.convertAces(removeAces),
null);
newObjectId = objectIdHolder.getValue();
} finally {
readUnlock();
}
if (newObjectId == null) {
return null;
}
return getSession().createObjectId(newObjectId);
}
public List<Document> getAllVersions() {
return getAllVersions(getSession().getDefaultContext());
}
public List<Document> getAllVersions(OperationContext context) {
String objectId;
String versionSeriesId;
readLock();
try {
objectId = getObjectId();
versionSeriesId = getVersionSeriesId();
} finally {
readUnlock();
}
List<ObjectData> versions = getBinding().getVersioningService().getAllVersions(getRepositoryId(), objectId,
versionSeriesId, context.getFilterString(), context.isIncludeAllowableActions(), null);
ObjectFactory objectFactory = getSession().getObjectFactory();
List<Document> result = new ArrayList<Document>();
if (versions != null) {
for (ObjectData objectData : versions) {
CmisObject doc = objectFactory.convertObject(objectData, context);
if (!(doc instanceof Document)) {
// should not happen...
continue;
}
result.add((Document) doc);
}
}
return result;
}
public Document getObjectOfLatestVersion(boolean major) {
return getObjectOfLatestVersion(major, getSession().getDefaultContext());
}
public Document getObjectOfLatestVersion(boolean major, OperationContext context) {
String objectId;
String versionSeriesId;
readLock();
try {
objectId = getObjectId();
versionSeriesId = getVersionSeriesId();
} finally {
readUnlock();
}
if (versionSeriesId == null) {
throw new CmisRuntimeException("Version series id is unknown!");
}
ObjectData objectData = getBinding().getVersioningService().getObjectOfLatestVersion(getRepositoryId(),
objectId, versionSeriesId, major, context.getFilterString(), context.isIncludeAllowableActions(),
context.getIncludeRelationships(), context.getRenditionFilterString(), context.isIncludePolicies(),
context.isIncludeAcls(), null);
ObjectFactory objectFactory = getSession().getObjectFactory();
CmisObject result = objectFactory.convertObject(objectData, context);
if (!(result instanceof Document)) {
throw new CmisRuntimeException("Latest version is not a document!");
}
return (Document) result;
}
// content operations
public ContentStream getContentStream() {
return getContentStream(null);
}
public ContentStream getContentStream(String streamId) {
String objectId = getObjectId();
// get the stream
ContentStream contentStream;
try {
contentStream = getBinding().getObjectService().getContentStream(getRepositoryId(), objectId, streamId,
null, null, null);
} catch (CmisConstraintException e) {
// no content stream
return null;
}
// the AtomPub binding doesn't return a file name
// -> get the file name from properties, if present
String filename = contentStream.getFileName();
if (filename == null) {
filename = getContentStreamFileName();
}
long length = (contentStream.getBigLength() == null ? -1 : contentStream.getBigLength().longValue());
// convert and return stream object
return getSession().getObjectFactory().createContentStream(filename, length, contentStream.getMimeType(),
contentStream.getStream());
}
public Document setContentStream(ContentStream contentStream, boolean overwrite) {
ObjectId objectId = setContentStream(contentStream, overwrite, true);
if (objectId == null) {
return null;
}
if (!getObjectId().equals(objectId.getId())) {
return (Document) getSession().getObject(objectId, getCreationContext());
}
return this;
}
public ObjectId setContentStream(ContentStream contentStream, boolean overwrite, boolean refresh) {
String newObjectId = null;
readLock();
try {
Holder<String> objectIdHolder = new Holder<String>(getObjectId());
Holder<String> changeTokenHolder = new Holder<String>((String) getPropertyValue(PropertyIds.CHANGE_TOKEN));
getBinding().getObjectService().setContentStream(getRepositoryId(), objectIdHolder, overwrite,
changeTokenHolder, getObjectFactory().convertContentStream(contentStream), null);
newObjectId = objectIdHolder.getValue();
} finally {
readUnlock();
}
if (refresh) {
refresh();
}
if (newObjectId == null) {
return null;
}
return getSession().createObjectId(newObjectId);
}
public Document deleteContentStream() {
ObjectId objectId = deleteContentStream(true);
if (objectId == null) {
return null;
}
if (!getObjectId().equals(objectId.getId())) {
return (Document) getSession().getObject(objectId, getCreationContext());
}
return this;
}
public ObjectId deleteContentStream(boolean refresh) {
String newObjectId = null;
readLock();
try {
Holder<String> objectIdHolder = new Holder<String>(getObjectId());
Holder<String> changeTokenHolder = new Holder<String>((String) getPropertyValue(PropertyIds.CHANGE_TOKEN));
getBinding().getObjectService().deleteContentStream(getRepositoryId(), objectIdHolder, changeTokenHolder,
null);
newObjectId = objectIdHolder.getValue();
} finally {
readUnlock();
}
if (refresh) {
refresh();
}
if (newObjectId == null) {
return null;
}
return getSession().createObjectId(newObjectId);
}
public ObjectId checkIn(boolean major, Map<String, ?> properties, ContentStream contentStream, String checkinComment) {
return this.checkIn(major, properties, contentStream, checkinComment, null, null, null);
}
}