mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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:
86
source/java/org/alfresco/cmis/dictionary/BaseCMISTest.java
Normal file
86
source/java/org/alfresco/cmis/dictionary/BaseCMISTest.java
Normal 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();
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
72
source/java/org/alfresco/cmis/dictionary/CMISChoice.java
Normal file
72
source/java/org/alfresco/cmis/dictionary/CMISChoice.java
Normal 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();
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
373
source/java/org/alfresco/cmis/dictionary/CMISMapping.java
Normal file
373
source/java/org/alfresco/cmis/dictionary/CMISMapping.java
Normal 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;
|
||||
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
{
|
||||
|
||||
}
|
297
source/java/org/alfresco/cmis/dictionary/CMISTypeDefinition.java
Normal file
297
source/java/org/alfresco/cmis/dictionary/CMISTypeDefinition.java
Normal 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();
|
||||
}
|
||||
}
|
76
source/java/org/alfresco/cmis/dictionary/CMISTypeId.java
Normal file
76
source/java/org/alfresco/cmis/dictionary/CMISTypeId.java
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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)
|
||||
*/
|
||||
|
@@ -161,6 +161,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)
|
||||
@@ -185,6 +198,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)
|
||||
|
@@ -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
|
||||
|
@@ -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()
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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"/>
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
@@ -874,21 +874,22 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
||||
Field.Store fieldStore = store ? Field.Store.YES : Field.Store.NO;
|
||||
Field.Index fieldIndex;
|
||||
|
||||
if (index)
|
||||
if (index)
|
||||
{
|
||||
if (tokenise)
|
||||
{
|
||||
fieldIndex = Field.Index.TOKENIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldIndex = Field.Index.UN_TOKENIZED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldIndex = Field.Index.NO;
|
||||
}
|
||||
switch (tokenise) {
|
||||
case TRUE:
|
||||
case BOTH:
|
||||
default:
|
||||
fieldIndex = Field.Index.TOKENIZED;
|
||||
break;
|
||||
case FALSE:
|
||||
fieldIndex = Field.Index.UN_TOKENIZED;
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
fieldIndex = Field.Index.NO;
|
||||
}
|
||||
|
||||
if ((fieldIndex != Field.Index.NO) || (fieldStore != Field.Store.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)
|
||||
|
@@ -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))
|
||||
|
568
source/java/org/alfresco/repo/search/impl/parsers/CMIS.g
Normal file
568
source/java/org/alfresco/repo/search/impl/parsers/CMIS.g
Normal 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+
|
||||
;
|
||||
|
||||
|
||||
|
280
source/java/org/alfresco/repo/search/impl/parsers/FTS.g
Normal file
280
source/java/org/alfresco/repo/search/impl/parsers/FTS.g
Normal 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; } ;
|
@@ -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
|
||||
|
||||
}
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user