Merge from SEAMIST3

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10724 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2008-09-04 10:53:14 +00:00
parent 6cd69d17a2
commit 67733661cd
31 changed files with 3122 additions and 41 deletions

View File

@@ -46,6 +46,7 @@
<import resource="classpath:alfresco/site-services-context.xml"/>
<import resource="classpath:alfresco/tagging-services-context.xml"/>
<import resource="classpath:alfresco/cmis-ws-context.xml"/>
<import resource="classpath:alfresco/cmis-api-context.xml" />
<import resource="classpath*:alfresco/patch/*-context.xml" />
<import resource="classpath*:alfresco/domain/*-context.xml" />

View File

@@ -0,0 +1,26 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="CMISDictionaryService" class="org.alfresco.cmis.dictionary.CMISDictionaryService" >
<property name="dictionaryService">
<ref bean="dictionaryService" />
</property>
<property name="strict">
<value>true</value>
</property>
<property name="namespaceService">
<ref bean="namespaceService" />
</property>
</bean>
<bean id="CMIS.DictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
<property name="models">
<list>
<value>alfresco/model/cmisModel.xml</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,348 @@
<model name="cmis:cmismodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<description>CMIS Model Definitions</description>
<version>1.0</version>
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys" />
</imports>
<namespaces>
<namespace uri="http://www.alfresco.org/model/cmis/0.3" prefix="cmis" />
</namespaces>
<types>
<type name="cmis:DOCUMENT_OBJECT_TYPE">
<title>Document</title>
<description>Document Type</description>
<properties>
<property name="cmis:IS_IMMUTABLE">
<title>Is Immutable</title>
<description>Is the document immutable?</description>
<type>d:boolean</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="false" />
</property>
<property name="cmis:IS_LATEST_VERSION">
<title>Is Latest Version</title>
<description>Is this the latest version of the document?</description>
<type>d:boolean</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:IS_MAJOR_VERSION">
<title>Is Major Version</title>
<description>Is this a major version of the document?</description>
<type>d:boolean</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:IS_LATEST_MAJOR_VERSION">
<title>Is Latest Major Version</title>
<description>Is this the latest major version of the document?</description>
<type>d:boolean</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:VERSION_SERIES_IS_CHECKED_OUT">
<title>Version Series Is Checked Out</title>
<description>Is the version series checked out?</description>
<type>d:boolean</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:VERSION_SERIES_CHECKED_OUT_BY">
<title>Version Series Checked Out By</title>
<description>The authority who checked out this document version series</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:VERSION_SERIES_CHECKED_OUT_ID">
<title>Version Series Checked Out Id</title>
<description>The checked out version series id</description>
<type>d:noderef</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:CHECKIN_COMMENT">
<title>Checkin Comment</title>
<description>The checkin comment</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:CONTENT_STREAM_ALLOWED">
<title>Content Stream Allowed</title>
<description>Is a content stream allowed?</description>
<type>d:boolean</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:CONTENT_STREAM_LENGTH">
<title>Content Stream Length</title>
<description>The length of the content stream</description>
<type>d:int</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:CONTENT_STREAM_MIME_TYPE">
<title>Content Stream MIME Type</title>
<description>The content stream MIME type</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:CONTENT_STREAM_FILEMANE">
<title>Content Stream Filename</title>
<description>The content stream filename</description>
<type>d:text</type>
<protected>false</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
<property name="cmis:CONTENT_STREAM_URI">
<title>Content Stream URI</title>
<description>The content stream URI</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>true</tokenised>
</index>
</property>
</properties>
<mandatory-aspects>
<aspect>cmis:NAMED</aspect>
</mandatory-aspects>
</type>
<type name="cmis:FOLDER_OBJECT_TYPE">
<title>Folder</title>
<description>Folder Type</description>
<properties>
<property name="cmis:PARENT">
<title>Parent</title>
<description>The parent of the folder</description>
<type>d:noderef</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:ALLOWED_CHILD_OBJECT_TYPES">
<title>Allowed Child Object Types</title>
<description>The allowed child object types</description>
<type>d:qname</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>true</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
</properties>
<mandatory-aspects>
<aspect>cmis:NAMED</aspect>
</mandatory-aspects>
</type>
<type name="cmis:RELATIONSHIP_OBJECT_TYPE">
<title>Relationship</title>
<description>Relationship Type</description>
<properties>
<property name="cmis:SOURCE_ID">
<title>Source Id</title>
<description>The source id for the relationship</description>
<type>d:noderef</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:TARGET_ID">
<title>Target Id</title>
<description>The target id for the relationship</description>
<type>d:noderef</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
</properties>
<mandatory-aspects>
<aspect>cmis:CORE</aspect>
</mandatory-aspects>
</type>
</types>
<aspects>
<aspect name="cmis:CORE">
<properties>
<property name="cmis:OBJECT_ID">
<title>Object Id</title>
<description>The unique object id (a node ref)</description>
<type>d:noderef</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:URI">
<title>URI</title>
<description>URI</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="false">false</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:OBJECT_TYPE_ID">
<title>Object Type Id</title>
<description>The object type id</description>
<type>d:qname</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:CREATED_BY">
<title>Created by</title>
<description>The authority who created this object</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:CREATION_DATE">
<title>Creation Date</title>
<description>The object creation date</description>
<type>d:datetime</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:LAST_MODIFIED_BY">
<title>Last Modified By</title>
<description>The authority who last modified this object</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:LAST_MODIFICATION_DATE">
<title>Last Modified Date</title>
<description>The date this object was last modified</description>
<type>d:datetime</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
<property name="cmis:CHANGE_TOKEN">
<title>Change token</title>
<description>Change Token</description>
<type>d:text</type>
<protected>true</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>false</tokenised>
</index>
</property>
</properties>
</aspect>
<aspect name="cmis:NAMED">
<parent>cmis:CORE</parent>
<properties>
<property name="cmis:NAME">
<title>Name</title>
<description>Name</description>
<type>d:text</type>
<protected>false</protected>
<mandatory enforced="true">true</mandatory>
<multiple>false</multiple>
<index enabled="true">
<tokenised>both</tokenised>
</index>
</property>
</properties>
</aspect>
</aspects>
</model>

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2005-2007 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 javax.transaction.Status;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
/**
* Base CMIS test
* Basic TX control and authentication
*
* @author andyh
*
*/
public abstract class BaseCMISTest extends TestCase
{
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
protected CMISDictionaryService cmisDictionaryService;
protected DictionaryService dictionaryService;
protected TransactionService transactionService;
protected AuthenticationComponent authenticationComponent;
protected UserTransaction testTX;
public void setUp() throws Exception
{
cmisDictionaryService = (CMISDictionaryService) ctx.getBean("CMISDictionaryService");
dictionaryService = (DictionaryService) ctx.getBean("dictionaryService");
transactionService = (TransactionService) ctx.getBean("transactionComponent");
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
testTX = transactionService.getUserTransaction();
testTX.begin();
this.authenticationComponent.setSystemUserAsCurrentUser();
}
@Override
protected void tearDown() throws Exception
{
if (testTX.getStatus() == Status.STATUS_ACTIVE)
{
testTX.rollback();
}
AuthenticationUtil.clearCurrentSecurityContext();
super.tearDown();
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2005-2007 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;
/**
* Cardinality for property definitions
*
* @author andyh
*
*/
public enum CMISCardinality
{
/**
* Single-valued
*/
SINGLE_VALUED,
/**
* Multi-valued
*/
MULTI_VALUED;
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2005-2007 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;
/**
* Choice for property definitions
*
* @author andyh
*
*/
public class CMISChoice
{
/**
* Get the name of the choice
* @return
*/
public String getName()
{
throw new UnsupportedOperationException();
}
/**
* Get the value when chosen
* @return
*/
public CMISPropertyValue getValue()
{
throw new UnsupportedOperationException();
}
/**
* Get the index that determined the choices position amongst it siblings
* @return
*/
public int getIndex()
{
throw new UnsupportedOperationException();
}
/**
* Get sub-choices
* @return
*/
public Collection<CMISChoice> getChildren()
{
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,249 @@
/*
* Copyright (C) 2005-2007 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 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.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* Service to query the CMIS meta model
*
* @author andyh
*/
public class CMISDictionaryService
{
private DictionaryService dictionaryService;
private NamespaceService namespaceService;
private boolean strict = true;
/**
* Set the dictionary Service
*
* @param dictionaryService
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Set the namespace service
*
* @param namespaceService
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/**
* 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.isValidCmisType(dictionaryService, typeQName))
{
answer.add(CMISMapping.getCmisTypeId(typeQName));
}
}
for (QName associationName : alfrescoAssociationQNames)
{
if (CMISMapping.isValidCmisAssociation(dictionaryService, associationName))
{
answer.add(CMISMapping.getCmisTypeId(associationName));
}
}
return answer;
}
/**
* 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
*
* @param typeId
* @return
*/
public CMISTypeDefinition getType(CMISTypeId typeId)
{
// Types
QName typeQName = CMISMapping.getTypeQname(typeId);
TypeDefinition typeDefinition = dictionaryService.getType(typeQName);
if (typeDefinition != null)
{
if (CMISMapping.isValidCmisType(dictionaryService, typeQName))
{
return new CMISTypeDefinition(dictionaryService, namespaceService, typeQName);
}
else
{
return null;
}
}
// Associations
AssociationDefinition associationDefinition = dictionaryService.getAssociation(typeQName);
if (associationDefinition != null)
{
if (CMISMapping.isValidCmisAssociation(dictionaryService, typeQName))
{
return new CMISTypeDefinition(dictionaryService, namespaceService, typeQName);
}
else
{
return null;
}
}
// Unknown type
return null;
}
/**
* Get all the property definitions for a type
*
* @param typeId
* @return
*/
public Map<String, CMISPropertyDefinition> getPropertyDefinitions(CMISTypeId typeId)
{
HashMap<String, CMISPropertyDefinition> properties = new HashMap<String, CMISPropertyDefinition>();
QName typeQName = CMISMapping.getTypeQname(typeId);
TypeDefinition typeDefinition = dictionaryService.getType(typeQName);
if (typeDefinition != null)
{
if (CMISMapping.isValidCmisType(dictionaryService, typeQName))
{
for (QName qname : typeDefinition.getProperties().keySet())
{
if (CMISMapping.getPropertyType(dictionaryService, qname) != null)
{
CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(dictionaryService, namespaceService, qname);
properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition);
}
}
for (AspectDefinition aspect : typeDefinition.getDefaultAspects())
{
for (QName qname : aspect.getProperties().keySet())
{
if (CMISMapping.getPropertyType(dictionaryService, qname) != null)
{
CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(dictionaryService, namespaceService, qname);
properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition);
}
}
}
}
else
{
return properties;
}
}
// Associations
AssociationDefinition associationDefinition = dictionaryService.getAssociation(typeQName);
if (associationDefinition != null)
{
if (CMISMapping.isValidCmisAssociation(dictionaryService, typeQName))
{
return getPropertyDefinitions(new CMISTypeId(CMISMapping.RELATIONSHIP_OBJECT_TYPE));
}
else
{
return properties;
}
}
// Unknown type
return properties;
}
/**
* Get a single property definition
*
* @param typeId
* @param propertyName
* @return
*/
public CMISPropertyDefinition getPropertyDefinition(CMISTypeId typeId, String propertyName)
{
return getPropertyDefinitions(typeId).get(propertyName);
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2005-2007 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;
public class CMISDictionaryTest extends BaseCMISTest
{
public void testBasicTypes()
{
cmisDictionaryService.setStrict(true);
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
{
System.out.println(name);
}
assertEquals(3, cmisDictionaryService.getAllObjectTypeIds().size());
}
public void testBasicTypeDefinitions()
{
cmisDictionaryService.setStrict(false);
for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds())
{
System.out.println(cmisDictionaryService.getType(name));
}
}
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 (CMISPropertyDefinition proDef : cmisDictionaryService.getPropertyDefinitions(name).values())
{
System.out.println(proDef);
}
}
}
}

View File

@@ -0,0 +1,373 @@
/*
* Copyright (C) 2005-2007 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 java.util.HashMap;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
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;
/**
* CMIS <-> Alfresco mappings
*
* @author andyh
*/
public class CMISMapping
{
/**
* The Alfresco CMIS model URI.
*/
public static String CMIS_MODEL_URI = "http://www.alfresco.org/model/cmis/0.3";
/**
* The Alfresco CMIS Model name.
*/
public static String CMIS_MODEL_NAME = "cmismodel";
/**
* The QName for the Alfresco CMIS Model.
*/
public static QName CMIS_MODEL_QNAME = QName.createQName(CMIS_MODEL_URI, CMIS_MODEL_NAME);
/**
* Type id for CMIS documents, from the spec.
*/
public static String DOCUMENT_OBJECT_TYPE = "DOCUMENT_OBJECT_TYPE";
/**
* Type is for CMIS folders, from the spec.
*/
public static String FOLDER_OBJECT_TYPE = "FOLDER_OBJECT_TYPE";
/**
* Type Id for CMIS Relationships, from the spec.
*/
public static String RELATIONSHIP_OBJECT_TYPE = "RELATIONSHIP_OBJECT_TYPE";
/**
* 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);
// Mappings
// - no entry means no mapping and pass through as is
private static HashMap<CMISTypeId, QName> cmisTypeIdToTypeQName = new HashMap<CMISTypeId, QName>();
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, CMISPropertyType> alfrescoPropertyTypesToCimsPropertyTypes = new HashMap<QName, CMISPropertyType>();
/**
* Set up mappings
*/
static
{
cmisTypeIdToTypeQName.put(new CMISTypeId(DOCUMENT_OBJECT_TYPE), DOCUMENT_QNAME);
cmisTypeIdToTypeQName.put(new CMISTypeId(FOLDER_OBJECT_TYPE), FOLDER_QNAME);
cmisTypeIdToTypeQName.put(new CMISTypeId(RELATIONSHIP_OBJECT_TYPE), RELATIONSHIP_QNAME);
qNameToCmisTypeId.put(DOCUMENT_QNAME, new CMISTypeId(DOCUMENT_OBJECT_TYPE));
qNameToCmisTypeId.put(FOLDER_QNAME, new CMISTypeId(FOLDER_OBJECT_TYPE));
qNameToCmisTypeId.put(RELATIONSHIP_QNAME, new CMISTypeId(RELATIONSHIP_OBJECT_TYPE));
cmisToAlfrecsoTypes.put(DOCUMENT_QNAME, ContentModel.TYPE_CONTENT);
cmisToAlfrecsoTypes.put(FOLDER_QNAME, ContentModel.TYPE_FOLDER);
cmisToAlfrecsoTypes.put(RELATIONSHIP_QNAME, null);
alfrescoToCmisTypes.put(ContentModel.TYPE_CONTENT, DOCUMENT_QNAME);
alfrescoToCmisTypes.put(ContentModel.TYPE_FOLDER, FOLDER_QNAME);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.ANY, null);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.ASSOC_REF, null);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.BOOLEAN, CMISPropertyType.BOOLEAN);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.CATEGORY, CMISPropertyType.ID);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.CHILD_ASSOC_REF, null);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.CONTENT, null);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.DATE, CMISPropertyType.DATE_TIME);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.DATETIME, CMISPropertyType.DATE_TIME);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.DOUBLE, CMISPropertyType.DECIMAL);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.FLOAT, CMISPropertyType.DECIMAL);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.INT, CMISPropertyType.INTEGER);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.LOCALE, null);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.LONG, CMISPropertyType.INTEGER);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.MLTEXT, CMISPropertyType.STRING);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.NODE_REF, CMISPropertyType.ID);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.PATH, null);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.QNAME, null);
alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.TEXT, CMISPropertyType.STRING);
}
/**
* Id this a CMIS core type defined in the Alfresco CMIS model
*
* @param typeQName
* @return
*/
public static boolean isCmisCoreType(QName typeQName)
{
return qNameToCmisTypeId.get(typeQName) != null;
}
/**
* Get the CMIS Type Id given the Alfresco QName for the type in any Alfresco model
*
* @param typeQName
* @return
*/
public static CMISTypeId getCmisTypeId(QName typeQName)
{
CMISTypeId typeId = qNameToCmisTypeId.get(typeQName);
if (typeId == null)
{
return new CMISTypeId(typeQName.toString());
}
else
{
return typeId;
}
}
/**
* Given a type id - get the appropriate Alfresco QName
*
* @param typeId
* @return
*/
public static QName getTypeQname(CMISTypeId typeId)
{
QName typeQName = cmisTypeIdToTypeQName.get(typeId);
if (typeQName != null)
{
return typeQName;
}
else
{
return QName.createQName(typeId.getTypeId());
}
}
/**
* Get the query name for Alfresco qname
*
* @param namespaceService
* @param typeQName
* @return
*/
public static String getQueryName(NamespaceService namespaceService, QName typeQName)
{
return buildPrefixEncodedString(namespaceService, typeQName);
}
private static String buildPrefixEncodedString(NamespaceService namespaceService, QName qname)
{
StringBuilder builder = new StringBuilder(128);
if (!qname.getNamespaceURI().equals(CMIS_MODEL_URI))
{
Collection<String> prefixes = namespaceService.getPrefixes(qname.getNamespaceURI());
if (prefixes.size() == 0)
{
throw new NamespaceException("A namespace prefix is not registered for uri " + qname.getNamespaceURI());
}
String resolvedPrefix = prefixes.iterator().next();
builder.append(resolvedPrefix);
builder.append("_");
}
builder.append(qname.getLocalName());
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 static boolean isValidCmisType(DictionaryService dictionaryService, QName typeQName)
{
if (CMISMapping.isCmisCoreType(typeQName))
{
return true;
}
if (dictionaryService.isSubClass(typeQName, ContentModel.TYPE_CONTENT) || dictionaryService.isSubClass(typeQName, ContentModel.TYPE_FOLDER))
{
if (typeQName.equals(ContentModel.TYPE_CONTENT))
{
return false;
}
else if (typeQName.equals(ContentModel.TYPE_FOLDER))
{
return false;
}
else
{
return true;
}
}
return false;
}
/**
* Is an association valid in CMIS? It must be a non-child relationship and the source and target must both be valid
* CMIS types.
*
* @param dictionaryService
* @param associationQName
* @return
*/
public static boolean isValidCmisAssociation(DictionaryService dictionaryService, QName associationQName)
{
AssociationDefinition associationDefinition = dictionaryService.getAssociation(associationQName);
if (associationDefinition == null)
{
return false;
}
if (associationDefinition.isChild())
{
return false;
}
if (!isValidCmisType(dictionaryService, getCmisType(associationDefinition.getSourceClass().getName())))
{
return false;
}
if (!isValidCmisType(dictionaryService, getCmisType(associationDefinition.getTargetClass().getName())))
{
return false;
}
return true;
}
/**
* Given an Alfresco model type map it to the appropriate type. Maps cm:folder and cm:content to the CMIS
* definitions
*
* @param typeQName
* @return
*/
public static QName getCmisType(QName typeQName)
{
QName mapped = alfrescoToCmisTypes.get(typeQName);
if (mapped != null)
{
return mapped;
}
return typeQName;
}
/**
* Get the root CMIS object (in the alfresco model) for any type.
*
* @param dictionaryService
* @param typeQName
* @return
*/
public static QName getCmisRootType(DictionaryService dictionaryService, QName typeQName)
{
if (isCmisCoreType(typeQName))
{
return typeQName;
}
if (dictionaryService.isSubClass(typeQName, ContentModel.TYPE_CONTENT))
{
return DOCUMENT_QNAME;
}
if (dictionaryService.isSubClass(typeQName, ContentModel.TYPE_FOLDER))
{
return FOLDER_QNAME;
}
if (isValidCmisAssociation(dictionaryService, typeQName))
{
return RELATIONSHIP_QNAME;
}
throw new UnsupportedOperationException();
}
public static String getCmisPropertyName(NamespaceService namespaceService, QName propertyQName)
{
return buildPrefixEncodedString(namespaceService, propertyQName);
}
public static CMISPropertyType getPropertyType(DictionaryService dictionaryService, QName propertyQName)
{
PropertyDefinition propertyDefinition = dictionaryService.getProperty(propertyQName);
DataTypeDefinition dataTypeDefinition = propertyDefinition.getDataType();
QName dQName = dataTypeDefinition.getName();
if(propertyQName.getNamespaceURI().equals(CMIS_MODEL_URI) && dQName.equals(DataTypeDefinition.QNAME))
{
return CMISPropertyType.TYPE_ID;
}
return alfrescoPropertyTypesToCimsPropertyTypes.get(dQName);
}
public static QName getPropertyQName(DictionaryService dictionaryService, NamespaceService namespaceService, String cmisPropertyName)
{
// Try the cmis model first - it it matches we are done
QName cmisPropertyQName = QName.createQName(CMIS_MODEL_URI, cmisPropertyName);
if(dictionaryService.getProperty(cmisPropertyQName) != null)
{
return cmisPropertyQName;
}
int split = cmisPropertyName.indexOf('_');
String prefix = cmisPropertyName.substring(0, split);
String localName = cmisPropertyName.substring(split+1);
QName qname = QName.createQName(prefix, localName, namespaceService);
return qname;
}
}

