mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.1 to HEAD
12867: Part 1: JAWS-220: Fix existing tests and tests for sort 12879: JAWS-219: Part 1: First cut of support for CMIS objectid = objectid joins 12891: Complete minimalist support for Policies 12912: CMIS Query: JAWS-219: Tests, fixes and better checking 13062: Fix for ETHREEOH-1162:Issue with skipCount parameter for CMIS query service git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13224 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -40,6 +40,7 @@ import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
@@ -95,6 +96,8 @@ public abstract class BaseCMISTest extends TestCase
|
||||
|
||||
protected SearchService searchService;
|
||||
|
||||
protected ContentService contentService;
|
||||
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
|
||||
@@ -114,6 +117,8 @@ public abstract class BaseCMISTest extends TestCase
|
||||
|
||||
searchService = (SearchService) ctx.getBean("searchService");
|
||||
|
||||
contentService = (ContentService) ctx.getBean("contentService");
|
||||
|
||||
authenticationService = (AuthenticationService) ctx.getBean("authenticationService");
|
||||
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
|
||||
|
||||
@@ -121,7 +126,7 @@ public abstract class BaseCMISTest extends TestCase
|
||||
testTX.begin();
|
||||
this.authenticationComponent.setSystemUserAsCurrentUser();
|
||||
|
||||
String storeName = "CMISTest-" + getName() + "-" + (new Date().getTime());
|
||||
String storeName = "CMISTest-" + getStoreName() + "-" + (new Date().getTime());
|
||||
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, storeName);
|
||||
rootNodeRef = nodeService.getRootNode(storeRef);
|
||||
|
||||
@@ -131,6 +136,15 @@ public abstract class BaseCMISTest extends TestCase
|
||||
}
|
||||
authenticationService.createAuthentication("cmis", "cmis".toCharArray());
|
||||
}
|
||||
|
||||
private String getStoreName()
|
||||
{
|
||||
String testName = getName();
|
||||
testName = testName.replace("_", "-");
|
||||
testName = testName.replace("%", "-");
|
||||
return testName;
|
||||
|
||||
}
|
||||
|
||||
protected void runAs(String userName)
|
||||
{
|
||||
|
@@ -44,9 +44,9 @@ import org.alfresco.service.namespace.QName;
|
||||
public class CMISDictionaryService
|
||||
{
|
||||
private CMISMapping cmisMapping;
|
||||
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
|
||||
private boolean strict = true;
|
||||
|
||||
/**
|
||||
@@ -58,15 +58,15 @@ public class CMISDictionaryService
|
||||
{
|
||||
this.cmisMapping = cmisMapping;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return cmis mapping service
|
||||
* @return cmis mapping service
|
||||
*/
|
||||
public CMISMapping getCMISMapping()
|
||||
{
|
||||
return cmisMapping;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the dictionary Service
|
||||
*
|
||||
@@ -82,11 +82,11 @@ public class CMISDictionaryService
|
||||
*
|
||||
* @return dictionaryService
|
||||
*/
|
||||
/*package*/ DictionaryService getDictionaryService()
|
||||
/* package */DictionaryService getDictionaryService()
|
||||
{
|
||||
return this.dictionaryService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is the service strict (CMIS types only)
|
||||
*
|
||||
@@ -145,6 +145,8 @@ public class CMISDictionaryService
|
||||
{
|
||||
answer.add(cmisMapping.getCmisTypeId(CMISScope.RELATIONSHIP, typeQName));
|
||||
}
|
||||
// TODO: Policy
|
||||
// For now, policies are not reported
|
||||
}
|
||||
|
||||
for (QName associationName : alfrescoAssociationQNames)
|
||||
@@ -162,7 +164,8 @@ public class CMISDictionaryService
|
||||
* Gets all the object type ids within a type hierarchy
|
||||
*
|
||||
* @param typeId
|
||||
* @param descendants true => include all descendants, false => children only
|
||||
* @param descendants
|
||||
* true => include all descendants, false => children only
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeId> getChildTypeIds(CMISTypeId typeId, boolean descendants)
|
||||
@@ -218,11 +221,13 @@ public class CMISDictionaryService
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
case POLICY:
|
||||
// TODO: Policy
|
||||
default:
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the object type definition TODO: Note there can be name collisions between types and associations. e.g.
|
||||
* app:configurations Currently clashing types will give inconsistent behaviour
|
||||
@@ -262,11 +267,13 @@ public class CMISDictionaryService
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case POLICY:
|
||||
// TODO: Policy
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all the property definitions for a type
|
||||
*
|
||||
@@ -333,6 +340,39 @@ public class CMISDictionaryService
|
||||
}
|
||||
}
|
||||
break;
|
||||
case POLICY:
|
||||
AspectDefinition aspectDefinition = dictionaryService.getAspect(typeId.getQName());
|
||||
if (aspectDefinition != null)
|
||||
{
|
||||
|
||||
for (QName qname : aspectDefinition.getProperties().keySet())
|
||||
{
|
||||
if (cmisMapping.getPropertyType(qname) != null)
|
||||
{
|
||||
CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(this, qname, aspectDefinition.getName());
|
||||
properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition);
|
||||
}
|
||||
}
|
||||
for (AspectDefinition aspect : aspectDefinition.getDefaultAspects())
|
||||
{
|
||||
for (QName qname : aspect.getProperties().keySet())
|
||||
{
|
||||
if (cmisMapping.getPropertyType(qname) != null)
|
||||
{
|
||||
CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(this, qname, aspectDefinition.getName());
|
||||
properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add CMIS properties if required
|
||||
if (!cmisMapping.isCmisCoreType(typeId.getQName()))
|
||||
{
|
||||
properties.putAll(getPropertyDefinitions(typeId.getRootTypeId()));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
|
@@ -31,6 +31,7 @@ import org.alfresco.cmis.CMISPropertyTypeEnum;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
@@ -75,6 +76,11 @@ public class CMISMapping
|
||||
*/
|
||||
public static String RELATIONSHIP_OBJECT_TYPE = "Relationship";
|
||||
|
||||
/**
|
||||
* Type Id for CMIS Policies, from the spec.
|
||||
*/
|
||||
public static String POLICY_OBJECT_TYPE = "Policy";
|
||||
|
||||
/**
|
||||
* QName for CMIS documents in the Alfresco CMIS model.
|
||||
*/
|
||||
@@ -90,14 +96,18 @@ public class CMISMapping
|
||||
*/
|
||||
public static QName RELATIONSHIP_QNAME = QName.createQName(CMIS_MODEL_URI, RELATIONSHIP_OBJECT_TYPE);
|
||||
|
||||
public static QName POLICY_QNAME = QName.createQName(CMIS_MODEL_URI, POLICY_OBJECT_TYPE);
|
||||
|
||||
// TODO: spec issue - objectTypeEnum is lower cased - object type ids are repository specific in spec
|
||||
|
||||
|
||||
public static CMISTypeId DOCUMENT_TYPE_ID = new CMISTypeId(CMISScope.DOCUMENT, DOCUMENT_QNAME, DOCUMENT_OBJECT_TYPE.toLowerCase());
|
||||
|
||||
public static CMISTypeId FOLDER_TYPE_ID = new CMISTypeId(CMISScope.FOLDER, FOLDER_QNAME, FOLDER_OBJECT_TYPE.toLowerCase());
|
||||
|
||||
public static CMISTypeId RELATIONSHIP_TYPE_ID = new CMISTypeId(CMISScope.RELATIONSHIP, RELATIONSHIP_QNAME, RELATIONSHIP_OBJECT_TYPE.toLowerCase());
|
||||
|
||||
public static CMISTypeId POLICY_TYPE_ID = new CMISTypeId(CMISScope.POLICY, POLICY_QNAME, POLICY_OBJECT_TYPE.toLowerCase());
|
||||
|
||||
// CMIS properties
|
||||
|
||||
public static String PROP_OBJECT_ID = "ObjectId";
|
||||
@@ -156,6 +166,10 @@ public class CMISMapping
|
||||
|
||||
public static String PROP_TARGET_ID = "TargetId";
|
||||
|
||||
// QNames
|
||||
|
||||
public static QName PROP_OBJECT_ID_QNAME = QName.createQName(CMIS_MODEL_URI, PROP_OBJECT_ID);
|
||||
|
||||
// Mappings
|
||||
// - no entry means no mapping and pass through as is
|
||||
|
||||
@@ -175,10 +189,12 @@ public class CMISMapping
|
||||
qNameToCmisTypeId.put(DOCUMENT_QNAME, DOCUMENT_TYPE_ID);
|
||||
qNameToCmisTypeId.put(FOLDER_QNAME, FOLDER_TYPE_ID);
|
||||
qNameToCmisTypeId.put(RELATIONSHIP_QNAME, RELATIONSHIP_TYPE_ID);
|
||||
qNameToCmisTypeId.put(POLICY_QNAME, POLICY_TYPE_ID);
|
||||
|
||||
cmisToAlfrecsoTypes.put(DOCUMENT_QNAME, ContentModel.TYPE_CONTENT);
|
||||
cmisToAlfrecsoTypes.put(FOLDER_QNAME, ContentModel.TYPE_FOLDER);
|
||||
cmisToAlfrecsoTypes.put(RELATIONSHIP_QNAME, null);
|
||||
cmisToAlfrecsoTypes.put(POLICY_QNAME, null);
|
||||
|
||||
alfrescoToCmisTypes.put(ContentModel.TYPE_CONTENT, DOCUMENT_QNAME);
|
||||
alfrescoToCmisTypes.put(ContentModel.TYPE_FOLDER, FOLDER_QNAME);
|
||||
@@ -280,7 +296,10 @@ public class CMISMapping
|
||||
{
|
||||
return RELATIONSHIP_TYPE_ID;
|
||||
}
|
||||
// TODO: Policy root object type
|
||||
else if (typeId.equalsIgnoreCase(POLICY_TYPE_ID.getTypeId()))
|
||||
{
|
||||
return POLICY_TYPE_ID;
|
||||
}
|
||||
|
||||
// Is it an Alfresco type id?
|
||||
if (typeId.length() < 4 || typeId.charAt(1) != '/')
|
||||
@@ -347,7 +366,15 @@ public class CMISMapping
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
ClassDefinition classDef = dictionaryService.getClass(typeQName);
|
||||
if (classDef.isAspect())
|
||||
{
|
||||
return getCmisTypeId(CMISScope.POLICY, getCmisType(typeQName));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -395,6 +422,8 @@ public class CMISMapping
|
||||
*/
|
||||
public boolean isValidCmisType(QName typeQName)
|
||||
{
|
||||
// TODO: Policy: Include aspects types as policies
|
||||
// TODO: Policy: Add isValidCmispolicy(QName typeQName)
|
||||
return isValidCmisFolder(typeQName) || isValidCmisDocument(typeQName) || isValidCmisRelationship(typeQName);
|
||||
}
|
||||
|
||||
@@ -530,7 +559,7 @@ public class CMISMapping
|
||||
}
|
||||
return typeQName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a CMIS model type map it to the appropriate Alfresco type.
|
||||
*
|
||||
@@ -559,6 +588,21 @@ public class CMISMapping
|
||||
return buildPrefixEncodedString(propertyQName, false);
|
||||
}
|
||||
|
||||
public CMISTypeId getCmisTypeForProperty(QName propertyQName)
|
||||
{
|
||||
PropertyDefinition pDef = dictionaryService.getProperty(propertyQName);
|
||||
if (pDef != null)
|
||||
{
|
||||
QName typeQName = pDef.getContainerClass().getName();
|
||||
return getCmisTypeId(typeQName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CMIS property type for a property
|
||||
*
|
||||
@@ -615,6 +659,23 @@ public class CMISMapping
|
||||
// Find prefix and property name - in upper case
|
||||
|
||||
int split = cmisPropertyName.indexOf('_');
|
||||
|
||||
// CMIS case insensitive hunt - no prefix
|
||||
if (split == -1)
|
||||
{
|
||||
for (QName qname : dictionaryService.getAllProperties(null))
|
||||
{
|
||||
if (qname.getNamespaceURI().equals(CMIS_MODEL_URI))
|
||||
{
|
||||
if (qname.getLocalName().equalsIgnoreCase(cmisPropertyName))
|
||||
{
|
||||
return qname;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String prefix = cmisPropertyName.substring(0, split);
|
||||
String localName = cmisPropertyName.substring(split + 1);
|
||||
|
||||
@@ -671,10 +732,18 @@ public class CMISMapping
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (tableName.equalsIgnoreCase(POLICY_TYPE_ID.getTypeId()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find prefix and property name - in upper case
|
||||
|
||||
int split = tableName.indexOf('_');
|
||||
if (split == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String prefix = tableName.substring(0, split);
|
||||
String localName = tableName.substring(split + 1);
|
||||
|
||||
|
@@ -35,6 +35,7 @@ import org.alfresco.cmis.CMISContentStreamAllowedEnum;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -71,6 +72,7 @@ public class CMISTypeDefinition implements Serializable
|
||||
|
||||
private boolean queryable;
|
||||
|
||||
// TODO: Policy - report controllable true as policies can be applied
|
||||
private boolean controllable;
|
||||
|
||||
private boolean versionable;
|
||||
@@ -161,7 +163,7 @@ public class CMISTypeDefinition implements Serializable
|
||||
break;
|
||||
case DOCUMENT:
|
||||
case FOLDER:
|
||||
TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName());
|
||||
ClassDefinition typeDefinition = dictionaryService.getType(typeId.getQName());
|
||||
if (typeDefinition != null)
|
||||
{
|
||||
objectTypeId = typeId;
|
||||
@@ -227,6 +229,25 @@ public class CMISTypeDefinition implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case POLICY:
|
||||
ClassDefinition classDefinition = dictionaryService.getType(typeId.getQName());
|
||||
if (classDefinition != null)
|
||||
{
|
||||
objectTypeId = typeId;
|
||||
objectTypeQueryName = cmisMapping.getQueryName(typeId.getQName());
|
||||
displayName = (classDefinition.getTitle() != null) ? classDefinition.getTitle() : typeId.getTypeId();
|
||||
parentTypeId = CMISMapping.POLICY_TYPE_ID;
|
||||
rootTypeQueryName = cmisMapping.getQueryName(CMISMapping.POLICY_QNAME);
|
||||
description = classDefinition.getDescription();
|
||||
creatable = false;
|
||||
fileable = false;
|
||||
queryable = false;
|
||||
controllable = false;
|
||||
versionable = false;
|
||||
includedInSupertypeQuery = true;
|
||||
contentStreamAllowed = CMISContentStreamAllowedEnum.NOT_ALLOWED;
|
||||
}
|
||||
break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
|
@@ -95,6 +95,8 @@ public class CMISTypeId implements Serializable
|
||||
return CMISMapping.FOLDER_TYPE_ID;
|
||||
case RELATIONSHIP:
|
||||
return CMISMapping.RELATIONSHIP_TYPE_ID;
|
||||
case POLICY:
|
||||
return CMISMapping.POLICY_TYPE_ID;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
return null;
|
||||
|
Reference in New Issue
Block a user