/*******************************************************************************
* Copyright (c) 2013 aegif.
*
* This file is part of NemakiWare.
*
* NemakiWare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NemakiWare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with NemakiWare.
* If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* linzhixing(https://github.com/linzhixing) - initial API and implementation
******************************************************************************/
package jp.aegif.nemaki.cmis.aspect.impl;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.chemistry.opencmis.commons.PropertyIds;
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.ObjectList;
import org.apache.chemistry.opencmis.commons.data.PermissionMapping;
import org.apache.chemistry.opencmis.commons.data.Principal;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.data.RenditionData;
import org.apache.chemistry.opencmis.commons.data.RepositoryCapabilities;
import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
import org.apache.chemistry.opencmis.commons.definitions.SecondaryTypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
import org.apache.chemistry.opencmis.commons.enums.Action;
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
import org.apache.chemistry.opencmis.commons.enums.CapabilityRenditions;
import org.apache.chemistry.opencmis.commons.enums.ChangeType;
import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed;
import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
import org.apache.chemistry.opencmis.commons.enums.PropertyType;
import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyData;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AllowableActionsImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ChangeEventInfoDataImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.CmisExtensionElementImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectDataImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PolicyIdListImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyBooleanImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDateTimeImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.RenditionDataImpl;
import org.apache.chemistry.opencmis.commons.server.CallContext;
import org.apache.chemistry.opencmis.commons.spi.Holder;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.rits.cloning.Cloner;
import jp.aegif.nemaki.businesslogic.ContentService;
import jp.aegif.nemaki.cmis.aspect.CompileService;
import jp.aegif.nemaki.cmis.aspect.PermissionService;
import jp.aegif.nemaki.cmis.aspect.SortUtil;
import jp.aegif.nemaki.cmis.aspect.type.TypeManager;
import jp.aegif.nemaki.cmis.factory.info.AclCapabilities;
import jp.aegif.nemaki.cmis.factory.info.RepositoryInfoMap;
import jp.aegif.nemaki.cmis.service.RepositoryService;
import jp.aegif.nemaki.model.Ace;
import jp.aegif.nemaki.model.Acl;
import jp.aegif.nemaki.model.Aspect;
import jp.aegif.nemaki.model.AttachmentNode;
import jp.aegif.nemaki.model.Change;
import jp.aegif.nemaki.model.Content;
import jp.aegif.nemaki.model.Document;
import jp.aegif.nemaki.model.Folder;
import jp.aegif.nemaki.model.Item;
import jp.aegif.nemaki.model.Policy;
import jp.aegif.nemaki.model.Property;
import jp.aegif.nemaki.model.Relationship;
import jp.aegif.nemaki.model.Rendition;
import jp.aegif.nemaki.model.VersionSeries;
import jp.aegif.nemaki.util.DataUtil;
import jp.aegif.nemaki.util.cache.NemakiCachePool;
import jp.aegif.nemaki.util.constant.CmisExtensionToken;
import net.sf.ehcache.Element;
public class CompileServiceImpl implements CompileService {
private static final Log log = LogFactory
.getLog(CompileServiceImpl.class);
private RepositoryInfoMap repositoryInfoMap;
private RepositoryService repositoryService;
private ContentService contentService;
private PermissionService permissionService;
private TypeManager typeManager;
private AclCapabilities aclCapabilities;
private NemakiCachePool nemakiCachePool;
private SortUtil sortUtil;
private boolean includeRelationshipsEnabled = true;
/**
* Builds a CMIS ObjectData from the given CouchDB content.
*/
@Override
public ObjectData compileObjectData(CallContext callContext, String repositoryId,
Content content, String filter,
Boolean includeAllowableActions, IncludeRelationships includeRelationships,
String renditionFilter, Boolean includeAcl) {
ObjectDataImpl _result = new ObjectDataImpl();
ObjectData v = nemakiCachePool.get(repositoryId).getObjectDataCache().get(content.getId());
if(v == null){
_result = compileObjectDataWithFullAttributes(callContext, repositoryId, content);
}else{
_result = (ObjectDataImpl)v;
}
ObjectData result = filterObjectData(repositoryId, _result, filter, includeAllowableActions, includeRelationships, renditionFilter, includeAcl);
return result;
}
private ObjectDataImpl compileObjectDataWithFullAttributes(CallContext callContext, String repositoryId, Content content){
ObjectDataImpl result = new ObjectDataImpl();
//Filter(any property filter MUST be done here
PropertiesImpl properties = compileProperties(callContext, repositoryId, content);
result.setProperties(properties);
// Set Allowable actions
result.setAllowableActions(compileAllowableActions(callContext, repositoryId, content));
// Set Acl
Acl acl = contentService.calculateAcl(repositoryId, content);
result.setIsExactAcl(true);
result.setAcl(compileAcl(acl, contentService.getAclInheritedWithDefault(repositoryId, content), false));
//Set Relationship(BOTH)
if (!content.isRelationship()) {
if(includeRelationshipsEnabled){
result.setRelationships(compileRelationships(callContext, repositoryId, content, IncludeRelationships.BOTH));
}
}
// Set Renditions
if (content.isDocument()){
result.setRenditions(compileRenditions(callContext, repositoryId, content));
}
nemakiCachePool.get(repositoryId).getObjectDataCache().put(new Element(content.getId(), result));
return result;
}
private ObjectData filterObjectData(String repositoryId,
ObjectData fullObjectData, String filter,
Boolean includeAllowableActions, IncludeRelationships includeRelationships,
String renditionFilter, Boolean includeAcl){
//Deep copy ObjectData
//Shallow copy will cause a destructive effect after filtering some attributes
Cloner cloner=new Cloner();
ObjectDataImpl result = DataUtil.convertObjectDataImpl(cloner.deepClone(fullObjectData));
Properties filteredProperties = filterProperties(result.getProperties(), splitFilter(filter));
result.setProperties(filteredProperties);
// Filter Allowable actions
Boolean iaa = includeAllowableActions == null ? false: includeAllowableActions.booleanValue();
if (!iaa) {
result.setAllowableActions(null);
}
// Filter Acl
Boolean iacl = includeAcl == null ? false : includeAcl.booleanValue();
if (!iacl) {
result.setAcl(null);
}
// Filter Relationships
IncludeRelationships irl = includeRelationships == null ? IncludeRelationships.SOURCE : includeRelationships;
if (fullObjectData.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) {
result.setRelationships(filterRelationships(result.getId(), result.getRelationships(), irl));
}
// Filter Renditions
if (fullObjectData.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT
&& repositoryInfoMap.get(repositoryId).getCapabilities().getRenditionsCapability() == CapabilityRenditions.NONE) {
result.setRenditions(null);
}
return result;
}
private ObjectData filterObjectDataInList(CallContext callContext, String repositoryId,
ObjectData fullObjectData, String filter,
Boolean includeAllowableActions, IncludeRelationships includeRelationships,
String renditionFilter, Boolean includeAcl){
boolean allowed = permissionService.checkPermission(callContext, Action.CAN_GET_PROPERTIES, fullObjectData);
if(allowed){
return filterObjectData(repositoryId, fullObjectData, filter, includeAllowableActions, includeRelationships, renditionFilter, includeAcl);
}else{
return null;
}
}
private Properties filterProperties(Properties properties, Set<String> filter){
PropertiesImpl result = new PropertiesImpl();
//null filter as NO FILTER: do nothing
if(filter == null){
return properties;
}else{
for(String key : properties.getProperties().keySet()){
PropertyData<?> pd = properties.getProperties().get(key);
if(filter.contains(pd.getQueryName())){
result.addProperty(pd);
}
}
}
return result;
}
private List<ObjectData> filterRelationships(String objectId, List<ObjectData> bothRelationships, IncludeRelationships includeRelationships){
String propertyId;
switch(includeRelationships){
case NONE:
return null;
case SOURCE:
propertyId = PropertyIds.SOURCE_ID;
case TARGET:
propertyId = PropertyIds.TARGET_ID;
default:
}
List<ObjectData> filtered = new ArrayList<ObjectData>();
if(CollectionUtils.isNotEmpty(bothRelationships)){
for(ObjectData rel : bothRelationships){
PropertyData<?> filterId = rel.getProperties().
getProperties().get(PropertyIds.SOURCE_ID);
if(objectId.equals(filterId)){
filtered.add(rel);
}
}
return filtered;
}else{
return null;
}
}
@Override
public <T extends Content> ObjectList compileObjectDataList(CallContext callContext,
String repositoryId, List<T> contents, String filter,
Boolean includeAllowableActions, IncludeRelationships includeRelationships,
String renditionFilter, Boolean includeAcl, BigInteger maxItems,
BigInteger skipCount, boolean folderOnly, String orderBy) {
if (CollectionUtils.isEmpty(contents)) {
//Empty list
ObjectListImpl list = new ObjectListImpl();
list.setObjects(new ArrayList<ObjectData>());
list.setNumItems(BigInteger.ZERO);
list.setHasMoreItems(false);
return list;
}else{
List<ObjectData>ods = new ArrayList<ObjectData>();
for(T c : contents){
//Filter by folderOnly
if(folderOnly && !c.isFolder()){
continue;
}
//Get each ObjectData
ObjectData _od;
ObjectData v = nemakiCachePool.get(repositoryId).getObjectDataCache().get(c.getId());
if(v == null){
_od = compileObjectDataWithFullAttributes(callContext, repositoryId, c);
}else{
_od = (ObjectDataImpl)v;
}
ObjectData od = filterObjectDataInList(callContext, repositoryId, _od, filter, includeAllowableActions, includeRelationships, renditionFilter, includeAcl);
if(od != null){
ods.add(od);
}
}
//Sort
sortUtil.sort(repositoryId, ods, orderBy);
//Set metadata
ObjectListImpl list = new ObjectListImpl();
Integer _skipCount = skipCount.intValue();
Integer _maxItems = maxItems.intValue();
if(_skipCount >= ods.size()){
list.setHasMoreItems(false);
list.setObjects(new ArrayList<ObjectData>());
}else{
//hasMoreItems
Boolean hasMoreItems = _skipCount + _maxItems < ods.size();
list.setHasMoreItems(hasMoreItems);
//paged list
Integer toIndex = Math.min(_skipCount + _maxItems, ods.size());
list.setObjects(new ArrayList<>(ods.subList(_skipCount, toIndex)));
}
//totalNumItem
list.setNumItems(BigInteger.valueOf(ods.size()));
return list;
}
}
@Override
public ObjectList compileChangeDataList(CallContext context,
String repositoryId, List<Change> changes,
Holder<String> changeLogToken, Boolean includeProperties, String filter,
Boolean includePolicyIds, Boolean includeAcl) {
ObjectListImpl results = new ObjectListImpl();
results.setObjects(new ArrayList<ObjectData>());
Map<String, Content> cachedContents = new HashMap<String, Content>();
if (changes != null && CollectionUtils.isNotEmpty(changes)) {
for (Change change : changes) {
// Retrieve the content(using caches)
String objectId = change.getId();
Content content = new Content();
if (cachedContents.containsKey(objectId)) {
content = cachedContents.get(objectId);
} else {
content = contentService.getContent(repositoryId, objectId);
cachedContents.put(objectId, content);
}
// Compile a change object data depending on its type
results.getObjects().add(
compileChangeObjectData(repositoryId, change,
content, includePolicyIds, includeAcl));
}
}
results.setNumItems(BigInteger.valueOf(results.getObjects().size()));
String latestInRepository = repositoryService.getRepositoryInfo(repositoryId)
.getLatestChangeLogToken();
String latestInResults = changeLogToken.getValue();
if (latestInResults != null && latestInResults.equals(latestInRepository)) {
results.setHasMoreItems(false);
} else {
results.setHasMoreItems(true);
}
return results;
}
private ObjectData compileChangeObjectData(String repositoryId, Change change,
Content content, Boolean includePolicyIds, Boolean includeAcl) {
ObjectDataImpl o = new ObjectDataImpl();
// Set Properties
PropertiesImpl properties = new PropertiesImpl();
setCmisBasicChangeProperties(properties, change);
o.setProperties(properties);
// Set PolicyIds
setPolcyIds(o, change, includePolicyIds);
// Set Acl
if (!change.getChangeType().equals(ChangeType.DELETED)) {
setAcl(repositoryId, o, content, includeAcl);
}
// Set Change Event
setChangeEvent(o, change);
return o;
}
private void setCmisBasicChangeProperties(PropertiesImpl props,
Change change) {
props.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_ID, change
.getObjectId()));
props.addProperty(new PropertyIdImpl(PropertyIds.BASE_TYPE_ID, change
.getBaseType()));
props.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, change
.getObjectType()));
props.addProperty(new PropertyIdImpl(PropertyIds.NAME, change.getName()));
if (change.isOnDocument()) {
props.addProperty(new PropertyIdImpl(PropertyIds.VERSION_SERIES_ID,
change.getVersionSeriesId()));
props.addProperty(new PropertyStringImpl(PropertyIds.VERSION_LABEL,
change.getVersionLabel()));
}
}
private void setPolcyIds(ObjectDataImpl object, Change change,
Boolean includePolicyids) {
boolean iplc = (includePolicyids == null ? false : includePolicyids
.booleanValue());
if (iplc) {
List<String> policyIds = change.getPolicyIds();
PolicyIdListImpl plist = new PolicyIdListImpl();
plist.setPolicyIds(policyIds);
object.setPolicyIds(plist);
}
}
private void setAcl(String repositoryId, ObjectDataImpl object,
Content content, Boolean includeAcl) {
boolean iacl = (includeAcl == null ? false : includeAcl.booleanValue());
if (iacl) {
if (content != null) {
Acl acl = contentService.calculateAcl(repositoryId, content);
//object.setAcl(compileAcl(acl, content.isAclInherited(), false));
object.setAcl(compileAcl(acl, contentService.getAclInheritedWithDefault(repositoryId, content), false));
}
}
}
private void setChangeEvent(ObjectDataImpl object, Change change) {
// Set ChangeEventInfo
ChangeEventInfoDataImpl ce = new ChangeEventInfoDataImpl();
ce.setChangeType(change.getChangeType());
ce.setChangeTime(change.getTime());
object.setChangeEventInfo(ce);
}
/**
* Sets allowable action for the content
* @param content
*/
@Override
public AllowableActions compileAllowableActions(CallContext callContext,
String repositoryId, Content content) {
// Get parameters to calculate AllowableActions
TypeDefinition tdf = typeManager.getTypeDefinition(repositoryId, content
.getObjectType());
jp.aegif.nemaki.model.Acl contentAcl = content.getAcl();
if (tdf.isControllableAcl() && contentAcl == null)
return null;
Acl acl = contentService.calculateAcl(repositoryId, content);
Map<String, PermissionMapping> permissionMap = repositoryInfoMap.get(repositoryId)
.getAclCapabilities().getPermissionMapping();
String baseType = content.getType();
// Calculate AllowableActions
Set<Action> actionSet = new HashSet<Action>();
VersionSeries versionSeries = null;
if(content.isDocument()){
Document d = (Document)content;
versionSeries = contentService.getVersionSeries(repositoryId, d);
}
for (Entry<String, PermissionMapping> mappingEntry : permissionMap
.entrySet()) {
String key = mappingEntry.getValue().getKey();
// TODO WORKAROUND. implement class cast check
// FIXME WORKAROUND: skip canCreatePolicy.Folder
if (PermissionMapping.CAN_CREATE_POLICY_FOLDER.equals(key)) {
continue;
}
// Additional check
if (!isAllowableByCapability(repositoryId, key)) {
continue;
}
if (!isAllowableByType(key, content, tdf)) {
continue;
}
if (contentService.isRoot(repositoryId, content)) {
if (Action.CAN_MOVE_OBJECT == convertKeyToAction(key)) {
continue;
}
}
if (versionSeries != null) {
Document d = (Document) content;
DocumentTypeDefinition dtdf = (DocumentTypeDefinition) tdf;
if (!isAllowableActionForVersionableDocument(callContext,
mappingEntry.getKey(), d, versionSeries, dtdf)) {
continue;
}
}
// Add an allowable action
boolean allowable = permissionService.checkPermission(callContext,
repositoryId, mappingEntry.getKey(), acl, baseType, content);
if (allowable) {
actionSet.add(convertKeyToAction(key));
}
}
AllowableActionsImpl allowableActions = new AllowableActionsImpl();
allowableActions.setAllowableActions(actionSet);
return allowableActions;
}
private boolean isAllowableActionForVersionableDocument(
CallContext callContext, String permissionMappingKey,
Document document, VersionSeries versionSeries, DocumentTypeDefinition dtdf) {
//Versioning action(checkOut / checkIn)
if (permissionMappingKey
.equals(PermissionMapping.CAN_CHECKOUT_DOCUMENT)) {
return dtdf.isVersionable() && !versionSeries.isVersionSeriesCheckedOut() && document.isLatestVersion();
} else if (permissionMappingKey
.equals(PermissionMapping.CAN_CHECKIN_DOCUMENT)) {
return dtdf.isVersionable() && versionSeries.isVersionSeriesCheckedOut() && document.isPrivateWorkingCopy();
} else if (permissionMappingKey
.equals(PermissionMapping.CAN_CANCEL_CHECKOUT_DOCUMENT)) {
return dtdf.isVersionable() && versionSeries.isVersionSeriesCheckedOut() && document.isPrivateWorkingCopy();
}
//Lock as an effect of checkOut
if(dtdf.isVersionable()){
if(isLockableAction(permissionMappingKey)){
if(document.isLatestVersion()){
//LocK only when checked out
return !versionSeries.isVersionSeriesCheckedOut();
}else if(document.isPrivateWorkingCopy()){
//Only owner can do actions on pwc
return callContext.getUsername().equals(versionSeries.getVersionSeriesCheckedOutBy());
}else{
return false;
}
}
}
return true;
}
private boolean isLockableAction(String key) {
return key.equals(PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT)
|| key.equals(PermissionMapping.CAN_SET_CONTENT_DOCUMENT)
|| key.equals(PermissionMapping.CAN_ADD_POLICY_OBJECT)
|| key.equals(PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT)
|| key.equals(PermissionMapping.CAN_APPLY_ACL_OBJECT)
|| key.equals(PermissionMapping.CAN_DELETE_CONTENT_DOCUMENT)
|| key.equals(PermissionMapping.CAN_DELETE_OBJECT)
|| key.equals(PermissionMapping.CAN_MOVE_OBJECT)
|| key.equals(PermissionMapping.CAN_REMOVE_FROM_FOLDER_OBJECT)
|| key.equals(PermissionMapping.CAN_REMOVE_POLICY_OBJECT);
}
private boolean isAllowableByCapability(String repositoryId, String key) {
RepositoryCapabilities capabilities = repositoryInfoMap.get(repositoryId).getCapabilities();
// Multifiling or Unfiling Capabilities
if (PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT.equals(key)
|| PermissionMapping.CAN_ADD_TO_FOLDER_FOLDER.equals(key)) {
// This is not a explicit spec, but it's plausible.
return capabilities.isUnfilingSupported()
|| capabilities.isMultifilingSupported();
} else if (PermissionMapping.CAN_REMOVE_FROM_FOLDER_OBJECT.equals(key)
|| PermissionMapping.CAN_REMOVE_FROM_FOLDER_FOLDER.equals(key)) {
return capabilities.isUnfilingSupported();
// GetDescendents or GetFolderTree Capabilities
} else if (PermissionMapping.CAN_GET_DESCENDENTS_FOLDER.equals(key)) {
return capabilities.isGetDescendantsSupported()
|| capabilities.isGetFolderTreeSupported();
} else {
return true;
}
}
private boolean isAllowableByType(String key, Content content,
TypeDefinition tdf) {
// ControllableACL
if (PermissionMapping.CAN_APPLY_ACL_OBJECT.equals(key)) {
// Default to FALSE
boolean ctrlAcl = (tdf.isControllableAcl() == null) ? false : tdf
.isControllableAcl();
return ctrlAcl;
// ControllablePolicy
} else if (PermissionMapping.CAN_ADD_POLICY_OBJECT.equals(key)
|| PermissionMapping.CAN_ADD_POLICY_POLICY.equals(key)
|| PermissionMapping.CAN_REMOVE_POLICY_OBJECT.equals(key)
|| PermissionMapping.CAN_REMOVE_POLICY_POLICY.equals(key)) {
// Default to FALSE
boolean ctrlPolicy = (tdf.isControllablePolicy() == null) ? false
: tdf.isControllablePolicy();
return ctrlPolicy;
// setContent
} else if (PermissionMapping.CAN_SET_CONTENT_DOCUMENT.equals(key)) {
if (BaseTypeId.CMIS_DOCUMENT != tdf.getBaseTypeId())
return true;
DocumentTypeDefinition _tdf = (DocumentTypeDefinition) tdf;
// Default to REQUIRED
ContentStreamAllowed csa = (_tdf.getContentStreamAllowed() == null) ? ContentStreamAllowed.REQUIRED
: _tdf.getContentStreamAllowed();
return !(csa == ContentStreamAllowed.NOTALLOWED);
// deleteContent
} else if (PermissionMapping.CAN_DELETE_CONTENT_DOCUMENT.equals(key)) {
if (BaseTypeId.CMIS_DOCUMENT != tdf.getBaseTypeId())
return true;
DocumentTypeDefinition _tdf = (DocumentTypeDefinition) tdf;
// Default to REQUIRED
ContentStreamAllowed csa = (_tdf.getContentStreamAllowed() == null) ? ContentStreamAllowed.REQUIRED
: _tdf.getContentStreamAllowed();
return !(csa == ContentStreamAllowed.REQUIRED);
} else {
return true;
}
}
private List<ObjectData> compileRelationships(CallContext context,
String repositoryId, Content content, IncludeRelationships irl) {
if (IncludeRelationships.NONE == irl) {
return null;
}
RelationshipDirection rd;
switch (irl) {
case SOURCE:
rd = RelationshipDirection.SOURCE;
break;
case TARGET:
rd = RelationshipDirection.TARGET;
break;
case BOTH:
rd = RelationshipDirection.EITHER;
break;
default:
rd = RelationshipDirection.SOURCE;
break;
}
List<Relationship> _rels = contentService.getRelationsipsOfObject(
repositoryId, content.getId(), rd);
List<ObjectData> rels = new ArrayList<ObjectData>();
if (CollectionUtils.isNotEmpty(_rels)) {
for (Relationship _rel : _rels) {
ObjectData rel = compileObjectData(context, repositoryId, _rel, null,
false, IncludeRelationships.NONE, null, false);
rels.add(rel);
}
}
return rels;
}
private List<RenditionData> compileRenditions(CallContext callContext,
String repositoryId, Content content) {
List<RenditionData> renditions = new ArrayList<RenditionData>();
List<Rendition> _renditions = contentService.getRenditions(repositoryId, content
.getId());
if (CollectionUtils.isNotEmpty(_renditions)) {
for (Rendition _rd : _renditions) {
RenditionDataImpl rd = new RenditionDataImpl();
rd.setStreamId(_rd.getId());
rd.setMimeType(_rd.getMimetype());
rd.setBigLength(BigInteger.valueOf(_rd.getLength()));
rd.setKind(_rd.getKind());
rd.setTitle(_rd.getTitle());
rd.setBigHeight(BigInteger.valueOf(_rd.getHeight()));
rd.setBigWidth(BigInteger.valueOf(_rd.getWidth()));
rd.setRenditionDocumentId(_rd.getRenditionDocumentId());
renditions.add(rd);
}
}
return renditions;
}
/**
* Compiles properties of a piece of content.
*/
@Override
public PropertiesImpl compileProperties(CallContext callContext, String repositoryId, Content content) {
TypeDefinitionContainer tdfc = typeManager.getTypeById(repositoryId, content.getObjectType());
TypeDefinition tdf = tdfc.getTypeDefinition();
PropertiesImpl properties = new PropertiesImpl();
if (content.isFolder()) {
Folder folder = (Folder) content;
// Root folder
if (contentService.isRoot(repositoryId, folder)) {
properties = compileRootFolderProperties(repositoryId, folder,
properties, tdf);
// Other than root folder
} else {
properties = compileFolderProperties(repositoryId, folder, properties, tdf);
}
} else if (content.isDocument()) {
Document document = (Document) content;
properties = compileDocumentProperties(callContext, repositoryId, document, properties, tdf);
} else if (content.isRelationship()) {
Relationship relationship = (Relationship) content;
properties = compileRelationshipProperties(repositoryId,
relationship, properties, tdf);
} else if (content.isPolicy()) {
Policy policy = (Policy) content;
properties = compilePolicyProperties(repositoryId, policy, properties, tdf);
} else if (content.isItem()) {
Item item = (Item) content;
properties = compileItemProperties(repositoryId, item, properties, tdf);
}
return properties;
}
private PropertiesImpl compileRootFolderProperties(String repositoryId,
Folder folder, PropertiesImpl properties, TypeDefinition tdf) {
setCmisBaseProperties(repositoryId, properties, tdf, folder);
// Add parentId property without value
String _null = null;
PropertyIdImpl parentId = new PropertyIdImpl(PropertyIds.PARENT_ID, _null);
properties.addProperty(parentId);
setCmisFolderProperties(repositoryId, properties, tdf, folder);
return properties;
}
private PropertiesImpl compileFolderProperties(String repositoryId,
Folder folder, PropertiesImpl properties, TypeDefinition tdf) {
setCmisBaseProperties(repositoryId, properties, tdf, folder);
addProperty(properties, tdf, PropertyIds.PARENT_ID, folder.getParentId());
setCmisFolderProperties(repositoryId, properties, tdf, folder);
return properties;
}
private PropertiesImpl compileDocumentProperties(CallContext callContext,
String repositoryId, Document document, PropertiesImpl properties, TypeDefinition tdf) {
setCmisBaseProperties(repositoryId, properties, tdf, document);
setCmisDocumentProperties(callContext, repositoryId, properties, tdf, document);
setCmisAttachmentProperties(repositoryId, properties, tdf, document);
return properties;
}
private PropertiesImpl compileRelationshipProperties(
String repositoryId, Relationship relationship,
PropertiesImpl properties, TypeDefinition tdf) {
setCmisBaseProperties(repositoryId, properties, tdf, relationship);
setCmisRelationshipProperties(properties, tdf, relationship);
return properties;
}
private PropertiesImpl compilePolicyProperties(String repositoryId,
Policy policy, PropertiesImpl properties, TypeDefinition tdf) {
setCmisBaseProperties(repositoryId, properties, tdf, policy);
setCmisPolicyProperties(properties, tdf, policy);
return properties;
}
private PropertiesImpl compileItemProperties(String repositoryId,
Item item, PropertiesImpl properties, TypeDefinition tdf) {
setCmisBaseProperties(repositoryId, properties, tdf, item);
setCmisItemProperties(properties, tdf, item);
return properties;
}
private void setCmisBaseProperties(String repositoryId,
PropertiesImpl properties, TypeDefinition tdf, Content content) {
addProperty(properties, tdf, PropertyIds.NAME, content.getName());
addProperty(properties, tdf, PropertyIds.DESCRIPTION, content.getDescription());
addProperty(properties, tdf, PropertyIds.OBJECT_ID, content.getId());
addProperty(properties, tdf, PropertyIds.OBJECT_TYPE_ID, content.getObjectType());
if (content.getCreated() != null)
addProperty(properties, tdf, PropertyIds.CREATION_DATE, content.getCreated());
if (content.getCreator() != null)
addProperty(properties, tdf, PropertyIds.CREATED_BY, content.getCreator());
if (content.getModified() != null) {
addProperty(properties, tdf, PropertyIds.LAST_MODIFICATION_DATE,
content.getModified());
} else {
addProperty(properties, tdf, PropertyIds.LAST_MODIFICATION_DATE,
content.getCreated());
}
if (content.getModifier() != null) {
addProperty(properties, tdf, PropertyIds.LAST_MODIFIED_BY,
content.getModifier());
} else {
addProperty(properties, tdf, PropertyIds.LAST_MODIFIED_BY,
content.getCreator());
}
addProperty(properties, tdf, PropertyIds.CHANGE_TOKEN, String.valueOf(content.getChangeToken()));
// TODO If subType properties is not registered in DB, return void
// properties via CMIS
// SubType properties
List<PropertyDefinition<?>> specificPropertyDefinitions = typeManager
.getSpecificPropertyDefinitions(tdf.getId());
if (!CollectionUtils.isEmpty(specificPropertyDefinitions)) {
for (PropertyDefinition<?> propertyDefinition : specificPropertyDefinitions) {
Property property = extractSubTypeProperty(content,
propertyDefinition.getId());
Object value = (property == null) ? null : property.getValue();
addProperty(properties,tdf, propertyDefinition.getId(),
value);
}
}
// Secondary properties
setCmisSecondaryTypes(repositoryId, properties, content, tdf);
}
private Property extractSubTypeProperty(Content content, String propertyId) {
List<Property> subTypeProperties = content.getSubTypeProperties();
if (CollectionUtils.isNotEmpty(subTypeProperties)) {
for (Property subTypeProperty : subTypeProperties) {
if (subTypeProperty.getKey().equals(propertyId)) {
return subTypeProperty;
}
}
}
return null;
}
private void setCmisFolderProperties(String repositoryId,
PropertiesImpl properties, TypeDefinition tdf, Folder folder) {
addProperty(properties, tdf, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_FOLDER.value());
addProperty(properties, tdf, PropertyIds.PATH, contentService.calculatePath(repositoryId, folder));
if (checkAddProperty(properties, tdf, PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS)) {
List<String> values = new ArrayList<String>();
// If not specified, all child types are allowed.
if (!CollectionUtils.isEmpty(folder.getAllowedChildTypeIds())) {
values = folder.getAllowedChildTypeIds();
}
PropertyData<String> pd = new PropertyIdImpl(
PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS, values);
properties.addProperty(pd);
}
}
private void setCmisDocumentProperties(CallContext callContext,
String repositoryId, PropertiesImpl properties, TypeDefinition tdf, Document document) {
addProperty(properties, tdf, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value());
Boolean isImmutable = (document.isImmutable() == null) ? (Boolean) typeManager
.getSingleDefaultValue(PropertyIds.IS_IMMUTABLE, tdf.getId(), repositoryId)
: document.isImmutable();
addProperty(properties, tdf, PropertyIds.IS_IMMUTABLE, isImmutable);
DocumentTypeDefinition type = (DocumentTypeDefinition) typeManager
.getTypeDefinition(repositoryId, tdf.getId());
if (type.isVersionable()) {
addProperty(properties, tdf, PropertyIds.IS_PRIVATE_WORKING_COPY,
document.isPrivateWorkingCopy());
addProperty(properties, tdf, PropertyIds.IS_LATEST_VERSION,
document.isLatestVersion());
addProperty(properties, tdf, PropertyIds.IS_MAJOR_VERSION,
document.isMajorVersion());
addProperty(properties, tdf, PropertyIds.IS_LATEST_MAJOR_VERSION,
document.isLatestMajorVersion());
addProperty(properties, tdf, PropertyIds.VERSION_LABEL, document.getVersionLabel());
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_ID,
document.getVersionSeriesId());
addProperty(properties, tdf, PropertyIds.CHECKIN_COMMENT,
document.getCheckinComment());
VersionSeries vs = contentService.getVersionSeries(repositoryId, document);
addProperty(properties, tdf, PropertyIds.IS_VERSION_SERIES_CHECKED_OUT,
vs.isVersionSeriesCheckedOut());
if (vs.isVersionSeriesCheckedOut()) {
String userId = callContext.getUsername();
String checkedOutBy = vs.getVersionSeriesCheckedOutBy();
if(userId.equals(checkedOutBy)){
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID,
vs.getVersionSeriesCheckedOutId());
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_BY,
checkedOutBy);
}else{
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID,
null);
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_BY,
checkedOutBy);
}
} else {
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID,
null);
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_BY,
null);
}
// TODO comment
} else {
addProperty(properties, tdf, PropertyIds.IS_PRIVATE_WORKING_COPY,
false);
addProperty(properties, tdf, PropertyIds.IS_LATEST_VERSION,
false);
addProperty(properties, tdf, PropertyIds.IS_MAJOR_VERSION,
false);
addProperty(properties, tdf, PropertyIds.IS_LATEST_MAJOR_VERSION,
false);
addProperty(properties, tdf, PropertyIds.VERSION_LABEL, "");
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_ID,
"");
addProperty(properties, tdf, PropertyIds.CHECKIN_COMMENT,
"");
addProperty(properties, tdf, PropertyIds.IS_VERSION_SERIES_CHECKED_OUT,
false);
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID,
"");
addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_BY,
"");
}
}
private void setCmisAttachmentProperties(String repositoryId,
PropertiesImpl properties, TypeDefinition tdf, Document document) {
Long length = null;
String mimeType = null;
String fileName = null;
String streamId = null;
//Check if ContentStream is attached
DocumentTypeDefinition dtdf = (DocumentTypeDefinition)tdf;
ContentStreamAllowed csa = dtdf.getContentStreamAllowed();
if(ContentStreamAllowed.REQUIRED == csa ||
ContentStreamAllowed.ALLOWED == csa && StringUtils.isNotBlank(document.getAttachmentNodeId())){
AttachmentNode attachment = contentService.getAttachmentRef(repositoryId, document
.getAttachmentNodeId());
if(attachment == null){
String attachmentId = (document.getAttachmentNodeId() == null) ? "" : document.getAttachmentNodeId();
log.warn("[objectId=" + document.getId() + " has no file (" +
attachmentId + ")");
}else{
length = attachment.getLength();
mimeType = attachment.getMimeType();
fileName = document.getName();
streamId = attachment.getId();
}
}
//Add ContentStream properties to Document object
addProperty(properties, dtdf, PropertyIds.CONTENT_STREAM_LENGTH,
length);
addProperty(properties, dtdf, PropertyIds.CONTENT_STREAM_MIME_TYPE,
mimeType);
addProperty(properties, dtdf, PropertyIds.CONTENT_STREAM_FILE_NAME,
fileName);
addProperty(properties, dtdf, PropertyIds.CONTENT_STREAM_ID, streamId);
}
private void setCmisRelationshipProperties(PropertiesImpl properties,
TypeDefinition typeId, Relationship relationship) {
addProperty(properties, typeId, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_RELATIONSHIP.value());
addProperty(properties, typeId, PropertyIds.SOURCE_ID, relationship.getSourceId());
addProperty(properties, typeId, PropertyIds.TARGET_ID, relationship.getTargetId());
}
private void setCmisPolicyProperties(PropertiesImpl properties,
TypeDefinition tdf, Policy policy) {
addProperty(properties, tdf, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_POLICY.value());
addProperty(properties, tdf, PropertyIds.POLICY_TEXT, policy.getPolicyText());
}
private void setCmisItemProperties(PropertiesImpl properties,
TypeDefinition tdf, Item item) {
addProperty(properties, tdf, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_ITEM.value());
}
private void setCmisSecondaryTypes(String repositoryId, PropertiesImpl props,
Content content, TypeDefinition tdf) {
List<Aspect> aspects = content.getAspects();
List<String> secondaryIds = new ArrayList<String>();
// cmis:secondaryObjectTypeIds
if (CollectionUtils.isNotEmpty(content.getSecondaryIds())) {
for (String secondaryId : content.getSecondaryIds()) {
secondaryIds.add(secondaryId);
}
}
new PropertyIdImpl(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryIds);
addProperty(props, tdf, PropertyIds.SECONDARY_OBJECT_TYPE_IDS,
secondaryIds);
// each secondary properties
for (String secondaryId : secondaryIds) {
List<PropertyDefinition<?>> secondaryPropertyDefinitions = typeManager
.getSpecificPropertyDefinitions(secondaryId);
if (CollectionUtils.isEmpty(secondaryPropertyDefinitions))
continue;
Aspect aspect = extractAspect(aspects, secondaryId);
List<Property> properties = (aspect == null) ? new ArrayList<Property>()
: aspect.getProperties();
SecondaryTypeDefinition stdf = (SecondaryTypeDefinition)typeManager.getTypeDefinition(repositoryId, secondaryId);
for (PropertyDefinition<?> secondaryPropertyDefinition : secondaryPropertyDefinitions) {
Property property = extractProperty(properties,
secondaryPropertyDefinition.getId());
Object value = (property == null) ? null : property.getValue();
addProperty(props, stdf, secondaryPropertyDefinition.getId(),
value);
}
}
}
private Aspect extractAspect(List<Aspect> aspects, String aspectId) {
for (Aspect aspect : aspects) {
if (aspect.getName().equals(aspectId)) {
return aspect;
}
}
return null;
}
private Property extractProperty(List<Property> properties,
String propertyId) {
for (Property property : properties) {
if (property.getKey().equals(propertyId)) {
return property;
}
}
return null;
}
/**
* Verifies that parameters are safe.
*/
private boolean checkAddProperty(Properties properties, TypeDefinition tdf, String id) {
if ((properties == null) || (properties.getProperties() == null))
throw new IllegalArgumentException("Properties must not be null!");
if (StringUtils.isEmpty(id))
throw new IllegalArgumentException("ID must not be null!");
// TODO :performance
if (!tdf.getPropertyDefinitions().containsKey(id))
throw new IllegalArgumentException("Unknown property: " + id);
//String queryName = tdf.getPropertyDefinitions().get(id).getQueryName();
/*
if ((queryName != null) && (filter != null)) {
if (!filter.contains(queryName)) {
return false;
} else {
filter.remove(queryName);
}
}*/
return true;
}
/**
* Adds specified property in property set.
*
* @param props
* property set
* @param tdf
* object type (e.g. cmis:document)
* @param id
* property ID
* @param value
* actual property value
*/
// TODO if cast fails, continue the operation
private void addProperty(PropertiesImpl props, TypeDefinition tdf,
String id, Object value) {
try {
PropertyDefinition<?> pdf = tdf.getPropertyDefinitions().get(id);
if (!checkAddProperty(props, tdf, id))
return;
switch (pdf.getPropertyType()) {
case BOOLEAN:
PropertyBooleanImpl propBoolean;
if (value instanceof List<?>) {
propBoolean = new PropertyBooleanImpl(id,
(List<Boolean>) value);
} else if (value instanceof Boolean) {
propBoolean = new PropertyBooleanImpl(id, (Boolean) value);
} else {
Boolean _null = null;
propBoolean = new PropertyBooleanImpl(id, _null);
if (value != null) {
String msg = buildCastErrMsg(tdf.getId(), id,
pdf.getPropertyType(), value.getClass()
.getName(), Boolean.class.getName());
log.warn(msg);
}
}
addPropertyBase(props, id, propBoolean, pdf);
break;
case INTEGER:
PropertyIntegerImpl propInteger;
if (value instanceof List<?>) {
propInteger = new PropertyIntegerImpl(id,
(List<BigInteger>) value);
} else if (value instanceof Long || value instanceof Integer) {
propInteger = new PropertyIntegerImpl(id,
BigInteger.valueOf((Long) value));
} else {
BigInteger _null = null;
propInteger = new PropertyIntegerImpl(id, _null);
if (value != null) {
String msg = buildCastErrMsg(tdf.getId(), id,
pdf.getPropertyType(), value.getClass()
.getName(), Long.class.getName());
log.warn(msg);
}
}
addPropertyBase(props, id, propInteger, pdf);
break;
case DATETIME:
PropertyDateTimeImpl propDate;
if (value instanceof List<?>) {
propDate = new PropertyDateTimeImpl(id,
(List<GregorianCalendar>) value);
} else if (value instanceof GregorianCalendar) {
propDate = new PropertyDateTimeImpl(id,
(GregorianCalendar) value);
} else {
GregorianCalendar _null = null;
propDate = new PropertyDateTimeImpl(id, _null);
if (value != null) {
String msg = buildCastErrMsg(tdf.getId(), id,
pdf.getPropertyType(), value.getClass()
.getName(),
GregorianCalendar.class.getName());
log.warn(msg);
}
}
addPropertyBase(props, id, propDate, pdf);
break;
case STRING:
PropertyStringImpl propString = new PropertyStringImpl();
propString.setId(id);
if (value instanceof List<?>) {
propString.setValues((List<String>) value);
} else if (value instanceof String) {
propString.setValue(String.valueOf(value));
} else {
String _null = null;
propString = new PropertyStringImpl(id, _null);
if (value != null) {
String msg = buildCastErrMsg(tdf.getId(), id,
pdf.getPropertyType(), value.getClass()
.getName(), String.class.getName());
log.warn(msg);
}
}
addPropertyBase(props, id, propString, pdf);
break;
case ID:
PropertyIdImpl propId = new PropertyIdImpl();
propId.setId(id);
if (value instanceof List<?>) {
propId.setValues((List<String>) value);
} else if (value instanceof String) {
propId.setValue(String.valueOf(value));
} else {
String _null = null;
propId = new PropertyIdImpl(id, _null);
if (value != null) {
String msg = buildCastErrMsg(tdf.getId(), id,
pdf.getPropertyType(), value.getClass()
.getName(), String.class.getName());
log.warn(msg);
}
}
addPropertyBase(props, id, propId, pdf);
break;
default:
}
} catch (Exception e) {
log.warn("typeId:" + tdf + ", propertyId:" + id
+ " Fail to add a property!", e);
}
}
private String buildCastErrMsg(String typeId, String propertyId,
PropertyType propertyType, String sourceClass, String targetClass) {
return "[typeId:" + typeId + ", propertyId:" + propertyId
+ ", propertyType:" + propertyType.value() + "]Cannot convert "
+ sourceClass + " to " + targetClass;
}
private <T> void addPropertyBase(PropertiesImpl props, String id,
AbstractPropertyData<T> p, PropertyDefinition<?> pdf) {
p.setDisplayName(pdf.getDisplayName());
p.setLocalName(id);
p.setQueryName(pdf.getQueryName());
props.addProperty(p);
}
/**
* Separates filter string with ','. If filter is null or empty, it means
* all properties can go.
*/
// TODO implement CMIS filterNotValid exception?
// NOTE: "not set" can mean "all properties" and invalid queryName should be
// ignored.
// NOTE: So, filterNotValid exception might not be needed.
@Override
public Set<String> splitFilter(String filter) {
final String ASTERISK = "*";
final String COMMA = ",";
if (filter == null || filter.trim().length() == 0) {
return null;
}
Set<String> filters = new HashSet<String>();
for (String s : filter.split(COMMA)) {
s = s.trim();
if (s.equals(ASTERISK)) {
return null;
} else if (s.length() > 0) {
filters.add(s);
}
}
// set a few base properties for ObjetInfo
// query name == id (for base type properties)
filters.add(PropertyIds.OBJECT_ID);
filters.add(PropertyIds.OBJECT_TYPE_ID);
filters.add(PropertyIds.BASE_TYPE_ID);
return filters;
}
private Action convertKeyToAction(String key) {
// NavigationServices
if (PermissionMapping.CAN_GET_DESCENDENTS_FOLDER.equals(key))
return Action.CAN_GET_DESCENDANTS;
if (PermissionMapping.CAN_GET_CHILDREN_FOLDER.equals(key))
return Action.CAN_GET_CHILDREN;
if (PermissionMapping.CAN_GET_FOLDER_PARENT_OBJECT.equals(key))
return Action.CAN_GET_FOLDER_PARENT;
if (PermissionMapping.CAN_GET_PARENTS_FOLDER.equals(key))
return Action.CAN_GET_OBJECT_PARENTS;
// Object Services
if (PermissionMapping.CAN_CREATE_DOCUMENT_FOLDER.equals(key))
return Action.CAN_CREATE_DOCUMENT;
if (PermissionMapping.CAN_CREATE_FOLDER_FOLDER.equals(key))
return Action.CAN_CREATE_FOLDER;
// FIXME the constant already implemented?
// if (PermissionMapping.CAN_CREATE_POLICY_FOLDER.equals(key))
// return null;
if (PermissionMapping.CAN_CREATE_RELATIONSHIP_SOURCE.equals(key))
return Action.CAN_CREATE_RELATIONSHIP;
if (PermissionMapping.CAN_CREATE_RELATIONSHIP_TARGET.equals(key))
return Action.CAN_CREATE_RELATIONSHIP;
if (PermissionMapping.CAN_GET_PROPERTIES_OBJECT.equals(key))
return Action.CAN_GET_PROPERTIES;
if (PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT.equals(key))
return Action.CAN_UPDATE_PROPERTIES;
if (PermissionMapping.CAN_MOVE_OBJECT.equals(key))
return Action.CAN_MOVE_OBJECT;
if (PermissionMapping.CAN_MOVE_TARGET.equals(key))
return Action.CAN_MOVE_OBJECT;
if (PermissionMapping.CAN_MOVE_SOURCE.equals(key))
return Action.CAN_MOVE_OBJECT;
if (PermissionMapping.CAN_DELETE_OBJECT.equals(key))
return Action.CAN_DELETE_OBJECT;
if (PermissionMapping.CAN_VIEW_CONTENT_OBJECT.equals(key))
return Action.CAN_GET_CONTENT_STREAM;
if (PermissionMapping.CAN_SET_CONTENT_DOCUMENT.equals(key))
return Action.CAN_SET_CONTENT_STREAM;
if (PermissionMapping.CAN_DELETE_CONTENT_DOCUMENT.equals(key))
return Action.CAN_DELETE_CONTENT_STREAM;
if (PermissionMapping.CAN_DELETE_TREE_FOLDER.equals(key))
return Action.CAN_DELETE_TREE;
// Filing Services
if (PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT.equals(key))
return Action.CAN_ADD_OBJECT_TO_FOLDER;
if (PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT.equals(key))
return Action.CAN_ADD_OBJECT_TO_FOLDER;
if (PermissionMapping.CAN_REMOVE_FROM_FOLDER_OBJECT.equals(key))
return Action.CAN_REMOVE_OBJECT_FROM_FOLDER;
if (PermissionMapping.CAN_REMOVE_FROM_FOLDER_FOLDER.equals(key))
return Action.CAN_REMOVE_OBJECT_FROM_FOLDER;
// Versioning Services
if (PermissionMapping.CAN_CHECKOUT_DOCUMENT.equals(key))
return Action.CAN_CHECK_OUT;
if (PermissionMapping.CAN_CANCEL_CHECKOUT_DOCUMENT.equals(key))
return Action.CAN_CANCEL_CHECK_OUT;
if (PermissionMapping.CAN_CHECKIN_DOCUMENT.equals(key))
return Action.CAN_CHECK_IN;
if (PermissionMapping.CAN_GET_ALL_VERSIONS_VERSION_SERIES.equals(key))
return Action.CAN_GET_ALL_VERSIONS;
// Relationship Services
if (PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT.equals(key))
return Action.CAN_GET_OBJECT_RELATIONSHIPS;
// Policy Services
if (PermissionMapping.CAN_ADD_POLICY_OBJECT.equals(key))
return Action.CAN_APPLY_POLICY;
if (PermissionMapping.CAN_ADD_POLICY_POLICY.equals(key))
return Action.CAN_APPLY_POLICY;
if (PermissionMapping.CAN_REMOVE_POLICY_OBJECT.equals(key))
return Action.CAN_REMOVE_POLICY;
if (PermissionMapping.CAN_REMOVE_POLICY_POLICY.equals(key))
return Action.CAN_REMOVE_POLICY;
if (PermissionMapping.CAN_GET_APPLIED_POLICIES_OBJECT.equals(key))
return Action.CAN_GET_APPLIED_POLICIES;
// ACL Services
if (PermissionMapping.CAN_GET_ACL_OBJECT.equals(key))
return Action.CAN_GET_ACL;
if (PermissionMapping.CAN_APPLY_ACL_OBJECT.equals(key))
return Action.CAN_APPLY_ACL;
return null;
}
@Override
public org.apache.chemistry.opencmis.commons.data.Acl compileAcl(
Acl acl, Boolean isInherited, Boolean onlyBasicPermissions){
//Default to FALSE
boolean obp = (onlyBasicPermissions == null) ? false : onlyBasicPermissions;
AccessControlListImpl cmisAcl = new AccessControlListImpl();
cmisAcl.setAces(new ArrayList<org.apache.chemistry.opencmis.commons.data.Ace>());
if(acl != null){
// Set local ACEs
buildCmisAce(cmisAcl, true, acl.getLocalAces(), obp);
// Set inherited ACEs
buildCmisAce(cmisAcl, false, acl.getInheritedAces(), obp);
}
// Set "exact" property
cmisAcl.setExact(true);
// Set "inherited" property, which is out of bounds to CMIS
String namespace = CmisExtensionToken.ACL_INHERITANCE_NAMESPACE;
//boolean iht = (isInherited == null)? false : isInherited;
CmisExtensionElementImpl inherited = new CmisExtensionElementImpl(
namespace, CmisExtensionToken.ACL_INHERITANCE_INHERITED, null, String.valueOf(isInherited));
List<CmisExtensionElement> exts = new ArrayList<CmisExtensionElement>();
exts.add(inherited);
cmisAcl.setExtensions(exts);
return cmisAcl;
}
private void buildCmisAce(AccessControlListImpl cmisAcl, boolean direct, List<Ace> aces, boolean onlyBasicPermissions){
if(CollectionUtils.isNotEmpty(aces)){
for (Ace ace : aces) {
//Set principal
Principal principal = new AccessControlPrincipalDataImpl(
ace.getPrincipalId());
//Set permissions
List<String> permissions= new ArrayList<String>();
if(onlyBasicPermissions && CollectionUtils.isNotEmpty(ace.getPermissions())){
HashMap<String,String> map = aclCapabilities.getBasicPermissionConversion();
//Translate permissions as CMIS Basic permissions
for(String p : ace.getPermissions()){
permissions.add(map.get(p));
}
}else{
permissions = ace.getPermissions();
}
//Build CMIS ACE
AccessControlEntryImpl cmisAce = new AccessControlEntryImpl(
principal, permissions);
//Set direct flag
cmisAce.setDirect(direct);
cmisAcl.getAces().add(cmisAce);
}
}
}
public void setRepositoryInfoMap(RepositoryInfoMap repositoryInfoMap) {
this.repositoryInfoMap = repositoryInfoMap;
}
public void setRepositoryService(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}
public void setContentService(ContentService contentService) {
this.contentService = contentService;
}
public void setPermissionService(PermissionService permissionService) {
this.permissionService = permissionService;
}
public void setAclCapabilities(AclCapabilities aclCapabilities) {
this.aclCapabilities = aclCapabilities;
}
public void setTypeManager(TypeManager typeManager) {
this.typeManager = typeManager;
}
public void setNemakiCachePool(NemakiCachePool nemakiCachePool) {
this.nemakiCachePool = nemakiCachePool;
}
public void setIncludeRelationshipsEnabled(boolean includeRelationshipsEnabled) {
this.includeRelationshipsEnabled = includeRelationshipsEnabled;
}
public void setSortUtil(SortUtil sortUtil) {
this.sortUtil = sortUtil;
}
}