View File

@@ -0,0 +1,303 @@
/*
* Copyright (C) 2005-2007 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 java.util.HashSet;
import org.alfresco.repo.dictionary.IndexTokenisationMode;
import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.DoubleAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.FloatAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.IntegerAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.LongAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.PathAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* A CMIS property definition
*
* @author andyh
*/
public class CMISPropertyDefinition
{
private String propertyName;
private String displayName;
private String description;
private CMISPropertyType propertyType;
private CMISCardinality 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 CMISUpdatability updatability;
private boolean queryable;
private boolean orderable;
public CMISPropertyDefinition(DictionaryService dictionaryService, NamespaceService namespaceService, QName propertyQName)
{
PropertyDefinition propDef = dictionaryService.getProperty(propertyQName);
if (propDef.getContainerClass().getName().equals(CMISMapping.RELATIONSHIP_QNAME))
{
// Properties of associations - all the same
propertyName = CMISMapping.getCmisPropertyName(namespaceService, propertyQName);
displayName = propDef.getTitle();
description = propDef.getDescription();
propertyType = CMISMapping.getPropertyType(dictionaryService, propertyQName);
cardinality = propDef.isMultiValued() ? CMISCardinality.MULTI_VALUED : CMISCardinality.SINGLE_VALUED;
required = propDef.isMandatory();
defaultValue = propDef.getDefaultValue();
updatability = propDef.isProtected() ? CMISUpdatability.READ_ONLY : CMISUpdatability.READ_AND_WRITE;
queryable = false;
orderable = false;
}
else
{
propertyName = CMISMapping.getCmisPropertyName(namespaceService, propertyQName);
displayName = propDef.getTitle();
description = propDef.getDescription();
propertyType = CMISMapping.getPropertyType(dictionaryService, propertyQName);
cardinality = propDef.isMultiValued() ? CMISCardinality.MULTI_VALUED : CMISCardinality.SINGLE_VALUED;
required = propDef.isMandatory();
defaultValue = propDef.getDefaultValue();
updatability = propDef.isProtected() ? CMISUpdatability.READ_ONLY : CMISUpdatability.READ_AND_WRITE;
queryable = propDef.isIndexed();
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;
}
}
}
}
/**
* Get the property name
* @return
*/
public String getPropertyName()
{
return propertyName;
}
/**
* Get the display name
* @return
*/
public String getDisplayName()
{
return displayName;
}
/**
* Get the description
* @return
*/
public String getDescription()
{
return description;
}
/**
* Get the property type
* @return
*/
public CMISPropertyType getPropertyType()
{
return propertyType;
}
/**
* Get the cardinality
* @return
*/
public CMISCardinality getCardinality()
{
return cardinality;
}
/**
* For variable length properties, get the maximum length allowed.
* Unsupported.
*
* @return
*/
public int getMaximumLength()
{
return maximumLength;
}
/**
* For properties of type CMISPropertyType.XML the schema to which the property must conform. Unsupported
*
* @return - the schema URI
*/
public String getSchemaURI()
{
return schemaURI;
}
/**
* For properties of type CMISPropertyType.XML the encoding used for the property value
*
* @return the encoding
*/
public String getEncoding()
{
return encoding;
}
/**
* Get the choices available as values for this property
* TODO: not implemented yet
* @return
*/
public Collection<CMISChoice> getChioces()
{
return choices;
}
/**
* Is this a choice where a user can enter other values (ie a list with common options)
* @return
*/
public boolean isOpenChioce()
{
return isOpenChoice;
}
/**
* Is this property required?
* @return
*/
public boolean isRequired()
{
return required;
}
/**
* get the default value as a String
*
* @return
*/
public String getDefaultValue()
{
return defaultValue;
}
/**
* Is this property updatable?
* @return
*/
public CMISUpdatability getUpdatability()
{
return updatability;
}
/**
* Is this property queryable?
* @return
*/
public boolean isQueryable()
{
return queryable;
}
/**
* Is this property orderable in queries?
* @return
*/
public boolean isOrderable()
{
return orderable;
}
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("CMISPropertyDefinition[");
builder.append("PropertyName=").append(getPropertyName()).append(", ");
builder.append("DisplayName=").append(getDisplayName()).append(", ");
builder.append("Description=").append(getDescription()).append(", ");
builder.append("PropertyType=").append(getPropertyType()).append(", ");
builder.append("Cardinality=").append(getCardinality()).append(", ");
builder.append("MaximumLength=").append(getMaximumLength()).append(", ");
builder.append("SchemaURI=").append(getSchemaURI()).append(", ");
builder.append("Encoding=").append(getEncoding()).append(", ");
builder.append("Choices=").append(getChioces()).append(", ");
builder.append("IsOpenChoice=").append(isOpenChioce()).append(", ");
builder.append("Required=").append(isRequired()).append(", ");
builder.append("Default=").append(getDefaultValue()).append(", ");
builder.append("Updatable=").append(getUpdatability()).append(", ");
builder.append("Queryable=").append(isQueryable()).append(", ");
builder.append("Orderable=").append(isOrderable());
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2005-2007 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;
/**
* CMIS Property Types
* @author andyh
*
*/
public enum CMISPropertyType
{
/**
* String
*/
STRING,
/**
* Decimal
*/
DECIMAL,
/**
* Integer
*/
INTEGER,
/**
* Boolean
*/
BOOLEAN,
/**
* Date-time
*/
DATE_TIME,
/**
* URI
*/
URI,
/**
* HTML
*/
HTML,
/**
* XML
*/
XML,
/**
* ID
*/
ID,
/**
* Type Id
*/
TYPE_ID;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2005-2007 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;
public interface CMISPropertyValue
{
}

View File

@@ -0,0 +1,297 @@
/*
* Copyright (C) 2005-2007 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 org.alfresco.model.ContentModel;
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.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* The base type definition for CMIS
*
* @author andyh
*/
public class CMISTypeDefinition
{
private CMISTypeId objectTypeId;
private String objectTypeQueryName;
private String displayName;
private CMISTypeId parentTypeId;
private String rootTypeQueryName;
private String description;
private boolean queryable;
private boolean versionable;
private String constraints = "";
private boolean isAssociation;
private ArrayList<CMISTypeId> allowedSourceTypes = new ArrayList<CMISTypeId>(1);
private ArrayList<CMISTypeId> allowedTargetTypes = new ArrayList<CMISTypeId>(1);
public CMISTypeDefinition(DictionaryService dictionaryService, NamespaceService namespaceService, QName typeQName)
{
isAssociation = (typeQName.equals(CMISMapping.RELATIONSHIP_QNAME) || (dictionaryService.getAssociation(typeQName) != null));
if (isAssociation)
{
AssociationDefinition associationDefinition = dictionaryService.getAssociation(typeQName);
if (associationDefinition != null)
{
objectTypeId = CMISMapping.getCmisTypeId(typeQName);
objectTypeQueryName = CMISMapping.getQueryName(namespaceService, typeQName);
displayName = associationDefinition.getTitle();
parentTypeId = CMISMapping.getCmisTypeId(CMISMapping.RELATIONSHIP_QNAME);
rootTypeQueryName = CMISMapping.getQueryName(namespaceService, CMISMapping.RELATIONSHIP_QNAME);
description = associationDefinition.getDescription();
queryable = false;
versionable = false;
isAssociation = true;
allowedSourceTypes.add(CMISMapping.getCmisTypeId(CMISMapping.getCmisType(associationDefinition.getSourceClass().getName())));
allowedTargetTypes.add(CMISMapping.getCmisTypeId(CMISMapping.getCmisType(associationDefinition.getTargetClass().getName())));
}
else
{
// TODO: Add CMIS Association mapping??
TypeDefinition typeDefinition = dictionaryService.getType(typeQName);
objectTypeId = CMISMapping.getCmisTypeId(typeQName);
objectTypeQueryName = CMISMapping.getQueryName(namespaceService, typeQName);
displayName = typeDefinition.getTitle();
parentTypeId = CMISMapping.getCmisTypeId(CMISMapping.RELATIONSHIP_QNAME);
rootTypeQueryName = CMISMapping.getQueryName(namespaceService, CMISMapping.RELATIONSHIP_QNAME);
description = typeDefinition.getDescription();
queryable = false;
versionable = false;
isAssociation = true;
}
}
else
{
TypeDefinition typeDefinition = dictionaryService.getType(typeQName);
if (typeDefinition != null)
{
objectTypeId = CMISMapping.getCmisTypeId(typeQName);
objectTypeQueryName = CMISMapping.getQueryName(namespaceService, typeQName);
displayName = typeDefinition.getTitle();
QName parentTypeQName = CMISMapping.getCmisType(typeDefinition.getParentName());
if (parentTypeQName == null)
{
// Core and unknown types
parentTypeId = null;
}
else
{
if (CMISMapping.isValidCmisType(dictionaryService, typeQName))
{
parentTypeId = CMISMapping.getCmisTypeId(parentTypeQName);
}
}
rootTypeQueryName = CMISMapping.getQueryName(namespaceService, CMISMapping.getCmisRootType(dictionaryService, typeQName));
description = typeDefinition.getDescription();
queryable = true;
versionable = false;
List<AspectDefinition> defaultAspects = typeDefinition.getDefaultAspects();
for (AspectDefinition aspectDefinition : defaultAspects)
{
if (aspectDefinition.getName().equals(ContentModel.ASPECT_VERSIONABLE))
{
versionable = true;
break;
}
}
}
}
}
/**
* Get the unique identifier for the type
*
* @return - the type id
*/
public CMISTypeId getObjectTypeId()
{
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 getObjectTypeQueryName()
{
return objectTypeQueryName;
}
/**
* Get the display name for the type.
*
* @return - the display name
*/
public String getObjectTypeDisplayName()
{
return displayName;
}
/**
* Get the type id for the parent
*
* @return - the parent type id
*/
public CMISTypeId getParentTypeId()
{
return parentTypeId;
}
/**
* 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;
}
/**
* 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;
}
/**
* Is this type versionable? If true this implies all instances of the type are versionable.
*
* @return true if versionable
*/
public boolean isVersionable()
{
return versionable;
}
/**
* Get the constraints for the type. These are not currently supported.
*
* @return
*/
public String getConstraints()
{
return constraints;
}
/**
* Is this an association type?
*
* @return true for an association type.
*/
public boolean isAssociation()
{
return isAssociation;
}
/**
* 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;
}
/**
* 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 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("Queryable=").append(isQueryable()).append(", ");
builder.append("Versionable=").append(isVersionable()).append(", ");
builder.append("Constraints=").append(getConstraints()).append(", ");
builder.append("IsAssociation=").append(isAssociation()).append(", ");
builder.append("AllowedSourceTypes=").append(getAllowedSourceTypes()).append(", ");
builder.append("AllowedTargetTypes=").append(getAllowedTargetTypes());
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2005-2007 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;
public class CMISTypeId implements CMISPropertyValue
{
private String typeId;
public CMISTypeId(String typeId)
{
this.typeId = typeId;
}
public String getTypeId()
{
return typeId;
}
public String toString()
{
return getTypeId();
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((typeId == null) ? 0 : typeId.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final CMISTypeId other = (CMISTypeId) obj;
if (typeId == null)
{
if (other.typeId != null)
return false;
}
else if (!typeId.equals(other.typeId))
return false;
return true;
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2005-2007 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;
public enum CMISUpdatability
{
READ_ONLY, READ_AND_WRITE, READ_AND_WRITE_WHEN_CHECKED_OUT;
}

View File

@@ -404,6 +404,15 @@ import org.apache.commons.logging.LogFactory;
return associations.get(name);
}
/**
* @return the compiled associations
*/
public Collection<AssociationDefinition> getAssociations()
{
return associations.values();
}
/* (non-Javadoc)
* @see org.alfresco.repo.dictionary.impl.ModelQuery#getConstraint(QName)
*/

View File

@@ -162,6 +162,19 @@ public class DictionaryComponent implements DictionaryService, TenantDeployer
return aspects;
}
/* (non-Javadoc)
* @see org.alfresco.repo.dictionary.DictionaryService#getAllAssociations()
*/
public Collection<QName> getAllAssociations()
{
Collection<QName> associations = new ArrayList<QName>(64);
for (QName model : getAllModels())
{
associations.addAll(getAssociations(model));
}
return associations;
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.dictionary.DictionaryService#getSubAspects(org.alfresco.service.namespace.QName, boolean)
@@ -186,6 +199,20 @@ public class DictionaryComponent implements DictionaryService, TenantDeployer
return qnames;
}
/* (non-Javadoc)
* @see org.alfresco.repo.dictionary.DictionaryService#getAssociations(org.alfresco.repo.ref.QName)
*/
public Collection<QName> getAssociations(QName model)
{
Collection<AssociationDefinition> associations = dictionaryDAO.getAssociations(model);
Collection<QName> qnames = new ArrayList<QName>(associations.size());
for (AssociationDefinition def : associations)
{
qnames.add(def.getName());
}
return qnames;
}
/* (non-Javadoc)
* @see org.alfresco.repo.dictionary.DictionaryService#isSubClass(org.alfresco.repo.ref.QName, org.alfresco.repo.ref.QName)

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.dictionary;
import java.util.Collection;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ModelDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.NamespaceDefinition;
@@ -79,6 +80,13 @@ public interface DictionaryDAO extends ModelQuery
*/
public Collection<AspectDefinition> getAspects(QName model);
/**
* @param model the model to retrieve associations for
* @return the associations of the model
*/
public Collection<AssociationDefinition> getAssociations(QName model);
/**
* @param superAspect
* @param follow true => follow up the super-class hierarchy, false => immediate sub aspects only

View File

@@ -688,6 +688,12 @@ public class DictionaryDAOImpl implements DictionaryDAO
return null;
}
public Collection<AssociationDefinition> getAssociations(QName modelName)
{
CompiledModel model = getCompiledModel(modelName);
return model.getAssociations();
}
/* (non-Javadoc)
* @see org.alfresco.repo.dictionary.impl.DictionaryDAO#getModels()

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2005-2007 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.repo.dictionary;
/**
* How tokenisation is supported in the index.
*
*
* @author andyh
*
*/
public enum IndexTokenisationMode {
/**
* Tokenise the property. If the analyser supported ordering then the field
* supports ordering FTS is supported via analysis.
*/
TRUE,
/**
* Do not tokenise the property. The field supports ordering and pattern
* matching.
*/
FALSE,
/**
* There may be two indexes - one to support ordering and one to support
* search.
*/
BOTH;
public static String serializer(IndexTokenisationMode indexTokenisationMode) {
return indexTokenisationMode.toString();
}
public static IndexTokenisationMode deserializer(String value) {
if (value == null) {
return null;
} else if (value.equalsIgnoreCase(TRUE.toString())) {
return TRUE;
} else if (value.equalsIgnoreCase(FALSE.toString())) {
return FALSE;
} else if (value.equalsIgnoreCase(BOTH.toString())) {
return BOTH;
} else {
throw new IllegalArgumentException(
"Invalid IndexTokenisationMode: " + value);
}
}
}

View File

@@ -50,7 +50,7 @@ public class M2Property
private boolean isIndexed = true;
private boolean isIndexedAtomically = true;
private boolean isStoredInIndex = false;
private boolean isTokenisedInIndex = true;
private IndexTokenisationMode indexTokenisationMode = IndexTokenisationMode.TRUE;
private List<M2Constraint> constraints;
/*package*/ M2Property()
@@ -204,15 +204,15 @@ public class M2Property
}
public boolean isTokenisedInIndex()
public IndexTokenisationMode getIndexTokenisationMode()
{
return isTokenisedInIndex;
return indexTokenisationMode;
}
public void setTokenisedInIndex(boolean isTokenisedInIndex)
public void setIndexTokenisationMode(IndexTokenisationMode indexTokenisationMode)
{
this.isTokenisedInIndex = isTokenisedInIndex;
this.indexTokenisationMode = indexTokenisationMode;
}

View File

@@ -214,7 +214,7 @@ import org.alfresco.service.namespace.QName;
property.setProtected(propertyDef.isProtected());
property.setStoredInIndex(propertyDef.isStoredInIndex());
property.setTitle(propertyDef.getTitle());
property.setTokenisedInIndex(propertyDef.isTokenisedInIndex());
property.setIndexTokenisationMode(propertyDef.getIndexTokenisationMode());
return property;
}
@@ -240,7 +240,7 @@ import org.alfresco.service.namespace.QName;
sb.append("isIndexed: " + isIndexed() + "\n");
sb.append("isStoredInIndex: " + isStoredInIndex() + "\n");
sb.append("isIndexedAtomically: " + isIndexedAtomically() + "\n");
sb.append("isTokenisedInIndex: " + isTokenisedInIndex() + "\n");
sb.append("indexTokenisationMode: " + getIndexTokenisationMode() + "\n");
return sb.toString();
}
@@ -378,9 +378,9 @@ import org.alfresco.service.namespace.QName;
/* (non-Javadoc)
* @see org.alfresco.repo.dictionary.PropertyDefinition#isTokenisedInIndex()
*/
public boolean isTokenisedInIndex()
public IndexTokenisationMode getIndexTokenisationMode()
{
return m2Property.isTokenisedInIndex();
return m2Property.getIndexTokenisationMode();
}

