Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.chemistry.opencmis.client.runtime.AbstractCmisObject Maven / Gradle / Ivy
/*
* 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 static org.apache.chemistry.opencmis.commons.impl.CollectionsHelper.isNotEmpty;
import static org.apache.chemistry.opencmis.commons.impl.CollectionsHelper.isNullOrEmpty;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.chemistry.opencmis.client.api.CmisObject;
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.Property;
import org.apache.chemistry.opencmis.client.api.Relationship;
import org.apache.chemistry.opencmis.client.api.Rendition;
import org.apache.chemistry.opencmis.client.api.SecondaryType;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.Ace;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.data.AllowableActions;
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
import org.apache.chemistry.opencmis.commons.data.ObjectData;
import org.apache.chemistry.opencmis.commons.data.RenditionData;
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
import org.apache.chemistry.opencmis.commons.enums.Action;
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel;
import org.apache.chemistry.opencmis.commons.enums.Updatability;
import org.apache.chemistry.opencmis.commons.spi.CmisBinding;
import org.apache.chemistry.opencmis.commons.spi.Holder;
/**
* Base class for all persistent session object impl classes.
*/
public abstract class AbstractCmisObject implements CmisObject, Serializable {
private static final long serialVersionUID = 1L;
private SessionImpl session;
private ObjectType objectType;
private List secondaryTypes;
private Map> properties;
private AllowableActions allowableActions;
private List renditions;
private Acl acl;
private List policies;
private List relationships;
private Map> extensions;
private OperationContext creationContext;
private long refreshTimestamp;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
/**
* Initializes the object.
*/
protected void initialize(SessionImpl session, ObjectType objectType, ObjectData objectData,
OperationContext context) {
if (session == null) {
throw new IllegalArgumentException("Session must be set!");
}
if (objectType == null) {
throw new IllegalArgumentException("Object type must be set!");
}
if (objectType.getPropertyDefinitions() == null || objectType.getPropertyDefinitions().size() < 9) {
// there must be at least the 9 standard properties that all objects
// have
throw new IllegalArgumentException("Object type must have property definitions!");
}
if (objectData == null) {
throw new IllegalArgumentException("Object data must be set!");
}
if (objectData.getProperties() == null) {
throw new IllegalArgumentException("Properties must be set!");
}
if (objectData.getId() == null) {
throw new IllegalArgumentException("Object ID must be set!");
}
this.session = session;
this.objectType = objectType;
this.secondaryTypes = null;
this.extensions = new EnumMap>(ExtensionLevel.class);
this.creationContext = new OperationContextImpl(context);
this.refreshTimestamp = System.currentTimeMillis();
ObjectFactory of = getObjectFactory();
// get secondary types
if (objectData.getProperties().getProperties() != null
&& objectData.getProperties().getProperties().containsKey(PropertyIds.SECONDARY_OBJECT_TYPE_IDS)) {
@SuppressWarnings("unchecked")
List stids = (List) objectData.getProperties().getProperties()
.get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS).getValues();
if (isNotEmpty(stids)) {
secondaryTypes = new ArrayList();
for (String stid : stids) {
if (stid != null) {
ObjectType type = session.getTypeDefinition(stid);
if (type instanceof SecondaryType) {
secondaryTypes.add((SecondaryType) type);
}
}
}
} else {
secondaryTypes = null;
}
}
// handle properties
this.properties = of.convertProperties(objectType, secondaryTypes, objectData.getProperties());
extensions.put(ExtensionLevel.PROPERTIES, objectData.getProperties().getExtensions());
// handle allowable actions
if (objectData.getAllowableActions() != null) {
allowableActions = objectData.getAllowableActions();
extensions.put(ExtensionLevel.ALLOWABLE_ACTIONS, objectData.getAllowableActions().getExtensions());
} else {
allowableActions = null;
}
// handle renditions
if (objectData.getRenditions() != null && !objectData.getRenditions().isEmpty()) {
renditions = new ArrayList();
for (RenditionData rd : objectData.getRenditions()) {
renditions.add(of.convertRendition(getId(), rd));
}
} else {
renditions = null;
}
// handle ACL
if (objectData.getAcl() != null) {
acl = objectData.getAcl();
extensions.put(ExtensionLevel.ACL, objectData.getAcl().getExtensions());
if (objectData.isExactAcl() != null) {
final Acl objectAcl = objectData.getAcl();
final Boolean isExact = objectData.isExactAcl();
acl = new Acl() {
@Override
public void setExtensions(List extensions) {
objectAcl.setExtensions(extensions);
}
@Override
public List getExtensions() {
return objectAcl.getExtensions();
}
@Override
public Boolean isExact() {
return isExact;
}
@Override
public List getAces() {
return objectAcl.getAces();
}
};
}
} else {
acl = null;
}
// handle policies
if (objectData.getPolicyIds() != null && objectData.getPolicyIds().getPolicyIds() != null) {
if (objectData.getPolicyIds().getPolicyIds().isEmpty()) {
policies = null;
} else {
policies = new ArrayList();
for (String pid : objectData.getPolicyIds().getPolicyIds()) {
CmisObject policy = session.getObject(pid);
if (policy instanceof Policy) {
policies.add((Policy) policy);
}
}
}
extensions.put(ExtensionLevel.POLICIES, objectData.getPolicyIds().getExtensions());
} else {
policies = null;
}
// handle relationships
if (objectData.getRelationships() != null && !objectData.getRelationships().isEmpty()) {
relationships = new ArrayList();
for (ObjectData rod : objectData.getRelationships()) {
CmisObject relationship = of.convertObject(rod, this.creationContext);
if (relationship instanceof Relationship) {
relationships.add((Relationship) relationship);
}
}
} else {
relationships = null;
}
extensions.put(ExtensionLevel.OBJECT, objectData.getExtensions());
}
/**
* Acquires a write lock.
*/
protected void writeLock() {
lock.writeLock().lock();
}
/**
* Releases a write lock.
*/
protected void writeUnlock() {
lock.writeLock().unlock();
}
/**
* Acquires a read lock.
*/
protected void readLock() {
lock.readLock().lock();
}
/**
* Releases a read lock.
*/
protected void readUnlock() {
lock.readLock().unlock();
}
/**
* Returns the session object.
*/
protected SessionImpl getSession() {
return session;
}
/**
* Returns the repository id.
*/
protected String getRepositoryId() {
return getSession().getRepositoryId();
}
/**
* Returns the object type.
*/
protected ObjectType getObjectType() {
readLock();
try {
return objectType;
} finally {
readUnlock();
}
}
/**
* Returns the binding object.
*/
protected CmisBinding getBinding() {
return getSession().getBinding();
}
/**
* Returns the object factory.
*/
protected ObjectFactory getObjectFactory() {
return getSession().getObjectFactory();
}
/**
* Returns the id of this object or throws an exception if the id is
* unknown.
*/
protected String getObjectId() {
String objectId = getId();
if (objectId == null) {
throw new IllegalStateException("Object Id is unknown!");
}
return objectId;
}
/**
* Returns the {@link OperationContext} that was used to create this object.
*/
protected OperationContext getCreationContext() {
return creationContext;
}
/**
* Returns the query name of a property.
*/
protected String getPropertyQueryName(String propertyId) {
readLock();
try {
PropertyDefinition> propDef = objectType.getPropertyDefinitions().get(propertyId);
if (propDef == null) {
return null;
}
return propDef.getQueryName();
} finally {
readUnlock();
}
}
// --- delete ---
@Override
public void delete() {
delete(true);
}
@Override
public void delete(boolean allVersions) {
readLock();
try {
getSession().delete(this, allVersions);
} finally {
readUnlock();
}
}
// --- update properties ---
@Override
public CmisObject updateProperties(Map properties) {
ObjectId objectId = updateProperties(properties, true);
if (objectId == null) {
return null;
}
if (!getObjectId().equals(objectId.getId())) {
return getSession().getObject(objectId, getCreationContext());
}
return this;
}
@Override
public ObjectId updateProperties(Map properties, boolean refresh) {
if (isNullOrEmpty(properties)) {
throw new IllegalArgumentException("Properties must not be empty!");
}
readLock();
String newObjectId = null;
try {
String objectId = getObjectId();
Holder objectIdHolder = new Holder(objectId);
String changeToken = getChangeToken();
Holder changeTokenHolder = new Holder(changeToken);
Set updatebility = EnumSet.noneOf(Updatability.class);
updatebility.add(Updatability.READWRITE);
// check if checked out
Boolean isCheckedOut = getPropertyValue(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT);
if (Boolean.TRUE.equals(isCheckedOut)) {
updatebility.add(Updatability.WHENCHECKEDOUT);
}
// it's time to update
getBinding().getObjectService().updateProperties(
getRepositoryId(),
objectIdHolder,
changeTokenHolder,
getObjectFactory()
.convertProperties(properties, this.objectType, this.secondaryTypes, updatebility), null);
newObjectId = objectIdHolder.getValue();
// remove the object from the cache, it has been changed
getSession().removeObjectFromCache(objectId);
} finally {
readUnlock();
}
if (refresh) {
refresh();
}
if (newObjectId == null) {
return null;
}
return getSession().createObjectId(newObjectId);
}
@Override
public CmisObject rename(String newName) {
if (newName == null || newName.length() == 0) {
throw new IllegalArgumentException("New name must not be empty!");
}
Map prop = new HashMap();
prop.put(PropertyIds.NAME, newName);
return updateProperties(prop);
}
@Override
public ObjectId rename(String newName, boolean refresh) {
if (newName == null || newName.length() == 0) {
throw new IllegalArgumentException("New name must not be empty!");
}
Map prop = new HashMap();
prop.put(PropertyIds.NAME, newName);
return updateProperties(prop, refresh);
}
// --- properties ---
@Override
public ObjectType getBaseType() {
BaseTypeId baseTypeId = getBaseTypeId();
if (baseTypeId == null) {
return null;
}
return getSession().getTypeDefinition(baseTypeId.value());
}
@Override
public BaseTypeId getBaseTypeId() {
String baseType = getPropertyValue(PropertyIds.BASE_TYPE_ID);
if (baseType == null) {
return null;
}
return BaseTypeId.fromValue(baseType);
}
@Override
public String getChangeToken() {
return getPropertyValue(PropertyIds.CHANGE_TOKEN);
}
@Override
public String getCreatedBy() {
return getPropertyValue(PropertyIds.CREATED_BY);
}
@Override
public GregorianCalendar getCreationDate() {
return getPropertyValue(PropertyIds.CREATION_DATE);
}
@Override
public String getId() {
return getPropertyValue(PropertyIds.OBJECT_ID);
}
@Override
public GregorianCalendar getLastModificationDate() {
return getPropertyValue(PropertyIds.LAST_MODIFICATION_DATE);
}
@Override
public String getLastModifiedBy() {
return getPropertyValue(PropertyIds.LAST_MODIFIED_BY);
}
@Override
public String getName() {
return getPropertyValue(PropertyIds.NAME);
}
@Override
public String getDescription() {
return getPropertyValue(PropertyIds.DESCRIPTION);
}
@Override
public List> getProperties() {
readLock();
try {
return Collections.unmodifiableList(new ArrayList>(properties.values()));
} finally {
readUnlock();
}
}
@Override
@SuppressWarnings("unchecked")
public Property getProperty(String id) {
readLock();
try {
return (Property) properties.get(id);
} finally {
readUnlock();
}
}
@Override
@SuppressWarnings("unchecked")
public T getPropertyValue(String id) {
Property property = getProperty(id);
if (property == null) {
return null;
}
// explicit cast needed by the Sun compiler
return (T) property.getValue();
}
@Override
public ObjectType getType() {
readLock();
try {
return this.objectType;
} finally {
readUnlock();
}
}
@Override
public List getSecondaryTypes() {
readLock();
try {
return secondaryTypes;
} finally {
readUnlock();
}
}
@Override
public List findObjectType(String id) {
List result = null;
readLock();
try {
if (objectType.getPropertyDefinitions().containsKey(id)) {
result = new ArrayList();
result.add(objectType);
}
if (secondaryTypes != null) {
for (SecondaryType secondaryType : secondaryTypes) {
if (secondaryType.getPropertyDefinitions() != null
&& secondaryType.getPropertyDefinitions().containsKey(id)) {
if (result == null) {
result = new ArrayList();
}
result.add(secondaryType);
}
}
}
} finally {
readUnlock();
}
return result;
}
// --- allowable actions ---
@Override
public AllowableActions getAllowableActions() {
readLock();
try {
return this.allowableActions;
} finally {
readUnlock();
}
}
@Override
public boolean hasAllowableAction(Action action) {
if (action == null) {
throw new IllegalArgumentException("Action must be set!");
}
AllowableActions currentAllowableActions = getAllowableActions();
if (currentAllowableActions == null || currentAllowableActions.getAllowableActions() == null) {
throw new IllegalStateException("Allowable Actions are not available!");
}
return currentAllowableActions.getAllowableActions().contains(action);
}
// --- renditions ---
@Override
public List getRenditions() {
readLock();
try {
return this.renditions;
} finally {
readUnlock();
}
}
// --- ACL ---
public Acl getAcl(boolean onlyBasicPermissions) {
String objectId = getObjectId();
return getBinding().getAclService().getAcl(getRepositoryId(), objectId, onlyBasicPermissions, null);
}
@Override
public Acl applyAcl(List addAces, List removeAces, AclPropagation aclPropagation) {
Acl result = getSession().applyAcl(this, addAces, removeAces, aclPropagation);
refresh();
return result;
}
@Override
public Acl addAcl(List addAces, AclPropagation aclPropagation) {
return applyAcl(addAces, null, aclPropagation);
}
@Override
public Acl removeAcl(List removeAces, AclPropagation aclPropagation) {
return applyAcl(null, removeAces, aclPropagation);
}
@Override
public Acl setAcl(List aces) {
Acl result = getSession().setAcl(this, aces);
refresh();
return result;
}
@Override
public Acl getAcl() {
readLock();
try {
return acl;
} finally {
readUnlock();
}
}
@Override
public Set getPermissionsForPrincipal(String principalId) {
if (principalId == null) {
throw new IllegalArgumentException("Principal must be set!");
}
Acl currentAcl = getAcl();
if (currentAcl == null) {
throw new IllegalStateException("ACLs are not available!");
}
if (isNullOrEmpty(acl.getAces())) {
return Collections.emptySet();
}
HashSet result = new HashSet();
for (Ace ace : acl.getAces()) {
if (principalId.equals(ace.getPrincipalId()) && ace.getPermissions() != null) {
result.addAll(ace.getPermissions());
}
}
return result;
}
@Deprecated
@Override
public Set getPermissonsForPrincipal(String principalId) {
return getPermissionsForPrincipal(principalId);
}
// --- policies ---
@Override
public void applyPolicy(ObjectId... policyIds) {
readLock();
try {
getSession().applyPolicy(this, policyIds);
} finally {
readUnlock();
}
refresh();
}
@Override
public void applyPolicy(ObjectId policyId, boolean refresh) {
readLock();
try {
getSession().applyPolicy(this, policyId);
} finally {
readUnlock();
}
if (refresh) {
refresh();
}
}
@Override
public void removePolicy(ObjectId... policyIds) {
readLock();
try {
getSession().removePolicy(this, policyIds);
} finally {
readUnlock();
}
refresh();
}
@Override
public void removePolicy(ObjectId policyId, boolean refresh) {
readLock();
try {
getSession().removePolicy(this, policyId);
} finally {
readUnlock();
}
if (refresh) {
refresh();
}
}
@Override
public List getPolicies() {
readLock();
try {
return policies;
} finally {
readUnlock();
}
}
// --- relationships ---
@Override
public List getRelationships() {
readLock();
try {
return this.relationships;
} finally {
readUnlock();
}
}
// --- extensions ---
@Override
public List getExtensions(ExtensionLevel level) {
List ext = extensions.get(level);
if (ext == null) {
return null;
}
return Collections.unmodifiableList(ext);
}
// --- adapters ---
@Override
public T getAdapter(Class adapterInterface) {
return null;
}
// --- other ---
@Override
public long getRefreshTimestamp() {
readLock();
try {
return this.refreshTimestamp;
} finally {
readUnlock();
}
}
@Override
public void refresh() {
writeLock();
try {
String objectId = getObjectId();
OperationContext oc = getCreationContext();
// get the latest data from the repository
ObjectData objectData = getSession()
.getBinding()
.getObjectService()
.getObject(getRepositoryId(), objectId, oc.getFilterString(), oc.isIncludeAllowableActions(),
oc.getIncludeRelationships(), oc.getRenditionFilterString(), oc.isIncludePolicies(),
oc.isIncludeAcls(), null);
// reset this object
initialize(session, session.getTypeDefinition(objectType.getId()), objectData, creationContext);
} finally {
writeUnlock();
}
}
@Override
public void refreshIfOld(long durationInMillis) {
writeLock();
try {
if (this.refreshTimestamp < System.currentTimeMillis() - durationInMillis) {
refresh();
}
} finally {
writeUnlock();
}
}
@Override
public String toString() {
readLock();
try {
if (objectType == null) {
return "";
}
return objectType.getBaseTypeId() + " (" + objectType.getId() + "): " + getId();
} finally {
readUnlock();
}
}
}