/* * 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.inmemory.storedobj.impl; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.chemistry.opencmis.commons.data.ContentStream; import org.apache.chemistry.opencmis.commons.data.Properties; import org.apache.chemistry.opencmis.commons.data.PropertyData; import org.apache.chemistry.opencmis.commons.enums.VersioningState; import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException; import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException; import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory; import org.apache.chemistry.opencmis.inmemory.FilterParser; import org.apache.chemistry.opencmis.inmemory.storedobj.api.DocumentVersion; import org.apache.chemistry.opencmis.inmemory.storedobj.api.VersionedDocument; public class VersionedDocumentImpl extends FilingImpl implements VersionedDocument { private boolean fIsCheckedOut; private String fCheckedOutUser; private final List<DocumentVersion> fVersions; public VersionedDocumentImpl() { super(); fVersions = new ArrayList<DocumentVersion>(); fIsCheckedOut = false; } @Override public DocumentVersion addVersion(VersioningState verState, String user) { if (isCheckedOut()) { throw new CmisConstraintException("Cannot add a version to document, document is checked out."); } DocumentVersionImpl ver = new DocumentVersionImpl(fRepositoryId, this, verState); ver.setSystemBasePropertiesWhenCreatedDirect(getName(), getTypeId(), user); // copy // name and type id from version series. fVersions.add(ver); if (verState == VersioningState.CHECKEDOUT) { fCheckedOutUser = user; fIsCheckedOut = true; } return ver; } @Override public boolean deleteVersion(DocumentVersion version) { if (fIsCheckedOut) { // Note: Do not throw an exception here if the document is // checked-out. In AtomPub binding cancelCheckout // mapped to a deleteVersion() call! DocumentVersion pwc = getPwc(); if (pwc == version) { // NOSONAR cancelCheckOut(false); // note object is already deleted from // map in ObjectStore return !fVersions.isEmpty(); } } boolean found = fVersions.remove(version); if (!found) { throw new CmisInvalidArgumentException("Version is not contained in the document:" + version.getId()); } return !fVersions.isEmpty(); } @Override public void cancelCheckOut(String user) { cancelCheckOut(true); } @Override public void checkIn(boolean isMajor, Properties properties, ContentStream content, String checkinComment, List<String> policyIds, String user) { if (fIsCheckedOut) { if (fCheckedOutUser.equals(user)) { fIsCheckedOut = false; fCheckedOutUser = null; } else { throw new CmisConstraintException("Error: Can't checkin. Document " + getId() + " user " + user + " has not checked out the document"); } } else { throw new CmisConstraintException("Error: Can't cancel checkout, Document " + getId() + " is not checked out."); } DocumentVersion pwc = getPwc(); if (null != content) { pwc.setContent(content); } if (null != properties && null != properties.getProperties()) { ((DocumentVersionImpl) pwc).setCustomProperties(properties.getProperties()); } pwc.setCheckinComment(checkinComment); pwc.commit(isMajor); if (policyIds != null && policyIds.size() > 0) { ((DocumentVersionImpl) pwc).setAppliedPolicies(policyIds); } } @Override public DocumentVersion checkOut(String user) { if (fIsCheckedOut) { throw new CmisConstraintException("Error: Can't checkout, Document " + getId() + " is already checked out."); } // create PWC DocumentVersion pwc = addVersion(VersioningState.CHECKEDOUT, user); // will // set check-out flag return pwc; } @Override public List<DocumentVersion> getAllVersions() { return fVersions; } @Override public DocumentVersion getLatestVersion(boolean major) { DocumentVersion latest = null; if (fVersions.size() == 0) { return null; } if (major) { for (DocumentVersion ver : fVersions) { if (ver.isMajor() && !ver.isPwc()) { latest = ver; } } } else { if (null == getPwc()) { latest = fVersions.get(fVersions.size() - 1); } else if (fVersions.size() > 1) { latest = fVersions.get(fVersions.size() - 2); } else { latest = null; } if (null == getPwc()) { latest = fVersions.get(fVersions.size() - 1); } else if (fVersions.size() > 1) { latest = fVersions.get(fVersions.size() - 2); } else { latest = null; } } return latest; } @Override public boolean isCheckedOut() { return fIsCheckedOut; } @Override public String getCheckedOutBy() { return fCheckedOutUser; } @Override public DocumentVersion getPwc() { for (DocumentVersion ver : fVersions) { if (ver.isPwc()) { return ver; } } return null; } @Override public void fillProperties(Map<String, PropertyData<?>> properties, BindingsObjectFactory objFactory, List<String> requestedIds) { DocumentVersion pwc = getPwc(); super.fillProperties(properties, objFactory, requestedIds); if (FilterParser.isContainedInFilter(PropertyIds.IS_IMMUTABLE, requestedIds)) { properties.put(PropertyIds.IS_IMMUTABLE, objFactory.createPropertyBooleanData(PropertyIds.IS_IMMUTABLE, false)); } // overwrite the version related properties if (FilterParser.isContainedInFilter(PropertyIds.VERSION_SERIES_ID, requestedIds)) { properties.put(PropertyIds.VERSION_SERIES_ID, objFactory.createPropertyIdData(PropertyIds.VERSION_SERIES_ID, getId())); } if (FilterParser.isContainedInFilter(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT, requestedIds)) { properties.put(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT, objFactory.createPropertyBooleanData(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT, isCheckedOut())); } if (FilterParser.isContainedInFilter(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, requestedIds)) { properties.put(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, objFactory.createPropertyStringData(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, getCheckedOutBy())); } if (FilterParser.isContainedInFilter(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, requestedIds)) { properties.put( PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, objFactory.createPropertyIdData(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, pwc == null ? null : pwc.getId())); } } private void cancelCheckOut(boolean deleteInObjectStore) { DocumentVersion pwc = getPwc(); fIsCheckedOut = false; fCheckedOutUser = null; fVersions.remove(pwc); if (fVersions.size() > 0) { String nameLatestVer = getLatestVersion(false).getName(); if (!getName().equals(nameLatestVer)) { setName(nameLatestVer); } } if (deleteInObjectStore) { // TODO: } } }