View File

@@ -114,7 +114,7 @@
<value style="attribute" name="enabled" field="isIndexed"/>
<value name="atomic" field="isIndexedAtomically" usage="optional"/>
<value name="stored" field="isStoredInIndex" usage="optional"/>
<value name="tokenised" field="isTokenisedInIndex" usage="optional"/>
<value name="tokenised" field="indexTokenisationMode" usage="optional" serializer="org.alfresco.repo.dictionary.IndexTokenisationMode.serializer" deserializer="org.alfresco.repo.dictionary.IndexTokenisationMode.deserializer"/>
</structure>
<structure name="constraints" usage="optional">
<collection field="constraints" item-type="org.alfresco.repo.dictionary.M2Constraint" factory="org.alfresco.repo.dictionary.M2Model.createList"/>

View File

@@ -57,6 +57,7 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.content.transform.ContentTransformerRegistry;
import org.alfresco.repo.dictionary.DictionaryDAO;
import org.alfresco.repo.dictionary.IndexTokenisationMode;
import org.alfresco.repo.dictionary.M2Aspect;
import org.alfresco.repo.dictionary.M2Model;
import org.alfresco.repo.dictionary.M2Property;
@@ -224,7 +225,7 @@ public class RuleServiceCoverageTest extends TestCase
genCatProp.setMandatory(true);
genCatProp.setMultiValued(true);
genCatProp.setStoredInIndex(true);
genCatProp.setTokenisedInIndex(true);
genCatProp.setIndexTokenisationMode(IndexTokenisationMode.TRUE);
genCatProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
// Save the mode

