mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
CMIS Dictionary Refactor
- follows pattern of Alfresco Dictionary - simplified and much reduced DictionaryService interface - model now compiled and cached (no more lots of small continuous object creations) - walk model via simple getters - validated (no dangling references) - fix up property inheritance - fix up sub-types for all types - implements strict mode only for now (i.e. doesn't go outside of CMIS doc, folder, rel and policy) - abstract helper for building other CMIS dictionaries (e.g. mapping all types in Alfresco) Alfresco Dictionary: - add event for initialized or re-initialized Fix up usage in CMIS REST, Web Services and query. Tests pass. REST support for custom sub-types and properties now reliable as constrained by validated CMIS model. TODO: - hook property value accessors into CMIS Dictionary git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13768 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.alfresco.cmis.CMISDataTypeEnum;
|
||||
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||
import org.alfresco.repo.dictionary.DictionaryListener;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.AbstractLifecycleBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Common CMIS Dictionary Support including registry of Types.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class AbstractCMISDictionaryService extends AbstractLifecycleBean implements CMISDictionaryService, DictionaryListener
|
||||
{
|
||||
// Logger
|
||||
protected static final Log logger = LogFactory.getLog(AbstractCMISDictionaryService.class);
|
||||
|
||||
// service dependencies
|
||||
private DictionaryDAO dictionaryDAO;
|
||||
protected CMISMapping cmisMapping;
|
||||
protected DictionaryService dictionaryService;
|
||||
|
||||
/**
|
||||
* Set the mapping service
|
||||
*
|
||||
* @param cmisMapping
|
||||
*/
|
||||
public void setCMISMapping(CMISMapping cmisMapping)
|
||||
{
|
||||
this.cmisMapping = cmisMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dictionary Service
|
||||
*
|
||||
* @param dictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dictionary DAO
|
||||
*
|
||||
* @param dictionaryDAO
|
||||
*/
|
||||
public void setDictionaryDAO(DictionaryDAO dictionaryDAO)
|
||||
{
|
||||
this.dictionaryDAO = dictionaryDAO;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Handle tenants
|
||||
// TODO: read / write locks
|
||||
private DictionaryRegistry registry;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Dictionary registry
|
||||
*
|
||||
* Index of CMIS Type Definitions
|
||||
*/
|
||||
/*package*/ class DictionaryRegistry
|
||||
{
|
||||
// Type Definitions Index
|
||||
Map<QName, CMISObjectTypeDefinition> typeDefsByQName = new HashMap<QName, CMISObjectTypeDefinition>();
|
||||
Map<QName, CMISObjectTypeDefinition> assocDefsByQName = new HashMap<QName, CMISObjectTypeDefinition>();
|
||||
Map<CMISTypeId, CMISObjectTypeDefinition> objectDefsByTypeId = new HashMap<CMISTypeId, CMISObjectTypeDefinition>();
|
||||
Map<CMISTypeId, CMISTypeDefinition> typeDefsByTypeId = new HashMap<CMISTypeId, CMISTypeDefinition>();
|
||||
Map<String, CMISTypeDefinition> typeDefsByTable = new HashMap<String, CMISTypeDefinition>();
|
||||
|
||||
// Property Definitions Index
|
||||
Map<String, CMISPropertyDefinition> propDefsByName = new HashMap<String, CMISPropertyDefinition>();
|
||||
Map<QName, CMISPropertyDefinition> propDefsByQName = new HashMap<QName, CMISPropertyDefinition>();
|
||||
Map<CMISPropertyId, CMISPropertyDefinition> propDefsByPropId = new HashMap<CMISPropertyId, CMISPropertyDefinition>();
|
||||
|
||||
/**
|
||||
* Register Type Definition
|
||||
*
|
||||
* @param typeDefinition
|
||||
*/
|
||||
public void registerTypeDefinition(CMISObjectTypeDefinition typeDefinition)
|
||||
{
|
||||
QName typeQName = typeDefinition.getTypeId().getQName();
|
||||
if (typeQName != null)
|
||||
{
|
||||
if (typeDefinition instanceof CMISRelationshipTypeDefinition)
|
||||
{
|
||||
assocDefsByQName.put(typeQName, typeDefinition);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeDefsByQName.put(typeQName, typeDefinition);
|
||||
}
|
||||
}
|
||||
objectDefsByTypeId.put(typeDefinition.getTypeId(), typeDefinition);
|
||||
typeDefsByTypeId.put(typeDefinition.getTypeId(), typeDefinition);
|
||||
typeDefsByTable.put(typeDefinition.getQueryName().toLowerCase(), typeDefinition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registry Property Definition
|
||||
*
|
||||
* @param propDef
|
||||
*/
|
||||
public void registerPropertyDefinition(CMISPropertyDefinition propDef)
|
||||
{
|
||||
propDefsByPropId.put(propDef.getPropertyId(), propDef);
|
||||
propDefsByQName.put(propDef.getPropertyId().getQName(), propDef);
|
||||
propDefsByName.put(propDef.getPropertyId().getName().toLowerCase(), propDef);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("DictionaryRegistry[");
|
||||
builder.append("Types=").append(typeDefsByTypeId.size()).append(", ");
|
||||
builder.append("Properties=").append(propDefsByPropId.size());
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getTypeId(java.lang.String)
|
||||
*/
|
||||
public CMISTypeId getTypeId(String typeId)
|
||||
{
|
||||
return cmisMapping.getCmisTypeId(typeId);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getTypeId(org.alfresco.service.namespace.QName, org.alfresco.cmis.dictionary.CMISScope)
|
||||
*/
|
||||
public CMISTypeId getTypeId(QName clazz, CMISScope matchingScope)
|
||||
{
|
||||
CMISTypeDefinition typeDef = null;
|
||||
if (matchingScope != null && matchingScope == CMISScope.RELATIONSHIP)
|
||||
{
|
||||
typeDef = registry.assocDefsByQName.get(clazz);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeDef = registry.typeDefsByQName.get(clazz);
|
||||
}
|
||||
|
||||
CMISTypeDefinition matchingTypeDef = null;
|
||||
if (matchingScope == null)
|
||||
{
|
||||
matchingTypeDef = typeDef;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeDef != null && typeDef.getTypeId().getScope() == matchingScope)
|
||||
{
|
||||
matchingTypeDef = typeDef;
|
||||
}
|
||||
}
|
||||
return matchingTypeDef == null ? null : matchingTypeDef.getTypeId();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getTypeIdFromTable(java.lang.String)
|
||||
*/
|
||||
public CMISTypeId getTypeIdFromTable(String table)
|
||||
{
|
||||
CMISTypeDefinition typeDef = registry.typeDefsByTable.get(table.toLowerCase());
|
||||
return (typeDef == null) ? null : typeDef.getTypeId();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getType(org.alfresco.cmis.dictionary.CMISTypeId)
|
||||
*/
|
||||
public CMISTypeDefinition getType(CMISTypeId typeId)
|
||||
{
|
||||
return registry.objectDefsByTypeId.get(typeId);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getAllTypes()
|
||||
*/
|
||||
public Collection<CMISTypeDefinition> getAllTypes()
|
||||
{
|
||||
return Collections.unmodifiableCollection(registry.typeDefsByTypeId.values());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getProperty(org.alfresco.cmis.dictionary.CMISPropertyId)
|
||||
*/
|
||||
public CMISPropertyDefinition getProperty(CMISPropertyId propertyId)
|
||||
{
|
||||
return registry.propDefsByPropId.get(propertyId);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getPropertyId(java.lang.String)
|
||||
*/
|
||||
public CMISPropertyId getPropertyId(String property)
|
||||
{
|
||||
CMISPropertyDefinition propDef = registry.propDefsByName.get(property.toLowerCase());
|
||||
return (propDef == null) ? null : propDef.getPropertyId();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getPropertyId(org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public CMISPropertyId getPropertyId(QName property)
|
||||
{
|
||||
CMISPropertyDefinition propDef = registry.propDefsByQName.get(property);
|
||||
return (propDef == null) ? null : propDef.getPropertyId();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#getDataType(org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public CMISDataTypeEnum getDataType(QName dataType)
|
||||
{
|
||||
return cmisMapping.getDataType(dataType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Factory for creating CMIS Definitions
|
||||
*
|
||||
* @param registry
|
||||
*/
|
||||
abstract protected void createDefinitions(DictionaryRegistry registry);
|
||||
|
||||
|
||||
/**
|
||||
* Dictionary Initialisation - creates a new registry
|
||||
*/
|
||||
private void init()
|
||||
{
|
||||
DictionaryRegistry registry = new DictionaryRegistry();
|
||||
|
||||
// phase 1: construct type definitions
|
||||
createDefinitions(registry);
|
||||
for (CMISObjectTypeDefinition objectTypeDef : registry.objectDefsByTypeId.values())
|
||||
{
|
||||
Map<CMISPropertyId, CMISPropertyDefinition> propDefs = objectTypeDef.createProperties(cmisMapping, dictionaryService);
|
||||
for (CMISPropertyDefinition propDef : propDefs.values())
|
||||
{
|
||||
registry.registerPropertyDefinition(propDef);
|
||||
}
|
||||
objectTypeDef.createSubTypes(cmisMapping, dictionaryService);
|
||||
}
|
||||
|
||||
// phase 2: link together
|
||||
for (CMISObjectTypeDefinition objectTypeDef : registry.objectDefsByTypeId.values())
|
||||
{
|
||||
objectTypeDef.resolveDependencies(registry);
|
||||
}
|
||||
|
||||
// phase 3: resolve inheritance
|
||||
Map<Integer,List<CMISObjectTypeDefinition>> order = new TreeMap<Integer, List<CMISObjectTypeDefinition>>();
|
||||
for (CMISObjectTypeDefinition typeDef : registry.objectDefsByTypeId.values())
|
||||
{
|
||||
// calculate class depth in hierarchy
|
||||
int depth = 0;
|
||||
CMISTypeDefinition parent = typeDef.getParentType();
|
||||
while (parent != null)
|
||||
{
|
||||
depth = depth +1;
|
||||
parent = parent.getParentType();
|
||||
}
|
||||
|
||||
// map class to depth
|
||||
List<CMISObjectTypeDefinition> classes = order.get(depth);
|
||||
if (classes == null)
|
||||
{
|
||||
classes = new ArrayList<CMISObjectTypeDefinition>();
|
||||
order.put(depth, classes);
|
||||
}
|
||||
classes.add(typeDef);
|
||||
}
|
||||
for (int depth = 0; depth < order.size(); depth++)
|
||||
{
|
||||
for (CMISObjectTypeDefinition typeDef : order.get(depth))
|
||||
{
|
||||
typeDef.resolveInheritance(registry);
|
||||
}
|
||||
}
|
||||
|
||||
// publish new registry
|
||||
this.registry = registry;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Initialized CMIS Dictionary. Types:" + registry.typeDefsByTypeId.size() + ", Properties:" + registry.propDefsByPropId.size());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.dictionary.DictionaryListener#onInit()
|
||||
*/
|
||||
public void onDictionaryInit()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.dictionary.DictionaryListener#afterInit()
|
||||
*/
|
||||
public void afterDictionaryInit()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
protected void onBootstrap(ApplicationEvent event)
|
||||
{
|
||||
afterDictionaryInit();
|
||||
dictionaryDAO.register(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.util.AbstractLifecycleBean#onShutdown(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
protected void onShutdown(ApplicationEvent event)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
@@ -65,7 +65,7 @@ public abstract class BaseCMISTest extends TestCase
|
||||
protected CMISMapping cmisMapping;
|
||||
|
||||
protected CMISDictionaryService cmisDictionaryService;
|
||||
|
||||
|
||||
protected DictionaryService dictionaryService;
|
||||
|
||||
protected TransactionService transactionService;
|
||||
@@ -103,7 +103,7 @@ public abstract class BaseCMISTest extends TestCase
|
||||
serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
|
||||
|
||||
cmisDictionaryService = (CMISDictionaryService) ctx.getBean("CMISDictionaryService");
|
||||
cmisMapping = cmisDictionaryService.getCMISMapping();
|
||||
cmisMapping = (CMISMapping) ctx.getBean("CMISMapping");
|
||||
cmisPropertyService = (CMISPropertyService) ctx.getBean("CMISPropertyService");
|
||||
cmisQueryService = (CMISQueryService) ctx.getBean("CMISQueryService");
|
||||
cmisService = (CMISService) ctx.getBean("CMISService");
|
||||
|
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
|
||||
/**
|
||||
* CMIS <-> Alfresco mappings
|
||||
*
|
||||
* @author andyh
|
||||
*/
|
||||
public interface CMISDictionaryModel
|
||||
{
|
||||
/**
|
||||
* Type id for CMIS documents, from the spec.
|
||||
*/
|
||||
public static String DOCUMENT_OBJECT_TYPE = "Document";
|
||||
|
||||
/**
|
||||
* Type is for CMIS folders, from the spec.
|
||||
*/
|
||||
public static String FOLDER_OBJECT_TYPE = "Folder";
|
||||
|
||||
/**
|
||||
* Type Id for CMIS Relationships, from the spec.
|
||||
*/
|
||||
public static String RELATIONSHIP_OBJECT_TYPE = "Relationship";
|
||||
|
||||
/**
|
||||
* Type Id for CMIS Policies, from the spec.
|
||||
*/
|
||||
public static String POLICY_OBJECT_TYPE = "Policy";
|
||||
|
||||
// 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_OBJECT_TYPE.toLowerCase(), ContentModel.TYPE_CONTENT);
|
||||
public static CMISTypeId FOLDER_TYPE_ID = new CMISTypeId(CMISScope.FOLDER, FOLDER_OBJECT_TYPE.toLowerCase(), ContentModel.TYPE_FOLDER);
|
||||
public static CMISTypeId RELATIONSHIP_TYPE_ID = new CMISTypeId(CMISScope.RELATIONSHIP, RELATIONSHIP_OBJECT_TYPE.toLowerCase(), CMISMapping.RELATIONSHIP_QNAME);
|
||||
public static CMISTypeId POLICY_TYPE_ID = new CMISTypeId(CMISScope.POLICY, POLICY_OBJECT_TYPE.toLowerCase(), CMISMapping.POLICY_QNAME);
|
||||
|
||||
// CMIS properties
|
||||
public static String PROP_OBJECT_ID = "ObjectId";
|
||||
public static String PROP_URI = "Uri";
|
||||
public static String PROP_OBJECT_TYPE_ID = "ObjectTypeId";
|
||||
public static String PROP_CREATED_BY = "CreatedBy";
|
||||
public static String PROP_CREATION_DATE = "CreationDate";
|
||||
public static String PROP_LAST_MODIFIED_BY = "LastModifiedBy";
|
||||
public static String PROP_LAST_MODIFICATION_DATE = "LastModificationDate";
|
||||
public static String PROP_CHANGE_TOKEN = "ChangeToken";
|
||||
public static String PROP_NAME = "Name";
|
||||
public static String PROP_IS_IMMUTABLE = "IsImmutable";
|
||||
public static String PROP_IS_LATEST_VERSION = "IsLatestVersion";
|
||||
public static String PROP_IS_MAJOR_VERSION = "IsMajorVersion";
|
||||
public static String PROP_IS_LATEST_MAJOR_VERSION = "IsLatestMajorVersion";
|
||||
public static String PROP_VERSION_LABEL = "VersionLabel";
|
||||
public static String PROP_VERSION_SERIES_ID = "VersionSeriesId";
|
||||
public static String PROP_IS_VERSION_SERIES_CHECKED_OUT = "IsVersionSeriesCheckedOut";
|
||||
public static String PROP_VERSION_SERIES_CHECKED_OUT_BY = "VersionSeriesCheckedOutBy";
|
||||
public static String PROP_VERSION_SERIES_CHECKED_OUT_ID = "VersionSeriesCheckedOutId";
|
||||
public static String PROP_CHECKIN_COMMENT = "CheckinComment";
|
||||
public static String PROP_CONTENT_STREAM_ALLOWED = "ContentStreamAllowed";
|
||||
public static String PROP_CONTENT_STREAM_LENGTH = "ContentStreamLength";
|
||||
public static String PROP_CONTENT_STREAM_MIME_TYPE = "ContentStreamMimeType";
|
||||
public static String PROP_CONTENT_STREAM_FILENAME = "ContentStreamFilename";
|
||||
public static String PROP_CONTENT_STREAM_URI = "ContentStreamUri";
|
||||
public static String PROP_PARENT_ID = "ParentId";
|
||||
public static String PROP_ALLOWED_CHILD_OBJECT_TYPE_IDS = "AllowedChildObjectTypeIds";
|
||||
public static String PROP_SOURCE_ID = "SourceId";
|
||||
public static String PROP_TARGET_ID = "TargetId";
|
||||
|
||||
}
|
@@ -25,371 +25,97 @@
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.cmis.CMISDataTypeEnum;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Service to query the CMIS meta model
|
||||
*
|
||||
* @author andyh
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISDictionaryService
|
||||
public interface CMISDictionaryService
|
||||
{
|
||||
private CMISMapping cmisMapping;
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
private boolean strict = true;
|
||||
|
||||
/**
|
||||
* Set the mapping service
|
||||
*
|
||||
* @param cmisMapping
|
||||
*/
|
||||
public void setCMISMapping(CMISMapping cmisMapping)
|
||||
{
|
||||
this.cmisMapping = cmisMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return cmis mapping service
|
||||
*/
|
||||
public CMISMapping getCMISMapping()
|
||||
{
|
||||
return cmisMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dictionary Service
|
||||
*
|
||||
* @param dictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dictionary service
|
||||
*
|
||||
* @return dictionaryService
|
||||
*/
|
||||
/* package */DictionaryService getDictionaryService()
|
||||
{
|
||||
return this.dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the service strict (CMIS types only)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isStrict()
|
||||
{
|
||||
return strict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set strict mode. In strict mode only CMIS types and properties are returned
|
||||
*
|
||||
* @param strict
|
||||
*/
|
||||
public void setStrict(boolean strict)
|
||||
{
|
||||
this.strict = strict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the all the object types ids TODO: Note there can be name collisions between types and associations. e.g.
|
||||
* app:configurations
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeId> getAllObjectTypeIds()
|
||||
{
|
||||
Collection<QName> alfrescoTypeQNames;
|
||||
Collection<QName> alfrescoAssociationQNames;
|
||||
|
||||
if (strict)
|
||||
{
|
||||
alfrescoTypeQNames = dictionaryService.getTypes(CMISMapping.CMIS_MODEL_QNAME);
|
||||
alfrescoAssociationQNames = dictionaryService.getAssociations(CMISMapping.CMIS_MODEL_QNAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
alfrescoTypeQNames = dictionaryService.getAllTypes();
|
||||
alfrescoAssociationQNames = dictionaryService.getAllAssociations();
|
||||
}
|
||||
|
||||
Collection<CMISTypeId> answer = new HashSet<CMISTypeId>(alfrescoTypeQNames.size() + alfrescoAssociationQNames.size());
|
||||
|
||||
for (QName typeQName : alfrescoTypeQNames)
|
||||
{
|
||||
if (cmisMapping.isValidCmisDocument(typeQName))
|
||||
{
|
||||
answer.add(cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, typeQName));
|
||||
}
|
||||
else if (cmisMapping.isValidCmisFolder(typeQName))
|
||||
{
|
||||
answer.add(cmisMapping.getCmisTypeId(CMISScope.FOLDER, typeQName));
|
||||
}
|
||||
else if (typeQName.equals(CMISMapping.RELATIONSHIP_QNAME))
|
||||
{
|
||||
answer.add(cmisMapping.getCmisTypeId(CMISScope.RELATIONSHIP, typeQName));
|
||||
}
|
||||
// TODO: Policy
|
||||
// For now, policies are not reported
|
||||
}
|
||||
|
||||
for (QName associationName : alfrescoAssociationQNames)
|
||||
{
|
||||
if (cmisMapping.isValidCmisRelationship(associationName))
|
||||
{
|
||||
answer.add(cmisMapping.getCmisTypeId(CMISScope.RELATIONSHIP, associationName));
|
||||
}
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the object type ids within a type hierarchy
|
||||
*
|
||||
* @param typeId
|
||||
* @param descendants
|
||||
* true => include all descendants, false => children only
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeId> getChildTypeIds(CMISTypeId typeId, boolean descendants)
|
||||
{
|
||||
switch (typeId.getScope())
|
||||
{
|
||||
case RELATIONSHIP:
|
||||
if (typeId.equals(CMISMapping.RELATIONSHIP_TYPE_ID))
|
||||
{
|
||||
// all associations are sub-type of RELATIONSHIP_OBJECT_TYPE
|
||||
// NOTE: ignore descendants
|
||||
Collection<QName> alfrescoAssociationQNames = dictionaryService.getAllAssociations();
|
||||
Collection<CMISTypeId> types = new HashSet<CMISTypeId>(alfrescoAssociationQNames.size());
|
||||
for (QName associationName : alfrescoAssociationQNames)
|
||||
{
|
||||
if (cmisMapping.isValidCmisRelationship(associationName))
|
||||
{
|
||||
types.add(cmisMapping.getCmisTypeId(CMISScope.RELATIONSHIP, associationName));
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
case DOCUMENT:
|
||||
case FOLDER:
|
||||
TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName());
|
||||
if (typeDefinition != null)
|
||||
{
|
||||
if (cmisMapping.isValidCmisType(typeId.getQName()))
|
||||
{
|
||||
QName alfrescoQName = cmisMapping.getAlfrescoType(typeId.getQName());
|
||||
Collection<QName> alfrescoTypeQNames = dictionaryService.getSubTypes(alfrescoQName, descendants);
|
||||
Collection<CMISTypeId> types = new HashSet<CMISTypeId>(alfrescoTypeQNames.size());
|
||||
for (QName typeQName : alfrescoTypeQNames)
|
||||
{
|
||||
CMISTypeId subTypeId = cmisMapping.getCmisTypeId(typeQName);
|
||||
if (typeId != null)
|
||||
{
|
||||
types.add(subTypeId);
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
* Get Type Id
|
||||
*
|
||||
* @param typeId
|
||||
* @return
|
||||
*/
|
||||
public CMISTypeDefinition getType(CMISTypeId typeId)
|
||||
{
|
||||
switch (typeId.getScope())
|
||||
{
|
||||
case RELATIONSHIP:
|
||||
// Associations
|
||||
if (cmisMapping.isValidCmisRelationship(typeId.getQName()))
|
||||
{
|
||||
return new CMISTypeDefinition(this, typeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case DOCUMENT:
|
||||
case FOLDER:
|
||||
TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName());
|
||||
if (typeDefinition != null)
|
||||
{
|
||||
if (cmisMapping.isValidCmisType(typeId.getQName()))
|
||||
{
|
||||
return new CMISTypeDefinition(this, typeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case POLICY:
|
||||
// TODO: Policy
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public CMISTypeId getTypeId(String typeId);
|
||||
|
||||
/**
|
||||
* Get Type Id from Table Name
|
||||
*
|
||||
* @param table
|
||||
* @return
|
||||
*/
|
||||
public CMISTypeId getTypeIdFromTable(String table);
|
||||
|
||||
/**
|
||||
* Get Type Id from Alfresco Class Name
|
||||
*
|
||||
* @param clazz
|
||||
* @param matchingScope if provided, only return type id matching scope
|
||||
* @return
|
||||
*/
|
||||
public CMISTypeId getTypeId(QName clazz, CMISScope matchingScope);
|
||||
|
||||
/**
|
||||
* Get all the property definitions for a type
|
||||
* Get Type Definition
|
||||
*
|
||||
* @param typeId
|
||||
* @return
|
||||
*/
|
||||
public Map<String, CMISPropertyDefinition> getPropertyDefinitions(CMISTypeId typeId)
|
||||
{
|
||||
HashMap<String, CMISPropertyDefinition> properties = new HashMap<String, CMISPropertyDefinition>();
|
||||
|
||||
switch (typeId.getScope())
|
||||
{
|
||||
case RELATIONSHIP:
|
||||
// Associations - only have CMIS properties
|
||||
AssociationDefinition associationDefinition = dictionaryService.getAssociation(typeId.getQName());
|
||||
if (associationDefinition != null)
|
||||
{
|
||||
if (cmisMapping.isValidCmisRelationship(typeId.getQName()))
|
||||
{
|
||||
return getPropertyDefinitions(CMISMapping.RELATIONSHIP_TYPE_ID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!typeId.getQName().equals(CMISMapping.RELATIONSHIP_QNAME))
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Fall through for CMISMapping.RELATIONSHIP_QNAME
|
||||
case DOCUMENT:
|
||||
case FOLDER:
|
||||
TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName());
|
||||
if (typeDefinition != null)
|
||||
{
|
||||
if (cmisMapping.isValidCmisDocumentOrFolder(typeId.getQName()) || typeId.getQName().equals(CMISMapping.RELATIONSHIP_QNAME))
|
||||
{
|
||||
for (QName qname : typeDefinition.getProperties().keySet())
|
||||
{
|
||||
if (cmisMapping.getPropertyType(qname) != null)
|
||||
{
|
||||
CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(this, qname, typeDefinition.getName());
|
||||
properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition);
|
||||
}
|
||||
}
|
||||
for (AspectDefinition aspect : typeDefinition.getDefaultAspects())
|
||||
{
|
||||
for (QName qname : aspect.getProperties().keySet())
|
||||
{
|
||||
if (cmisMapping.getPropertyType(qname) != null)
|
||||
{
|
||||
CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(this, qname, typeDefinition.getName());
|
||||
properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmisMapping.isValidCmisDocumentOrFolder(typeId.getQName()))
|
||||
{
|
||||
// Add CMIS properties if required
|
||||
if (!cmisMapping.isCmisCoreType(typeId.getQName()))
|
||||
{
|
||||
properties.putAll(getPropertyDefinitions(typeId.getRootTypeId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
public CMISTypeDefinition getType(CMISTypeId typeId);
|
||||
|
||||
/**
|
||||
* Get a single property definition
|
||||
* Get All Type Definitions
|
||||
*
|
||||
* @param typeId
|
||||
* @param propertyName
|
||||
* @return
|
||||
*/
|
||||
public CMISPropertyDefinition getPropertyDefinition(CMISTypeId typeId, String propertyName)
|
||||
{
|
||||
return getPropertyDefinitions(typeId).get(propertyName);
|
||||
}
|
||||
public Collection<CMISTypeDefinition> getAllTypes();
|
||||
|
||||
/**
|
||||
* Get Property Id for Alfresco property name
|
||||
*
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public CMISPropertyId getPropertyId(QName property);
|
||||
|
||||
/**
|
||||
* Get Property Id
|
||||
*
|
||||
* @param propertyId
|
||||
* @return
|
||||
*/
|
||||
public CMISPropertyId getPropertyId(String propertyId);
|
||||
|
||||
/**
|
||||
* Get Property
|
||||
*
|
||||
* @param propertyId
|
||||
* @return
|
||||
*/
|
||||
public CMISPropertyDefinition getProperty(CMISPropertyId propertyId);
|
||||
|
||||
/**
|
||||
* Get Data Type
|
||||
*
|
||||
* @param dataType
|
||||
* @return
|
||||
*/
|
||||
public CMISDataTypeEnum getDataType(QName dataType);
|
||||
|
||||
|
||||
// public CMISTypeDef findType(CMISTypeId typeId)
|
||||
// public CMISTypeDef findType(String typeId)
|
||||
// public CMISTypeDef findTypeForClass(QName clazz, CMISScope matchingScope, ...)
|
||||
// public CMISTypeDef findTypeForTable(String tableName)
|
||||
// public CMISTypeDef getAllTypes();
|
||||
// public CMISPropertyDefinition getProperty(QName property)
|
||||
// public CMISPropertyDefinition getProperty(CMISTypeDef typeDef, String property)
|
||||
// public CMISDataTypeEnum getDataType(QName dataType)
|
||||
|
||||
}
|
||||
|
@@ -28,99 +28,48 @@ public class CMISDictionaryTest extends BaseCMISTest
|
||||
{
|
||||
public void testBasicTypes()
|
||||
{
|
||||
cmisDictionaryService.setStrict(true);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
for (CMISTypeDefinition type : cmisDictionaryService.getAllTypes())
|
||||
{
|
||||
System.out.println(name);
|
||||
System.out.println(type);
|
||||
}
|
||||
assertEquals(3, cmisDictionaryService.getAllObjectTypeIds().size());
|
||||
}
|
||||
|
||||
public void testBasicTypeDefinitions()
|
||||
{
|
||||
cmisDictionaryService.setStrict(false);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
{
|
||||
System.out.println(cmisDictionaryService.getType(name));
|
||||
}
|
||||
}
|
||||
|
||||
public void testSubTypes()
|
||||
{
|
||||
cmisDictionaryService.setStrict(true);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
for (CMISTypeDefinition type : cmisDictionaryService.getAllTypes())
|
||||
{
|
||||
System.out.println(name + " children (strict)");
|
||||
for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, false))
|
||||
System.out.println(type.getTypeId() + " children:");
|
||||
for (CMISTypeDefinition subType : type.getSubTypes(false))
|
||||
{
|
||||
System.out.println(" " + subName);
|
||||
System.out.println(" " + subType.getTypeId());
|
||||
}
|
||||
System.out.println(name + " descendants (strict)");
|
||||
for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, true))
|
||||
System.out.println(type.getTypeId() + " descendants:");
|
||||
for (CMISTypeDefinition subType : type.getSubTypes(true))
|
||||
{
|
||||
System.out.println(" " + subName);
|
||||
}
|
||||
}
|
||||
cmisDictionaryService.setStrict(false);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
{
|
||||
System.out.println(name + " children");
|
||||
for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, false))
|
||||
{
|
||||
System.out.println(" " + subName);
|
||||
}
|
||||
System.out.println(name + " descendants");
|
||||
for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, true))
|
||||
{
|
||||
System.out.println(" " + subName);
|
||||
System.out.println(" " + subType.getTypeId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testTypeIds()
|
||||
{
|
||||
cmisDictionaryService.setStrict(false);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
for (CMISTypeDefinition typeDef : cmisDictionaryService.getAllTypes())
|
||||
{
|
||||
String typeId = name.getTypeId();
|
||||
CMISTypeId lookup = cmisMapping.getCmisTypeId(typeId);
|
||||
assertEquals(name, lookup);
|
||||
System.out.println(name + " => " + lookup);
|
||||
CMISTypeDefinition type = cmisDictionaryService.getType(lookup);
|
||||
assertNotNull(type);
|
||||
assertEquals(lookup, type.getObjectTypeId());
|
||||
CMISTypeId typeId = typeDef.getTypeId();
|
||||
CMISTypeDefinition typeDefLookup = cmisDictionaryService.getType(typeId);
|
||||
assertNotNull(typeDefLookup);
|
||||
assertEquals(typeDef, typeDefLookup);
|
||||
}
|
||||
}
|
||||
|
||||
public void testBasicProperties()
|
||||
{
|
||||
cmisDictionaryService.setStrict(false);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
{
|
||||
for (String propertyName : cmisDictionaryService.getPropertyDefinitions(name).keySet())
|
||||
{
|
||||
System.out.println(name +" -> "+ propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testBasicPropertyDefinitions()
|
||||
{
|
||||
cmisDictionaryService.setStrict(true);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
for (CMISTypeDefinition type : cmisDictionaryService.getAllTypes())
|
||||
{
|
||||
for (CMISPropertyDefinition proDef : cmisDictionaryService.getPropertyDefinitions(name).values())
|
||||
System.out.println(type.getTypeId() + " properties:");
|
||||
for (CMISPropertyDefinition proDef : type.getPropertyDefinitions().values())
|
||||
{
|
||||
System.out.println(proDef);
|
||||
}
|
||||
}
|
||||
|
||||
cmisDictionaryService.setStrict(false);
|
||||
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
|
||||
{
|
||||
for (CMISPropertyDefinition proDef : cmisDictionaryService.getPropertyDefinitions(name).values())
|
||||
{
|
||||
System.out.println(proDef);
|
||||
System.out.println(" " + proDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2005-20079 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.CMISContentStreamAllowedEnum;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Document Type Definition
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISDocumentTypeDefinition extends CMISObjectTypeDefinition
|
||||
{
|
||||
private static final long serialVersionUID = -7209732754962781522L;
|
||||
|
||||
// document specific properties
|
||||
protected boolean fileable;
|
||||
protected boolean versionable;
|
||||
protected CMISContentStreamAllowedEnum contentStreamAllowed;
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisMapping
|
||||
* @param typeId
|
||||
* @param cmisClassDef
|
||||
*/
|
||||
public CMISDocumentTypeDefinition(CMISMapping cmisMapping, CMISTypeId typeId, ClassDefinition cmisClassDef)
|
||||
{
|
||||
// Object type properties
|
||||
this.cmisClassDef = cmisClassDef;
|
||||
objectTypeId = typeId;
|
||||
objectTypeQueryName = (typeId == CMISDictionaryModel.DOCUMENT_TYPE_ID) ? typeId.getId() : cmisMapping.buildPrefixEncodedString(typeId.getQName(), false);
|
||||
displayName = (cmisClassDef.getTitle() != null) ? cmisClassDef.getTitle() : typeId.getId();
|
||||
QName parentQName = cmisMapping.getCmisType(cmisClassDef.getParentName());
|
||||
if (cmisMapping.isValidCmisDocument(parentQName))
|
||||
{
|
||||
parentTypeId = cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, parentQName);
|
||||
}
|
||||
description = cmisClassDef.getDescription();
|
||||
creatable = true;
|
||||
queryable = true;
|
||||
controllable = false;
|
||||
includeInSuperTypeQuery = true;
|
||||
|
||||
// Document type properties
|
||||
versionable = false;
|
||||
List<AspectDefinition> defaultAspects = cmisClassDef.getDefaultAspects();
|
||||
for (AspectDefinition aspectDefinition : defaultAspects)
|
||||
{
|
||||
if (aspectDefinition.getName().equals(ContentModel.ASPECT_VERSIONABLE))
|
||||
{
|
||||
versionable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fileable = true;
|
||||
contentStreamAllowed = CMISContentStreamAllowedEnum.ALLOWED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are objects of this type fileable?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFileable()
|
||||
{
|
||||
return fileable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type versionable? If true this implies all instances of the type are versionable.
|
||||
*
|
||||
* @return true if versionable
|
||||
*/
|
||||
public boolean isVersionable()
|
||||
{
|
||||
return versionable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a content stream allowed for this type? It may be disallowed, optional or mandatory.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CMISContentStreamAllowedEnum getContentStreamAllowed()
|
||||
{
|
||||
return contentStreamAllowed;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CMISDocumentTypeDefinition[");
|
||||
builder.append("ObjectTypeId=").append(getTypeId()).append(", ");
|
||||
builder.append("ObjectTypeQueryName=").append(getQueryName()).append(", ");
|
||||
builder.append("ObjectTypeDisplayName=").append(getDisplayName()).append(", ");
|
||||
builder.append("ParentTypeId=").append(getParentType() == null ? "<none>" : getParentType().getTypeId()).append(", ");
|
||||
builder.append("Description=").append(getDescription()).append(", ");
|
||||
builder.append("Creatable=").append(isCreatable()).append(", ");
|
||||
builder.append("Queryable=").append(isQueryable()).append(", ");
|
||||
builder.append("Controllable=").append(isControllable()).append(", ");
|
||||
builder.append("IncludeInSuperTypeQuery=").append(isIncludeInSuperTypeQuery()).append(", ");
|
||||
builder.append("Fileable=").append(isFileable()).append(", ");
|
||||
builder.append("Versionable=").append(isVersionable()).append(", ");
|
||||
builder.append("ContentStreamAllowed=").append(getContentStreamAllowed()).append(", ");
|
||||
builder.append("SubTypes=").append(getSubTypes(false).size()).append(", ");
|
||||
builder.append("Properties=").append(getPropertyDefinitions().size());
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Folder Type Definition
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISFolderTypeDefinition extends CMISObjectTypeDefinition
|
||||
{
|
||||
private static final long serialVersionUID = 7526155195125799106L;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
* @param cmisMapping
|
||||
* @param typeId
|
||||
* @param cmisClassDef
|
||||
*/
|
||||
public CMISFolderTypeDefinition(CMISMapping cmisMapping, CMISTypeId typeId, ClassDefinition cmisClassDef)
|
||||
{
|
||||
// Object type properties
|
||||
this.cmisClassDef = cmisClassDef;
|
||||
objectTypeId = typeId;
|
||||
objectTypeQueryName = (typeId == CMISDictionaryModel.FOLDER_TYPE_ID) ? typeId.getId() : cmisMapping.buildPrefixEncodedString(typeId.getQName(), false);
|
||||
displayName = (cmisClassDef.getTitle() != null) ? cmisClassDef.getTitle() : typeId.getId();
|
||||
QName parentQName = cmisMapping.getCmisType(cmisClassDef.getParentName());
|
||||
if (cmisMapping.isValidCmisFolder(parentQName))
|
||||
{
|
||||
parentTypeId = cmisMapping.getCmisTypeId(CMISScope.FOLDER, parentQName);
|
||||
}
|
||||
description = cmisClassDef.getDescription();
|
||||
creatable = true;
|
||||
queryable = true;
|
||||
controllable = false;
|
||||
includeInSuperTypeQuery = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CMISFolderTypeDefinition[");
|
||||
builder.append("ObjectTypeId=").append(getTypeId()).append(", ");
|
||||
builder.append("ObjectTypeQueryName=").append(getQueryName()).append(", ");
|
||||
builder.append("ObjectTypeDisplayName=").append(getDisplayName()).append(", ");
|
||||
builder.append("ParentTypeId=").append(getParentType() == null ? "<none>" : getParentType().getTypeId()).append(", ");
|
||||
builder.append("Description=").append(getDescription()).append(", ");
|
||||
builder.append("Creatable=").append(isCreatable()).append(", ");
|
||||
builder.append("Queryable=").append(isQueryable()).append(", ");
|
||||
builder.append("Controllable=").append(isControllable()).append(", ");
|
||||
builder.append("IncludeInSuperTypeQuery=").append(isIncludeInSuperTypeQuery()).append(", ");
|
||||
builder.append("SubTypes=").append(getSubTypes(false).size()).append(", ");
|
||||
builder.append("Properties=").append(getPropertyDefinitions().size());
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
@@ -27,14 +27,13 @@ package org.alfresco.cmis.dictionary;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.alfresco.cmis.CMISPropertyTypeEnum;
|
||||
import org.alfresco.cmis.CMISDataTypeEnum;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
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.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -61,143 +60,40 @@ public class CMISMapping
|
||||
*/
|
||||
public static QName CMIS_MODEL_QNAME = QName.createQName(CMIS_MODEL_URI, CMIS_MODEL_NAME);
|
||||
|
||||
/**
|
||||
* The QNames for CMIS Data Types.
|
||||
*/
|
||||
|
||||
// CMIS Data Types
|
||||
public static QName CMIS_DATATYPE_ID = QName.createQName(CMIS_MODEL_URI, "id");
|
||||
public static QName CMIS_DATATYPE_URI = QName.createQName(CMIS_MODEL_URI, "uri");
|
||||
public static QName CMIS_DATATYPE_XML = QName.createQName(CMIS_MODEL_URI, "xml");
|
||||
public static QName CMIS_DATATYPE_HTML = QName.createQName(CMIS_MODEL_URI, "html");
|
||||
|
||||
/**
|
||||
* Type id for CMIS documents, from the spec.
|
||||
*/
|
||||
public static String DOCUMENT_OBJECT_TYPE = "Document";
|
||||
// CMIS Types
|
||||
public static QName DOCUMENT_QNAME = QName.createQName(CMIS_MODEL_URI, CMISDictionaryModel.DOCUMENT_OBJECT_TYPE);
|
||||
public static QName FOLDER_QNAME = QName.createQName(CMIS_MODEL_URI, CMISDictionaryModel.FOLDER_OBJECT_TYPE);
|
||||
public static QName RELATIONSHIP_QNAME = QName.createQName(CMIS_MODEL_URI, CMISDictionaryModel.RELATIONSHIP_OBJECT_TYPE);
|
||||
public static QName POLICY_QNAME = QName.createQName(CMIS_MODEL_URI, CMISDictionaryModel.POLICY_OBJECT_TYPE);
|
||||
|
||||
/**
|
||||
* Type is for CMIS folders, from the spec.
|
||||
*/
|
||||
public static String FOLDER_OBJECT_TYPE = "Folder";
|
||||
|
||||
/**
|
||||
* Type Id for CMIS Relationships, from the spec.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public static QName DOCUMENT_QNAME = QName.createQName(CMIS_MODEL_URI, DOCUMENT_OBJECT_TYPE);
|
||||
|
||||
/**
|
||||
* QName for CMIS folders in the Alfresco CMIS model
|
||||
*/
|
||||
public static QName FOLDER_QNAME = QName.createQName(CMIS_MODEL_URI, FOLDER_OBJECT_TYPE);
|
||||
|
||||
/**
|
||||
* QName for CMIS relationships in the the Alfresco CMIS model.
|
||||
*/
|
||||
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";
|
||||
|
||||
public static String PROP_URI = "Uri";
|
||||
|
||||
public static String PROP_OBJECT_TYPE_ID = "ObjectTypeId";
|
||||
|
||||
public static String PROP_CREATED_BY = "CreatedBy";
|
||||
|
||||
public static String PROP_CREATION_DATE = "CreationDate";
|
||||
|
||||
public static String PROP_LAST_MODIFIED_BY = "LastModifiedBy";
|
||||
|
||||
public static String PROP_LAST_MODIFICATION_DATE = "LastModificationDate";
|
||||
|
||||
public static String PROP_CHANGE_TOKEN = "ChangeToken";
|
||||
|
||||
public static String PROP_NAME = "Name";
|
||||
|
||||
public static String PROP_IS_IMMUTABLE = "IsImmutable";
|
||||
|
||||
public static String PROP_IS_LATEST_VERSION = "IsLatestVersion";
|
||||
|
||||
public static String PROP_IS_MAJOR_VERSION = "IsMajorVersion";
|
||||
|
||||
public static String PROP_IS_LATEST_MAJOR_VERSION = "IsLatestMajorVersion";
|
||||
|
||||
public static String PROP_VERSION_LABEL = "VersionLabel";
|
||||
|
||||
public static String PROP_VERSION_SERIES_ID = "VersionSeriesId";
|
||||
|
||||
public static String PROP_IS_VERSION_SERIES_CHECKED_OUT = "IsVersionSeriesCheckedOut";
|
||||
|
||||
public static String PROP_VERSION_SERIES_CHECKED_OUT_BY = "VersionSeriesCheckedOutBy";
|
||||
|
||||
public static String PROP_VERSION_SERIES_CHECKED_OUT_ID = "VersionSeriesCheckedOutId";
|
||||
|
||||
public static String PROP_CHECKIN_COMMENT = "CheckinComment";
|
||||
|
||||
public static String PROP_CONTENT_STREAM_ALLOWED = "ContentStreamAllowed";
|
||||
|
||||
public static String PROP_CONTENT_STREAM_LENGTH = "ContentStreamLength";
|
||||
|
||||
public static String PROP_CONTENT_STREAM_MIME_TYPE = "ContentStreamMimeType";
|
||||
|
||||
public static String PROP_CONTENT_STREAM_FILENAME = "ContentStreamFilename";
|
||||
|
||||
public static String PROP_CONTENT_STREAM_URI = "ContentStreamUri";
|
||||
|
||||
public static String PROP_PARENT_ID = "ParentId";
|
||||
|
||||
public static String PROP_ALLOWED_CHILD_OBJECT_TYPE_IDS = "AllowedChildObjectTypeIds";
|
||||
|
||||
public static String PROP_SOURCE_ID = "SourceId";
|
||||
|
||||
public static String PROP_TARGET_ID = "TargetId";
|
||||
|
||||
// QNames
|
||||
|
||||
public static QName PROP_OBJECT_ID_QNAME = QName.createQName(CMIS_MODEL_URI, PROP_OBJECT_ID);
|
||||
// Properties
|
||||
public static QName PROP_OBJECT_ID_QNAME = QName.createQName(CMIS_MODEL_URI, CMISDictionaryModel.PROP_OBJECT_ID);
|
||||
|
||||
// Mappings
|
||||
// - no entry means no mapping and pass through as is
|
||||
|
||||
private static HashMap<QName, CMISTypeId> qNameToCmisTypeId = new HashMap<QName, CMISTypeId>();
|
||||
|
||||
private static HashMap<QName, QName> cmisToAlfrecsoTypes = new HashMap<QName, QName>();
|
||||
|
||||
private static HashMap<QName, QName> alfrescoToCmisTypes = new HashMap<QName, QName>();
|
||||
private static HashMap<QName, CMISDataTypeEnum> alfrescoPropertyTypesToCmisPropertyTypes = new HashMap<QName, CMISDataTypeEnum>();
|
||||
|
||||
private static HashMap<QName, CMISPropertyTypeEnum> alfrescoPropertyTypesToCmisPropertyTypes = new HashMap<QName, CMISPropertyTypeEnum>();
|
||||
|
||||
|
||||
/**
|
||||
* Set up mappings
|
||||
*/
|
||||
static
|
||||
{
|
||||
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);
|
||||
qNameToCmisTypeId.put(DOCUMENT_QNAME, CMISDictionaryModel.DOCUMENT_TYPE_ID);
|
||||
qNameToCmisTypeId.put(FOLDER_QNAME, CMISDictionaryModel.FOLDER_TYPE_ID);
|
||||
qNameToCmisTypeId.put(RELATIONSHIP_QNAME, CMISDictionaryModel.RELATIONSHIP_TYPE_ID);
|
||||
qNameToCmisTypeId.put(POLICY_QNAME, CMISDictionaryModel.POLICY_TYPE_ID);
|
||||
|
||||
cmisToAlfrecsoTypes.put(DOCUMENT_QNAME, ContentModel.TYPE_CONTENT);
|
||||
cmisToAlfrecsoTypes.put(FOLDER_QNAME, ContentModel.TYPE_FOLDER);
|
||||
@@ -209,30 +105,29 @@ public class CMISMapping
|
||||
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.ANY, null);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.ASSOC_REF, null);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.BOOLEAN, CMISPropertyTypeEnum.BOOLEAN);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.CATEGORY, CMISPropertyTypeEnum.ID);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.BOOLEAN, CMISDataTypeEnum.BOOLEAN);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.CATEGORY, CMISDataTypeEnum.ID);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.CHILD_ASSOC_REF, null);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.CONTENT, null);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.DATE, CMISPropertyTypeEnum.DATETIME);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.DATETIME, CMISPropertyTypeEnum.DATETIME);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.DOUBLE, CMISPropertyTypeEnum.DECIMAL);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.FLOAT, CMISPropertyTypeEnum.DECIMAL);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.INT, CMISPropertyTypeEnum.INTEGER);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.DATE, CMISDataTypeEnum.DATETIME);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.DATETIME, CMISDataTypeEnum.DATETIME);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.DOUBLE, CMISDataTypeEnum.DECIMAL);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.FLOAT, CMISDataTypeEnum.DECIMAL);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.INT, CMISDataTypeEnum.INTEGER);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.LOCALE, null);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.LONG, CMISPropertyTypeEnum.INTEGER);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.MLTEXT, CMISPropertyTypeEnum.STRING);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.NODE_REF, CMISPropertyTypeEnum.ID);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.LONG, CMISDataTypeEnum.INTEGER);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.MLTEXT, CMISDataTypeEnum.STRING);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.NODE_REF, CMISDataTypeEnum.ID);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.PATH, null);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.QNAME, null);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.TEXT, CMISPropertyTypeEnum.STRING);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_ID, CMISPropertyTypeEnum.ID);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_URI, CMISPropertyTypeEnum.URI);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_XML, CMISPropertyTypeEnum.XML);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_HTML, CMISPropertyTypeEnum.HTML);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(DataTypeDefinition.TEXT, CMISDataTypeEnum.STRING);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_ID, CMISDataTypeEnum.ID);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_URI, CMISDataTypeEnum.URI);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_XML, CMISDataTypeEnum.XML);
|
||||
alfrescoPropertyTypesToCmisPropertyTypes.put(CMIS_DATATYPE_HTML, CMISDataTypeEnum.HTML);
|
||||
}
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
/**
|
||||
@@ -270,47 +165,35 @@ public class CMISMapping
|
||||
*
|
||||
* @return namespaceService
|
||||
*/
|
||||
/* package */NamespaceService getNamespaceService()
|
||||
/*package*/ NamespaceService getNamespaceService()
|
||||
{
|
||||
return this.namespaceService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Id this a CMIS core type defined in the Alfresco CMIS model
|
||||
*
|
||||
* @param typeQName
|
||||
* @return
|
||||
*/
|
||||
public boolean isCmisCoreType(QName typeQName)
|
||||
{
|
||||
return qNameToCmisTypeId.get(typeQName) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CMIS Type Id given the serialized type Id
|
||||
*
|
||||
* @param typeId
|
||||
* type id in the form of <ROOT_TYPE_ID>/<PREFIX>_<LOCALNAME>
|
||||
* @param typeId type id in the form of <ROOT_TYPE_ID>/<PREFIX>_<LOCALNAME>
|
||||
* @return
|
||||
*/
|
||||
public CMISTypeId getCmisTypeId(String typeId)
|
||||
{
|
||||
// Is it a CMIS root object type id?
|
||||
if (typeId.equalsIgnoreCase(DOCUMENT_TYPE_ID.getTypeId()))
|
||||
if (typeId.equalsIgnoreCase(CMISDictionaryModel.DOCUMENT_TYPE_ID.getId()))
|
||||
{
|
||||
return DOCUMENT_TYPE_ID;
|
||||
return CMISDictionaryModel.DOCUMENT_TYPE_ID;
|
||||
}
|
||||
else if (typeId.equalsIgnoreCase(FOLDER_TYPE_ID.getTypeId()))
|
||||
else if (typeId.equalsIgnoreCase(CMISDictionaryModel.FOLDER_TYPE_ID.getId()))
|
||||
{
|
||||
return FOLDER_TYPE_ID;
|
||||
return CMISDictionaryModel.FOLDER_TYPE_ID;
|
||||
}
|
||||
else if (typeId.equalsIgnoreCase(RELATIONSHIP_TYPE_ID.getTypeId()))
|
||||
else if (typeId.equalsIgnoreCase(CMISDictionaryModel.RELATIONSHIP_TYPE_ID.getId()))
|
||||
{
|
||||
return RELATIONSHIP_TYPE_ID;
|
||||
return CMISDictionaryModel.RELATIONSHIP_TYPE_ID;
|
||||
}
|
||||
else if (typeId.equalsIgnoreCase(POLICY_TYPE_ID.getTypeId()))
|
||||
else if (typeId.equalsIgnoreCase(CMISDictionaryModel.POLICY_TYPE_ID.getId()))
|
||||
{
|
||||
return POLICY_TYPE_ID;
|
||||
return CMISDictionaryModel.POLICY_TYPE_ID;
|
||||
}
|
||||
|
||||
// Is it an Alfresco type id?
|
||||
@@ -328,7 +211,7 @@ public class CMISMapping
|
||||
QName typeQName = QName.resolveToQName(namespaceService, typeId.substring(2).replace('_', ':'));
|
||||
|
||||
// Construct CMIS Type Id
|
||||
return new CMISTypeId(scope, typeQName, typeId);
|
||||
return new CMISTypeId(scope, typeId, typeQName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,7 +229,7 @@ public class CMISMapping
|
||||
builder.append(scope.discriminator());
|
||||
builder.append("/");
|
||||
builder.append(buildPrefixEncodedString(typeQName, false));
|
||||
return new CMISTypeId(scope, typeQName, builder.toString());
|
||||
return new CMISTypeId(scope, builder.toString(), typeQName);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -354,56 +237,45 @@ public class CMISMapping
|
||||
}
|
||||
}
|
||||
|
||||
public CMISTypeId getCmisTypeId(QName typeQName)
|
||||
public CMISTypeId getCmisTypeId(QName classQName)
|
||||
{
|
||||
if (isValidCmisDocument(typeQName))
|
||||
if (classQName.equals(ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
return getCmisTypeId(CMISScope.DOCUMENT, getCmisType(typeQName));
|
||||
return getCmisTypeId(CMISScope.DOCUMENT, classQName);
|
||||
}
|
||||
else if (isValidCmisFolder(typeQName))
|
||||
if (classQName.equals(ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
return getCmisTypeId(CMISScope.FOLDER, getCmisType(typeQName));
|
||||
return getCmisTypeId(CMISScope.FOLDER, classQName);
|
||||
}
|
||||
else if (typeQName.equals(CMISMapping.RELATIONSHIP_QNAME))
|
||||
if (classQName.equals(CMISMapping.RELATIONSHIP_QNAME))
|
||||
{
|
||||
return getCmisTypeId(CMISScope.RELATIONSHIP, getCmisType(typeQName));
|
||||
return getCmisTypeId(CMISScope.RELATIONSHIP, classQName);
|
||||
}
|
||||
else if (typeQName.equals(ContentModel.TYPE_CONTENT))
|
||||
if (classQName.equals(CMISMapping.POLICY_QNAME))
|
||||
{
|
||||
return getCmisTypeId(CMISScope.DOCUMENT, getCmisType(typeQName));
|
||||
return getCmisTypeId(CMISScope.POLICY, classQName);
|
||||
}
|
||||
else if (typeQName.equals(ContentModel.TYPE_FOLDER))
|
||||
if (isValidCmisDocument(classQName))
|
||||
{
|
||||
return getCmisTypeId(CMISScope.FOLDER, getCmisType(typeQName));
|
||||
return getCmisTypeId(CMISScope.DOCUMENT, classQName);
|
||||
}
|
||||
else
|
||||
if (isValidCmisFolder(classQName))
|
||||
{
|
||||
ClassDefinition classDef = dictionaryService.getClass(typeQName);
|
||||
if (classDef.isAspect())
|
||||
{
|
||||
return getCmisTypeId(CMISScope.POLICY, getCmisType(typeQName));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return getCmisTypeId(CMISScope.FOLDER, classQName);
|
||||
}
|
||||
if (isValidCmisRelationship(classQName))
|
||||
{
|
||||
return getCmisTypeId(CMISScope.RELATIONSHIP, classQName);
|
||||
}
|
||||
if (isValidCmisPolicy(classQName))
|
||||
{
|
||||
return getCmisTypeId(CMISScope.POLICY, classQName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query name for Alfresco qname
|
||||
*
|
||||
* @param namespaceService
|
||||
* @param typeQName
|
||||
* @return
|
||||
*/
|
||||
public String getQueryName(QName typeQName)
|
||||
{
|
||||
return buildPrefixEncodedString(typeQName, false);
|
||||
}
|
||||
|
||||
private String buildPrefixEncodedString(QName qname, boolean upperCase)
|
||||
/*package*/ String buildPrefixEncodedString(QName qname, boolean upperCase)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(128);
|
||||
|
||||
@@ -424,21 +296,6 @@ public class CMISMapping
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a valid CMIS type The type must be a core CMIS type or extend cm:content or cm:folder The alfresco types
|
||||
* cm:content and cm:folder are hidden by the CMIS types
|
||||
*
|
||||
* @param dictionaryService
|
||||
* @param typeQName
|
||||
* @return
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a valid cmis document or folder type (not a relationship)
|
||||
*
|
||||
@@ -513,10 +370,41 @@ public class CMISMapping
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a valid CMIS policy type?
|
||||
*
|
||||
* @param dictionaryService
|
||||
* @param typeQName
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidCmisPolicy(QName typeQName)
|
||||
{
|
||||
if (typeQName == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (typeQName.equals(POLICY_QNAME))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AspectDefinition aspectDef = dictionaryService.getAspect(typeQName);
|
||||
if (aspectDef == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aspectDef.getName().equals(ContentModel.ASPECT_VERSIONABLE) ||
|
||||
aspectDef.getName().equals(ContentModel.ASPECT_AUDITABLE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is an association valid in CMIS? It must be a non-child relationship and the source and target must both be valid
|
||||
* CMIS types.
|
||||
@@ -572,6 +460,17 @@ public class CMISMapping
|
||||
return typeQName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Alfresco Type mapped to an alternative CMIS Type?
|
||||
*
|
||||
* @param typeQName
|
||||
* @return
|
||||
*/
|
||||
public boolean isRemappedType(QName typeQName)
|
||||
{
|
||||
return alfrescoToCmisTypes.containsKey(typeQName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a CMIS model type map it to the appropriate Alfresco type.
|
||||
*
|
||||
@@ -600,21 +499,6 @@ 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
|
||||
*
|
||||
@@ -622,22 +506,14 @@ public class CMISMapping
|
||||
* @param propertyQName
|
||||
* @return
|
||||
*/
|
||||
public CMISPropertyTypeEnum getPropertyType(QName propertyQName)
|
||||
public CMISDataTypeEnum getDataType(DataTypeDefinition datatype)
|
||||
{
|
||||
PropertyDefinition propertyDefinition = dictionaryService.getProperty(propertyQName);
|
||||
DataTypeDefinition dataTypeDefinition;
|
||||
if (propertyDefinition != null)
|
||||
{
|
||||
dataTypeDefinition = propertyDefinition.getDataType();
|
||||
}
|
||||
else
|
||||
{
|
||||
dataTypeDefinition = dictionaryService.getDataType(propertyQName);
|
||||
}
|
||||
|
||||
QName dQName = dataTypeDefinition.getName();
|
||||
return alfrescoPropertyTypesToCmisPropertyTypes.get(dQName);
|
||||
|
||||
return getDataType(datatype.getName());
|
||||
}
|
||||
|
||||
public CMISDataTypeEnum getDataType(QName dataType)
|
||||
{
|
||||
return alfrescoPropertyTypesToCmisPropertyTypes.get(dataType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -712,86 +588,6 @@ public class CMISMapping
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
public QName getAlfrescoClassQNameFromCmisTableName(String tableName)
|
||||
{
|
||||
if (tableName.equalsIgnoreCase(DOCUMENT_TYPE_ID.getTypeId()))
|
||||
{
|
||||
return ContentModel.TYPE_CONTENT;
|
||||
}
|
||||
else if (tableName.equalsIgnoreCase(FOLDER_TYPE_ID.getTypeId()))
|
||||
{
|
||||
return ContentModel.TYPE_FOLDER;
|
||||
}
|
||||
else if (tableName.equalsIgnoreCase(RELATIONSHIP_TYPE_ID.getTypeId()))
|
||||
{
|
||||
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);
|
||||
|
||||
// Try lower case version first.
|
||||
|
||||
QName classQName = QName.createQName(prefix.toLowerCase(), localName.toLowerCase(), namespaceService);
|
||||
if (dictionaryService.getClass(classQName) != null)
|
||||
{
|
||||
return classQName;
|
||||
}
|
||||
|
||||
// Full case insensitive hunt
|
||||
|
||||
for (String test : namespaceService.getPrefixes())
|
||||
{
|
||||
if (test.equalsIgnoreCase(prefix))
|
||||
{
|
||||
prefix = test;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String uri = namespaceService.getNamespaceURI(prefix);
|
||||
|
||||
for (QName qname : dictionaryService.getAllTypes())
|
||||
{
|
||||
if (qname.getNamespaceURI().equals(uri))
|
||||
{
|
||||
if (qname.getLocalName().equalsIgnoreCase(localName))
|
||||
{
|
||||
return qname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (QName qname : dictionaryService.getAllAspects())
|
||||
{
|
||||
if (qname.getNamespaceURI().equals(uri))
|
||||
{
|
||||
if (qname.getLocalName().equalsIgnoreCase(localName))
|
||||
{
|
||||
return qname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -808,7 +604,6 @@ public class CMISMapping
|
||||
else
|
||||
{
|
||||
return propertyQName.toString();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright (C) 2005-20079 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISContentStreamAllowedEnum;
|
||||
import org.alfresco.cmis.dictionary.AbstractCMISDictionaryService.DictionaryRegistry;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Object Type Definition
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISObjectTypeDefinition implements CMISTypeDefinition, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -3131505923356013430L;
|
||||
|
||||
// Object type properties
|
||||
protected ClassDefinition cmisClassDef;
|
||||
protected CMISTypeId objectTypeId;
|
||||
protected String objectTypeQueryName;
|
||||
protected String displayName;
|
||||
protected CMISTypeId parentTypeId;
|
||||
protected CMISTypeDefinition parentType;
|
||||
protected CMISTypeDefinition rootType;
|
||||
protected String description;
|
||||
protected boolean creatable;
|
||||
protected boolean queryable;
|
||||
protected boolean controllable;
|
||||
protected boolean includeInSuperTypeQuery;
|
||||
protected Collection<CMISTypeId> subTypeIds = new ArrayList<CMISTypeId>();
|
||||
protected Collection<CMISTypeDefinition> subTypes = new ArrayList<CMISTypeDefinition>();
|
||||
protected Map<CMISPropertyId, CMISPropertyDefinition> properties = new HashMap<CMISPropertyId, CMISPropertyDefinition>();
|
||||
protected Map<CMISPropertyId, CMISPropertyDefinition> inheritedProperties = new HashMap<CMISPropertyId, CMISPropertyDefinition>();
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisMapping
|
||||
* @param dictionaryService
|
||||
* @return
|
||||
*/
|
||||
/*package*/ Map<CMISPropertyId, CMISPropertyDefinition> createProperties(CMISMapping cmisMapping, DictionaryService dictionaryService)
|
||||
{
|
||||
// map properties directly defined on this type
|
||||
for (PropertyDefinition propDef : cmisClassDef.getProperties().values())
|
||||
{
|
||||
if (propDef.getContainerClass().equals(cmisClassDef))
|
||||
{
|
||||
if (cmisMapping.getDataType(propDef.getDataType()) != null)
|
||||
{
|
||||
CMISPropertyDefinition cmisPropDef = createProperty(cmisMapping, propDef);
|
||||
properties.put(cmisPropDef.getPropertyId(), cmisPropDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// map properties directly defined on default aspects
|
||||
for (AspectDefinition aspectDef : cmisClassDef.getDefaultAspects(false))
|
||||
{
|
||||
for (PropertyDefinition propDef : aspectDef.getProperties().values())
|
||||
{
|
||||
if (cmisMapping.getDataType(propDef.getDataType()) != null)
|
||||
{
|
||||
CMISPropertyDefinition cmisPropDef = createProperty(cmisMapping, propDef);
|
||||
properties.put(cmisPropDef.getPropertyId(), cmisPropDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Property Definition
|
||||
*
|
||||
* @param cmisMapping
|
||||
* @param propDef
|
||||
* @return
|
||||
*/
|
||||
private CMISPropertyDefinition createProperty(CMISMapping cmisMapping, PropertyDefinition propDef)
|
||||
{
|
||||
QName propertyQName = propDef.getName();
|
||||
String propertyName = cmisMapping.getCmisPropertyName(propertyQName);
|
||||
String propertyId = cmisMapping.getCmisPropertyId(propertyQName);
|
||||
CMISPropertyId cmisPropertyId = new CMISPropertyId(propertyName, propertyId, propertyQName);
|
||||
return new CMISPropertyDefinition(cmisMapping, cmisPropertyId, propDef, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Sub Types
|
||||
*
|
||||
* @param cmisMapping
|
||||
* @param dictionaryService
|
||||
*/
|
||||
/*package*/ void createSubTypes(CMISMapping cmisMapping, DictionaryService dictionaryService)
|
||||
{
|
||||
Collection<QName> subTypes = dictionaryService.getSubTypes(objectTypeId.getQName(), false);
|
||||
for (QName subType : subTypes)
|
||||
{
|
||||
if (cmisMapping.isValidCmisDocumentOrFolder(subType))
|
||||
{
|
||||
CMISTypeId subTypeId = cmisMapping.getCmisTypeId(subType);
|
||||
if (subTypeId != null)
|
||||
{
|
||||
subTypeIds.add(subTypeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve Dependencies
|
||||
*
|
||||
* @param registry
|
||||
*/
|
||||
/*package*/ void resolveDependencies(DictionaryRegistry registry)
|
||||
{
|
||||
if (parentTypeId != null)
|
||||
{
|
||||
parentType = registry.typeDefsByTypeId.get(parentTypeId);
|
||||
if (parentType == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to retrieve parent type for type id " + parentTypeId);
|
||||
}
|
||||
}
|
||||
CMISTypeId rootTypeId = objectTypeId.getRootTypeId();
|
||||
if (rootTypeId != null)
|
||||
{
|
||||
rootType = registry.typeDefsByTypeId.get(rootTypeId);
|
||||
if (rootType == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to retrieve root type for type id " + rootTypeId);
|
||||
}
|
||||
}
|
||||
for (CMISTypeId subTypeId : subTypeIds)
|
||||
{
|
||||
CMISTypeDefinition subType = registry.typeDefsByTypeId.get(subTypeId);
|
||||
if (subType == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to retrieve sub type for type id " + subTypeId + " for parent type " + objectTypeId);
|
||||
}
|
||||
subTypes.add(subType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve Inheritance
|
||||
*
|
||||
* @param registry
|
||||
*/
|
||||
/*package*/ void resolveInheritance(DictionaryRegistry registry)
|
||||
{
|
||||
inheritedProperties.putAll(properties);
|
||||
if (parentType != null)
|
||||
{
|
||||
inheritedProperties.putAll(parentType.getPropertyDefinitions());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the unique identifier for the type
|
||||
*
|
||||
* @return - the type id
|
||||
*/
|
||||
public CMISTypeId getTypeId()
|
||||
{
|
||||
return objectTypeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table name used for queries against the type. This is also a unique identifier for the type. The string
|
||||
* conforms to SQL table naming conventions. TODO: Should we impose a maximum length and if so how do we avoid
|
||||
* collisions from truncations?
|
||||
*
|
||||
* @return the sql table name
|
||||
*/
|
||||
public String getQueryName()
|
||||
{
|
||||
return objectTypeQueryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name for the type.
|
||||
*
|
||||
* @return - the display name
|
||||
*/
|
||||
public String getDisplayName()
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CMISTypeDefinition getParentType()
|
||||
{
|
||||
return parentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CMISTypeDefinition getRootType()
|
||||
{
|
||||
return rootType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sub types
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeDefinition> getSubTypes(boolean includeDescendants)
|
||||
{
|
||||
if (!includeDescendants)
|
||||
{
|
||||
return subTypes;
|
||||
}
|
||||
|
||||
// recurse sub-type hierarchy
|
||||
Collection<CMISTypeDefinition> descendants = new ArrayList<CMISTypeDefinition>();
|
||||
LinkedList<CMISTypeDefinition> stack = new LinkedList<CMISTypeDefinition>();
|
||||
stack.addLast(this);
|
||||
while (stack.size() > 0)
|
||||
{
|
||||
CMISTypeDefinition current = stack.removeLast();
|
||||
if (!current.equals(this)) // do not add this type
|
||||
{
|
||||
descendants.add(current);
|
||||
}
|
||||
|
||||
// descend...
|
||||
for (CMISTypeDefinition type : current.getSubTypes(false))
|
||||
{
|
||||
stack.addLast(type);
|
||||
}
|
||||
}
|
||||
return descendants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for the type
|
||||
*
|
||||
* @return - the description
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can objects of this type be created?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isCreatable()
|
||||
{
|
||||
return creatable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type queryable? If not, the type may not appear in the FROM clause of a query. This property of the type
|
||||
* is not inherited in the type hierarchy. It is set on each type.
|
||||
*
|
||||
* @return true if queryable
|
||||
*/
|
||||
public boolean isQueryable()
|
||||
{
|
||||
return queryable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are objects of this type controllable.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isControllable()
|
||||
{
|
||||
return controllable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are objects of this type included in super type queries
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isIncludeInSuperTypeQuery()
|
||||
{
|
||||
return includeInSuperTypeQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the property definitions for this type
|
||||
*
|
||||
* @return property definitions
|
||||
*/
|
||||
public Map<CMISPropertyId, CMISPropertyDefinition> getPropertyDefinitions()
|
||||
{
|
||||
return inheritedProperties;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Document Type specific
|
||||
//
|
||||
|
||||
/**
|
||||
* Is Fileable?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFileable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Versionable?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isVersionable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Content Stream Allowed?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CMISContentStreamAllowedEnum getContentStreamAllowed()
|
||||
{
|
||||
return CMISContentStreamAllowedEnum.NOT_ALLOWED;
|
||||
}
|
||||
|
||||
//
|
||||
// Relationship Type specific
|
||||
//
|
||||
|
||||
/**
|
||||
* Get allowed source types
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeDefinition> getAllowedSourceTypes()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed target types
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeDefinition> getAllowedTargetTypes()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.alfresco.cmis.dictionary.AbstractCMISDictionaryService.DictionaryRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Policy Type Definition
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISPolicyTypeDefinition extends CMISObjectTypeDefinition
|
||||
{
|
||||
private static final long serialVersionUID = 1621538303752395828L;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisMapping
|
||||
* @param typeId
|
||||
* @param cmisClassDef
|
||||
*/
|
||||
public CMISPolicyTypeDefinition(CMISMapping cmisMapping, CMISTypeId typeId, ClassDefinition cmisClassDef)
|
||||
{
|
||||
this.cmisClassDef = cmisClassDef;
|
||||
objectTypeId = typeId;
|
||||
displayName = (cmisClassDef.getTitle() != null) ? cmisClassDef.getTitle() : typeId.getId();
|
||||
if (typeId == CMISDictionaryModel.POLICY_TYPE_ID)
|
||||
{
|
||||
objectTypeQueryName = typeId.getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
objectTypeQueryName = cmisMapping.buildPrefixEncodedString(typeId.getQName(), false);
|
||||
parentTypeId = CMISDictionaryModel.POLICY_TYPE_ID;
|
||||
}
|
||||
description = cmisClassDef.getDescription();
|
||||
creatable = false;
|
||||
queryable = false;
|
||||
controllable = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISObjectTypeDefinition#createSubTypes(org.alfresco.cmis.dictionary.CMISMapping, org.alfresco.service.cmr.dictionary.DictionaryService)
|
||||
*/
|
||||
@Override
|
||||
/*package*/ void createSubTypes(CMISMapping cmisMapping, DictionaryService dictionaryService)
|
||||
{
|
||||
if (objectTypeId.equals(CMISDictionaryModel.POLICY_TYPE_ID))
|
||||
{
|
||||
// all aspects are sub-type of POLICY_OBJECT_TYPE
|
||||
Collection<QName> aspects = dictionaryService.getAllAspects();
|
||||
for (QName aspect : aspects)
|
||||
{
|
||||
if (cmisMapping.isValidCmisPolicy(aspect))
|
||||
{
|
||||
subTypeIds.add(cmisMapping.getCmisTypeId(CMISScope.POLICY, aspect));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISObjectTypeDefinition#resolveInheritance(org.alfresco.cmis.dictionary.AbstractCMISDictionaryService.DictionaryRegistry)
|
||||
*/
|
||||
@Override
|
||||
/*package*/ void resolveInheritance(DictionaryRegistry registry)
|
||||
{
|
||||
// NOTE: Force no inheritance of base Policy type
|
||||
inheritedProperties.putAll(properties);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CMISPolicyTypeDefinition[");
|
||||
builder.append("ObjectTypeId=").append(getTypeId()).append(", ");
|
||||
builder.append("ObjectTypeQueryName=").append(getQueryName()).append(", ");
|
||||
builder.append("ObjectTypeDisplayName=").append(getDisplayName()).append(", ");
|
||||
builder.append("ParentTypeId=").append(getParentType() == null ? "<none>" : getParentType().getTypeId()).append(", ");
|
||||
builder.append("Description=").append(getDescription()).append(", ");
|
||||
builder.append("Creatable=").append(isCreatable()).append(", ");
|
||||
builder.append("Queryable=").append(isQueryable()).append(", ");
|
||||
builder.append("Controllable=").append(isControllable()).append(", ");
|
||||
builder.append("IncludeInSuperTypeQuery=").append(isIncludeInSuperTypeQuery()).append(", ");
|
||||
builder.append("SubTypes=").append(getSubTypes(false).size()).append(", ");
|
||||
builder.append("Properties=").append(getPropertyDefinitions().size());
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
@@ -29,7 +29,7 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.alfresco.cmis.CMISCardinalityEnum;
|
||||
import org.alfresco.cmis.CMISPropertyTypeEnum;
|
||||
import org.alfresco.cmis.CMISDataTypeEnum;
|
||||
import org.alfresco.cmis.CMISUpdatabilityEnum;
|
||||
import org.alfresco.repo.dictionary.IndexTokenisationMode;
|
||||
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
|
||||
@@ -44,171 +44,129 @@ import org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser;
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* A CMIS property definition
|
||||
* CMIS Property Definition
|
||||
*
|
||||
* @author andyh
|
||||
*/
|
||||
public class CMISPropertyDefinition implements Serializable
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -8119257313852558466L;
|
||||
|
||||
private String propertyName;
|
||||
|
||||
private String propertyId;
|
||||
|
||||
// Properties of Property
|
||||
private CMISTypeDefinition typeDef;
|
||||
private CMISPropertyId propertyId;
|
||||
private String displayName;
|
||||
|
||||
private String description;
|
||||
|
||||
private boolean isInherited;
|
||||
|
||||
private CMISPropertyTypeEnum propertyType;
|
||||
|
||||
private CMISDataTypeEnum propertyType;
|
||||
private CMISCardinalityEnum cardinality;
|
||||
|
||||
private int maximumLength = -1;
|
||||
|
||||
private String schemaURI = null;
|
||||
|
||||
private String encoding = null;
|
||||
|
||||
private Collection<CMISChoice> choices = new HashSet<CMISChoice>();
|
||||
|
||||
private boolean isOpenChoice = false;
|
||||
|
||||
private boolean required;
|
||||
|
||||
private String defaultValue;
|
||||
|
||||
private CMISUpdatabilityEnum updatability;
|
||||
|
||||
private boolean queryable;
|
||||
|
||||
private boolean orderable;
|
||||
|
||||
public CMISPropertyDefinition(CMISDictionaryService cmisDictionary, QName propertyQName, QName typeQName)
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisMapping
|
||||
* @param propertyId
|
||||
* @param propDef
|
||||
* @param typeDef
|
||||
*/
|
||||
public CMISPropertyDefinition(CMISMapping cmisMapping, CMISPropertyId propertyId, PropertyDefinition propDef, CMISTypeDefinition typeDef)
|
||||
{
|
||||
CMISMapping cmisMapping = cmisDictionary.getCMISMapping();
|
||||
PropertyDefinition propDef = cmisDictionary.getDictionaryService().getProperty(propertyQName);
|
||||
if (propDef.getContainerClass().getName().equals(CMISMapping.RELATIONSHIP_QNAME))
|
||||
this.propertyId = propertyId;
|
||||
this.typeDef = typeDef;
|
||||
displayName = (propDef.getTitle() != null) ? propDef.getTitle() : propertyId.getName();
|
||||
description = propDef.getDescription();
|
||||
propertyType = cmisMapping.getDataType(propDef.getDataType());
|
||||
cardinality = propDef.isMultiValued() ? CMISCardinalityEnum.MULTI_VALUED : CMISCardinalityEnum.SINGLE_VALUED;
|
||||
for (ConstraintDefinition constraintDef : propDef.getConstraints())
|
||||
{
|
||||
// Properties of associations - all the same
|
||||
propertyName = cmisMapping.getCmisPropertyName(propertyQName);
|
||||
propertyId = cmisMapping.getCmisPropertyId(propertyQName);
|
||||
displayName = (propDef.getTitle() != null) ? propDef.getTitle() : propertyName;
|
||||
description = propDef.getDescription();
|
||||
isInherited = false;
|
||||
propertyType = cmisMapping.getPropertyType(propertyQName);
|
||||
cardinality = propDef.isMultiValued() ? CMISCardinalityEnum.MULTI_VALUED : CMISCardinalityEnum.SINGLE_VALUED;
|
||||
required = propDef.isMandatory();
|
||||
defaultValue = propDef.getDefaultValue();
|
||||
updatability = propDef.isProtected() ? CMISUpdatabilityEnum.READ_ONLY : CMISUpdatabilityEnum.READ_AND_WRITE;
|
||||
queryable = false;
|
||||
orderable = false;
|
||||
Constraint constraint = constraintDef.getConstraint();
|
||||
if (constraint instanceof ListOfValuesConstraint)
|
||||
{
|
||||
int position = 1; // CMIS is 1 based (according to XSDs)
|
||||
ListOfValuesConstraint lovc = (ListOfValuesConstraint) constraint;
|
||||
for (String allowed : lovc.getAllowedValues())
|
||||
{
|
||||
CMISChoice choice = new CMISChoice(allowed, allowed, position++);
|
||||
choices.add(choice);
|
||||
}
|
||||
}
|
||||
if (constraint instanceof StringLengthConstraint)
|
||||
{
|
||||
StringLengthConstraint slc = (StringLengthConstraint) constraint;
|
||||
maximumLength = slc.getMaxLength();
|
||||
}
|
||||
}
|
||||
required = propDef.isMandatory();
|
||||
defaultValue = propDef.getDefaultValue();
|
||||
updatability = propDef.isProtected() ? CMISUpdatabilityEnum.READ_ONLY : CMISUpdatabilityEnum.READ_AND_WRITE;
|
||||
queryable = propDef.isIndexed();
|
||||
if (queryable)
|
||||
{
|
||||
IndexTokenisationMode indexTokenisationMode = IndexTokenisationMode.TRUE;
|
||||
if (propDef.getIndexTokenisationMode() != null)
|
||||
{
|
||||
indexTokenisationMode = propDef.getIndexTokenisationMode();
|
||||
}
|
||||
switch (indexTokenisationMode)
|
||||
{
|
||||
case BOTH:
|
||||
case FALSE:
|
||||
orderable = true;
|
||||
break;
|
||||
case TRUE:
|
||||
default:
|
||||
String analyserClassName = propDef.getDataType().getAnalyserClassName();
|
||||
if (analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName())
|
||||
|| analyserClassName.equals(DoubleAnalyser.class.getCanonicalName()) || analyserClassName.equals(FloatAnalyser.class.getCanonicalName())
|
||||
|| analyserClassName.equals(IntegerAnalyser.class.getCanonicalName()) || analyserClassName.equals(LongAnalyser.class.getCanonicalName())
|
||||
|| analyserClassName.equals(PathAnalyser.class.getCanonicalName()) || analyserClassName.equals(VerbatimAnalyser.class.getCanonicalName()))
|
||||
{
|
||||
orderable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
orderable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
propertyName = cmisMapping.getCmisPropertyName(propertyQName);
|
||||
propertyId = cmisMapping.getCmisPropertyId(propertyQName);
|
||||
displayName = (propDef.getTitle() != null) ? propDef.getTitle() : propertyName;
|
||||
description = propDef.getDescription();
|
||||
if(propDef.getContainerClass().isAspect())
|
||||
{
|
||||
isInherited = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isInherited = !propDef.getContainerClass().equals(typeQName);
|
||||
}
|
||||
propertyType = cmisMapping.getPropertyType(propertyQName);
|
||||
cardinality = propDef.isMultiValued() ? CMISCardinalityEnum.MULTI_VALUED : CMISCardinalityEnum.SINGLE_VALUED;
|
||||
for (ConstraintDefinition constraintDef : propDef.getConstraints())
|
||||
{
|
||||
Constraint constraint = constraintDef.getConstraint();
|
||||
if (constraint instanceof ListOfValuesConstraint)
|
||||
{
|
||||
int position = 1; // CMIS is 1 based (according to XSDs)
|
||||
ListOfValuesConstraint lovc = (ListOfValuesConstraint) constraint;
|
||||
for (String allowed : lovc.getAllowedValues())
|
||||
{
|
||||
CMISChoice choice = new CMISChoice(allowed, allowed, position++);
|
||||
choices.add(choice);
|
||||
}
|
||||
}
|
||||
if (constraint instanceof StringLengthConstraint)
|
||||
{
|
||||
StringLengthConstraint slc = (StringLengthConstraint) constraint;
|
||||
maximumLength = slc.getMaxLength();
|
||||
}
|
||||
}
|
||||
required = propDef.isMandatory();
|
||||
defaultValue = propDef.getDefaultValue();
|
||||
updatability = propDef.isProtected() ? CMISUpdatabilityEnum.READ_ONLY : CMISUpdatabilityEnum.READ_AND_WRITE;
|
||||
queryable = propDef.isIndexed();
|
||||
if (queryable)
|
||||
{
|
||||
IndexTokenisationMode indexTokenisationMode = IndexTokenisationMode.TRUE;
|
||||
if (propDef.getIndexTokenisationMode() != null)
|
||||
{
|
||||
indexTokenisationMode = propDef.getIndexTokenisationMode();
|
||||
}
|
||||
switch (indexTokenisationMode)
|
||||
{
|
||||
case BOTH:
|
||||
case FALSE:
|
||||
orderable = true;
|
||||
break;
|
||||
case TRUE:
|
||||
default:
|
||||
String analyserClassName = propDef.getDataType().getAnalyserClassName();
|
||||
if (analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName())
|
||||
|| analyserClassName.equals(DoubleAnalyser.class.getCanonicalName()) || analyserClassName.equals(FloatAnalyser.class.getCanonicalName())
|
||||
|| analyserClassName.equals(IntegerAnalyser.class.getCanonicalName()) || analyserClassName.equals(LongAnalyser.class.getCanonicalName())
|
||||
|| analyserClassName.equals(PathAnalyser.class.getCanonicalName()) || analyserClassName.equals(VerbatimAnalyser.class.getCanonicalName()))
|
||||
{
|
||||
orderable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
orderable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
orderable = false;
|
||||
}
|
||||
orderable = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property name
|
||||
* Get Property Id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPropertyName()
|
||||
{
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPropertyId()
|
||||
public CMISPropertyId getPropertyId()
|
||||
{
|
||||
return propertyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Owning Type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CMISTypeDefinition getOwningType()
|
||||
{
|
||||
return typeDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name
|
||||
*
|
||||
@@ -228,23 +186,13 @@ public class CMISPropertyDefinition implements Serializable
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the property definition inherited?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isInherited()
|
||||
{
|
||||
return isInherited;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CMISPropertyTypeEnum getPropertyType()
|
||||
public CMISDataTypeEnum getDataType()
|
||||
{
|
||||
return propertyType;
|
||||
}
|
||||
@@ -359,16 +307,21 @@ public class CMISPropertyDefinition implements Serializable
|
||||
return orderable;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CMISPropertyDefinition[");
|
||||
builder.append("PropertyName=").append(getPropertyName()).append(", ");
|
||||
builder.append("PropertyId=").append(getPropertyId()).append(", ");
|
||||
builder.append("OwningTypeId=").append(getOwningType().getTypeId()).append(", ");
|
||||
builder.append("PropertyName=").append(getPropertyId().getName()).append(", ");
|
||||
builder.append("PropertyId=").append(getPropertyId().getId()).append(", ");
|
||||
builder.append("DisplayName=").append(getDisplayName()).append(", ");
|
||||
builder.append("Description=").append(getDescription()).append(", ");
|
||||
builder.append("IsInherited=").append(isInherited()).append(", ");
|
||||
builder.append("PropertyType=").append(getPropertyType()).append(", ");
|
||||
builder.append("PropertyType=").append(getDataType()).append(", ");
|
||||
builder.append("Cardinality=").append(getCardinality()).append(", ");
|
||||
builder.append("MaximumLength=").append(getMaximumLength()).append(", ");
|
||||
builder.append("SchemaURI=").append(getSchemaURI()).append(", ");
|
||||
|
138
source/java/org/alfresco/cmis/dictionary/CMISPropertyId.java
Normal file
138
source/java/org/alfresco/cmis/dictionary/CMISPropertyId.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Property Id
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISPropertyId implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 4094778633095367606L;
|
||||
|
||||
// Id properties
|
||||
private String propertyName;
|
||||
private String propertyId;
|
||||
private QName qName;
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param propertyName
|
||||
* @param propertyId
|
||||
* @param qName
|
||||
*/
|
||||
public CMISPropertyId(String propertyName, String propertyId, QName qName)
|
||||
{
|
||||
this.propertyName = propertyName;
|
||||
this.propertyId = propertyId;
|
||||
this.qName = qName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return propertyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Alfresco model QName associated with the property
|
||||
*
|
||||
* @return alfresco QName
|
||||
*/
|
||||
public QName getQName()
|
||||
{
|
||||
return qName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final CMISPropertyId other = (CMISPropertyId) obj;
|
||||
if (propertyName == null)
|
||||
{
|
||||
if (other.propertyName != null)
|
||||
return false;
|
||||
}
|
||||
else if (!propertyName.equals(other.propertyName))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.dictionary.AbstractCMISDictionaryService.DictionaryRegistry;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
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.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Relationship Type Definition
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISRelationshipTypeDefinition extends CMISObjectTypeDefinition
|
||||
{
|
||||
private static final long serialVersionUID = 5291428171784061346L;
|
||||
|
||||
// Relationship properties
|
||||
private List<CMISTypeId> allowedSourceTypeIds = new ArrayList<CMISTypeId>();
|
||||
private List<CMISTypeDefinition> allowedSourceTypes = new ArrayList<CMISTypeDefinition>();
|
||||
private List<CMISTypeDefinition> inheritedAllowedSourceTypes = new ArrayList<CMISTypeDefinition>();
|
||||
private List<CMISTypeId> allowedTargetTypeIds = new ArrayList<CMISTypeId>();
|
||||
private List<CMISTypeDefinition> allowedTargetTypes = new ArrayList<CMISTypeDefinition>();
|
||||
private List<CMISTypeDefinition> inheritedAllowedTargetTypes = new ArrayList<CMISTypeDefinition>();
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisMapping
|
||||
* @param typeId
|
||||
* @param cmisClassDef
|
||||
* @param assocDef
|
||||
*/
|
||||
public CMISRelationshipTypeDefinition(CMISMapping cmisMapping, CMISTypeId typeId, ClassDefinition cmisClassDef, AssociationDefinition assocDef)
|
||||
{
|
||||
this.cmisClassDef = cmisClassDef;
|
||||
objectTypeId = typeId;
|
||||
creatable = false;
|
||||
queryable = false;
|
||||
controllable = false;
|
||||
|
||||
if (assocDef == null)
|
||||
{
|
||||
// TODO: Add CMIS Association mapping??
|
||||
displayName = (cmisClassDef.getTitle() != null) ? cmisClassDef.getTitle() : typeId.getId();
|
||||
objectTypeQueryName = typeId.getId();
|
||||
parentTypeId = null;
|
||||
description = cmisClassDef.getDescription();
|
||||
}
|
||||
else
|
||||
{
|
||||
displayName = (assocDef.getTitle() != null) ? assocDef.getTitle() : typeId.getId();
|
||||
objectTypeQueryName = cmisMapping.buildPrefixEncodedString(typeId.getQName(), false);
|
||||
parentTypeId = CMISDictionaryModel.RELATIONSHIP_TYPE_ID;
|
||||
description = assocDef.getDescription();
|
||||
|
||||
CMISTypeId sourceTypeId = cmisMapping.getCmisTypeId(cmisMapping.getCmisType(assocDef.getSourceClass().getName()));
|
||||
if (sourceTypeId != null && (sourceTypeId.getScope() == CMISScope.DOCUMENT || sourceTypeId.getScope() == CMISScope.FOLDER))
|
||||
{
|
||||
allowedSourceTypeIds.add(sourceTypeId);
|
||||
}
|
||||
|
||||
CMISTypeId targetTypeId = cmisMapping.getCmisTypeId(cmisMapping.getCmisType(assocDef.getTargetClass().getName()));
|
||||
if (targetTypeId != null && (targetTypeId.getScope() == CMISScope.DOCUMENT || targetTypeId.getScope() == CMISScope.FOLDER))
|
||||
{
|
||||
allowedTargetTypeIds.add(targetTypeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISObjectTypeDefinition#createProperties(org.alfresco.cmis.dictionary.CMISMapping, org.alfresco.service.cmr.dictionary.DictionaryService)
|
||||
*/
|
||||
@Override
|
||||
/*package*/ Map<CMISPropertyId, CMISPropertyDefinition> createProperties(CMISMapping cmisMapping, DictionaryService dictionaryService)
|
||||
{
|
||||
if (objectTypeId.equals(CMISDictionaryModel.RELATIONSHIP_TYPE_ID))
|
||||
{
|
||||
return super.createProperties(cmisMapping, dictionaryService);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISObjectTypeDefinition#createSubTypes(org.alfresco.cmis.dictionary.CMISMapping, org.alfresco.service.cmr.dictionary.DictionaryService)
|
||||
*/
|
||||
@Override
|
||||
/*package*/ void createSubTypes(CMISMapping cmisMapping, DictionaryService dictionaryService)
|
||||
{
|
||||
if (objectTypeId.equals(CMISDictionaryModel.RELATIONSHIP_TYPE_ID))
|
||||
{
|
||||
// all associations are sub-type of RELATIONSHIP_OBJECT_TYPE
|
||||
Collection<QName> assocs = dictionaryService.getAllAssociations();
|
||||
for (QName assoc : assocs)
|
||||
{
|
||||
if (cmisMapping.isValidCmisRelationship(assoc))
|
||||
{
|
||||
subTypeIds.add(cmisMapping.getCmisTypeId(CMISScope.RELATIONSHIP, assoc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISObjectTypeDefinition#resolveDependencies(org.alfresco.cmis.dictionary.AbstractCMISDictionaryService.DictionaryRegistry)
|
||||
*/
|
||||
@Override
|
||||
/*package*/ void resolveDependencies(DictionaryRegistry registry)
|
||||
{
|
||||
super.resolveDependencies(registry);
|
||||
for (CMISTypeId sourceTypeId : allowedSourceTypeIds)
|
||||
{
|
||||
CMISTypeDefinition type = registry.typeDefsByTypeId.get(sourceTypeId);
|
||||
if (type == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to retrieve allowed source type for type id " + sourceTypeId);
|
||||
}
|
||||
allowedSourceTypes.add(type);
|
||||
}
|
||||
for (CMISTypeId targetTypeId : allowedTargetTypeIds)
|
||||
{
|
||||
CMISTypeDefinition type = registry.typeDefsByTypeId.get(targetTypeId);
|
||||
if (type == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to retrieve allowed target type for type id " + targetTypeId);
|
||||
}
|
||||
allowedTargetTypes.add(registry.typeDefsByTypeId.get(targetTypeId));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.CMISObjectTypeDefinition#resolveInheritance(org.alfresco.cmis.dictionary.AbstractCMISDictionaryService.DictionaryRegistry)
|
||||
*/
|
||||
@Override
|
||||
/*package*/ void resolveInheritance(DictionaryRegistry registry)
|
||||
{
|
||||
super.resolveInheritance(registry);
|
||||
inheritedAllowedSourceTypes.addAll(allowedSourceTypes);
|
||||
inheritedAllowedTargetTypes.addAll(allowedTargetTypes);
|
||||
if (parentType != null)
|
||||
{
|
||||
inheritedAllowedSourceTypes.addAll(parentType.getAllowedSourceTypes());
|
||||
inheritedAllowedTargetTypes.addAll(parentType.getAllowedTargetTypes());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For an association, get the collection of valid source types. For non-associations the collection will be empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeDefinition> getAllowedSourceTypes()
|
||||
{
|
||||
return inheritedAllowedSourceTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* For an association, get the collection of valid target types. For non-associations the collection will be empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeDefinition> getAllowedTargetTypes()
|
||||
{
|
||||
return inheritedAllowedTargetTypes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CMISRelationshipTypeDefinition[");
|
||||
builder.append("ObjectTypeId=").append(getTypeId()).append(", ");
|
||||
builder.append("ObjectTypeQueryName=").append(getQueryName()).append(", ");
|
||||
builder.append("ObjectTypeDisplayName=").append(getDisplayName()).append(", ");
|
||||
builder.append("ParentTypeId=").append(getParentType() == null ? "<none>" : getParentType().getTypeId()).append(", ");
|
||||
builder.append("Description=").append(getDescription()).append(", ");
|
||||
builder.append("Creatable=").append(isCreatable()).append(", ");
|
||||
builder.append("Queryable=").append(isQueryable()).append(", ");
|
||||
builder.append("Controllable=").append(isControllable()).append(", ");
|
||||
builder.append("IncludeInSuperTypeQuery=").append(isIncludeInSuperTypeQuery()).append(", ");
|
||||
builder.append("AllowedSourceTypes=[");
|
||||
for (CMISTypeDefinition type : getAllowedSourceTypes())
|
||||
{
|
||||
builder.append(type.getTypeId()).append(",");
|
||||
}
|
||||
builder.append("], ");
|
||||
builder.append("AllowedTargetTypes=[");
|
||||
for (CMISTypeDefinition type : getAllowedTargetTypes())
|
||||
{
|
||||
builder.append(type.getTypeId()).append(",");
|
||||
}
|
||||
builder.append("], ");
|
||||
builder.append("SubTypes=").append(getSubTypes(false).size()).append(", ");
|
||||
builder.append("Properties=").append(getPropertyDefinitions().size());
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2005-20079 Alfresco Software Limited.
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Dictionary which provides Types that strictly conform to the CMIS specification.
|
||||
*
|
||||
* That is, only maps types to one of root Document, Folder, Relationship & Policy.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class CMISStrictDictionaryService extends AbstractCMISDictionaryService
|
||||
{
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.dictionary.AbstractCMISDictionaryService#createDefinitions(org.alfresco.cmis.dictionary.AbstractCMISDictionaryService.DictionaryRegistry)
|
||||
*/
|
||||
@Override
|
||||
protected void createDefinitions(DictionaryRegistry registry)
|
||||
{
|
||||
createTypeDefs(registry, dictionaryService.getAllTypes());
|
||||
createAssocDefs(registry, dictionaryService.getAllAssociations());
|
||||
createTypeDefs(registry, dictionaryService.getAllAspects());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Type Definitions
|
||||
*
|
||||
* @param registry
|
||||
* @param classQNames
|
||||
*/
|
||||
private void createTypeDefs(DictionaryRegistry registry, Collection<QName> classQNames)
|
||||
{
|
||||
for (QName classQName : classQNames)
|
||||
{
|
||||
// skip items that are remapped to CMIS model
|
||||
if (cmisMapping.isRemappedType(classQName))
|
||||
continue;
|
||||
|
||||
// skip all items that are not mapped to CMIS model
|
||||
CMISTypeId typeId = cmisMapping.getCmisTypeId(classQName);
|
||||
if (typeId == null)
|
||||
continue;
|
||||
|
||||
// create appropriate kind of type definition
|
||||
ClassDefinition classDef = dictionaryService.getClass(cmisMapping.getCmisType(typeId.getQName()));
|
||||
CMISObjectTypeDefinition objectTypeDef = null;
|
||||
if (typeId.getScope() == CMISScope.DOCUMENT)
|
||||
{
|
||||
objectTypeDef = new CMISDocumentTypeDefinition(cmisMapping, typeId, classDef);
|
||||
}
|
||||
else if (typeId.getScope() == CMISScope.FOLDER)
|
||||
{
|
||||
objectTypeDef = new CMISFolderTypeDefinition(cmisMapping, typeId, classDef);
|
||||
}
|
||||
else if (typeId.getScope() == CMISScope.RELATIONSHIP)
|
||||
{
|
||||
AssociationDefinition assocDef = dictionaryService.getAssociation(classQName);
|
||||
objectTypeDef = new CMISRelationshipTypeDefinition(cmisMapping, typeId, classDef, assocDef);
|
||||
}
|
||||
else if (typeId.getScope() == CMISScope.POLICY)
|
||||
{
|
||||
objectTypeDef = new CMISPolicyTypeDefinition(cmisMapping, typeId, classDef);
|
||||
}
|
||||
|
||||
registry.registerTypeDefinition(objectTypeDef);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Relationship Definitions
|
||||
*
|
||||
* @param registry
|
||||
* @param classQNames
|
||||
*/
|
||||
private void createAssocDefs(DictionaryRegistry registry, Collection<QName> classQNames)
|
||||
{
|
||||
for (QName classQName : classQNames)
|
||||
{
|
||||
if (!cmisMapping.isValidCmisRelationship(classQName))
|
||||
continue;
|
||||
|
||||
// create appropriate kind of type definition
|
||||
CMISTypeId typeId = cmisMapping.getCmisTypeId(CMISScope.RELATIONSHIP, classQName);
|
||||
AssociationDefinition assocDef = dictionaryService.getAssociation(classQName);
|
||||
CMISObjectTypeDefinition objectTypeDef = new CMISRelationshipTypeDefinition(cmisMapping, typeId, null, assocDef);
|
||||
|
||||
registry.registerTypeDefinition(objectTypeDef);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -22,249 +22,26 @@
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
|
||||
package org.alfresco.cmis.dictionary;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* The base type definition for CMIS
|
||||
*
|
||||
* @author andyh
|
||||
*/
|
||||
public class CMISTypeDefinition implements Serializable
|
||||
public interface CMISTypeDefinition
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -2216695347624799934L;
|
||||
|
||||
private CMISDictionaryService cmisDictionary;
|
||||
|
||||
private CMISTypeId objectTypeId;
|
||||
|
||||
private String objectTypeQueryName;
|
||||
|
||||
private String displayName;
|
||||
|
||||
private CMISTypeId parentTypeId;
|
||||
|
||||
private String rootTypeQueryName;
|
||||
|
||||
private String description;
|
||||
|
||||
private boolean creatable;
|
||||
|
||||
private boolean fileable;
|
||||
|
||||
private boolean queryable;
|
||||
|
||||
// TODO: Policy - report controllable true as policies can be applied
|
||||
private boolean controllable;
|
||||
|
||||
private boolean versionable;
|
||||
|
||||
private boolean includedInSupertypeQuery;
|
||||
|
||||
private CMISContentStreamAllowedEnum contentStreamAllowed;
|
||||
|
||||
private boolean isAssociation;
|
||||
|
||||
private ArrayList<CMISTypeId> allowedSourceTypes = new ArrayList<CMISTypeId>(1);
|
||||
|
||||
private ArrayList<CMISTypeId> allowedTargetTypes = new ArrayList<CMISTypeId>(1);
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisDictionary
|
||||
* @param typeId
|
||||
*/
|
||||
public CMISTypeDefinition(CMISDictionaryService cmisDictionary, CMISTypeId typeId)
|
||||
{
|
||||
this.cmisDictionary = cmisDictionary;
|
||||
DictionaryService dictionaryService = this.cmisDictionary.getDictionaryService();
|
||||
CMISMapping cmisMapping = cmisDictionary.getCMISMapping();
|
||||
|
||||
switch (typeId.getScope())
|
||||
{
|
||||
case RELATIONSHIP:
|
||||
AssociationDefinition associationDefinition = dictionaryService.getAssociation(typeId.getQName());
|
||||
if (associationDefinition != null)
|
||||
{
|
||||
objectTypeId = typeId;
|
||||
objectTypeQueryName = cmisMapping.getQueryName(typeId.getQName());
|
||||
displayName = (associationDefinition.getTitle() != null) ? associationDefinition.getTitle() : typeId.getTypeId();
|
||||
parentTypeId = CMISMapping.RELATIONSHIP_TYPE_ID;
|
||||
rootTypeQueryName = cmisMapping.getQueryName(CMISMapping.RELATIONSHIP_QNAME);
|
||||
description = associationDefinition.getDescription();
|
||||
creatable = false;
|
||||
fileable = false;
|
||||
queryable = false;
|
||||
controllable = false;
|
||||
versionable = false;
|
||||
includedInSupertypeQuery = true;
|
||||
contentStreamAllowed = CMISContentStreamAllowedEnum.NOT_ALLOWED;
|
||||
isAssociation = true;
|
||||
|
||||
QName sourceType = cmisMapping.getCmisType(associationDefinition.getSourceClass().getName());
|
||||
if (cmisMapping.isValidCmisDocument(sourceType))
|
||||
{
|
||||
allowedSourceTypes.add(cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, sourceType));
|
||||
}
|
||||
else if (cmisMapping.isValidCmisFolder(sourceType))
|
||||
{
|
||||
allowedSourceTypes.add(cmisMapping.getCmisTypeId(CMISScope.FOLDER, sourceType));
|
||||
}
|
||||
|
||||
QName targetType = cmisMapping.getCmisType(associationDefinition.getTargetClass().getName());
|
||||
if (cmisMapping.isValidCmisDocument(targetType))
|
||||
{
|
||||
allowedTargetTypes.add(cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, targetType));
|
||||
}
|
||||
else if (cmisMapping.isValidCmisFolder(targetType))
|
||||
{
|
||||
allowedTargetTypes.add(cmisMapping.getCmisTypeId(CMISScope.FOLDER, targetType));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Add CMIS Association mapping??
|
||||
TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName());
|
||||
objectTypeId = typeId;
|
||||
objectTypeQueryName = cmisMapping.getQueryName(typeId.getQName());
|
||||
displayName = (typeDefinition.getTitle() != null) ? typeDefinition.getTitle() : typeId.getTypeId();
|
||||
parentTypeId = null;
|
||||
rootTypeQueryName = cmisMapping.getQueryName(CMISMapping.RELATIONSHIP_QNAME);
|
||||
description = typeDefinition.getDescription();
|
||||
creatable = false;
|
||||
fileable = false;
|
||||
queryable = false;
|
||||
controllable = false;
|
||||
versionable = false;
|
||||
includedInSupertypeQuery = true;
|
||||
contentStreamAllowed = CMISContentStreamAllowedEnum.NOT_ALLOWED;
|
||||
isAssociation = true;
|
||||
}
|
||||
break;
|
||||
case DOCUMENT:
|
||||
case FOLDER:
|
||||
ClassDefinition typeDefinition = dictionaryService.getType(typeId.getQName());
|
||||
if (typeDefinition != null)
|
||||
{
|
||||
objectTypeId = typeId;
|
||||
|
||||
objectTypeQueryName = cmisMapping.getQueryName(typeId.getQName());
|
||||
|
||||
displayName = (typeDefinition.getTitle() != null) ? typeDefinition.getTitle() : typeId.getTypeId();
|
||||
|
||||
QName parentTypeQName = cmisMapping.getCmisType(typeDefinition.getParentName());
|
||||
if (parentTypeQName == null)
|
||||
{
|
||||
// Core and unknown types
|
||||
parentTypeId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cmisMapping.isValidCmisDocument(parentTypeQName))
|
||||
{
|
||||
parentTypeId = cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, parentTypeQName);
|
||||
}
|
||||
else if (cmisMapping.isValidCmisFolder(parentTypeQName))
|
||||
{
|
||||
parentTypeId = cmisMapping.getCmisTypeId(CMISScope.FOLDER, parentTypeQName);
|
||||
}
|
||||
}
|
||||
|
||||
rootTypeQueryName = cmisMapping.getQueryName(typeId.getRootTypeId().getQName());
|
||||
|
||||
description = typeDefinition.getDescription();
|
||||
|
||||
creatable = true;
|
||||
|
||||
fileable = true;
|
||||
|
||||
queryable = true;
|
||||
|
||||
controllable = false;
|
||||
|
||||
versionable = false;
|
||||
|
||||
includedInSupertypeQuery = true;
|
||||
|
||||
if (typeId.getScope() == CMISScope.DOCUMENT)
|
||||
{
|
||||
List<AspectDefinition> defaultAspects = typeDefinition.getDefaultAspects();
|
||||
for (AspectDefinition aspectDefinition : defaultAspects)
|
||||
{
|
||||
if (aspectDefinition.getName().equals(ContentModel.ASPECT_VERSIONABLE))
|
||||
{
|
||||
versionable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeId.getScope() == CMISScope.DOCUMENT)
|
||||
{
|
||||
contentStreamAllowed = CMISContentStreamAllowedEnum.ALLOWED;
|
||||
}
|
||||
else
|
||||
{
|
||||
contentStreamAllowed = CMISContentStreamAllowedEnum.NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unique identifier for the type
|
||||
*
|
||||
* @return - the type id
|
||||
*/
|
||||
public CMISTypeId getObjectTypeId()
|
||||
{
|
||||
return objectTypeId;
|
||||
}
|
||||
public CMISTypeId getTypeId();
|
||||
|
||||
/**
|
||||
* Get the table name used for queries against the type. This is also a unique identifier for the type. The string
|
||||
@@ -273,80 +50,50 @@ public class CMISTypeDefinition implements Serializable
|
||||
*
|
||||
* @return the sql table name
|
||||
*/
|
||||
public String getObjectTypeQueryName()
|
||||
{
|
||||
return objectTypeQueryName;
|
||||
}
|
||||
public String getQueryName();
|
||||
|
||||
/**
|
||||
* Get the display name for the type.
|
||||
*
|
||||
* @return - the display name
|
||||
*/
|
||||
public String getObjectTypeDisplayName()
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
public String getDisplayName();
|
||||
|
||||
/**
|
||||
* Get the type id for the parent
|
||||
*
|
||||
* @return - the parent type id
|
||||
*/
|
||||
public CMISTypeId getParentTypeId()
|
||||
{
|
||||
return parentTypeId;
|
||||
}
|
||||
public CMISTypeDefinition getParentType();
|
||||
|
||||
public Collection<CMISTypeDefinition> getSubTypes(boolean descendants);
|
||||
|
||||
/**
|
||||
* Get the root type id
|
||||
* @return - the root type id
|
||||
*/
|
||||
public CMISTypeId getRootTypeId()
|
||||
{
|
||||
return objectTypeId.getRootTypeId();
|
||||
}
|
||||
public CMISTypeDefinition getRootType();
|
||||
|
||||
/**
|
||||
* Get the sql table name for the root type of this type This will be getObjectTypeQueryName() for the base folder,
|
||||
* document or association
|
||||
*
|
||||
* @return - the sql table name for the root type
|
||||
*/
|
||||
public String getRootTypeQueryName()
|
||||
{
|
||||
return rootTypeQueryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for the type
|
||||
*
|
||||
* @return - the description
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
public String getDescription();
|
||||
|
||||
/**
|
||||
* Can objects of this type be created?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isCreatable()
|
||||
{
|
||||
return creatable;
|
||||
}
|
||||
public boolean isCreatable();
|
||||
|
||||
/**
|
||||
* Are objects of this type fileable?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFileable()
|
||||
{
|
||||
return fileable;
|
||||
}
|
||||
public boolean isFileable();
|
||||
|
||||
/**
|
||||
* Is this type queryable? If not, the type may not appear in the FROM clause of a query. This property of the type
|
||||
@@ -354,112 +101,55 @@ public class CMISTypeDefinition implements Serializable
|
||||
*
|
||||
* @return true if queryable
|
||||
*/
|
||||
public boolean isQueryable()
|
||||
{
|
||||
return queryable;
|
||||
}
|
||||
public boolean isQueryable();
|
||||
|
||||
/**
|
||||
* Are objects of this type controllable.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isControllable()
|
||||
{
|
||||
return controllable;
|
||||
}
|
||||
public boolean isControllable();
|
||||
|
||||
/**
|
||||
* Are objects of this type included in super type queries
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isIncludedInSupertypeQuery()
|
||||
{
|
||||
return includedInSupertypeQuery;
|
||||
}
|
||||
public boolean isIncludeInSuperTypeQuery();
|
||||
|
||||
/**
|
||||
* Is this type versionable? If true this implies all instances of the type are versionable.
|
||||
*
|
||||
* @return true if versionable
|
||||
*/
|
||||
public boolean isVersionable()
|
||||
{
|
||||
return versionable;
|
||||
}
|
||||
public boolean isVersionable();
|
||||
|
||||
/**
|
||||
* Is a content stream allowed for this type? It may be disallowed, optional or mandatory.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CMISContentStreamAllowedEnum getContentStreamAllowed()
|
||||
{
|
||||
return contentStreamAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an association type?
|
||||
*
|
||||
* @return true for an association type.
|
||||
*/
|
||||
public boolean isAssociation()
|
||||
{
|
||||
return isAssociation;
|
||||
}
|
||||
public CMISContentStreamAllowedEnum getContentStreamAllowed();
|
||||
|
||||
/**
|
||||
* For an association, get the collection of valid source types. For non-associations the collection will be empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeId> getAllowedSourceTypes()
|
||||
{
|
||||
return allowedSourceTypes;
|
||||
}
|
||||
public Collection<CMISTypeDefinition> getAllowedSourceTypes();
|
||||
|
||||
/**
|
||||
* For an association, get the collection of valid target types. For non-associations the collection will be empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<CMISTypeId> getAllowedTargetTypes()
|
||||
{
|
||||
return allowedTargetTypes;
|
||||
}
|
||||
public Collection<CMISTypeDefinition> getAllowedTargetTypes();
|
||||
|
||||
/**
|
||||
* Gets the property definitions for this type
|
||||
*
|
||||
* @return property definitions
|
||||
*/
|
||||
public Map<String, CMISPropertyDefinition> getPropertyDefinitions()
|
||||
{
|
||||
return cmisDictionary.getPropertyDefinitions(objectTypeId);
|
||||
}
|
||||
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CMISTypeDefinition[");
|
||||
builder.append("ObjectTypeId=").append(getObjectTypeId()).append(", ");
|
||||
builder.append("ObjectTypeQueryName=").append(getObjectTypeQueryName()).append(", ");
|
||||
builder.append("ObjectTypeDisplayName=").append(getObjectTypeDisplayName()).append(", ");
|
||||
builder.append("ParentTypeId=").append(getParentTypeId()).append(", ");
|
||||
builder.append("RootTypeQueryName=").append(getRootTypeQueryName()).append(", ");
|
||||
builder.append("Description=").append(getDescription()).append(", ");
|
||||
builder.append("Creatable=").append(isCreatable()).append(", ");
|
||||
builder.append("Fileable=").append(isFileable()).append(", ");
|
||||
builder.append("Queryable=").append(isQueryable()).append(", ");
|
||||
builder.append("Controllable=").append(isControllable()).append(", ");
|
||||
builder.append("Versionable=").append(isVersionable()).append(", ");
|
||||
builder.append("ContentStreamAllowed=").append(getContentStreamAllowed()).append(", ");
|
||||
builder.append("IsAssociation=").append(isAssociation()).append(", ");
|
||||
builder.append("AllowedSourceTypes=").append(getAllowedSourceTypes()).append(", ");
|
||||
builder.append("AllowedTargetTypes=").append(getAllowedTargetTypes());
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
public Map<CMISPropertyId, CMISPropertyDefinition> getPropertyDefinitions();
|
||||
|
||||
}
|
||||
|
@@ -29,49 +29,42 @@ import java.io.Serializable;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* A CMIS property type id
|
||||
* CMIS Type Id
|
||||
*
|
||||
* @author andyh
|
||||
*
|
||||
*/
|
||||
public class CMISTypeId implements Serializable
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4709046883083948302L;
|
||||
|
||||
private String typeId;
|
||||
|
||||
private CMISScope scope;
|
||||
|
||||
private QName qName;
|
||||
|
||||
public CMISTypeId(CMISScope scope, QName qName, String typeId)
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param scope
|
||||
* @param typeId
|
||||
* @param qName
|
||||
*/
|
||||
public CMISTypeId(CMISScope scope, String typeId, QName qName)
|
||||
{
|
||||
this.scope = scope;
|
||||
this.qName = qName;
|
||||
this.typeId = typeId;
|
||||
this.qName = qName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CMIS type id string
|
||||
* @return
|
||||
*/
|
||||
public String getTypeId()
|
||||
public String getId()
|
||||
{
|
||||
return typeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Alfresco model QName associated with the type
|
||||
* @return
|
||||
*/
|
||||
public QName getQName()
|
||||
{
|
||||
return qName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scope for the type (Doc, Folder, Relationship or unknown)
|
||||
* @return
|
||||
@@ -81,6 +74,16 @@ public class CMISTypeId implements Serializable
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Alfresco model QName associated with the type
|
||||
*
|
||||
* @return alfresco QName
|
||||
*/
|
||||
public QName getQName()
|
||||
{
|
||||
return qName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root type id
|
||||
* @return
|
||||
@@ -90,13 +93,13 @@ public class CMISTypeId implements Serializable
|
||||
switch (scope)
|
||||
{
|
||||
case DOCUMENT:
|
||||
return CMISMapping.DOCUMENT_TYPE_ID;
|
||||
return CMISDictionaryModel.DOCUMENT_TYPE_ID;
|
||||
case FOLDER:
|
||||
return CMISMapping.FOLDER_TYPE_ID;
|
||||
return CMISDictionaryModel.FOLDER_TYPE_ID;
|
||||
case RELATIONSHIP:
|
||||
return CMISMapping.RELATIONSHIP_TYPE_ID;
|
||||
return CMISDictionaryModel.RELATIONSHIP_TYPE_ID;
|
||||
case POLICY:
|
||||
return CMISMapping.POLICY_TYPE_ID;
|
||||
return CMISDictionaryModel.POLICY_TYPE_ID;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
return null;
|
||||
@@ -105,7 +108,7 @@ public class CMISTypeId implements Serializable
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getTypeId();
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user