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:
Andrew Hind
2009-02-13 12:52:35 +00:00
parent fc69f52b45
commit 4e9a4cc1c6
59 changed files with 1734 additions and 1003 deletions

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -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:

View File

@@ -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;