View File

@@ -39,6 +39,7 @@ import junit.framework.TestCase;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.dictionary.DictionaryDAO;
import org.alfresco.repo.dictionary.IndexTokenisationMode;
import org.alfresco.repo.dictionary.M2Aspect;
import org.alfresco.repo.dictionary.M2Model;
import org.alfresco.repo.dictionary.M2Property;
@@ -286,7 +287,7 @@ public class ADMLuceneCategoryTest extends TestCase
genCatProp.setMandatory(true);
genCatProp.setMultiValued(true);
genCatProp.setStoredInIndex(true);
genCatProp.setTokenisedInIndex(false);
genCatProp.setIndexTokenisationMode(IndexTokenisationMode.FALSE);
genCatProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
assetClassCategorisationQName = QName.createQName(TEST_NAMESPACE, "assetClass");
@@ -298,7 +299,7 @@ public class ADMLuceneCategoryTest extends TestCase
acProp.setMandatory(true);
acProp.setMultiValued(true);
acProp.setStoredInIndex(true);
acProp.setTokenisedInIndex(false);
acProp.setIndexTokenisationMode(IndexTokenisationMode.FALSE);
acProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
investmentRegionCategorisationQName = QName.createQName(TEST_NAMESPACE, "investmentRegion");
@@ -310,7 +311,7 @@ public class ADMLuceneCategoryTest extends TestCase
irProp.setMandatory(true);
irProp.setMultiValued(true);
irProp.setStoredInIndex(true);
irProp.setTokenisedInIndex(false);
irProp.setIndexTokenisationMode(IndexTokenisationMode.FALSE);
irProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
marketingRegionCategorisationQName = QName.createQName(TEST_NAMESPACE, "marketingRegion");
@@ -322,7 +323,7 @@ public class ADMLuceneCategoryTest extends TestCase
mrProp.setMandatory(true);
mrProp.setMultiValued(true);
mrProp.setStoredInIndex(true);
mrProp.setTokenisedInIndex(false);
mrProp.setIndexTokenisationMode(IndexTokenisationMode.FALSE);
mrProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName());
dictionaryDAO.putModel(model);

View File

@@ -51,9 +51,9 @@ import org.alfresco.repo.avm.util.SimplePath;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.dictionary.IndexTokenisationMode;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.search.IndexMode;
import org.alfresco.repo.search.Indexer;
import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser;
import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware;
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
@@ -677,7 +677,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
boolean store = true;
boolean index = true;
boolean tokenise = true;
IndexTokenisationMode tokenise = IndexTokenisationMode.TRUE;
@SuppressWarnings("unused")
boolean atomic = true;
boolean isContent = false;
@@ -690,7 +690,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
{
index = propertyDef.isIndexed();
store = propertyDef.isStoredInIndex();
tokenise = propertyDef.isTokenisedInIndex();
tokenise = propertyDef.getIndexTokenisationMode();
atomic = propertyDef.isIndexedAtomically();
isContent = propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT);
isMultiLingual = propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT);
@@ -876,17 +876,18 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
if (index)
{
if (tokenise)
{
switch (tokenise) {
case TRUE:
case BOTH:
default:
fieldIndex = Field.Index.TOKENIZED;
}
else
{
break;
case FALSE:
fieldIndex = Field.Index.UN_TOKENIZED;
break;
}
}
else
{
} else {
fieldIndex = Field.Index.NO;
}
@@ -926,15 +927,26 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
{
locale = I18NUtil.getLocale();
}
if (tokenise)
StringBuilder builder;
switch(tokenise)
{
StringBuilder builder = new StringBuilder();
default:
case TRUE:
builder = new StringBuilder();
builder.append("\u0000").append(locale.toString()).append("\u0000").append(strValue);
doc.add(new Field(attributeName, builder.toString(), fieldStore, fieldIndex, Field.TermVector.NO));
}
else
{
break;
case FALSE:
doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO));
break;
case BOTH:
builder = new StringBuilder();
builder.append("\u0000").append(locale.toString()).append("\u0000").append(strValue);
doc.add(new Field(attributeName, builder.toString(), fieldStore, fieldIndex, Field.TermVector.NO));
doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO));
break;
}
}
else if (isDateTime)

View File

@@ -29,6 +29,7 @@ import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.dictionary.IndexTokenisationMode;
import org.alfresco.repo.search.MLAnalysisMode;
import org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.LongAnalyser;
@@ -178,7 +179,7 @@ public class LuceneAnalyser extends Analyzer
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
if (propertyDef != null)
{
if (propertyDef.isTokenisedInIndex())
if ((propertyDef.getIndexTokenisationMode() == IndexTokenisationMode.BOTH) || (propertyDef.getIndexTokenisationMode() == IndexTokenisationMode.TRUE))
{
DataTypeDefinition dataType = propertyDef.getDataType();
if (dataType.getName().equals(DataTypeDefinition.CONTENT))

View File

@@ -0,0 +1,568 @@
/*
* Copyright (C) 2005-2007 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"
*/
/*
* Parser for the CMIS query language
*
* The semantics of multivalued properties are ignored for the initial parse of the language.
* They are applied in a second pass, when we have enough information to determine the column type.
*/
grammar CMIS;
options
{
output=AST;
}
tokens
{
QUERY;
ALL_COLUMNS;
COLUMN;
COLUMNS;
COLUMN_REF;
QUALIFIER;
STRING_FUNCTION;
NUMERIC_FUNCTION;
SOURCE;
TABLE;
TABLE_REF;
PARAMETER;
CONJUNCTION;
DISJUNCTION;
NEGATION;
PRED_COMPARISON;
PRED_IN;
PRED_EXISTS;
PRED_LIKE;
PRED_FTS;
LIST;
PRED_CHILD;
PRED_DESCENDANT;
SORT_SPECIFICATION;
NUMERIC_LITERAL;
STRING_LITERAL;
}
/*
* Instance methods and properties for the parser.
* Realisations of the parser should over-ride these as required
*/
@members
{
/**
* CMIS strict
*/
public boolean strict()
{
return true;
}
}
/**
* This is mostly a direct take fom the CMIS spec.
* The only significant chnanges are to remove left recursion which is not supported in antlr
*
* The top level rule for the parser
*/
query
: SELECT selectList fromClause whereClause? orderByClause?
-> ^(QUERY selectList fromClause whereClause? orderByClause?)
;
selectList
: STAR
-> ^(ALL_COLUMNS)
| selectSubList ( COMMA selectSubList )*
-> ^(COLUMNS selectSubList+)
;
selectSubList
: (valueExpression)=> valueExpression ( AS? columnName )?
-> ^(COLUMN valueExpression columnName?)
| qualifier DOTSTAR
-> ^(ALL_COLUMNS qualifier)
| multiValuedColumnReference
-> /* No AST - MVCs are included in value expressions */
;
valueExpression
: columnReference
-> columnReference
| stringValueFunction
-> stringValueFunction
| numericValueFunction
-> numericValueFunction
;
columnReference
: ( qualifier DOT )? columnName
-> ^(COLUMN_REF columnName qualifier?)
;
/*
* This production is proteted by a dynamic predicate.
* TODO Add look a head and perform the test
*/
multiValuedColumnReference
: ( qualifier DOT )? multiValuedColumnName
-> ^(COLUMN_REF multiValuedColumnName qualifier?)
;
stringValueFunction
: ( functionName=UPPER | functionName=LOWER ) LPAREN columnReference RPAREN
-> ^(STRING_FUNCTION $functionName columnReference)
;
numericValueFunction
: functionName=SCORE LPAREN qualifier? RPAREN
-> ^(NUMERIC_FUNCTION $functionName qualifier?)
;
qualifier
: (tableName) => tableName
-> tableName
| correlationName
-> correlationName
;
fromClause
: FROM tableReference
-> tableReference
;
tableReference
: singleTable ((joinedTable) => joinedTable)*
-> ^(SOURCE singleTable joinedTable*)
;
/*
* Created to avoid left recursion between tableReference and joinedTable.
*/
singleTable
: tableName ( AS? correlationName )?
-> ^(TABLE_REF tableName correlationName?)
| LPAREN joinedTables RPAREN
-> ^(TABLE joinedTables)
;
joinedTable
: joinType? JOIN tableReference ((joinSpecification) => joinSpecification)?
-> ^(JOIN tableReference joinType? joinSpecification?)
;
joinedTables
: singleTable joinedTable+
-> singleTable joinedTable+
;
joinType
: INNER
-> INNER
| LEFT OUTER?
-> LEFT OUTER?
;
joinSpecification
: ON LPAREN lhs=columnReference EQUALS rhs=columnReference RPAREN
-> ^(ON $lhs EQUALS $rhs)
;
/*
* Broken out the left recursion from the spec
*/
whereClause
: WHERE searchOrCondition
-> searchOrCondition
;
/**
* Broken left recursion.
*/
searchOrCondition
: searchAndCondition (OR searchAndCondition)*
-> ^(DISJUNCTION searchAndCondition+)
;
/**
* Broken left recursion.
*/
searchAndCondition
: searchNotCondition (AND searchNotCondition)*
-> ^(CONJUNCTION searchNotCondition+)
;
searchNotCondition
: NOT searchTest
-> ^(NEGATION searchTest)
| searchTest
-> searchTest
;
searchTest
: predicate
-> predicate
| LPAREN searchOrCondition RPAREN
-> searchOrCondition
;
predicate
: comparisonPredicate
| inPredicate
| likePredicate
| nullPredicate
| quantifiedComparisonPredicate
| quantifiedInPredicate
| textSearchPredicate
| folderPredicate
;
comparisonPredicate
: valueExpression compOp literalOrParameterName
-> ^(PRED_COMPARISON ANY valueExpression compOp literalOrParameterName)
;
compOp
: EQUALS
| NOTEQUALS
| LESSTHAN
| GREATERTHAN
| LESSTHANOREQUALS
| GREATERTHANOREQUALS
;
literalOrParameterName
: literal
| parameterName
;
literal
: signedNumericLiteral
| characterStringLiteral
;
inPredicate
: columnReference NOT? IN LPAREN inValueList RPAREN
-> ^(PRED_IN ANY columnReference NOT? inValueList)
;
inValueList
: literalOrParameterName (COMMA literalOrParameterName )*
-> ^(LIST literalOrParameterName+)
;
likePredicate
: columnReference NOT? LIKE characterStringLiteral
-> ^(PRED_LIKE columnReference NOT? characterStringLiteral)
;
nullPredicate
: ( (columnReference)=> columnReference | multiValuedColumnReference) IS NOT? NULL
-> ^(PRED_EXISTS columnReference NOT?)
;
quantifiedComparisonPredicate
: literalOrParameterName compOp ANY multiValuedColumnReference
-> ^(PRED_COMPARISON ANY literalOrParameterName compOp multiValuedColumnReference)
;
quantifiedInPredicate
: ANY multiValuedColumnReference NOT? IN LPAREN inValueList RPAREN
-> ^(PRED_IN ANY multiValuedColumnReference NOT? inValueList)
;
textSearchPredicate
: CONTAINS LPAREN (qualifier COMMA | COMMA)? textSearchExpression RPAREN
-> ^(PRED_FTS textSearchExpression qualifier)
;
folderPredicate
: IN_FOLDER folderPredicateArgs
-> ^(PRED_CHILD folderPredicateArgs)
| IN_TREE folderPredicateArgs
-> ^(PRED_DESCENDANT folderPredicateArgs)
;
folderPredicateArgs
: LPAREN (qualifier COMMA | COMMA)? folderId RPAREN
-> folderId qualifier?
;
orderByClause
: ORDER BY sortSpecification ( COMMA sortSpecification )*
-> ^(ORDER sortSpecification+)
;
sortSpecification
: columnName
-> ^(SORT_SPECIFICATION columnName ASC)
| columnName ( by=ASC | by=DESC )
-> ^(SORT_SPECIFICATION columnName $by)
;
correlationName
: identifier
;
/*
* Parse time validation of the table name
* TODO wire up the look a head
*/
tableName
: identifier
-> identifier
;
columnName
: identifier
-> identifier
;
multiValuedColumnName
: identifier
-> identifier
;
parameterName
: COLON identifier
-> ^(PARAMETER identifier)
;
folderId
: characterStringLiteral
-> characterStringLiteral
;
textSearchExpression
: QUOTED_STRING
;
identifier
: ID
-> ID
| DOUBLE_QUOTE keyWordOrId DOUBLE_QUOTE
-> ^(keyWordOrId)
;
signedNumericLiteral
: FLOATING_POINT_LITERAL
-> ^(NUMERIC_LITERAL FLOATING_POINT_LITERAL)
| integerLiteral
-> integerLiteral
;
integerLiteral
: DECIMAL_INTEGER_LITERAL
-> ^(NUMERIC_LITERAL DECIMAL_INTEGER_LITERAL)
;
characterStringLiteral
: QUOTED_STRING
-> ^(STRING_LITERAL QUOTED_STRING)
;
keyWord : SELECT
| AS
| UPPER
| LOWER
| FROM
| JOIN
| INNER
| LEFT
| OUTER
| ON
| WHERE
| OR
| AND
| NOT
| IN
| LIKE
| IS
| NULL
| ANY
| CONTAINS
| IN_FOLDER
| IN_TREE
| ORDER
| BY
| ASC
| DESC
| SCORE
;
keyWordOrId
: keyWord
-> keyWord
| ID
-> ID
;
/*
* LEXER
*/
SELECT : ('S'|'s')('E'|'e')('L'|'l')('E'|'e')('C'|'c')('T'|'t');
AS : ('A'|'a')('S'|'s');
UPPER : ('U'|'u')('P'|'p')('P'|'p')('E'|'e')('R'|'r');
LOWER : ('L'|'l')('O'|'o')('W'|'w')('E'|'e')('R'|'r');
FROM : ('F'|'f')('R'|'r')('O'|'o')('M'|'m');
JOIN : ('J'|'j')('O'|'o')('I'|'i')('N'|'n');
INNER : ('I'|'i')('N'|'n')('N'|'n')('E'|'e')('R'|'r');
LEFT : ('L'|'l')('E'|'e')('F'|'f')('T'|'t');
OUTER : ('O'|'o')('U'|'u')('T'|'t')('E'|'e')('R'|'r');
ON : ('O'|'o')('N'|'n');
WHERE : ('W'|'w')('H'|'h')('E'|'e')('R'|'r')('E'|'e');
OR : ('O'|'o')('R'|'r');
AND : ('A'|'a')('N'|'n')('D'|'d');
NOT : ('N'|'n')('O'|'o')('T'|'t');
IN : ('I'|'i')('N'|'n');
LIKE : ('L'|'l')('I'|'i')('K'|'k')('E'|'e');
IS : ('I'|'i')('S'|'s');
NULL : ('N'|'n')('U'|'u')('L'|'l')('L'|'l');
ANY : ('A'|'a')('N'|'n')('Y'|'y');
CONTAINS: ('C'|'c')('O'|'o')('N'|'n')('T'|'t')('A'|'a')('I'|'i')('N'|'n')('S'|'s');
IN_FOLDER
: ('I'|'i')('N'|'n')'_'('F'|'f')('O'|'o')('L'|'l')('D'|'d')('E'|'e')('R'|'r');
IN_TREE : ('I'|'i')('N'|'n')'_'('T'|'t')('R'|'r')('E'|'e')('E'|'e');
ORDER : ('O'|'o')('R'|'r')('D'|'d')('E'|'e')('R'|'r');
BY : ('B'|'b')('Y'|'y');
ASC : ('A'|'a')('S'|'s')('C'|'c');
DESC : ('D'|'d')('E'|'e')('S'|'s')('C'|'c');
SCORE : ('S'|'s')('C'|'c')('O'|'o')('R'|'r')('E'|'e');
LPAREN : '(' ;
RPAREN : ')' ;
STAR : '*' ;
COMMA : ',' ;
DOTSTAR : '.*' ;
DOT : '.' ;
DOTDOT : '..' ;
EQUALS : '=' ;
TILDA : '~' ;
NOTEQUALS
: '<>' ;
GREATERTHAN
: '>' ;
LESSTHAN
: '<' ;
GREATERTHANOREQUALS
: '>=' ;
LESSTHANOREQUALS
: '<=' ;
COLON : ':' ;
SINGLE_QUOTE
: '\'';
DOUBLE_QUOTE
: '"'
;
QUOTED_STRING
: SINGLE_QUOTE ( ~SINGLE_QUOTE | ESCAPED_SINGLE_QUOTE)* SINGLE_QUOTE
;
/*
* Decimal adapted from the Java spec
*/
DECIMAL_INTEGER_LITERAL
: ( PLUS | MINUS )? DECIMAL_NUMERAL
;
/*
* Floating point adapted from the Java spec
*/
FLOATING_POINT_LITERAL
: DIGIT+ DOT DIGIT* EXPONENT?
| DOT DIGIT+ EXPONENT?
| DIGIT+ EXPONENT
;
ID : ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'0'..'0'|'_'|'$'|'#')* ;
WS : ( ' ' | '\t' | '\r' | '\n' )+ { $channel = HIDDEN; } ;
/*
* Fragments for quoted strings
*/
fragment
ESCAPED_SINGLE_QUOTE
: '\'\'';
/**
* Fragments for decimal
*/
fragment
DECIMAL_NUMERAL
: ZERO_DIGIT
| NON_ZERO_DIGIT DIGIT*
;
fragment
DIGIT : ZERO_DIGIT | NON_ZERO_DIGIT ;
fragment
ZERO_DIGIT
: '0' ;
fragment
NON_ZERO_DIGIT
: '1'..'9' ;
fragment
PLUS : '+' ;
fragment
MINUS : '-' ;
fragment
E : ('e' | 'E') ;
/*
* Fragments for floating point
*/
fragment
EXPONENT
: E SIGNED_INTEGER
;
fragment
SIGNED_INTEGER
: (PLUS | MINUS)? DIGIT+
;

View File

@@ -0,0 +1,280 @@
/*
* Copyright (C) 2005-2007 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"
*/
/*
* Parser for the CMIS query language
*
* The semantics of multivalued properties are ignored for the initial parse of the language.
* They are applied in a second pass, when we have enough information to determine the column type.
*/
grammar FTS;
options
{
output=AST;
}
tokens
{
FTS;
DISJUNCTION;
CONJUNCTION;
NEGATION;
TERM;
EXACT_TERM;
PHRASE;
SYNONYM;
FIELD_DISJUNCTION;
FIELD_CONJUNCTION;
FIELD_NEGATION;
FIELD_GROUP;
FG_TERM;
FG_EXACT_TERM;
FG_PHRASE;
FG_SYNONYM;
FG_PROXIMITY;
FG_RANGE;
COLUMN_REF;
}
@members
{
public boolean defaultConjunction()
{
return true;
}
public boolean defaultFieldConjunction()
{
return true;
}
}
fts : ftsImplicitConjunctionOrDisjunction
-> ftsImplicitConjunctionOrDisjunction
;
ftsImplicitConjunctionOrDisjunction
: {defaultConjunction()}? ftsExplicitDisjunction (ftsExplicitDisjunction)*
-> ^(CONJUNCTION ftsExplicitDisjunction+)
| ftsExplicitDisjunction (ftsExplicitDisjunction)*
-> ^(DISJUNCTION ftsExplicitDisjunction+)
;
ftsExplicitDisjunction
: ftsExplictConjunction (OR ftsExplictConjunction)*
-> ^(DISJUNCTION ftsExplictConjunction+)
;
ftsExplictConjunction
: ftsNot (AND ftsNot)*
-> ^(CONJUNCTION ftsNot)
;
ftsNot : MINUS ftsTest
-> ^(NEGATION ftsTest)
| ftsTest
-> ftsTest
;
ftsTest : ftsTerm
-> ^(TERM ftsTerm)
| ftsExactTerm
-> ^(EXACT_TERM ftsExactTerm)
| ftsPhrase
-> ^(PHRASE ftsPhrase)
| ftsSynonym
-> ^(SYNONYM ftsSynonym)
| ftsFieldGroupProximity
-> ^(FG_PROXIMITY ftsFieldGroupProximity)
| ftsFieldGroupRange
-> ^(FG_RANGE ftsFieldGroupRange)
| ftsFieldGroup
| LPAREN ftsImplicitConjunctionOrDisjunction RPAREN
-> ftsImplicitConjunctionOrDisjunction
;
ftsTerm
: (columnReference COLON)? FTSWORD
-> FTSWORD columnReference?
;
ftsExactTerm
: PLUS ftsTerm
-> ftsTerm
;
ftsPhrase
: (columnReference COLON)? FTSPHRASE
-> FTSPHRASE columnReference?
;
ftsSynonym
: TILDA ftsTerm
-> ftsTerm
;
ftsFieldGroup
: columnReference COLON LPAREN ftsFieldGroupImplicitConjunctionOrDisjunction RPAREN
-> ^(FIELD_GROUP columnReference ftsFieldGroupImplicitConjunctionOrDisjunction)
;
ftsFieldGroupImplicitConjunctionOrDisjunction
: {defaultFieldConjunction}? ftsFieldGroupExplicitDisjunction (ftsFieldGroupExplicitDisjunction)*
-> ^(FIELD_CONJUNCTION ftsFieldGroupExplicitDisjunction+)
| ftsFieldGroupExplicitDisjunction (ftsFieldGroupExplicitDisjunction)*
-> ^(FIELD_DISJUNCTION ftsFieldGroupExplicitDisjunction+)
;
ftsFieldGroupExplicitDisjunction
: ftsFieldGroupExplictConjunction (OR ftsFieldGroupExplictConjunction)*
-> ^(FIELD_DISJUNCTION ftsFieldGroupExplictConjunction+)
;
ftsFieldGroupExplictConjunction
: ftsFieldGroupNot (AND ftsFieldGroupNot)*
-> ^(FIELD_CONJUNCTION ftsFieldGroupNot+)
;
ftsFieldGroupNot : MINUS ftsFieldGroupTest
-> FIELD_NEGATION ftsFieldGroupTest
| ftsFieldGroupTest
-> ftsFieldGroupTest
;
ftsFieldGroupTest
: ftsFieldGroupTerm
-> ^(FG_TERM ftsFieldGroupTerm)
| ftsFieldGroupExactTerm
-> ^(FG_EXACT_TERM ftsFieldGroupExactTerm)
| ftsFieldGroupPhrase
-> ^(FG_PHRASE ftsFieldGroupPhrase)
| ftsFieldGroupSynonym
-> ^(FG_SYNONYM ftsFieldGroupSynonym)
| ftsFieldGroupProximity
-> ^(FG_PROXIMITY ftsFieldGroupProximity)
| ftsFieldGroupRange
-> ^(FG_RANGE ftsFieldGroupRange)
| LPAREN ftsFieldGroupImplicitConjunctionOrDisjunction RPAREN
-> ftsFieldGroupImplicitConjunctionOrDisjunction
;
ftsFieldGroupTerm
: FTSWORD
;
ftsFieldGroupExactTerm
: PLUS ftsFieldGroupTerm
-> ftsFieldGroupTerm
;
ftsFieldGroupPhrase
: FTSPHRASE
;
ftsFieldGroupSynonym
: TILDA ftsFieldGroupTerm
-> ftsFieldGroupTerm
;
ftsFieldGroupProximity
: ftsFieldGroupTerm STAR ftsFieldGroupTerm
-> ftsFieldGroupTerm ftsFieldGroupTerm
;
ftsFieldGroupRange: ftsFieldGroupTerm DOTDOT ftsFieldGroupTerm
-> ftsFieldGroupTerm ftsFieldGroupTerm
;
columnReference
: ( qualifier=identifier DOT )? name=identifier
-> ^(COLUMN_REF $name $qualifier?)
;
identifier
: ID
;
OR : ('O'|'o')('R'|'r');
AND : ('A'|'a')('N'|'n')('D'|'d');
NOT : ('N'|'n')('O'|'o')('T'|'t');
TILDA : '~' ;
LPAREN : '(' ;
RPAREN : ')' ;
PLUS : '+' ;
MINUS : '-' ;
COLON : ':' ;
STAR : '*' ;
DOTDOT : '..' ;
DOT : '.' ;
FTSWORD : INWORD+;
fragment
INWORD : '\u0041' .. '\u005A'
| '\u0061' .. '\u007A'
| '\u00C0' .. '\u00D6'
| '\u00D8' .. '\u00F6'
| '\u00F8' .. '\u00FF'
| '\u0100' .. '\u1FFF'
| '\u3040' .. '\u318F'
| '\u3300' .. '\u337F'
| '\u3400' .. '\u3D2D'
| '\u4E00' .. '\u9FFF'
| '\uF900' .. '\uFAFF'
| '\uAC00' .. '\uD7AF'
| '\u0030' .. '\u0039'
| '\u0660' .. '\u0669'
| '\u06F0' .. '\u06F9'
| '\u0966' .. '\u096F'
| '\u09E6' .. '\u09EF'
| '\u0A66' .. '\u0A6F'
| '\u0AE6' .. '\u0AEF'
| '\u0B66' .. '\u0B6F'
| '\u0BE7' .. '\u0BEF'
| '\u0C66' .. '\u0C6F'
| '\u0CE6' .. '\u0CEF'
| '\u0D66' .. '\u0D6F'
| '\u0E50' .. '\u0E59'
| '\u0ED0' .. '\u0ED9'
| '\u1040' .. '\u1049'
;
FTSPHRASE
: '"' (~'"' | '""')* '"' ;
ID : ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'0'..'0'|'_'|'$'|'#')* ;
WS : ( ' ' | '\t' | '\r' | '\n' )+ { $channel = HIDDEN; } ;

View File

@@ -149,6 +149,13 @@ public interface DictionaryService
@NotAuditable
Collection<QName> getAspects(QName model);
/**
* @param model the model to retrieve associations for
* @return the names of all associations defined within the specified model
*/
@NotAuditable
public Collection<QName> getAssociations(QName model);
/**
* @param name the name of the aspect to retrieve
* @return the aspect definition (or null, if it doesn't exist)
@@ -231,7 +238,7 @@ public interface DictionaryService
Collection<QName> getProperties(QName model, QName dataType);
/**
* Get all poroperties for the specified model
* Get all properties for the specified model
*
* @param model
* @return
@@ -247,6 +254,14 @@ public interface DictionaryService
@NotAuditable
AssociationDefinition getAssociation(QName associationName);
/**
* Get all the association definitions
* @return all the association qnames
*/
@NotAuditable
Collection<QName> getAllAssociations();
// TODO: Behaviour definitions
}

View File

@@ -26,6 +26,7 @@ package org.alfresco.service.cmr.dictionary;
import java.util.List;
import org.alfresco.repo.dictionary.IndexTokenisationMode;
import org.alfresco.service.namespace.QName;
/**
@@ -103,9 +104,9 @@ public interface PropertyDefinition
public boolean isStoredInIndex();
/**
* @return true => tokenised when it is indexed (the stored value will not be tokenised)
* @return IndexTokenisationMode.TREU => tokenised when it is indexed (the stored value will not be tokenised)
*/
public boolean isTokenisedInIndex();
public IndexTokenisationMode getIndexTokenisationMode();
/**
* All non atomic properties will be indexed at the same time.