diff --git a/config/alfresco/cmis-api-context.xml b/config/alfresco/cmis-api-context.xml index 96feff9f01..53dbc018ec 100644 --- a/config/alfresco/cmis-api-context.xml +++ b/config/alfresco/cmis-api-context.xml @@ -20,7 +20,7 @@ - true + false @@ -42,7 +42,7 @@ - 0.43 + 0.44 workspace/SpacesStore/Company Home @@ -59,9 +59,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.alfresco.repo.search.impl.querymodel.QueryEngine + + + + + + + + + + + + + + + + + + org.alfresco.repo.search.impl.querymodel.QueryEngine.executeQuery=AFTER_ACL_NODE.sys:base.Read + org.alfresco.repo.search.impl.querymodel.QueryEngine.getQueryModelFactory=ACL_ALLOW + + \ No newline at end of file diff --git a/config/alfresco/model/cmisModel.xml b/config/alfresco/model/cmisModel.xml index 1582c0d63c..081a8981bf 100644 --- a/config/alfresco/model/cmisModel.xml +++ b/config/alfresco/model/cmisModel.xml @@ -9,7 +9,7 @@ - + @@ -17,9 +17,9 @@ - NOT_ALLOWED - ALLOWED - REQUIRED + notallowed + allowed + required diff --git a/source/java/org/alfresco/cmis/dictionary/BaseCMISTest.java b/source/java/org/alfresco/cmis/dictionary/BaseCMISTest.java index 7f19fd8c3d..6ce49e3746 100644 --- a/source/java/org/alfresco/cmis/dictionary/BaseCMISTest.java +++ b/source/java/org/alfresco/cmis/dictionary/BaseCMISTest.java @@ -35,12 +35,14 @@ import org.alfresco.cmis.property.CMISPropertyService; import org.alfresco.cmis.search.CMISQueryService; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.MutableAuthenticationDao; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ApplicationContextHelper; @@ -83,12 +85,16 @@ public abstract class BaseCMISTest extends TestCase protected CMISQueryService cmisQueryService; + private AuthenticationService authenticationService; + + private MutableAuthenticationDao authenticationDAO; + public void setUp() throws Exception { serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry"); - cmisMapping = (CMISMapping) ctx.getBean("CMISMapping"); cmisDictionaryService = (CMISDictionaryService) ctx.getBean("CMISDictionaryService"); + cmisMapping = cmisDictionaryService.getCMISMapping(); cmisPropertyService = (CMISPropertyService) ctx.getBean("CMISPropertyService"); cmisQueryService = (CMISQueryService) ctx.getBean("CMISQueryService"); dictionaryService = (DictionaryService) ctx.getBean("dictionaryService"); @@ -99,6 +105,9 @@ public abstract class BaseCMISTest extends TestCase transactionService = (TransactionService) ctx.getBean("transactionComponent"); authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); + authenticationService = (AuthenticationService) ctx.getBean("authenticationService"); + authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao"); + testTX = transactionService.getUserTransaction(); testTX.begin(); this.authenticationComponent.setSystemUserAsCurrentUser(); @@ -106,8 +115,20 @@ public abstract class BaseCMISTest extends TestCase String storeName = "CMISTest-" + getName() + "-" + (new Date().getTime()); StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, storeName); rootNodeRef = nodeService.getRootNode(storeRef); + + if(authenticationDAO.userExists("cmis")) + { + authenticationService.deleteAuthentication("cmis"); + } + authenticationService.createAuthentication("cmis", "cmis".toCharArray()); } + protected void runAs(String userName) + { + authenticationService.authenticate(userName, userName.toCharArray()); + assertNotNull(authenticationService.getCurrentUserName()); + } + @Override protected void tearDown() throws Exception { diff --git a/source/java/org/alfresco/cmis/dictionary/CMISDictionaryService.java b/source/java/org/alfresco/cmis/dictionary/CMISDictionaryService.java index ddc2f8adab..cca9d795ee 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISDictionaryService.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISDictionaryService.java @@ -25,6 +25,7 @@ package org.alfresco.cmis.dictionary; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -48,6 +49,24 @@ public class CMISDictionaryService private boolean strict = true; + /** + * Set the mapping service + * + * @param cmisMapping + */ + public void setCMISMapping(CMISMapping cmisMapping) + { + this.cmisMapping = cmisMapping; + } + + /** + * @return cmis mapping service + */ + public CMISMapping getCMISMapping() + { + return cmisMapping; + } + /** * Set the dictionary Service * @@ -59,16 +78,15 @@ public class CMISDictionaryService } /** - * Set the mapping service + * Gets the dictionary service * - * @param cmisMapping + * @return dictionaryService */ - public void setCMISMapping(CMISMapping cmisMapping) + /*package*/ DictionaryService getDictionaryService() { - this.cmisMapping = cmisMapping; + return this.dictionaryService; } - /** * Is the service strict (CMIS types only) * @@ -140,6 +158,74 @@ public class CMISDictionaryService return answer; } + /** + * Gets all the object type ids within a type hierarchy + * + * @param typeId + * @param descendants true => include all descendants, false => children only + * @return + */ + public Collection getChildTypeIds(CMISTypeId typeId, boolean descendants) + { + switch (typeId.getScope()) + { + case RELATIONSHIP: + if (typeId.equals(CMISMapping.RELATIONSHIP_TYPE_ID)) + { + // all associations are sub-type of RELATIONSHIP_OBJECT_TYPE + // NOTE: ignore descendants + Collection alfrescoAssociationQNames = dictionaryService.getAllAssociations(); + Collection types = new HashSet(alfrescoAssociationQNames.size()); + for (QName associationName : alfrescoAssociationQNames) + { + if (cmisMapping.isValidCmisRelationship(associationName)) + { + types.add(cmisMapping.getCmisTypeId(CMISScope.RELATIONSHIP, associationName)); + } + } + return types; + } + else + { + return Collections.emptySet(); + } + case DOCUMENT: + case FOLDER: + TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName()); + if (typeDefinition != null) + { + if (cmisMapping.isValidCmisType(typeId.getQName())) + { + QName alfrescoQName = cmisMapping.getAlfrescoType(typeId.getQName()); + Collection alfrescoTypeQNames = dictionaryService.getSubTypes(alfrescoQName, descendants); + Collection types = new HashSet(alfrescoTypeQNames.size()); + for (QName typeQName : alfrescoTypeQNames) + { + if (cmisMapping.isValidCmisDocument(typeQName)) + { + types.add(cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, typeQName)); + } + else if (cmisMapping.isValidCmisFolder(typeQName)) + { + types.add(cmisMapping.getCmisTypeId(CMISScope.FOLDER, typeQName)); + } + } + return types; + } + else + { + return Collections.emptySet(); + } + } + else + { + return Collections.emptySet(); + } + default: + return Collections.emptySet(); + } + } + /** * Get the object type definition TODO: Note there can be name collisions between types and associations. e.g. * app:configurations Currently clashing types will give inconsistent behaviour @@ -155,13 +241,12 @@ public class CMISDictionaryService // Associations if (cmisMapping.isValidCmisRelationship(typeId.getQName())) { - return new CMISTypeDefinition(cmisMapping, typeId); + return new CMISTypeDefinition(this, typeId); } else { return null; } - case DOCUMENT: case FOLDER: TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName()); @@ -169,7 +254,7 @@ public class CMISDictionaryService { if (cmisMapping.isValidCmisType(typeId.getQName())) { - return new CMISTypeDefinition(cmisMapping, typeId); + return new CMISTypeDefinition(this, typeId); } else { @@ -184,7 +269,7 @@ public class CMISDictionaryService return null; } } - + /** * Get all the property definitions for a type * @@ -225,7 +310,7 @@ public class CMISDictionaryService { if (cmisMapping.getPropertyType(qname) != null) { - CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(cmisMapping, qname, typeDefinition.getName()); + CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(this, qname, typeDefinition.getName()); properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition); } } @@ -235,12 +320,11 @@ public class CMISDictionaryService { if (cmisMapping.getPropertyType(qname) != null) { - CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(cmisMapping, qname, typeDefinition.getName()); + CMISPropertyDefinition cmisPropDefinition = new CMISPropertyDefinition(this, qname, typeDefinition.getName()); properties.put(cmisPropDefinition.getPropertyName(), cmisPropDefinition); } } } - } if (cmisMapping.isValidCmisDocumentOrFolder(typeId.getQName())) { diff --git a/source/java/org/alfresco/cmis/dictionary/CMISDictionaryTest.java b/source/java/org/alfresco/cmis/dictionary/CMISDictionaryTest.java index c303736cc3..40d8fd0954 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISDictionaryTest.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISDictionaryTest.java @@ -45,6 +45,38 @@ public class CMISDictionaryTest extends BaseCMISTest } } + public void testSubTypes() + { + cmisDictionaryService.setStrict(true); + for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds()) + { + System.out.println(name + " children (strict)"); + for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, false)) + { + System.out.println(" " + subName); + } + System.out.println(name + " descendants (strict)"); + for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, true)) + { + System.out.println(" " + subName); + } + } + cmisDictionaryService.setStrict(false); + for (CMISTypeId name : cmisDictionaryService.getAllObjectTypeIds()) + { + System.out.println(name + " children"); + for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, false)) + { + System.out.println(" " + subName); + } + System.out.println(name + " descendants"); + for (CMISTypeId subName :cmisDictionaryService.getChildTypeIds(name, true)) + { + System.out.println(" " + subName); + } + } + } + public void testTypeIds() { cmisDictionaryService.setStrict(false); diff --git a/source/java/org/alfresco/cmis/dictionary/CMISMapping.java b/source/java/org/alfresco/cmis/dictionary/CMISMapping.java index 0bc6c5abb1..133dc617a1 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISMapping.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISMapping.java @@ -47,7 +47,7 @@ public class CMISMapping /** * The Alfresco CMIS model URI. */ - public static String CMIS_MODEL_URI = "http://www.alfresco.org/model/cmis/0.3"; + public static String CMIS_MODEL_URI = "http://www.alfresco.org/model/cmis/0.44"; /** * The Alfresco CMIS Model name. @@ -122,9 +122,9 @@ public class CMISMapping public static String PROP_IS_MAJOR_VERSION = "IS_MAJOR_VERSION"; public static String PROP_IS_LATEST_MAJOR_VERSION = "IS_LATEST_MAJOR_VERSION"; - + public static String PROP_VERSION_LABEL = "VERSION_LABEL"; - + public static String PROP_VERSION_SERIES_ID = "VERSION_SERIES_ID"; public static String PROP_VERSION_SERIES_IS_CHECKED_OUT = "VERSION_SERIES_IS_CHECKED_OUT"; @@ -182,29 +182,28 @@ public class CMISMapping alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.ANY, null); alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.ASSOC_REF, null); - alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.BOOLEAN, CMISPropertyType.BOOLEAN); + 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.DATE, CMISPropertyType.DateTime); + alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.DATETIME, CMISPropertyType.DateTime); + 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.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); + alfrescoPropertyTypesToCimsPropertyTypes.put(DataTypeDefinition.TEXT, CMISPropertyType.String); } - private DictionaryService dictionaryService; + private NamespaceService namespaceService; - /** * Set the dictionary Service * @@ -220,11 +219,11 @@ public class CMISMapping * * @return dictionaryService */ - /*package*/ DictionaryService getDictionaryService() + /* package */DictionaryService getDictionaryService() { return this.dictionaryService; } - + /** * Set the namespace service * @@ -234,13 +233,13 @@ public class CMISMapping { this.namespaceService = namespaceService; } - + /** * Gets the namespace service * * @return namespaceService */ - /*package*/ NamespaceService getNamespaceService() + /* package */NamespaceService getNamespaceService() { return this.namespaceService; } @@ -259,12 +258,13 @@ public class CMISMapping /** * Gets the CMIS Type Id given the serialized type Id * - * @param typeId type id in the form of /_ + * @param typeId + * type id in the form of /_ * @return */ public CMISTypeId getCmisTypeId(String typeId) { - // Is it a CMIS root object type id? + // Is it a CMIS root object type id? if (typeId.equals(DOCUMENT_TYPE_ID.getTypeId())) { return DOCUMENT_TYPE_ID; @@ -278,13 +278,13 @@ public class CMISMapping return RELATIONSHIP_TYPE_ID; } // TODO: Policy root object type - + // Is it an Alfresco type id? if (typeId.length() < 4 || typeId.charAt(1) != '/') { throw new AlfrescoRuntimeException("Malformed type id '" + typeId + "'"); } - + // Alfresco type id CMISScope scope = CMISScope.toScope(typeId.charAt(0)); if (scope == null) @@ -296,7 +296,7 @@ public class CMISMapping // Construct CMIS Type Id return new CMISTypeId(scope, typeQName, typeId); } - + /** * Gets the CMIS Type Id given the Alfresco QName for the type in any Alfresco model * @@ -320,6 +320,35 @@ public class CMISMapping } } + public CMISTypeId getCmisTypeId(QName typeQName) + { + if (isValidCmisDocument(typeQName)) + { + return getCmisTypeId(CMISScope.DOCUMENT, getCmisType(typeQName)); + } + else if (isValidCmisFolder(typeQName)) + { + return getCmisTypeId(CMISScope.FOLDER, getCmisType(typeQName)); + } + else if (typeQName.equals(CMISMapping.RELATIONSHIP_QNAME)) + { + return getCmisTypeId(CMISScope.RELATIONSHIP, getCmisType(typeQName)); + } + else if (typeQName.equals(ContentModel.TYPE_CONTENT)) + { + return getCmisTypeId(CMISScope.DOCUMENT, getCmisType(typeQName)); + } + else if (typeQName.equals(ContentModel.TYPE_FOLDER)) + { + return getCmisTypeId(CMISScope.FOLDER, getCmisType(typeQName)); + } + else + { + return null; + } + + } + /** * Get the query name for Alfresco qname * @@ -498,6 +527,22 @@ public class CMISMapping } return typeQName; } + + /** + * Given a CMIS model type map it to the appropriate Alfresco type. + * + * @param cmisTypeQName + * @return + */ + public QName getAlfrescoType(QName cmisTypeQName) + { + QName mapped = cmisToAlfrecsoTypes.get(cmisTypeQName); + if (mapped != null) + { + return mapped; + } + return cmisTypeQName; + } /** * Get the CMIS property name from the property QName. @@ -521,11 +566,20 @@ public class CMISMapping public CMISPropertyType getPropertyType(QName propertyQName) { PropertyDefinition propertyDefinition = dictionaryService.getProperty(propertyQName); - DataTypeDefinition dataTypeDefinition = propertyDefinition.getDataType(); + DataTypeDefinition dataTypeDefinition; + if (propertyDefinition != null) + { + dataTypeDefinition = propertyDefinition.getDataType(); + } + else + { + dataTypeDefinition = dictionaryService.getDataType(propertyQName); + } + QName dQName = dataTypeDefinition.getName(); if (propertyQName.getNamespaceURI().equals(CMIS_MODEL_URI)) { - if(dQName.equals(DataTypeDefinition.QNAME) || dQName.equals(DataTypeDefinition.NODE_REF)) + if (dQName.equals(DataTypeDefinition.QNAME) || dQName.equals(DataTypeDefinition.NODE_REF)) { return CMISPropertyType.ID; } @@ -647,7 +701,7 @@ public class CMISMapping } } } - + for (QName qname : dictionaryService.getAllAspects()) { if (qname.getNamespaceURI().equals(uri)) @@ -677,7 +731,7 @@ public class CMISMapping else { return propertyQName.toString(); - + } } } diff --git a/source/java/org/alfresco/cmis/dictionary/CMISPropertyDefinition.java b/source/java/org/alfresco/cmis/dictionary/CMISPropertyDefinition.java index 133563ae97..5346d97705 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISPropertyDefinition.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISPropertyDefinition.java @@ -24,6 +24,7 @@ */ package org.alfresco.cmis.dictionary; +import java.io.Serializable; import java.util.Collection; import java.util.HashSet; @@ -47,8 +48,13 @@ import org.alfresco.service.namespace.QName; * * @author andyh */ -public class CMISPropertyDefinition +public class CMISPropertyDefinition implements Serializable { + /** + * + */ + private static final long serialVersionUID = -8119257313852558466L; + private String propertyName; private String propertyId; @@ -83,9 +89,10 @@ public class CMISPropertyDefinition private boolean orderable; - public CMISPropertyDefinition(CMISMapping cmisMapping, QName propertyQName, QName typeQName) + public CMISPropertyDefinition(CMISDictionaryService cmisDictionary, QName propertyQName, QName typeQName) { - PropertyDefinition propDef = cmisMapping.getDictionaryService().getProperty(propertyQName); + CMISMapping cmisMapping = cmisDictionary.getCMISMapping(); + PropertyDefinition propDef = cmisDictionary.getDictionaryService().getProperty(propertyQName); if (propDef.getContainerClass().getName().equals(CMISMapping.RELATIONSHIP_QNAME)) { // Properties of associations - all the same @@ -124,7 +131,7 @@ public class CMISPropertyDefinition Constraint constraint = constraintDef.getConstraint(); if (constraint instanceof ListOfValuesConstraint) { - int position = 0; + int position = 1; // CMIS is 1 based (according to XSDs) ListOfValuesConstraint lovc = (ListOfValuesConstraint) constraint; for (String allowed : lovc.getAllowedValues()) { @@ -284,7 +291,7 @@ public class CMISPropertyDefinition * * @return */ - public Collection getChioces() + public Collection getChoices() { return choices; } @@ -294,7 +301,7 @@ public class CMISPropertyDefinition * * @return */ - public boolean isOpenChioce() + public boolean isOpenChoice() { return isOpenChoice; } @@ -363,8 +370,8 @@ public class CMISPropertyDefinition 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("Choices=").append(getChoices()).append(", "); + builder.append("IsOpenChoice=").append(isOpenChoice()).append(", "); builder.append("Required=").append(isRequired()).append(", "); builder.append("Default=").append(getDefaultValue()).append(", "); builder.append("Updatable=").append(getUpdatability()).append(", "); diff --git a/source/java/org/alfresco/cmis/dictionary/CMISPropertyType.java b/source/java/org/alfresco/cmis/dictionary/CMISPropertyType.java index 1d5c25c411..aa14017e58 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISPropertyType.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISPropertyType.java @@ -31,40 +31,13 @@ package org.alfresco.cmis.dictionary; */ public enum CMISPropertyType { - /** - * String - */ - STRING, - /** - * Decimal - */ - DECIMAL, - /** - * Integer - */ - INTEGER, - /** - * Boolean - */ - BOOLEAN, - /** - * Date-time - */ - DATE_TIME, - /** - * URI - */ + String, + Decimal, + Integer, + Boolean, + DateTime, URI, - /** - * HTML - */ - HTML, - /** - * XML - */ + ID, XML, - /** - * ID - */ - ID; + HTML; } diff --git a/source/java/org/alfresco/cmis/dictionary/CMISTypeDefinition.java b/source/java/org/alfresco/cmis/dictionary/CMISTypeDefinition.java index fff7df21c2..fb0bb5ce79 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISTypeDefinition.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISTypeDefinition.java @@ -25,13 +25,16 @@ package org.alfresco.cmis.dictionary; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import org.alfresco.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.QName; @@ -40,8 +43,15 @@ import org.alfresco.service.namespace.QName; * * @author andyh */ -public class CMISTypeDefinition +public class CMISTypeDefinition implements Serializable { + /** + * + */ + private static final long serialVersionUID = -2216695347624799934L; + + private CMISDictionaryService cmisDictionary; + private CMISTypeId objectTypeId; private String objectTypeQueryName; @@ -72,12 +82,23 @@ public class CMISTypeDefinition private ArrayList allowedTargetTypes = new ArrayList(1); - public CMISTypeDefinition(CMISMapping cmisMapping, CMISTypeId typeId) + + /** + * Construct + * + * @param cmisDictionary + * @param typeId + */ + public CMISTypeDefinition(CMISDictionaryService cmisDictionary, CMISTypeId typeId) { + this.cmisDictionary = cmisDictionary; + DictionaryService dictionaryService = this.cmisDictionary.getDictionaryService(); + CMISMapping cmisMapping = cmisDictionary.getCMISMapping(); + switch (typeId.getScope()) { case RELATIONSHIP: - AssociationDefinition associationDefinition = cmisMapping.getDictionaryService().getAssociation(typeId.getQName()); + AssociationDefinition associationDefinition = dictionaryService.getAssociation(typeId.getQName()); if (associationDefinition != null) { objectTypeId = typeId; @@ -113,12 +134,11 @@ public class CMISTypeDefinition { allowedTargetTypes.add(cmisMapping.getCmisTypeId(CMISScope.FOLDER, targetType)); } - } else { // TODO: Add CMIS Association mapping?? - TypeDefinition typeDefinition = cmisMapping.getDictionaryService().getType(typeId.getQName()); + TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName()); objectTypeId = typeId; objectTypeQueryName = cmisMapping.getQueryName(typeId.getQName()); displayName = typeDefinition.getTitle(); @@ -136,7 +156,7 @@ public class CMISTypeDefinition break; case DOCUMENT: case FOLDER: - TypeDefinition typeDefinition = cmisMapping.getDictionaryService().getType(typeId.getQName()); + TypeDefinition typeDefinition = dictionaryService.getType(typeId.getQName()); if (typeDefinition != null) { objectTypeId = typeId; @@ -362,6 +382,17 @@ public class CMISTypeDefinition return allowedTargetTypes; } + /** + * Gets the property definitions for this type + * + * @return property definitions + */ + public Map getPropertyDefinitions() + { + return cmisDictionary.getPropertyDefinitions(objectTypeId); + } + + public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/source/java/org/alfresco/cmis/property/CMISPropertyServiceImpl.java b/source/java/org/alfresco/cmis/property/CMISPropertyServiceImpl.java index 02ff0f5b0a..3d877f09f8 100644 --- a/source/java/org/alfresco/cmis/property/CMISPropertyServiceImpl.java +++ b/source/java/org/alfresco/cmis/property/CMISPropertyServiceImpl.java @@ -63,6 +63,14 @@ public class CMISPropertyServiceImpl implements CMISPropertyService, Initializin this.cmisMapping = cmisMapping; } + /** + * @return cmis mapping service + */ + public CMISMapping getCMISMapping() + { + return cmisMapping; + } + /** * @param serviceRegistry */ diff --git a/source/java/org/alfresco/cmis/search/CMISQueryOptions.java b/source/java/org/alfresco/cmis/search/CMISQueryOptions.java index ecf0e99c06..97afc94ba3 100644 --- a/source/java/org/alfresco/cmis/search/CMISQueryOptions.java +++ b/source/java/org/alfresco/cmis/search/CMISQueryOptions.java @@ -24,56 +24,22 @@ */ package org.alfresco.cmis.search; -import java.util.ArrayList; -import java.util.List; import java.util.Locale; import org.alfresco.i18n.I18NUtil; -import org.alfresco.repo.search.MLAnalysisMode; +import org.alfresco.repo.search.impl.querymodel.QueryOptions; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.QueryParameterDefinition; /** * The options for a CMIS query * * @author andyh */ -public class CMISQueryOptions +public class CMISQueryOptions extends QueryOptions { - public enum Connective - { - AND, OR; - } - - public enum CMISQueryMode - { - STRICT; - } - - private String query; - - private List stores = new ArrayList(1); - - private int maxItems = -1; - - private int skipCount = 0; - - private Connective defaultFTSConnective = Connective.AND; - - private Connective defaultFTSFieldConnective = Connective.AND; - + private CMISQueryMode queryMode = CMISQueryMode.STRICT; - private int fetchSize = 1000; - - private List locales = new ArrayList(1); - - private MLAnalysisMode mlAnalaysisMode = MLAnalysisMode.EXACT_LANGUAGE_AND_ALL; - - private List queryParameterDefinitions = new ArrayList(4); - - private boolean includeInTransactionData = true; - /** * Create a CMISQueryOptions instance with the default options other than the query and store ref. * The query will be run using the locale returned by I18NUtil.getLocale() @@ -94,135 +60,12 @@ public class CMISQueryOptions */ public CMISQueryOptions(String query, StoreRef storeRef, Locale locale) { - this.query = query; - this.stores.add(storeRef); - this.locales.add(locale); + super(query, storeRef, locale); } - /** - * Get the query string - * - * @return the query - */ - public String getQuery() - { - return query; - } - - /** - * Set the query string - * - * @param query the query to set - */ - public void setQuery(String query) - { - this.query = query; - } - - /** - * Get the list of stores in which to run the query. - * Only one store is supported at the momentOnly one store is supported at the moment - * - * @return the stores - */ - public List getStores() - { - return stores; - } - - /** - * Set the stores against which to run the query. - * Only one store is supported at the moment. - * - * @param stores the stores to set - */ - public void setStores(List stores) - { - this.stores = stores; - } - - /** - * Get the max number of rows for the result set - * 0 or less is unlimited - * - * @return the maxItems - */ - public int getMaxItems() - { - return maxItems; - } - - /** - * Set the max number of rows for the result set - * 0 or less is unlimited - * - * @param maxItems the maxItems to set - */ - public void setMaxItems(int maxItems) - { - this.maxItems = maxItems; - } - - /** - * Get the skip count - the number of rows to skip at the start of the query. - * - * @return the skipCount - */ - public int getSkipCount() - { - return skipCount; - } - - /** - * Set the skip count - the number of rows to skip at the start of the query. - * - * @param skipCount the skipCount to set - */ - public void setSkipCount(int skipCount) - { - this.skipCount = skipCount; - } - - /** - * Get the default connective used when OR and AND are not specified for the FTS contains() function. - * - * @return the defaultFTSConnective - */ - public Connective getDefaultFTSConnective() - { - return defaultFTSConnective; - } - - /** - * Set the default connective used when OR and AND are not specified for the FTS contains() function. - * - * @param defaultFTSConnective the defaultFTSConnective to set - */ - public void setDefaultFTSConnective(Connective defaultFTSConnective) - { - this.defaultFTSConnective = defaultFTSConnective; - } - - /** - * As getDefaultFTSConnective() but for field groups - * - * @return the defaultFTSFieldConnective - */ - public Connective getDefaultFTSFieldConnective() - { - return defaultFTSFieldConnective; - } - - /** - * As setDefaultFTSConnective() but for field groups - * - * @param defaultFTSFieldConnective the defaultFTSFieldConnective to set - */ - public void setDefaultFTSFieldConnective(Connective defaultFTSFieldConnective) - { - this.defaultFTSFieldConnective = defaultFTSFieldConnective; - } + + /** * Get the query mode. * @@ -242,110 +85,4 @@ public class CMISQueryOptions { this.queryMode = queryMode; } - - /** - * Get the fetch size - * 0 - no prefetch - * -1 - prefetch all - * - * @return the fetchSize - */ - public int getFetchSize() - { - return fetchSize; - } - - /** - * Set the fetch size - * 0 - no prefetch - * -1 - prefetch all - * - * @param fetchSize the fetchSize to set - */ - public void setFetchSize(int fetchSize) - { - this.fetchSize = fetchSize; - } - - /** - * Get the list of locales to use for the query - * - * @return the locales - */ - public List getLocales() - { - return locales; - } - - /** - * sSet the list of locales to use for the query - * - * @param locales the locales to set - */ - public void setLocales(List locales) - { - this.locales = locales; - } - - /** - * Get the mode for multi-lingual text analaysis - * - * @return the mlAnalaysisMode - */ - public MLAnalysisMode getMlAnalaysisMode() - { - return mlAnalaysisMode; - } - - /** - * Set the mode for multi-lingual text analaysis - * - * @param mlAnalaysisMode the mlAnalaysisMode to set - */ - public void setMlAnalaysisMode(MLAnalysisMode mlAnalaysisMode) - { - this.mlAnalaysisMode = mlAnalaysisMode; - } - - /** - * Get the query parameters - * - * @return the queryParameterDefinitions - */ - public List getQueryParameterDefinitions() - { - return queryParameterDefinitions; - } - - /** - * Set the query parameters - * - * @param queryParameterDefinitions the queryParameterDefinitions to set - */ - public void setQueryParameterDefinitions(List queryParameterDefinitions) - { - this.queryParameterDefinitions = queryParameterDefinitions; - } - - /** - * Does the search include any changes made in the current transaction? - * - * @return the includeInTransactionData - */ - public boolean isIncludeInTransactionData() - { - return includeInTransactionData; - } - - /** - * Set to true if the search include any changes made in the current transaction. - * - * @param includeInTransactionData the includeInTransactionData to set - */ - public void setIncludeInTransactionData(boolean includeInTransactionData) - { - this.includeInTransactionData = includeInTransactionData; - } - - } diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetColumnImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetColumnImpl.java new file mode 100644 index 0000000000..8b1fa0c5cc --- /dev/null +++ b/source/java/org/alfresco/cmis/search/CMISResultSetColumnImpl.java @@ -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.search; + +import org.alfresco.cmis.dictionary.CMISPropertyDefinition; +import org.alfresco.cmis.dictionary.CMISPropertyType; + +/** + * @author andyh + * + */ +public class CMISResultSetColumnImpl implements CMISResultSetColumn +{ + + private String name; + + private CMISPropertyDefinition propertyDefinition; + + private CMISPropertyType propertyType; + + CMISResultSetColumnImpl(String name, CMISPropertyDefinition propertyDefinition, CMISPropertyType propertyType) + { + this.name = name; + this.propertyDefinition = propertyDefinition; + this.propertyType = propertyType; + } + + + /* (non-Javadoc) + * @see org.alfresco.cmis.search.CMISResultSetColumn#getName() + */ + public String getName() + { + return name; + } + + /* (non-Javadoc) + * @see org.alfresco.cmis.search.CMISResultSetColumn#getPropertyDefinition() + */ + public CMISPropertyDefinition getPropertyDefinition() + { + return propertyDefinition; + } + + /* (non-Javadoc) + * @see org.alfresco.cmis.search.CMISResultSetColumn#getPropertyType() + */ + public CMISPropertyType getPropertyType() + { + return propertyType; + } + +} diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetImpl.java new file mode 100644 index 0000000000..4c8486ea71 --- /dev/null +++ b/source/java/org/alfresco/cmis/search/CMISResultSetImpl.java @@ -0,0 +1,172 @@ +/* + * 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.search; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.alfresco.cmis.dictionary.CMISDictionaryService; +import org.alfresco.cmis.property.CMISPropertyService; +import org.alfresco.repo.search.impl.querymodel.Query; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.search.LimitBy; +import org.alfresco.service.cmr.search.ResultSet; + +/** + * @author andyh + */ +public class CMISResultSetImpl implements CMISResultSet +{ + private Map wrapped; + + CMISQueryOptions options; + + NodeService nodeService; + + Query query; + + CMISDictionaryService cmisDictionaryService; + + CMISPropertyService cmisPropertyService; + + public CMISResultSetImpl(Map wrapped, CMISQueryOptions options, NodeService nodeService, Query query, CMISDictionaryService cmisDictionaryService, CMISPropertyService cmisPropertyService) + { + this.wrapped = wrapped; + this.options = options; + this.nodeService = nodeService; + this.query = query; + this.cmisDictionaryService = cmisDictionaryService; + this.cmisPropertyService = cmisPropertyService; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSet#close() + */ + public void close() + { + for (ResultSet resultSet : wrapped.values()) + { + resultSet.close(); + } + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSet#getMetaData() + */ + public CMISResultSetMetaData getMetaData() + { + return new CMISResultSetMetaDataImpl(options, query, cmisDictionaryService); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSet#getRow(int) + */ + public CMISResultSetRow getRow(int i) + { + return new CMISResultSetRowImpl(this, i, getScores(i), nodeService, getNodeRefs(i), query, cmisPropertyService, cmisDictionaryService); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSet#hasMore() + */ + public boolean hasMore() + { + for (ResultSet resultSet : wrapped.values()) + { + if(resultSet.getResultSetMetaData().getLimitedBy() != LimitBy.UNLIMITED) + { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSet#length() + */ + public int length() + { + for (ResultSet resultSet : wrapped.values()) + { + return resultSet.length(); + } + throw new IllegalStateException(); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSet#start() + */ + public int start() + { + return options.getSkipCount(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Iterable#iterator() + */ + public Iterator iterator() + { + return new CMISResultSetRowIteratorImpl(this); + } + + private Map getNodeRefs(int i) + { + HashMap refs = new HashMap(); + for (String selector : wrapped.keySet()) + { + ResultSet rs = wrapped.get(selector); + refs.put(selector, rs.getNodeRef(i)); + } + return refs; + } + + private Map getScores(int i) + { + HashMap scores = new HashMap(); + for (String selector : wrapped.keySet()) + { + ResultSet rs = wrapped.get(selector); + scores.put(selector, Float.valueOf(rs.getScore(i))); + } + return scores; + } + +} diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetMetaData.java b/source/java/org/alfresco/cmis/search/CMISResultSetMetaData.java index babf220bd6..7efcf689df 100644 --- a/source/java/org/alfresco/cmis/search/CMISResultSetMetaData.java +++ b/source/java/org/alfresco/cmis/search/CMISResultSetMetaData.java @@ -74,5 +74,5 @@ public interface CMISResultSetMetaData * @param name * @return - the column meta-data. */ - public CMISResultSetColumn getCoumn(String name); + public CMISResultSetColumn getColumn(String name); } diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetMetaDataImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetMetaDataImpl.java new file mode 100644 index 0000000000..e8ad32dc4f --- /dev/null +++ b/source/java/org/alfresco/cmis/search/CMISResultSetMetaDataImpl.java @@ -0,0 +1,166 @@ +/* + * 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.search; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.cmis.dictionary.CMISDictionaryService; +import org.alfresco.cmis.dictionary.CMISPropertyDefinition; +import org.alfresco.cmis.dictionary.CMISPropertyType; +import org.alfresco.cmis.dictionary.CMISTypeDefinition; +import org.alfresco.repo.search.impl.querymodel.Column; +import org.alfresco.repo.search.impl.querymodel.PropertyArgument; +import org.alfresco.repo.search.impl.querymodel.Query; +import org.alfresco.repo.search.impl.querymodel.Selector; +import org.alfresco.repo.search.impl.querymodel.impl.functions.PropertyAccessor; +import org.alfresco.service.namespace.QName; + +/** + * @author andyh + */ +public class CMISResultSetMetaDataImpl implements CMISResultSetMetaData +{ + private CMISQueryOptions options; + + private Query query; + + private Map columnMetaData; + + private Map selectorMetaData; + + private CMISDictionaryService cmisDictionaryService; + + public CMISResultSetMetaDataImpl(CMISQueryOptions options, Query query, CMISDictionaryService cmisDictionaryService) + { + this.options = options; + this.query = query; + + Map selectors = query.getSource().getSelectors(); + selectorMetaData = new LinkedHashMap(); + for(Selector selector : selectors.values()) + { + CMISTypeDefinition type = new CMISTypeDefinition(cmisDictionaryService, cmisDictionaryService.getCMISMapping().getCmisTypeId(selector.getType())); + CMISResultSetSelector smd = new CMISResultSetSelectorImpl(selector.getAlias(), type); + selectorMetaData.put(smd.getName(), smd); + } + + List columns = query.getColumns(); + columnMetaData = new LinkedHashMap(); + + int i = 0; + for (Column column : query.getColumns()) + { + CMISPropertyDefinition propertyDefinition = null; + CMISPropertyType type = null; + if (column.getFunction().getName().equals(PropertyAccessor.NAME)) + { + PropertyArgument arg = (PropertyArgument) column.getFunctionArguments().get(PropertyAccessor.ARG_PROPERTY); + QName propertyQName = arg.getPropertyName(); + QName typeQname = selectors.get(arg.getSelector()).getType(); + propertyDefinition = new CMISPropertyDefinition(cmisDictionaryService, propertyQName, typeQname); + type = propertyDefinition.getPropertyType(); + } + if (type == null) + { + type = cmisDictionaryService.getCMISMapping().getPropertyType(column.getFunction().getReturnType()); + } + CMISResultSetColumn cmd = new CMISResultSetColumnImpl(column.getAlias(), propertyDefinition, type); + columnMetaData.put(cmd.getName(), cmd); + } + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetMetaData#getColumnNames() + */ + public String[] getColumnNames() + { + return columnMetaData.keySet().toArray(new String[0]); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetMetaData#getColumns() + */ + public CMISResultSetColumn[] getColumns() + { + return columnMetaData.values().toArray(new CMISResultSetColumn[0]); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetMetaData#getCoumn(java.lang.String) + */ + public CMISResultSetColumn getColumn(String name) + { + return columnMetaData.get(name); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetMetaData#getQueryOptions() + */ + public CMISQueryOptions getQueryOptions() + { + return options; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetMetaData#getSelector(java.lang.String) + */ + public CMISResultSetSelector getSelector(String name) + { + return selectorMetaData.get(name); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetMetaData#getSelectorNames() + */ + public String[] getSelectorNames() + { + return selectorMetaData.keySet().toArray(new String[0]); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetMetaData#getSelectors() + */ + public CMISResultSetSelector[] getSelectors() + { + return selectorMetaData.values().toArray(new CMISResultSetSelector[0]); + } + +} diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetRowImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetRowImpl.java new file mode 100644 index 0000000000..dbc5f33356 --- /dev/null +++ b/source/java/org/alfresco/cmis/search/CMISResultSetRowImpl.java @@ -0,0 +1,171 @@ +/* + * 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.search; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.alfresco.cmis.dictionary.CMISDictionaryService; +import org.alfresco.cmis.property.CMISPropertyService; +import org.alfresco.repo.search.impl.querymodel.Column; +import org.alfresco.repo.search.impl.querymodel.Query; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; + +/** + * @author andyh + */ +public class CMISResultSetRowImpl implements CMISResultSetRow +{ + /** + * The containing result set + */ + private CMISResultSet resultSet; + + /** + * The current position in the containing result set + */ + private int index; + + private Map scores; + + private NodeService nodeService; + + private Map nodeRefs; + + private Query query; + + private CMISPropertyService cmisPropertyService; + + private CMISDictionaryService cmisDictionaryService; + + public CMISResultSetRowImpl(CMISResultSet resultSet, int index, Map scores, NodeService nodeService, Map nodeRefs, Query query, CMISPropertyService cmisPropertyService, CMISDictionaryService cmisDictionaryService ) + { + this.resultSet = resultSet; + this.index = index; + this.scores = scores; + this.nodeService = nodeService; + this.nodeRefs = nodeRefs; + this.query = query; + this.cmisPropertyService = cmisPropertyService; + this.cmisDictionaryService = cmisDictionaryService; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetRow#getIndex() + */ + public int getIndex() + { + return index; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetRow#getResultSet() + */ + public CMISResultSet getResultSet() + { + return resultSet; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetRow#getScore() + */ + public float getScore() + { + float count = 0; + float overall = 0; + for (Float score : scores.values()) + { + overall = (overall * (count / (count + 1.0f))) + (score / (count + 1.0f)); + } + return overall; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetRow#getScore(java.lang.String) + */ + public float getScore(String selectorName) + { + return scores.get(selectorName); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetRow#getScores() + */ + public Map getScores() + { + return scores; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetRow#getValue(java.lang.String) + */ + public Serializable getValue(String columnName) + { + for (Column column : query.getColumns()) + { + if (column.getAlias().equals(columnName)) + { + CmisFunctionEvaluationContext context = new CmisFunctionEvaluationContext(); + context.setCmisDictionaryService(cmisDictionaryService); + context.setCmisPropertyService(cmisPropertyService); + context.setNodeRefs(nodeRefs); + context.setNodeService(nodeService); + context.setScores(scores); + return column.getFunction().getValue(column.getFunctionArguments(), context); + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.cmis.search.CMISResultSetRow#getValues() + */ + public Map getValues() + { + LinkedHashMap answer = new LinkedHashMap(); + for (String column : resultSet.getMetaData().getColumnNames()) + { + answer.put(column, getValue(column)); + } + return answer; + } + +} diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetRowIteratorImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetRowIteratorImpl.java new file mode 100644 index 0000000000..745ad4ec51 --- /dev/null +++ b/source/java/org/alfresco/cmis/search/CMISResultSetRowIteratorImpl.java @@ -0,0 +1,135 @@ +/* + * 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.search; + +import java.util.ListIterator; + +/** + * @author andyh + */ +public class CMISResultSetRowIteratorImpl implements ListIterator +{ + /** + * The result set + */ + private CMISResultSet resultSet; + + /** + * The current position + */ + private int position = -1; + + /** + * The maximum position + */ + private int max; + + /** + * Create an iterator over the result set. Follows stadard ListIterator conventions + * + * @param resultSet + */ + public CMISResultSetRowIteratorImpl(CMISResultSet resultSet) + { + this.resultSet = resultSet; + this.max = resultSet.length(); + } + + public CMISResultSet getResultSet() + { + return resultSet; + } + + /* + * ListIterator implementation + */ + public boolean hasNext() + { + return position < (max - 1); + } + + public boolean allowsReverse() + { + return true; + } + + public boolean hasPrevious() + { + return position > 0; + } + + public CMISResultSetRow next() + { + return resultSet.getRow(moveToNextPosition()); + } + + protected int moveToNextPosition() + { + return ++position; + } + + public CMISResultSetRow previous() + { + return resultSet.getRow(moveToPreviousPosition()); + } + + protected int moveToPreviousPosition() + { + return --position; + } + + public int nextIndex() + { + return position + 1; + } + + public int previousIndex() + { + return position - 1; + } + + /* + * Mutation is not supported + */ + + public void remove() + { + // TODO Auto-generated method stub + throw new UnsupportedOperationException(); + } + + public void set(CMISResultSetRow o) + { + // TODO Auto-generated method stub + throw new UnsupportedOperationException(); + } + + public void add(CMISResultSetRow o) + { + // TODO Auto-generated method stub + throw new UnsupportedOperationException(); + } + +} diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetSelectorImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetSelectorImpl.java new file mode 100644 index 0000000000..f030117ce2 --- /dev/null +++ b/source/java/org/alfresco/cmis/search/CMISResultSetSelectorImpl.java @@ -0,0 +1,62 @@ +/* + * 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.search; + +import org.alfresco.cmis.dictionary.CMISTypeDefinition; + +/** + * @author andyh + * + */ +public class CMISResultSetSelectorImpl implements CMISResultSetSelector +{ + private String name; + + private CMISTypeDefinition typeDefinition; + + public CMISResultSetSelectorImpl(String name, CMISTypeDefinition typeDefinition) + { + this.name = name; + this.typeDefinition = typeDefinition; + } + + + /* (non-Javadoc) + * @see org.alfresco.cmis.search.CMISResultSetSelector#getName() + */ + public String getName() + { + return name; + } + + /* (non-Javadoc) + * @see org.alfresco.cmis.search.CMISResultSetSelector#getTypeDefinition() + */ + public CMISTypeDefinition getTypeDefinition() + { + return typeDefinition; + } + +} diff --git a/source/java/org/alfresco/cmis/search/CmisFunctionEvaluationContext.java b/source/java/org/alfresco/cmis/search/CmisFunctionEvaluationContext.java new file mode 100644 index 0000000000..fb44f14844 --- /dev/null +++ b/source/java/org/alfresco/cmis/search/CmisFunctionEvaluationContext.java @@ -0,0 +1,136 @@ +/* + * 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.search; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.cmis.dictionary.CMISDictionaryService; +import org.alfresco.cmis.property.CMISPropertyService; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +/** + * @author andyh + */ +public class CmisFunctionEvaluationContext implements FunctionEvaluationContext +{ + private Map nodeRefs; + + private Map scores; + + private NodeService nodeService; + + private CMISPropertyService cmisPropertyService; + + private CMISDictionaryService cmisDictionaryService; + + + + /** + * @param nodeRefs the nodeRefs to set + */ + protected void setNodeRefs(Map nodeRefs) + { + this.nodeRefs = nodeRefs; + } + + /** + * @param scores the scores to set + */ + protected void setScores(Map scores) + { + this.scores = scores; + } + + /** + * @param nodeService the nodeService to set + */ + protected void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param cmisPropertyService the cmisPropertyService to set + */ + protected void setCmisPropertyService(CMISPropertyService cmisPropertyService) + { + this.cmisPropertyService = cmisPropertyService; + } + + /** + * @param cmisDictionaryService the cmisDictionaryService to set + */ + protected void setCmisDictionaryService(CMISDictionaryService cmisDictionaryService) + { + this.cmisDictionaryService = cmisDictionaryService; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext#getNodeRefs() + */ + public Map getNodeRefs() + { + return nodeRefs; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext#getNodeService() + */ + public NodeService getNodeService() + { + return nodeService; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext#getProperty(org.alfresco.service.cmr.repository.NodeRef, + * org.alfresco.service.namespace.QName) + */ + public Serializable getProperty(NodeRef nodeRef, QName propertyQName) + { + String propertyName = cmisDictionaryService.getCMISMapping().getCmisPropertyName(propertyQName); + return cmisPropertyService.getProperty(nodeRef, propertyName); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext#getScores() + */ + public Map getScores() + { + return scores; + } + +} diff --git a/source/java/org/alfresco/cmis/search/QueryTest.java b/source/java/org/alfresco/cmis/search/QueryTest.java index 0708661cf3..4ab637fac6 100644 --- a/source/java/org/alfresco/cmis/search/QueryTest.java +++ b/source/java/org/alfresco/cmis/search/QueryTest.java @@ -25,42 +25,158 @@ package org.alfresco.cmis.search; import org.alfresco.cmis.dictionary.BaseCMISTest; +import org.alfresco.cmis.dictionary.CMISMapping; /** * @author andyh */ public class QueryTest extends BaseCMISTest { + public void testBasicSelectAsGuest() + { + runAs("guest"); + String query = "SELECT * FROM DOCUMENT_OBJECT_TYPE"; + CMISResultSet rs = cmisQueryService.query(query); + assertEquals(2, rs.length()); + rs.close(); + } + public void testBasicSelect() { String query = "SELECT * FROM DOCUMENT_OBJECT_TYPE"; - cmisQueryService.query(query); + CMISResultSet rs = cmisQueryService.query(query); + for (CMISResultSetRow row : rs) + { + System.out.println("Score " + row.getScore() + " " + row.getScores()); + } + rs.close(); + } + + public void testBasicDefaultMetaData() + { + String query = "SELECT * FROM DOCUMENT_OBJECT_TYPE"; + CMISResultSet rs = cmisQueryService.query(query); + CMISResultSetMetaData md = rs.getMetaData(); + assertNotNull(md.getQueryOptions()); + assertEquals(cmisDictionaryService.getPropertyDefinitions(CMISMapping.DOCUMENT_TYPE_ID).size(), md.getColumnNames().length); + assertNotNull(md.getColumn(CMISMapping.PROP_OBJECT_ID)); + assertEquals(1, md.getSelectors().length); + assertNotNull(md.getSelector("")); + rs.close(); + } + + public void testBasicMetaData() + { + String query = "SELECT DOC.OBJECT_ID, DOC.OBJECT_ID AS ID FROM DOCUMENT_OBJECT_TYPE AS DOC"; + CMISResultSet rs = cmisQueryService.query(query); + CMISResultSetMetaData md = rs.getMetaData(); + assertNotNull(md.getQueryOptions()); + assertEquals(2, md.getColumnNames().length); + assertNotNull(md.getColumn("DOC.OBJECT_ID")); + assertNotNull(md.getColumn("ID")); + assertEquals(1, md.getSelectors().length); + assertNotNull(md.getSelector("DOC")); + rs.close(); + } + + public void testBasicColumns() + { + String query = "SELECT DOC.OBJECT_ID, DOC.OBJECT_TYPE_ID AS ID FROM FOLDER_OBJECT_TYPE AS DOC"; + CMISResultSet rs = cmisQueryService.query(query); + CMISResultSetMetaData md = rs.getMetaData(); + assertNotNull(md.getQueryOptions()); + assertEquals(2, md.getColumnNames().length); + assertNotNull(md.getColumn("DOC.OBJECT_ID")); + assertNotNull(md.getColumn("ID")); + assertEquals(1, md.getSelectors().length); + assertNotNull(md.getSelector("DOC")); + for (CMISResultSetRow row : rs) + { + System.out.println("Id " + row.getValue("ID")); + } + rs.close(); + } + + public void testBasicAllDocumentColumns() + { + String query = "SELECT DOC.* FROM DOCUMENT_OBJECT_TYPE AS DOC"; + CMISResultSet rs = cmisQueryService.query(query); + CMISResultSetMetaData md = rs.getMetaData(); + + for (CMISResultSetRow row : rs) + { + for (String column : md.getColumnNames()) + { + System.out.println("Column " +column + " value =" + row.getValue(column)); + } + System.out.println("\n\n"); + } + rs.close(); } + public void testBasicAllFolderColumns() + { + String query = "SELECT * FROM FOLDER_OBJECT_TYPE AS DOC"; + CMISResultSet rs = cmisQueryService.query(query); + CMISResultSetMetaData md = rs.getMetaData(); + + for (CMISResultSetRow row : rs) + { + for (String column : md.getColumnNames()) + { + System.out.println("Column " +column + " value =" + row.getValue(column)); + } + System.out.println("\n\n"); + } + rs.close(); + } + + public void testBasicAll_ST_SITES_Columns() + { + String query = "SELECT * FROM ST_SITES AS DOC"; + CMISResultSet rs = cmisQueryService.query(query); + CMISResultSetMetaData md = rs.getMetaData(); + + for (CMISResultSetRow row : rs) + { + for (String column : md.getColumnNames()) + { + System.out.println("Column " +column + " value =" + row.getValue(column)); + } + System.out.println("\n\n"); + System.out.println(row.getValues()); + System.out.println("\n\n"); + } + + rs.close(); + } + + + public void xtestParse1() { String query = "SELECT UPPER(1.0) AS WOOF FROM DOCUMENT_OBJECT_TYPE AS DOC LEFT OUTER JOIN FOLDER_OBJECT_TYPE AS FOLDER ON (DOC.NAME = FOLDER.NAME) WHERE LOWER(DOC.NAME = ' woof' AND CONTAINS(, 'one two three') AND CONTAINS(, 'DOC.NAME:lemur AND woof') AND (DOC.NAME in ('one', 'two') AND IN_FOLDER('meep') AND DOC.NAME like 'woof' and DOC.NAME = 'woof' and DOC.OBJECT_ID = 'meep') ORDER BY DOC.NAME DESC, WOOF"; cmisQueryService.query(query); } - + public void xtestParse2() { String query = "SELECT TITLE, AUTHORS, DATE FROM WHITE_PAPER WHERE ( IN_TREE( , 'ID00093854763') ) AND ( 'SMITH' = ANY AUTHORS )"; cmisQueryService.query(query); } - + public void xtestParse3() { String query = "SELECT OBJECT_ID, SCORE() AS X, DESTINATION, DEPARTURE_DATES FROM TRAVEL_BROCHURE WHERE ( CONTAINS(, 'CARIBBEAN CENTRAL AMERICA CRUISE TOUR') ) AND ( '2009-1-1' < ANY DEPARTURE_DATES ) ORDER BY X DESC"; cmisQueryService.query(query); } - + public void xtestParse4() { String query = "SELECT * FROM CAR_REVIEW WHERE ( LOWER(MAKE) = 'buick' ) OR ( ANY FEATURES IN ('NAVIGATION SYSTEM', 'SATELLITE RADIO', 'MP3' ) )"; cmisQueryService.query(query); } - + public void xtestParse5() { String query = "SELECT Y.CLAIM_NUM, X.PROPERTY_ADDRESS, Y.DAMAGE_ESTIMATES FROM POLICY AS X JOIN CLAIMS AS Y ON ( X.POLICY_NUM = Y.POLICY_NUM ) WHERE ( 100000 <= ANY Y.DAMAGE_ESTIMATES ) AND ( Y.CAUSE NOT LIKE '%Katrina%' )"; diff --git a/source/java/org/alfresco/cmis/search/impl/CMISQueryParser.java b/source/java/org/alfresco/cmis/search/impl/CMISQueryParser.java index a320a81d47..52d62f1e4b 100644 --- a/source/java/org/alfresco/cmis/search/impl/CMISQueryParser.java +++ b/source/java/org/alfresco/cmis/search/impl/CMISQueryParser.java @@ -25,9 +25,11 @@ package org.alfresco.cmis.search.impl; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.alfresco.cmis.dictionary.CMISCardinality; import org.alfresco.cmis.dictionary.CMISDictionaryService; @@ -73,7 +75,6 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.NotEquals; import org.alfresco.repo.search.impl.querymodel.impl.functions.PropertyAccessor; import org.alfresco.repo.search.impl.querymodel.impl.functions.Score; import org.alfresco.repo.search.impl.querymodel.impl.functions.Upper; -import org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneQueryModelFactory; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.namespace.QName; import org.antlr.runtime.ANTLRStringStream; @@ -92,7 +93,7 @@ public class CMISQueryParser private CMISDictionaryService cmisDictionaryService; private CMISMapping cmisMapping; - + private JoinSupport joinSupport; public CMISQueryParser(CMISQueryOptions options, CMISDictionaryService cmisDictionaryService, CMISMapping cmisMapping, JoinSupport joinSupport) @@ -103,7 +104,7 @@ public class CMISQueryParser this.joinSupport = joinSupport; } - public Query parse() + public Query parse(QueryModelFactory factory) { CMISParser parser = null; try @@ -114,12 +115,19 @@ public class CMISQueryParser parser = new CMISParser(tokens); CommonTree queryNode = (CommonTree) parser.query().getTree(); - QueryModelFactory factory = new LuceneQueryModelFactory(); - CommonTree sourceNode = (CommonTree) queryNode.getFirstChildWithType(CMISParser.SOURCE); Source source = buildSource(sourceNode, joinSupport, factory); Map selectors = source.getSelectors(); ArrayList columns = buildColumns(queryNode, factory, selectors); + + HashSet columnNames = new HashSet(); + for(Column column : columns) + { + if(!columnNames.add(column.getAlias())) + { + throw new CMISQueryException("Duplicate column alias for "+column.getAlias()); + } + } ArrayList orderings = buildOrderings(queryNode, factory, selectors, columns); @@ -131,7 +139,9 @@ public class CMISQueryParser } Query query = factory.createQuery(columns, source, constraint, orderings); - + + // TODO: validate query and use of ID, function arguments matching up etc + return query; } catch (RecognitionException e) @@ -250,21 +260,21 @@ public class CMISQueryParser String functionName; Function function; CommonTree argNode; - List functionArguments; + Map functionArguments; Argument arg; switch (predicateNode.getType()) { case CMISParser.PRED_CHILD: functionName = Child.NAME; function = factory.getFunction(functionName); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); argNode = (CommonTree) predicateNode.getChild(0); arg = getFunctionArgument(argNode, function.getArgumentDefinition(Child.ARG_PARENT), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); if (predicateNode.getChildCount() > 1) { arg = getFunctionArgument(argNode, function.getArgumentDefinition(Child.ARG_SELECTOR), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); } return factory.createFunctionalConstraint(function, functionArguments); case CMISParser.PRED_COMPARISON: @@ -297,36 +307,36 @@ public class CMISQueryParser default: throw new CMISQueryException("Unknown comparison function " + predicateNode.getChild(2).getText()); } - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); argNode = (CommonTree) predicateNode.getChild(1); arg = getFunctionArgument(argNode, function.getArgumentDefinition(BaseComparison.ARG_LHS), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); argNode = (CommonTree) predicateNode.getChild(3); arg = getFunctionArgument(argNode, function.getArgumentDefinition(BaseComparison.ARG_RHS), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); return factory.createFunctionalConstraint(function, functionArguments); case CMISParser.PRED_DESCENDANT: functionName = Descendant.NAME; function = factory.getFunction(functionName); argNode = (CommonTree) predicateNode.getChild(0); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); arg = getFunctionArgument(argNode, function.getArgumentDefinition(Child.ARG_PARENT), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); if (predicateNode.getChildCount() > 1) { arg = getFunctionArgument(argNode, function.getArgumentDefinition(Child.ARG_SELECTOR), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); } return factory.createFunctionalConstraint(function, functionArguments); case CMISParser.PRED_EXISTS: functionName = Exists.NAME; function = factory.getFunction(functionName); argNode = (CommonTree) predicateNode.getChild(0); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); arg = getFunctionArgument(argNode, function.getArgumentDefinition(Exists.ARG_PROPERTY), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); arg = factory.createLiteralArgument(Exists.ARG_NOT, DataTypeDefinition.BOOLEAN, (predicateNode.getChildCount() == 1)); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); return factory.createFunctionalConstraint(function, functionArguments); case CMISParser.PRED_FTS: String ftsExpression = predicateNode.getChild(0).getText(); @@ -334,28 +344,28 @@ public class CMISQueryParser case CMISParser.PRED_IN: functionName = In.NAME; function = factory.getFunction(functionName); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); argNode = (CommonTree) predicateNode.getChild(0); arg = getFunctionArgument(argNode, function.getArgumentDefinition(In.ARG_PROPERTY), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); argNode = (CommonTree) predicateNode.getChild(1); arg = getFunctionArgument(argNode, function.getArgumentDefinition(In.ARG_COLLECTION), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); arg = factory.createLiteralArgument(In.ARG_NOT, DataTypeDefinition.BOOLEAN, (predicateNode.getChildCount() > 2)); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); return factory.createFunctionalConstraint(function, functionArguments); case CMISParser.PRED_LIKE: functionName = Like.NAME; function = factory.getFunction(functionName); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); argNode = (CommonTree) predicateNode.getChild(0); arg = getFunctionArgument(argNode, function.getArgumentDefinition(Like.ARG_PROPERTY), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); argNode = (CommonTree) predicateNode.getChild(1); arg = getFunctionArgument(argNode, function.getArgumentDefinition(Like.ARG_EXP), factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); arg = factory.createLiteralArgument(Like.ARG_NOT, DataTypeDefinition.BOOLEAN, (predicateNode.getChildCount() > 2)); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); return factory.createFunctionalConstraint(function, functionArguments); default: return null; @@ -451,7 +461,7 @@ public class CMISQueryParser { String functionName; Function function; - List functionArguments; + Map functionArguments; Argument arg; switch (testNode.getType()) { @@ -462,38 +472,38 @@ public class CMISQueryParser case FTSParser.TERM: functionName = FTSTerm.NAME; function = factory.getFunction(functionName); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); arg = factory.createLiteralArgument(FTSTerm.ARG_TERM, DataTypeDefinition.TEXT, testNode.getChild(0).getText()); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); if (testNode.getChildCount() > 1) { arg = buildColumnReference(FTSTerm.ARG_PROPERTY, (CommonTree) testNode.getChild(1), factory); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); } return factory.createFunctionalConstraint(function, functionArguments); case FTSParser.EXACT_TERM: functionName = FTSExactTerm.NAME; function = factory.getFunction(functionName); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); arg = factory.createLiteralArgument(FTSExactTerm.ARG_TERM, DataTypeDefinition.TEXT, testNode.getChild(0).getText()); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); if (testNode.getChildCount() > 1) { arg = buildColumnReference(FTSExactTerm.ARG_PROPERTY, (CommonTree) testNode.getChild(1), factory); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); } return factory.createFunctionalConstraint(function, functionArguments); case FTSParser.PHRASE: // TODO: transform "" to " to reverse escaping functionName = FTSPhrase.NAME; function = factory.getFunction(functionName); - functionArguments = new ArrayList(); + functionArguments = new LinkedHashMap(); arg = factory.createLiteralArgument(FTSPhrase.ARG_PHRASE, DataTypeDefinition.TEXT, testNode.getChild(0).getText()); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); if (testNode.getChildCount() > 1) { arg = buildColumnReference(FTSPhrase.ARG_PROPERTY, (CommonTree) testNode.getChild(1), factory); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); } return factory.createFunctionalConstraint(function, functionArguments); case FTSParser.SYNONYM: @@ -585,8 +595,8 @@ public class CMISQueryParser Function function = factory.getFunction(PropertyAccessor.NAME); QName propertyQName = cmisMapping.getPropertyQName(definition.getPropertyName()); Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, selector.getAlias(), propertyQName); - List functionArguments = new ArrayList(1); - functionArguments.add(arg); + Map functionArguments = new LinkedHashMap(); + functionArguments.put(arg.getName(), arg); String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyName() : definition.getPropertyName(); @@ -626,8 +636,8 @@ public class CMISQueryParser Function function = factory.getFunction(PropertyAccessor.NAME); QName propertyQName = cmisMapping.getPropertyQName(definition.getPropertyName()); Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, selector.getAlias(), propertyQName); - List functionArguments = new ArrayList(1); - functionArguments.add(arg); + Map functionArguments = new LinkedHashMap(); + functionArguments.put(arg.getName(), arg); String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyName() : definition.getPropertyName(); @@ -645,6 +655,7 @@ public class CMISQueryParser return orderings; } + @SuppressWarnings("unchecked") private ArrayList buildColumns(CommonTree queryNode, QueryModelFactory factory, Map selectors) { ArrayList columns = new ArrayList(); @@ -675,9 +686,10 @@ public class CMISQueryParser Function function = factory.getFunction(PropertyAccessor.NAME); QName propertyQName = cmisMapping.getPropertyQName(definition.getPropertyName()); Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, selector.getAlias(), propertyQName); - List functionArguments = new ArrayList(1); - functionArguments.add(arg); - Column column = factory.createColumn(function, functionArguments, selector.getAlias() + "." + definition.getPropertyName()); + Map functionArguments = new LinkedHashMap(); + functionArguments.put(arg.getName(), arg); + String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyName() : definition.getPropertyName(); + Column column = factory.createColumn(function, functionArguments, alias); columns.add(column); } } @@ -687,61 +699,15 @@ public class CMISQueryParser CommonTree columnsNode = (CommonTree) queryNode.getFirstChildWithType(CMISParser.COLUMNS); if (columnsNode != null) { - CommonTree allColumnsNode = (CommonTree) columnsNode.getFirstChildWithType(CMISParser.ALL_COLUMNS); - if (allColumnsNode != null) + for (CommonTree columnNode : (List)columnsNode.getChildren()) { - String qualifier = allColumnsNode.getChild(0).getText(); - Selector selector = selectors.get(qualifier); - if (selector == null) + if(columnNode.getType() == CMISParser.ALL_COLUMNS) { - throw new CMISQueryException("No selector for " + qualifier + " in " + qualifier + ".*"); - } - QName cmisType = cmisMapping.getCmisType(selector.getType()); - CMISTypeId typeId = null; - if (cmisMapping.isValidCmisDocument(cmisType)) - { - typeId = cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, cmisType); - } - else if (cmisMapping.isValidCmisFolder(cmisType)) - { - typeId = cmisMapping.getCmisTypeId(CMISScope.FOLDER, cmisType); - } - else - { - throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias()); - } - Map propDefs = cmisDictionaryService.getPropertyDefinitions(typeId); - for (CMISPropertyDefinition definition : propDefs.values()) - { - if (definition.getCardinality() == CMISCardinality.SINGLE_VALUED) - { - Function function = factory.getFunction(PropertyAccessor.NAME); - QName propertyQName = cmisMapping.getPropertyQName(definition.getPropertyName()); - Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, selector.getAlias(), propertyQName); - List functionArguments = new ArrayList(1); - functionArguments.add(arg); - Column column = factory.createColumn(function, functionArguments, selector.getAlias() + "." + definition.getPropertyName()); - columns.add(column); - } - } - } - - CommonTree columnNode = (CommonTree) columnsNode.getFirstChildWithType(CMISParser.COLUMN); - if (columnNode != null) - { - CommonTree columnRefNode = (CommonTree) columnNode.getFirstChildWithType(CMISParser.COLUMN_REF); - if (columnRefNode != null) - { - String columnName = columnRefNode.getChild(0).getText(); - String qualifier = ""; - if (columnRefNode.getChildCount() > 1) - { - qualifier = columnRefNode.getChild(1).getText(); - } + String qualifier = columnNode.getChild(0).getText(); Selector selector = selectors.get(qualifier); if (selector == null) { - throw new CMISQueryException("No selector for " + qualifier); + throw new CMISQueryException("No selector for " + qualifier + " in " + qualifier + ".*"); } QName cmisType = cmisMapping.getCmisType(selector.getType()); CMISTypeId typeId = null; @@ -757,72 +723,120 @@ public class CMISQueryParser { throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias()); } - CMISPropertyDefinition definition = cmisDictionaryService.getPropertyDefinition(typeId, columnName); - - if (definition == null) + Map propDefs = cmisDictionaryService.getPropertyDefinitions(typeId); + for (CMISPropertyDefinition definition : propDefs.values()) { - throw new CMISQueryException("Invalid column for " + cmisMapping.getQueryName(typeId.getQName()) + "." + columnName); + if (definition.getCardinality() == CMISCardinality.SINGLE_VALUED) + { + Function function = factory.getFunction(PropertyAccessor.NAME); + QName propertyQName = cmisMapping.getPropertyQName(definition.getPropertyName()); + Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, selector.getAlias(), propertyQName); + Map functionArguments = new LinkedHashMap(); + functionArguments.put(arg.getName(), arg); + String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyName() : definition.getPropertyName(); + Column column = factory.createColumn(function, functionArguments, alias); + columns.add(column); + } } - - Function function = factory.getFunction(PropertyAccessor.NAME); - QName propertyQName = cmisMapping.getPropertyQName(definition.getPropertyName()); - Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, selector.getAlias(), propertyQName); - List functionArguments = new ArrayList(1); - functionArguments.add(arg); - - String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyName() : definition.getPropertyName(); - if (columnNode.getChildCount() > 1) - { - alias = columnNode.getChild(1).getText(); - } - - Column column = factory.createColumn(function, functionArguments, alias); - columns.add(column); - } - CommonTree functionNode = (CommonTree) columnNode.getFirstChildWithType(CMISParser.FUNCTION); - if (functionNode != null) + if(columnNode.getType() == CMISParser.COLUMN) { - String functionName = getFunctionName((CommonTree) functionNode.getChild(0)); - Function function = factory.getFunction(functionName); - Set definitions = function.getArgumentDefinitions(); - List functionArguments = new ArrayList(); - - int childIndex = 1; - for (ArgumentDefinition definition : definitions) + CommonTree columnRefNode = (CommonTree) columnNode.getFirstChildWithType(CMISParser.COLUMN_REF); + if (columnRefNode != null) { - if (functionNode.getChildCount() > childIndex) + String columnName = columnRefNode.getChild(0).getText(); + String qualifier = ""; + if (columnRefNode.getChildCount() > 1) { - CommonTree argNode = (CommonTree) functionNode.getChild(childIndex++); - Argument arg = getFunctionArgument(argNode, definition, factory, selectors); - functionArguments.add(arg); + qualifier = columnRefNode.getChild(1).getText(); + } + Selector selector = selectors.get(qualifier); + if (selector == null) + { + throw new CMISQueryException("No selector for " + qualifier); + } + QName cmisType = cmisMapping.getCmisType(selector.getType()); + CMISTypeId typeId = null; + if (cmisMapping.isValidCmisDocument(cmisType)) + { + typeId = cmisMapping.getCmisTypeId(CMISScope.DOCUMENT, cmisType); + } + else if (cmisMapping.isValidCmisFolder(cmisType)) + { + typeId = cmisMapping.getCmisTypeId(CMISScope.FOLDER, cmisType); } else { - if (definition.isMandatory()) + throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias()); + } + CMISPropertyDefinition definition = cmisDictionaryService.getPropertyDefinition(typeId, columnName); + + if (definition == null) + { + throw new CMISQueryException("Invalid column for " + cmisMapping.getQueryName(typeId.getQName()) + "." + columnName); + } + + Function function = factory.getFunction(PropertyAccessor.NAME); + QName propertyQName = cmisMapping.getPropertyQName(definition.getPropertyName()); + Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, selector.getAlias(), propertyQName); + Map functionArguments = new LinkedHashMap(); + functionArguments.put(arg.getName(), arg); + + String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyName() : definition.getPropertyName(); + if (columnNode.getChildCount() > 1) + { + alias = columnNode.getChild(1).getText(); + } + + Column column = factory.createColumn(function, functionArguments, alias); + columns.add(column); + + } + + CommonTree functionNode = (CommonTree) columnNode.getFirstChildWithType(CMISParser.FUNCTION); + if (functionNode != null) + { + String functionName = getFunctionName((CommonTree) functionNode.getChild(0)); + Function function = factory.getFunction(functionName); + Collection definitions = function.getArgumentDefinitions().values(); + Map functionArguments = new LinkedHashMap(); + + int childIndex = 1; + for (ArgumentDefinition definition : definitions) + { + if (functionNode.getChildCount() > childIndex) { - // throw new CMISQueryException("Insufficient aruments for function " + ((CommonTree) - // functionNode.getChild(0)).getText() ); - break; + CommonTree argNode = (CommonTree) functionNode.getChild(childIndex++); + Argument arg = getFunctionArgument(argNode, definition, factory, selectors); + functionArguments.put(arg.getName(), arg); } else { - // ok + if (definition.isMandatory()) + { + // throw new CMISQueryException("Insufficient aruments for function " + + // ((CommonTree) + // functionNode.getChild(0)).getText() ); + break; + } + else + { + // ok + } } } - } - String alias = function.getName(); - if (columnNode.getChildCount() > 1) - { - alias = columnNode.getChild(1).getText(); - } + String alias = function.getName(); + if (columnNode.getChildCount() > 1) + { + alias = columnNode.getChild(1).getText(); + } - Column column = factory.createColumn(function, functionArguments, alias); - columns.add(column); + Column column = factory.createColumn(function, functionArguments, alias); + columns.add(column); + } } - } } @@ -918,8 +932,8 @@ public class CMISQueryParser { String functionName = getFunctionName((CommonTree) argNode.getChild(0)); Function function = factory.getFunction(functionName); - Set definitions = function.getArgumentDefinitions(); - List functionArguments = new ArrayList(); + Collection definitions = function.getArgumentDefinitions().values(); + Map functionArguments = new LinkedHashMap(); int childIndex = 1; for (ArgumentDefinition currentDefinition : definitions) @@ -928,7 +942,7 @@ public class CMISQueryParser { CommonTree currentArgNode = (CommonTree) argNode.getChild(childIndex++); Argument arg = getFunctionArgument(currentArgNode, currentDefinition, factory, selectors); - functionArguments.add(arg); + functionArguments.put(arg.getName(), arg); } else { @@ -1022,7 +1036,7 @@ public class CMISQueryParser { throw new UnsupportedOperationException("Outer joins are not supported"); } - + Constraint joinCondition = null; CommonTree joinConditionNode = (CommonTree) joinNode.getFirstChildWithType(CMISParser.ON); if (joinConditionNode != null) @@ -1031,9 +1045,9 @@ public class CMISQueryParser String functionName = getFunctionName((CommonTree) joinConditionNode.getChild(1)); Argument arg2 = buildColumnReference(Equals.ARG_RHS, (CommonTree) joinConditionNode.getChild(2), factory); Function function = factory.getFunction(functionName); - List functionArguments = new ArrayList(2); - functionArguments.add(arg1); - functionArguments.add(arg2); + Map functionArguments = new LinkedHashMap(); + functionArguments.put(arg1.getName(), arg1); + functionArguments.put(arg2.getName(), arg2); joinCondition = factory.createFunctionalConstraint(function, functionArguments); } diff --git a/source/java/org/alfresco/cmis/search/impl/CMISQueryServiceImpl.java b/source/java/org/alfresco/cmis/search/impl/CMISQueryServiceImpl.java index bf1fc3aff8..d1e8ebcf71 100644 --- a/source/java/org/alfresco/cmis/search/impl/CMISQueryServiceImpl.java +++ b/source/java/org/alfresco/cmis/search/impl/CMISQueryServiceImpl.java @@ -24,15 +24,24 @@ */ package org.alfresco.cmis.search.impl; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + import org.alfresco.cmis.CMISService; import org.alfresco.cmis.dictionary.CMISDictionaryService; import org.alfresco.cmis.dictionary.CMISMapping; +import org.alfresco.cmis.property.CMISPropertyService; import org.alfresco.cmis.search.CMISQueryOptions; import org.alfresco.cmis.search.CMISQueryService; import org.alfresco.cmis.search.CMISResultSet; +import org.alfresco.cmis.search.CMISResultSetImpl; import org.alfresco.cmis.search.FullTextSearchSupport; import org.alfresco.cmis.search.JoinSupport; import org.alfresco.repo.search.impl.querymodel.Query; +import org.alfresco.repo.search.impl.querymodel.QueryEngine; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.search.ResultSet; /** * @author andyh @@ -42,11 +51,18 @@ public class CMISQueryServiceImpl implements CMISQueryService private CMISService cmisService; private CMISDictionaryService cmisDictionaryService; + + private CMISPropertyService cmisPropertyService; private CMISMapping cmisMapping; - + + private QueryEngine queryEngine; + + private NodeService nodeService; + /** - * @param service the service to set + * @param service + * the service to set */ public void setCmisService(CMISService cmisService) { @@ -54,7 +70,8 @@ public class CMISQueryServiceImpl implements CMISQueryService } /** - * @param cmisDictionaryService the cmisDictionaryService to set + * @param cmisDictionaryService + * the cmisDictionaryService to set */ public void setCmisDictionaryService(CMISDictionaryService cmisDictionaryService) { @@ -62,13 +79,42 @@ public class CMISQueryServiceImpl implements CMISQueryService } /** - * @param cmisMapping the cmisMapping to set + * @param cmisMapping + * the cmisMapping to set */ public void setCmisMapping(CMISMapping cmisMapping) { this.cmisMapping = cmisMapping; } + /** + * @param queryEngine + * the queryEngine to set + */ + public void setQueryEngine(QueryEngine queryEngine) + { + this.queryEngine = queryEngine; + } + + /** + * @param nodeService + * the nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + + + /** + * @param cmisPropertyService the cmisPropertyService to set + */ + public void setCmisPropertyService(CMISPropertyService cmisPropertyService) + { + this.cmisPropertyService = cmisPropertyService; + } + /* * (non-Javadoc) * @@ -77,8 +123,21 @@ public class CMISQueryServiceImpl implements CMISQueryService public CMISResultSet query(CMISQueryOptions options) { CMISQueryParser parser = new CMISQueryParser(options, cmisDictionaryService, cmisMapping, getJoinSupport()); - Query query = parser.parse(); - System.out.println(query); + Query query = parser.parse(queryEngine.getQueryModelFactory()); + System.out.println(query); + try + { + ResultSet lucene = queryEngine.executeQuery(query, query.getSource().getSelector(), options); + Map wrapped = new HashMap(); + wrapped.put(query.getSource().getSelector(), lucene); + CMISResultSet cmis = new CMISResultSetImpl(wrapped, options, nodeService, query, cmisDictionaryService, cmisPropertyService); + return cmis; + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } return null; } @@ -93,7 +152,9 @@ public class CMISQueryServiceImpl implements CMISQueryService return query(options); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.alfresco.cmis.search.CMISQueryService#getAllVersionsSearchable() */ public boolean getAllVersionsSearchable() @@ -101,7 +162,9 @@ public class CMISQueryServiceImpl implements CMISQueryService return false; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.alfresco.cmis.search.CMISQueryService#getFullTextSearchSupport() */ public FullTextSearchSupport getFullTextSearchSupport() @@ -109,12 +172,14 @@ public class CMISQueryServiceImpl implements CMISQueryService return FullTextSearchSupport.FULL_TEXT_AND_STRUCTURED; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.alfresco.cmis.search.CMISQueryService#getJoinSupport() */ public JoinSupport getJoinSupport() { - return JoinSupport.NO_JOIN_SUPPORT; + return JoinSupport.NO_JOIN_SUPPORT; } } diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java index 58eb58f6b2..1efde7dd49 100644 --- a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java @@ -540,7 +540,8 @@ public class DictionaryDAOImpl implements DictionaryDAO else { // immediate sub types only - if (allTypesAndParents.get(type).equals(superType)) + QName typesSuperType = allTypesAndParents.get(type); + if (typesSuperType != null && typesSuperType.equals(superType)) { subTypes.add(type); } diff --git a/source/java/org/alfresco/repo/model/Repository.java b/source/java/org/alfresco/repo/model/Repository.java index d536b1eb3b..f49c28dbe1 100644 --- a/source/java/org/alfresco/repo/model/Repository.java +++ b/source/java/org/alfresco/repo/model/Repository.java @@ -285,7 +285,7 @@ public class Repository implements ApplicationContextAware, ApplicationListener, public NodeRef getPerson() { NodeRef person = null; - String currentUserName = AuthenticationUtil.getCurrentUserName(); + String currentUserName = AuthenticationUtil.getCurrentEffectiveUserName(); if (personService.personExists(currentUserName)) { person = personService.getPerson(currentUserName); diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java index 930cf16b5f..af25806d3f 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java @@ -831,4 +831,12 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS } + /* (non-Javadoc) + * @see org.alfresco.repo.search.impl.lucene.LuceneSearcher#getClosingIndexSearcher() + */ + public ClosingIndexSearcher getClosingIndexSearcher() + { + return getSearcher(indexer); + } + } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcher.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcher.java index 0dcd404b24..efd41eda12 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcher.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcher.java @@ -40,5 +40,6 @@ public interface LuceneIndexerAndSearcher extends IndexerAndSearcher, LuceneConf } public R doWithAllWriteLocks(WithAllWriteLocksWork lockWork); - + + } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcher.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcher.java index 44369cd998..e4767bf422 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcher.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcher.java @@ -62,4 +62,10 @@ public interface LuceneSearcher extends SearchService * @return */ public List> getTopTerms(String field, int count); + + /** + * Get a lucene searcher + * @return + */ + public ClosingIndexSearcher getClosingIndexSearcher(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/Function.java b/source/java/org/alfresco/repo/search/impl/querymodel/Function.java index 42e0bb2f0d..0afbb7faab 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/Function.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/Function.java @@ -25,8 +25,8 @@ package org.alfresco.repo.search.impl.querymodel; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.service.namespace.QName; @@ -34,14 +34,14 @@ import org.alfresco.service.namespace.QName; * @author andyh */ public interface Function -{ +{ /** * Evaluation a function * * @param args * @return */ - public Serializable getValue(Set args); + public Serializable getValue(Map args, FunctionEvaluationContext context); /** * Get the return type for the function @@ -61,7 +61,7 @@ public interface Function * Get the argument Definitions * @return */ - public LinkedHashSet getArgumentDefinitions(); + public LinkedHashMap getArgumentDefinitions(); /** @@ -69,5 +69,6 @@ public interface Function * @return */ public ArgumentDefinition getArgumentDefinition(String name); + } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/FunctionEvaluationContext.java b/source/java/org/alfresco/repo/search/impl/querymodel/FunctionEvaluationContext.java new file mode 100644 index 0000000000..b368ecac1c --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/querymodel/FunctionEvaluationContext.java @@ -0,0 +1,47 @@ +/* + * 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.search.impl.querymodel; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +/** + * @author andyh + * + */ +public interface FunctionEvaluationContext +{ + public Map getNodeRefs(); + + public Map getScores(); + + public Serializable getProperty(NodeRef nodeRef, QName propertyQName); + + public NodeService getNodeService(); +} diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/FunctionInvokation.java b/source/java/org/alfresco/repo/search/impl/querymodel/FunctionInvokation.java index 156038d714..c87dca646b 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/FunctionInvokation.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/FunctionInvokation.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel; -import java.util.List; +import java.util.Map; /** * @author andyh @@ -43,5 +43,5 @@ public interface FunctionInvokation * * @return */ - public List getFunctionArguments(); + public Map getFunctionArguments(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/QueryEngine.java b/source/java/org/alfresco/repo/search/impl/querymodel/QueryEngine.java new file mode 100644 index 0000000000..4543b21814 --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/querymodel/QueryEngine.java @@ -0,0 +1,40 @@ +/* + * 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.search.impl.querymodel; + +import java.io.IOException; + +import org.alfresco.service.cmr.search.ResultSet; + +/** + * @author andyh + * + */ +public interface QueryEngine +{ + public ResultSet executeQuery(Query query, String selectorName, QueryOptions options) throws IOException; + + public QueryModelFactory getQueryModelFactory(); +} diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/QueryModelException.java b/source/java/org/alfresco/repo/search/impl/querymodel/QueryModelException.java new file mode 100644 index 0000000000..033df5dab4 --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/querymodel/QueryModelException.java @@ -0,0 +1,81 @@ +/* + * 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.search.impl.querymodel; + +import org.alfresco.error.AlfrescoRuntimeException; + +/** + * @author andyh + * + */ +public class QueryModelException extends AlfrescoRuntimeException +{ + + /** + * + */ + private static final long serialVersionUID = 5103880924975096422L; + + /** + * @param msgId + */ + public QueryModelException(String msgId) + { + super(msgId); + // TODO Auto-generated constructor stub + } + + /** + * @param msgId + * @param msgParams + */ + public QueryModelException(String msgId, Object[] msgParams) + { + super(msgId, msgParams); + // TODO Auto-generated constructor stub + } + + /** + * @param msgId + * @param cause + */ + public QueryModelException(String msgId, Throwable cause) + { + super(msgId, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param msgId + * @param msgParams + * @param cause + */ + public QueryModelException(String msgId, Object[] msgParams, Throwable cause) + { + super(msgId, msgParams, cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/QueryModelFactory.java b/source/java/org/alfresco/repo/search/impl/querymodel/QueryModelFactory.java index c31a0a353b..627310167e 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/QueryModelFactory.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/QueryModelFactory.java @@ -27,6 +27,7 @@ package org.alfresco.repo.search.impl.querymodel; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.alfresco.service.namespace.QName; @@ -47,9 +48,9 @@ public interface QueryModelFactory public Constraint createNegation(Constraint constraint); - public Constraint createFunctionalConstraint(Function function, List functionArguments); + public Constraint createFunctionalConstraint(Function function, Map functionArguments); - public Column createColumn(Function function, List functionArguments, String alias); + public Column createColumn(Function function, Map functionArguments, String alias); public LiteralArgument createLiteralArgument(String name, QName type, Serializable value); @@ -65,5 +66,5 @@ public interface QueryModelFactory public ListArgument createListArgument(String name, ArrayList arguments); - public FunctionArgument createFunctionArgument(String name, Function function, List functionArguments); + public FunctionArgument createFunctionArgument(String name, Function function, Map functionArguments); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/QueryOptions.java b/source/java/org/alfresco/repo/search/impl/querymodel/QueryOptions.java new file mode 100644 index 0000000000..99db16c6e0 --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/querymodel/QueryOptions.java @@ -0,0 +1,329 @@ +/* + * 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.search.impl.querymodel; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.alfresco.i18n.I18NUtil; +import org.alfresco.repo.search.MLAnalysisMode; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.QueryParameterDefinition; + +/** + * The options for a query + * + * @author andyh + */ +public class QueryOptions +{ + public enum Connective + { + AND, OR; + } + + public enum CMISQueryMode + { + STRICT; + } + + private String query; + + private List stores = new ArrayList(1); + + private int maxItems = -1; + + private int skipCount = 0; + + private Connective defaultFTSConnective = Connective.AND; + + private Connective defaultFTSFieldConnective = Connective.AND; + + private int fetchSize = 1000; + + private List locales = new ArrayList(1); + + private MLAnalysisMode mlAnalaysisMode = MLAnalysisMode.EXACT_LANGUAGE_AND_ALL; + + private List queryParameterDefinitions = new ArrayList(4); + + private boolean includeInTransactionData = true; + + /** + * Create a CMISQueryOptions instance with the default options other than the query and store ref. + * The query will be run using the locale returned by I18NUtil.getLocale() + * + * @param query - the query to run + * @param storeRef - the store against which to run the query + */ + public QueryOptions(String query, StoreRef storeRef) + { + this(query, storeRef, I18NUtil.getLocale()); + } + + /** + * Create a CMISQueryOptions instance with the default options other than the query, store ref and locale. + * + * @param query - the query to run + * @param storeRef - the store against which to run the query + */ + public QueryOptions(String query, StoreRef storeRef, Locale locale) + { + this.query = query; + this.stores.add(storeRef); + this.locales.add(locale); + } + + /** + * Get the query string + * + * @return the query + */ + public String getQuery() + { + return query; + } + + /** + * Set the query string + * + * @param query the query to set + */ + public void setQuery(String query) + { + this.query = query; + } + + /** + * Get the list of stores in which to run the query. + * Only one store is supported at the momentOnly one store is supported at the moment + * + * @return the stores + */ + public List getStores() + { + return stores; + } + + /** + * Set the stores against which to run the query. + * Only one store is supported at the moment. + * + * @param stores the stores to set + */ + public void setStores(List stores) + { + this.stores = stores; + } + + /** + * Get the max number of rows for the result set + * 0 or less is unlimited + * + * @return the maxItems + */ + public int getMaxItems() + { + return maxItems; + } + + /** + * Set the max number of rows for the result set + * 0 or less is unlimited + * + * @param maxItems the maxItems to set + */ + public void setMaxItems(int maxItems) + { + this.maxItems = maxItems; + } + + /** + * Get the skip count - the number of rows to skip at the start of the query. + * + * @return the skipCount + */ + public int getSkipCount() + { + return skipCount; + } + + /** + * Set the skip count - the number of rows to skip at the start of the query. + * + * @param skipCount the skipCount to set + */ + public void setSkipCount(int skipCount) + { + this.skipCount = skipCount; + } + + /** + * Get the default connective used when OR and AND are not specified for the FTS contains() function. + * + * @return the defaultFTSConnective + */ + public Connective getDefaultFTSConnective() + { + return defaultFTSConnective; + } + + /** + * Set the default connective used when OR and AND are not specified for the FTS contains() function. + * + * @param defaultFTSConnective the defaultFTSConnective to set + */ + public void setDefaultFTSConnective(Connective defaultFTSConnective) + { + this.defaultFTSConnective = defaultFTSConnective; + } + + /** + * As getDefaultFTSConnective() but for field groups + * + * @return the defaultFTSFieldConnective + */ + public Connective getDefaultFTSFieldConnective() + { + return defaultFTSFieldConnective; + } + + /** + * As setDefaultFTSConnective() but for field groups + * + * @param defaultFTSFieldConnective the defaultFTSFieldConnective to set + */ + public void setDefaultFTSFieldConnective(Connective defaultFTSFieldConnective) + { + this.defaultFTSFieldConnective = defaultFTSFieldConnective; + } + + /** + * Get the fetch size + * 0 - no prefetch + * -1 - prefetch all + * + * @return the fetchSize + */ + public int getFetchSize() + { + return fetchSize; + } + + /** + * Set the fetch size + * 0 - no prefetch + * -1 - prefetch all + * + * @param fetchSize the fetchSize to set + */ + public void setFetchSize(int fetchSize) + { + this.fetchSize = fetchSize; + } + + /** + * Get the list of locales to use for the query + * + * @return the locales + */ + public List getLocales() + { + return locales; + } + + /** + * sSet the list of locales to use for the query + * + * @param locales the locales to set + */ + public void setLocales(List locales) + { + this.locales = locales; + } + + /** + * Get the mode for multi-lingual text analaysis + * + * @return the mlAnalaysisMode + */ + public MLAnalysisMode getMlAnalaysisMode() + { + return mlAnalaysisMode; + } + + /** + * Set the mode for multi-lingual text analaysis + * + * @param mlAnalaysisMode the mlAnalaysisMode to set + */ + public void setMlAnalaysisMode(MLAnalysisMode mlAnalaysisMode) + { + this.mlAnalaysisMode = mlAnalaysisMode; + } + + /** + * Get the query parameters + * + * @return the queryParameterDefinitions + */ + public List getQueryParameterDefinitions() + { + return queryParameterDefinitions; + } + + /** + * Set the query parameters + * + * @param queryParameterDefinitions the queryParameterDefinitions to set + */ + public void setQueryParameterDefinitions(List queryParameterDefinitions) + { + this.queryParameterDefinitions = queryParameterDefinitions; + } + + /** + * Does the search include any changes made in the current transaction? + * + * @return the includeInTransactionData + */ + public boolean isIncludeInTransactionData() + { + return includeInTransactionData; + } + + /** + * Set to true if the search include any changes made in the current transaction. + * + * @param includeInTransactionData the includeInTransactionData to set + */ + public void setIncludeInTransactionData(boolean includeInTransactionData) + { + this.includeInTransactionData = includeInTransactionData; + } + + +} diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/Source.java b/source/java/org/alfresco/repo/search/impl/querymodel/Source.java index aa7cd5b438..8e456cc9fc 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/Source.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/Source.java @@ -33,4 +33,8 @@ import java.util.Map; public interface Source { public Map getSelectors(); + + public Selector getSelector(String name); + + public String getSelector(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseColumn.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseColumn.java index a7dab4d8db..83d87334a8 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseColumn.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseColumn.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel.impl; -import java.util.List; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.Column; @@ -40,9 +40,9 @@ public class BaseColumn implements Column private Function function; - private List functionArguments; + private Map functionArguments; - public BaseColumn(Function function, List functionArguments, String alias) + public BaseColumn(Function function, Map functionArguments, String alias) { this.function = function; this.functionArguments = functionArguments; @@ -68,7 +68,7 @@ public class BaseColumn implements Column /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.FunctionInvokation#getFunctionArguments() */ - public List getFunctionArguments() + public Map getFunctionArguments() { return functionArguments; } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseComparison.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseComparison.java index 27b5683fa6..d28e47d604 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseComparison.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseComparison.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel.impl; -import java.util.LinkedHashSet; +import java.util.LinkedHashMap; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.Multiplicity; @@ -40,13 +40,13 @@ public abstract class BaseComparison extends BaseFunction public final static String ARG_RHS = "RHS"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_LHS, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_RHS, DataTypeDefinition.ANY, true)); + args = new LinkedHashMap(); + args.put(ARG_LHS, new BaseArgumentDefinition(Multiplicity.ANY, ARG_LHS, DataTypeDefinition.ANY, true)); + args.put(ARG_RHS, new BaseArgumentDefinition(Multiplicity.ANY, ARG_RHS, DataTypeDefinition.ANY, true)); } /** @@ -54,7 +54,7 @@ public abstract class BaseComparison extends BaseFunction * @param returnType * @param argumentDefinitions */ - public BaseComparison(String name, QName returnType, LinkedHashSet argumentDefinitions) + public BaseComparison(String name, QName returnType, LinkedHashMap argumentDefinitions) { super(name, returnType, argumentDefinitions); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunction.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunction.java index 43d11a4a8c..5f2dbc1f8a 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunction.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunction.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel.impl; -import java.util.LinkedHashSet; +import java.util.LinkedHashMap; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.Function; @@ -40,9 +40,9 @@ public abstract class BaseFunction implements Function private QName returnType; - private LinkedHashSet argumentDefinitions; + private LinkedHashMap argumentDefinitions; - public BaseFunction(String name, QName returnType, LinkedHashSet argumentDefinitions) + public BaseFunction(String name, QName returnType, LinkedHashMap argumentDefinitions) { this.name = name; this.returnType = returnType; @@ -54,7 +54,7 @@ public abstract class BaseFunction implements Function * * @see org.alfresco.repo.search.impl.querymodel.Function#getArgumentDefinitions() */ - public LinkedHashSet getArgumentDefinitions() + public LinkedHashMap getArgumentDefinitions() { return argumentDefinitions; } @@ -81,14 +81,15 @@ public abstract class BaseFunction implements Function public ArgumentDefinition getArgumentDefinition(String name) { - for (ArgumentDefinition def : getArgumentDefinitions()) + ArgumentDefinition definition = argumentDefinitions.get(name); + if (definition != null) { - if (def.getName().equals(name)) - { - return def; - } + return definition; + } + else + { + throw new IllegalArgumentException(name); } - throw new IllegalArgumentException(name); } public String toString() diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionArgument.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionArgument.java index 61a41a415f..f4d34bc099 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionArgument.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionArgument.java @@ -25,7 +25,7 @@ package org.alfresco.repo.search.impl.querymodel.impl; import java.io.Serializable; -import java.util.List; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.Function; @@ -40,9 +40,9 @@ public class BaseFunctionArgument extends BaseDynamicArgument implements Functio private Function function; - private List arguments; + private Map arguments; - public BaseFunctionArgument(String name, Function function, List arguments) + public BaseFunctionArgument(String name, Function function, Map arguments) { super(name); this.function = function; @@ -68,7 +68,7 @@ public class BaseFunctionArgument extends BaseDynamicArgument implements Functio /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.FunctionInvokation#getFunctionArguments() */ - public List getFunctionArguments() + public Map getFunctionArguments() { return arguments; } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionalConstraint.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionalConstraint.java index a13eb258f4..ba5bd13bf1 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionalConstraint.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseFunctionalConstraint.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel.impl; -import java.util.List; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.Function; @@ -38,9 +38,9 @@ public class BaseFunctionalConstraint implements FunctionalConstraint { private Function function; - private List arguments; + private Map arguments; - public BaseFunctionalConstraint(Function function, List arguments) + public BaseFunctionalConstraint(Function function, Map arguments) { this.function = function; this.arguments = arguments; @@ -65,7 +65,7 @@ public class BaseFunctionalConstraint implements FunctionalConstraint /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.FunctionInvokation#getFunctionArguments() */ - public List getFunctionArguments() + public Map getFunctionArguments() { return arguments; } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseJoin.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseJoin.java index 2e262abc5e..655f0ce3db 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseJoin.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseJoin.java @@ -133,4 +133,39 @@ public class BaseJoin implements Join } return answer; } + + /* (non-Javadoc) + * @see org.alfresco.repo.search.impl.querymodel.Source#getSelector(java.lang.String) + */ + public Selector getSelector(String name) + { + HashMap answer = new HashMap(); + Map leftSelectors = left.getSelectors(); + for(String selectorName : leftSelectors.keySet()) + { + Selector selector = leftSelectors.get(selectorName); + if(answer.put(selectorName, selector) != null) + { + throw new DuplicateSelectorNameException("There is a duplicate selector name for "+selectorName); + } + } + Map rightSelectors = right.getSelectors(); + for(String selectorName : rightSelectors.keySet()) + { + Selector selector = rightSelectors.get(selectorName); + if(answer.put(selectorName, selector) != null) + { + throw new DuplicateSelectorNameException("There is a duplicate selector name for "+selectorName); + } + } + return answer.get(name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.search.impl.querymodel.Source#getSelector() + */ + public String getSelector() + { + throw new UnsupportedOperationException(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseSelector.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseSelector.java index 697f3b2cc6..027769d0e8 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseSelector.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/BaseSelector.java @@ -87,4 +87,24 @@ public class BaseSelector implements Selector return answer; } + + public Selector getSelector(String name) + { + if(getAlias().equals(name)) + { + return this; + } + else + { + return null; + } + } + + /* (non-Javadoc) + * @see org.alfresco.repo.search.impl.querymodel.Source#getSelector() + */ + public String getSelector() + { + return getAlias(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Child.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Child.java index 5d061d52d2..d98f5a020b 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Child.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Child.java @@ -25,15 +25,19 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; /** * @author andyh @@ -43,16 +47,16 @@ public class Child extends BaseFunction public final static String NAME = "Child"; public final static String ARG_PARENT = "Parent"; - + public final static String ARG_SELECTOR = "Selector"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PARENT, DataTypeDefinition.TEXT, true)); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_SELECTOR, DataTypeDefinition.TEXT, false)); + args = new LinkedHashMap(); + args.put(ARG_PARENT, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PARENT, DataTypeDefinition.TEXT, true)); + args.put(ARG_SELECTOR, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_SELECTOR, DataTypeDefinition.TEXT, false)); } /** @@ -70,9 +74,23 @@ public class Child extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { - throw new UnsupportedOperationException(); + Argument selectorArgument = args.get(ARG_SELECTOR); + String selectorName = DefaultTypeConverter.INSTANCE.convert(String.class, selectorArgument.getValue()); + Argument parentArgument = args.get(ARG_PARENT); + NodeRef parent = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, parentArgument.getValue()); + + NodeRef child = context.getNodeRefs().get(selectorName); + + for (ChildAssociationRef car : context.getNodeService().getParentAssocs(child)) + { + if (car.getParentRef().equals(parent)) + { + return Boolean.TRUE; + } + } + return Boolean.FALSE; } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Descendant.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Descendant.java index 9b47c28323..e46b42d16e 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Descendant.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Descendant.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -46,13 +47,13 @@ public class Descendant extends BaseFunction public final static String ARG_SELECTOR = "Selector"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_ANCESTOR, DataTypeDefinition.TEXT, true)); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_SELECTOR, DataTypeDefinition.TEXT, false)); + args = new LinkedHashMap(); + args.put(ARG_ANCESTOR, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_ANCESTOR, DataTypeDefinition.TEXT, true)); + args.put(ARG_SELECTOR, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_SELECTOR, DataTypeDefinition.TEXT, false)); } /** @@ -70,7 +71,7 @@ public class Descendant extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Equals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Equals.java index 65a201317a..ef6fc5ec8a 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Equals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Equals.java @@ -25,9 +25,10 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.Set; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.impl.BaseComparison; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; @@ -52,7 +53,7 @@ public class Equals extends BaseComparison /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Exists.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Exists.java index 1fb3059ed5..4484d0b80a 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Exists.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Exists.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -46,13 +47,13 @@ public class Exists extends BaseFunction public final static String ARG_NOT = "Not"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_NOT, DataTypeDefinition.BOOLEAN, false)); + args = new LinkedHashMap(); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); + args.put(ARG_NOT, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_NOT, DataTypeDefinition.BOOLEAN, false)); } /** @@ -70,7 +71,7 @@ public class Exists extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSExactTerm.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSExactTerm.java index 43de269f9d..01b9d8e3e1 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSExactTerm.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSExactTerm.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -47,13 +48,13 @@ public class FTSExactTerm extends BaseFunction public final static String ARG_PROPERTY = "Property"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_TERM, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, false)); + args = new LinkedHashMap(); + args.put(ARG_TERM, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_TERM, DataTypeDefinition.ANY, true)); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, false)); } /** @@ -69,7 +70,7 @@ public class FTSExactTerm extends BaseFunction /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSPhrase.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSPhrase.java index 9437bff248..4f48fed06c 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSPhrase.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSPhrase.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -46,13 +47,13 @@ public class FTSPhrase extends BaseFunction public final static String ARG_PROPERTY = "Property"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PHRASE, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, false)); + args = new LinkedHashMap(); + args.put(ARG_PHRASE, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PHRASE, DataTypeDefinition.ANY, true)); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, false)); } /** @@ -70,7 +71,7 @@ public class FTSPhrase extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSTerm.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSTerm.java index 469af95a14..2ae63e6532 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSTerm.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/FTSTerm.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -47,13 +48,13 @@ public class FTSTerm extends BaseFunction public final static String ARG_PROPERTY = "Property"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_TERM, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, false)); + args = new LinkedHashMap(); + args.put(ARG_TERM, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_TERM, DataTypeDefinition.ANY, true)); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, false)); } /** @@ -69,7 +70,7 @@ public class FTSTerm extends BaseFunction /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThan.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThan.java index f3c56317d1..b46eb826b8 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThan.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThan.java @@ -25,9 +25,10 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.Set; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.impl.BaseComparison; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; @@ -52,7 +53,7 @@ public class GreaterThan extends BaseComparison /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThanOrEquals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThanOrEquals.java index 97d3bca1ef..1d00169948 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThanOrEquals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/GreaterThanOrEquals.java @@ -25,9 +25,10 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.Set; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.impl.BaseComparison; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; @@ -52,7 +53,7 @@ public class GreaterThanOrEquals extends BaseComparison /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/In.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/In.java index 18adcd10bf..5510cd44c1 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/In.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/In.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -51,15 +52,15 @@ public class In extends BaseFunction public final static String ARG_MODE = "Mode"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_MODE, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_PROPERTY, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_COLLECTION, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_NOT, DataTypeDefinition.ANY, false)); + args = new LinkedHashMap(); + args.put(ARG_MODE, new BaseArgumentDefinition(Multiplicity.ANY, ARG_MODE, DataTypeDefinition.ANY, true)); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.ANY, ARG_PROPERTY, DataTypeDefinition.ANY, true)); + args.put(ARG_COLLECTION, new BaseArgumentDefinition(Multiplicity.ANY, ARG_COLLECTION, DataTypeDefinition.ANY, true)); + args.put(ARG_NOT, new BaseArgumentDefinition(Multiplicity.ANY, ARG_NOT, DataTypeDefinition.ANY, false)); } /** @@ -75,7 +76,7 @@ public class In extends BaseFunction /* (non-Javadoc) * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThan.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThan.java index 280e664078..163a30df37 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThan.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThan.java @@ -25,20 +25,20 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.Set; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.impl.BaseComparison; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; /** * @author andyh - * */ public class LessThan extends BaseComparison { public final static String NAME = "LessThan"; - + /** * @param name * @param returnType @@ -46,13 +46,15 @@ public class LessThan extends BaseComparison */ public LessThan() { - super(NAME, DataTypeDefinition.BOOLEAN, args); + super(NAME, DataTypeDefinition.BOOLEAN, args); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThanOrEquals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThanOrEquals.java index 2c4ed5aaa4..26e3c1c413 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThanOrEquals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/LessThanOrEquals.java @@ -25,20 +25,20 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.Set; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.impl.BaseComparison; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; /** * @author andyh - * */ public class LessThanOrEquals extends BaseComparison { public final static String NAME = "LessThanOrEquals"; - + /** * @param name * @param returnType @@ -46,13 +46,15 @@ public class LessThanOrEquals extends BaseComparison */ public LessThanOrEquals() { - super(NAME, DataTypeDefinition.BOOLEAN, args); + super(NAME, DataTypeDefinition.BOOLEAN, args); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Like.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Like.java index fc7c669b25..545cd11e9e 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Like.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Like.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -37,28 +38,27 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition; /** * @author andyh - * */ public class Like extends BaseFunction { public final static String NAME = "Like"; - + public final static String ARG_PROPERTY = "Property"; - + public final static String ARG_EXP = "Exp"; - + public final static String ARG_NOT = "Not"; - - public static LinkedHashSet args; - - static + + public static LinkedHashMap args; + + static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_PROPERTY, DataTypeDefinition.ANY, true)); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_EXP, DataTypeDefinition.TEXT, true)); - args.add(new BaseArgumentDefinition(Multiplicity.ANY, ARG_NOT, DataTypeDefinition.BOOLEAN, false)); + args = new LinkedHashMap(); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.ANY, ARG_PROPERTY, DataTypeDefinition.ANY, true)); + args.put(ARG_EXP, new BaseArgumentDefinition(Multiplicity.ANY, ARG_EXP, DataTypeDefinition.TEXT, true)); + args.put(ARG_NOT, new BaseArgumentDefinition(Multiplicity.ANY, ARG_NOT, DataTypeDefinition.BOOLEAN, false)); } - + /** * @param name * @param returnType @@ -66,13 +66,15 @@ public class Like extends BaseFunction */ public Like() { - super(NAME, DataTypeDefinition.BOOLEAN, args); + super(NAME, DataTypeDefinition.BOOLEAN, args); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Lower.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Lower.java index 127eaab8ea..df27f3a65a 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Lower.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Lower.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -44,12 +45,12 @@ public class Lower extends BaseFunction public final static String ARG_PROPERTY = "Arg"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); + args = new LinkedHashMap(); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); } /** @@ -67,7 +68,7 @@ public class Lower extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/NotEquals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/NotEquals.java index 1658b45309..405f5bb684 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/NotEquals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/NotEquals.java @@ -25,20 +25,20 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.Set; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.impl.BaseComparison; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; /** * @author andyh - * */ public class NotEquals extends BaseComparison { public final static String NAME = "NotEquals"; - + /** * @param name * @param returnType @@ -46,13 +46,15 @@ public class NotEquals extends BaseComparison */ public NotEquals() { - super(NAME, DataTypeDefinition.BOOLEAN, args); + super(NAME, DataTypeDefinition.BOOLEAN, args); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/PropertyAccessor.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/PropertyAccessor.java index 5d26d2cac5..df9f3d3648 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/PropertyAccessor.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/PropertyAccessor.java @@ -25,15 +25,20 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; +import org.alfresco.repo.search.impl.querymodel.PropertyArgument; +import org.alfresco.repo.search.impl.querymodel.QueryModelException; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; /** * @author andyh @@ -44,12 +49,12 @@ public class PropertyAccessor extends BaseFunction public final static String ARG_PROPERTY = "Property"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); + args = new LinkedHashMap(); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); } /** @@ -67,9 +72,20 @@ public class PropertyAccessor extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { - throw new UnsupportedOperationException(); + Argument arg = args.get(ARG_PROPERTY); + if(!(arg instanceof PropertyArgument)) + { + throw new QueryModelException("Function "+NAME+" requires a property argument"); + } + PropertyArgument propertyArgument = (PropertyArgument)arg; + String selectorName = propertyArgument.getSelector(); + QName propertyQName = propertyArgument.getPropertyName(); + + NodeRef nodeRef = context.getNodeRefs().get(selectorName); + return context.getProperty(nodeRef, propertyQName); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Score.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Score.java index 119d0d6394..888d1721a0 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Score.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Score.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -44,12 +45,12 @@ public class Score extends BaseFunction public final static String ARG_QUALIFIER = "Qualifier"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_QUALIFIER, DataTypeDefinition.ANY, true)); + args = new LinkedHashMap(); + args.put(ARG_QUALIFIER, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_QUALIFIER, DataTypeDefinition.ANY, true)); } /** @@ -67,7 +68,7 @@ public class Score extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Upper.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Upper.java index fc86042c22..c572975cbb 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Upper.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/functions/Upper.java @@ -25,11 +25,12 @@ package org.alfresco.repo.search.impl.querymodel.impl.functions; import java.io.Serializable; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.LinkedHashMap; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition; +import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext; import org.alfresco.repo.search.impl.querymodel.Multiplicity; import org.alfresco.repo.search.impl.querymodel.impl.BaseArgumentDefinition; import org.alfresco.repo.search.impl.querymodel.impl.BaseFunction; @@ -44,12 +45,12 @@ public class Upper extends BaseFunction public final static String ARG_PROPERTY = "Property"; - public static LinkedHashSet args; + public static LinkedHashMap args; static { - args = new LinkedHashSet(); - args.add(new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); + args = new LinkedHashMap(); + args.put(ARG_PROPERTY, new BaseArgumentDefinition(Multiplicity.SINGLE_VALUED, ARG_PROPERTY, DataTypeDefinition.ANY, true)); } /** @@ -67,7 +68,7 @@ public class Upper extends BaseFunction * * @see org.alfresco.repo.search.impl.querymodel.Function#getValue(java.util.Set) */ - public Serializable getValue(Set args) + public Serializable getValue(Map args, FunctionEvaluationContext context) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneColumn.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneColumn.java index 9a5bec4677..565ee37bb5 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneColumn.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneColumn.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel.impl.lucene; -import java.util.List; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.Function; @@ -42,10 +42,9 @@ public class LuceneColumn extends BaseColumn * @param functionArguments * @param alias */ - public LuceneColumn(Function function, List functionArguments, String alias) + public LuceneColumn(Function function, Map functionArguments, String alias) { super(function, functionArguments, alias); - // TODO Auto-generated constructor stub } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionArgument.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionArgument.java index fe75c04ed1..dde22160bc 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionArgument.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionArgument.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel.impl.lucene; -import java.util.List; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.Function; @@ -42,7 +42,7 @@ public class LuceneFunctionArgument extends BaseFunctionArgument * @param function * @param arguments */ - public LuceneFunctionArgument(String name, Function function, List arguments) + public LuceneFunctionArgument(String name, Function function, Map arguments) { super(name, function, arguments); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionalConstraint.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionalConstraint.java index fa99bb534c..f69d78515f 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionalConstraint.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneFunctionalConstraint.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.search.impl.querymodel.impl.lucene; -import java.util.List; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.Function; @@ -41,7 +41,7 @@ public class LuceneFunctionalConstraint extends BaseFunctionalConstraint * @param function * @param arguments */ - public LuceneFunctionalConstraint(Function function, List arguments) + public LuceneFunctionalConstraint(Function function, Map arguments) { super(function, arguments); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQuery.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQuery.java index 12adefdd02..64c3335675 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQuery.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQuery.java @@ -29,13 +29,16 @@ import java.util.List; import org.alfresco.repo.search.impl.querymodel.Column; import org.alfresco.repo.search.impl.querymodel.Constraint; import org.alfresco.repo.search.impl.querymodel.Ordering; +import org.alfresco.repo.search.impl.querymodel.Selector; import org.alfresco.repo.search.impl.querymodel.Source; import org.alfresco.repo.search.impl.querymodel.impl.BaseQuery; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.apache.lucene.search.BooleanQuery; /** * @author andyh */ -public class LuceneQuery extends BaseQuery +public class LuceneQuery extends BaseQuery implements LuceneQueryBuilder { /** @@ -49,4 +52,32 @@ public class LuceneQuery extends BaseQuery super(columns, source, constraint, orderings); } + /* (non-Javadoc) + * @see org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneQueryBuilder#buildQuery() + */ + public BooleanQuery buildQuery(String selectorName, DictionaryService dictionaryService) + { + BooleanQuery luceneQuery = new BooleanQuery(); + BooleanQuery current = luceneQuery; + Selector selector = getSource().getSelector(selectorName); + if(selector != null) + { + if(selector instanceof LuceneQueryBuilderComponent) + { + LuceneQueryBuilderComponent LuceneQueryBuilderComponent = (LuceneQueryBuilderComponent)selector; + current = LuceneQueryBuilderComponent.addComponent(luceneQuery, current, dictionaryService); + return luceneQuery; + } + else + { + throw new UnsupportedOperationException(); + } + } + else + { + throw new UnsupportedOperationException(); + } + + } + } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryBuilder.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryBuilder.java new file mode 100644 index 0000000000..8140ba3940 --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryBuilder.java @@ -0,0 +1,36 @@ +/* + * 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.search.impl.querymodel.impl.lucene; + +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.apache.lucene.search.BooleanQuery; + +/** + * @author andyh + */ +public interface LuceneQueryBuilder +{ + public BooleanQuery buildQuery(String selectorName, DictionaryService dictionaryService); +} diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryBuilderComponent.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryBuilderComponent.java new file mode 100644 index 0000000000..57b726b4e1 --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryBuilderComponent.java @@ -0,0 +1,37 @@ +/* + * 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.search.impl.querymodel.impl.lucene; + +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.apache.lucene.search.BooleanQuery; + +/** + * @author andyh + * + */ +public interface LuceneQueryBuilderComponent +{ + public BooleanQuery addComponent(BooleanQuery base, BooleanQuery current, DictionaryService dictionaryService); +} diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryEngine.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryEngine.java new file mode 100644 index 0000000000..4ab25ca9c3 --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryEngine.java @@ -0,0 +1,140 @@ +/* + * 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.search.impl.querymodel.impl.lucene; + +import java.io.IOException; + +import org.alfresco.repo.search.impl.lucene.ClosingIndexSearcher; +import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcher; +import org.alfresco.repo.search.impl.lucene.LuceneResultSet; +import org.alfresco.repo.search.impl.lucene.LuceneSearcher; +import org.alfresco.repo.search.impl.querymodel.Query; +import org.alfresco.repo.search.impl.querymodel.QueryEngine; +import org.alfresco.repo.search.impl.querymodel.QueryModelFactory; +import org.alfresco.repo.search.impl.querymodel.QueryOptions; +import org.alfresco.repo.tenant.TenantService; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.LimitBy; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.search.SearchService; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Hits; + +/** + * @author andyh + */ +public class LuceneQueryEngine implements QueryEngine +{ + private DictionaryService dictionaryService; + + private LuceneIndexerAndSearcher indexAndSearcher; + + private NodeService nodeService; + + private TenantService tenantService; + + /** + * @param dictionaryService + * the dictionaryService to set + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * @param indexAndSearcher + * the indexAndSearcher to set + */ + public void setIndexAndSearcher(LuceneIndexerAndSearcher indexAndSearcher) + { + this.indexAndSearcher = indexAndSearcher; + } + + /** + * @param nodeService + * the nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param tenantService + * the tenantService to set + */ + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } + + public QueryModelFactory getQueryModelFactory() + { + return new LuceneQueryModelFactory(); + } + + public ResultSet executeQuery(Query query, String selectorName, QueryOptions options) throws IOException + { + StoreRef storeRef = options.getStores().get(0); + if (query instanceof LuceneQueryBuilder) + { + SearchService searchService = indexAndSearcher.getSearcher(storeRef, options.isIncludeInTransactionData()); + if (searchService instanceof LuceneSearcher) + { + LuceneSearcher luceneSearcher = (LuceneSearcher) searchService; + ClosingIndexSearcher searcher = luceneSearcher.getClosingIndexSearcher(); + LuceneQueryBuilder builder = (LuceneQueryBuilder) query; + BooleanQuery luceneQuery = builder.buildQuery(selectorName, dictionaryService); + System.out.println(luceneQuery); + SearchParameters sp = new SearchParameters(); + sp.setBulkFetch(options.getFetchSize() > 0); + sp.setBulkFetchSize(options.getFetchSize()); + if (options.getMaxItems() > 0) + { + sp.setLimit(options.getMaxItems() + options.getSkipCount()); + } + else + { + sp.setLimitBy(LimitBy.UNLIMITED); + } + Hits hits = searcher.search(luceneQuery); + return new LuceneResultSet(hits, searcher, nodeService, tenantService, null, sp, indexAndSearcher); + + } + else + { + throw new UnsupportedOperationException(); + } + } + else + { + throw new UnsupportedOperationException(); + } + } +} diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryModelFactory.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryModelFactory.java index cd5828363c..ae82d2598a 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryModelFactory.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneQueryModelFactory.java @@ -28,6 +28,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import org.alfresco.repo.search.impl.querymodel.Argument; import org.alfresco.repo.search.impl.querymodel.Column; @@ -90,9 +91,9 @@ import org.alfresco.service.namespace.QName; */ public class LuceneQueryModelFactory implements QueryModelFactory { - public static HashMap functions = new HashMap(); + public HashMap functions = new HashMap(); - static + public LuceneQueryModelFactory() { functions.put(Equals.NAME, new LuceneEquals()); functions.put(PropertyAccessor.NAME, new LucenePropertyAccessor()); @@ -109,14 +110,13 @@ public class LuceneQueryModelFactory implements QueryModelFactory functions.put(In.NAME, new LuceneIn()); functions.put(Like.NAME, new LuceneLike()); functions.put(Exists.NAME, new LuceneExists()); - + functions.put(Child.NAME, new LuceneChild()); functions.put(Descendant.NAME, new LuceneDescendant()); - + functions.put(FTSTerm.NAME, new LuceneFTSTerm()); functions.put(FTSExactTerm.NAME, new LuceneFTSExactTerm()); functions.put(FTSPhrase.NAME, new LuceneFTSPhrase()); - } @@ -126,7 +126,7 @@ public class LuceneQueryModelFactory implements QueryModelFactory * @see org.alfresco.repo.search.impl.querymodel.QueryModelFactory#createColumn(org.alfresco.repo.search.impl.querymodel.Function, * java.util.List, java.lang.String) */ - public Column createColumn(Function function, List functionArguments, String alias) + public Column createColumn(Function function, Map functionArguments, String alias) { return new LuceneColumn(function, functionArguments, alias); } @@ -157,7 +157,7 @@ public class LuceneQueryModelFactory implements QueryModelFactory * @see org.alfresco.repo.search.impl.querymodel.QueryModelFactory#createFunctionalConstraint(org.alfresco.repo.search.impl.querymodel.Function, * java.util.List) */ - public Constraint createFunctionalConstraint(Function function, List functionArguments) + public Constraint createFunctionalConstraint(Function function, Map functionArguments) { return new LuceneFunctionalConstraint(function, functionArguments); } @@ -280,18 +280,24 @@ public class LuceneQueryModelFactory implements QueryModelFactory return new LuceneSelectorArgument(name, selectorAlias); } - /* (non-Javadoc) - * @see org.alfresco.repo.search.impl.querymodel.QueryModelFactory#createListArgument(java.lang.String, java.util.ArrayList) + /* + * (non-Javadoc) + * + * @see org.alfresco.repo.search.impl.querymodel.QueryModelFactory#createListArgument(java.lang.String, + * java.util.ArrayList) */ public ListArgument createListArgument(String name, ArrayList arguments) { return new LuceneListArgument(name, arguments); } - /* (non-Javadoc) - * @see org.alfresco.repo.search.impl.querymodel.QueryModelFactory#createFunctionArgument(java.lang.String, org.alfresco.repo.search.impl.querymodel.Function, java.util.List) + /* + * (non-Javadoc) + * + * @see org.alfresco.repo.search.impl.querymodel.QueryModelFactory#createFunctionArgument(java.lang.String, + * org.alfresco.repo.search.impl.querymodel.Function, java.util.List) */ - public FunctionArgument createFunctionArgument(String name, Function function, List functionArguments) + public FunctionArgument createFunctionArgument(String name, Function function, Map functionArguments) { return new LuceneFunctionArgument(name, function, functionArguments); } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneSelector.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneSelector.java index a2f91d807b..f3b2fc1756 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneSelector.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/LuceneSelector.java @@ -24,14 +24,21 @@ */ package org.alfresco.repo.search.impl.querymodel.impl.lucene; +import java.util.Collection; + import org.alfresco.repo.search.impl.querymodel.impl.BaseSelector; +import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.namespace.QName; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.BooleanClause.Occur; /** * @author andyh * */ -public class LuceneSelector extends BaseSelector +public class LuceneSelector extends BaseSelector implements LuceneQueryBuilderComponent { /** @@ -43,4 +50,24 @@ public class LuceneSelector extends BaseSelector super(type, alias); } + /* (non-Javadoc) + * @see org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneQueryBuilderComponent#addComponent(org.apache.lucene.search.BooleanQuery, org.apache.lucene.search.BooleanQuery) + */ + public BooleanQuery addComponent(BooleanQuery base, BooleanQuery current, DictionaryService dictionaryService) + { + Collection subclasses = dictionaryService.getSubTypes(getType(), true); + BooleanQuery booleanQuery = new BooleanQuery(); + for (QName qname : subclasses) + { + TermQuery termQuery = new TermQuery(new Term("TYPE", qname.toString())); + if (termQuery != null) + { + booleanQuery.add(termQuery, Occur.SHOULD); + } + } + base.add(booleanQuery, Occur.MUST); + return current; + } + + } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneChild.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneChild.java index 632e1850a6..56401ee28b 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneChild.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneChild.java @@ -38,7 +38,7 @@ public class LuceneChild extends Child */ public LuceneChild() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneDescendant.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneDescendant.java index 76ed7513de..ba191154cd 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneDescendant.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneDescendant.java @@ -38,7 +38,7 @@ public class LuceneDescendant extends Descendant */ public LuceneDescendant() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneEquals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneEquals.java index 4595a2d5b8..7e1b73f2e3 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneEquals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneEquals.java @@ -32,5 +32,8 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.Equals; */ public class LuceneEquals extends Equals { - + public LuceneEquals() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneExists.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneExists.java index bf6af4e735..74502a7f25 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneExists.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneExists.java @@ -38,7 +38,7 @@ public class LuceneExists extends Exists */ public LuceneExists() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSExactTerm.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSExactTerm.java index f421931c21..5ee213debe 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSExactTerm.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSExactTerm.java @@ -33,5 +33,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.FTSExactTerm; public class LuceneFTSExactTerm extends FTSExactTerm { - + /** + * + */ + public LuceneFTSExactTerm() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSPhrase.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSPhrase.java index 120db76a6c..ce125aa377 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSPhrase.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSPhrase.java @@ -32,5 +32,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.FTSPhrase; */ public class LuceneFTSPhrase extends FTSPhrase { - + /** + * + */ + public LuceneFTSPhrase() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSTerm.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSTerm.java index c6de5ad5d7..67a25a72e2 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSTerm.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneFTSTerm.java @@ -32,5 +32,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.FTSTerm; */ public class LuceneFTSTerm extends FTSTerm { - + /** + * + */ + public LuceneFTSTerm() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThan.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThan.java index 0e40526377..483e3a1eea 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThan.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThan.java @@ -38,7 +38,7 @@ public class LuceneGreaterThan extends GreaterThan */ public LuceneGreaterThan() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThanOrEquals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThanOrEquals.java index 173be7d364..eb02205fd3 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThanOrEquals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneGreaterThanOrEquals.java @@ -38,7 +38,7 @@ public class LuceneGreaterThanOrEquals extends GreaterThanOrEquals */ public LuceneGreaterThanOrEquals() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneIn.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneIn.java index 919946c09c..37138ca1dd 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneIn.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneIn.java @@ -32,5 +32,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.In; */ public class LuceneIn extends In { - + /** + * + */ + public LuceneIn() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThan.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThan.java index a725eb6796..e8dbd1b60b 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThan.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThan.java @@ -38,7 +38,7 @@ public class LuceneLessThan extends LessThan */ public LuceneLessThan() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThanOrEquals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThanOrEquals.java index 251c1e1f64..89bb2b8bad 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThanOrEquals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLessThanOrEquals.java @@ -38,7 +38,7 @@ public class LuceneLessThanOrEquals extends LessThanOrEquals */ public LuceneLessThanOrEquals() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLike.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLike.java index 45d731d4d8..0b93d6b62c 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLike.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLike.java @@ -38,7 +38,7 @@ public class LuceneLike extends Like */ public LuceneLike() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLower.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLower.java index f8ab946efd..c7a590e0e9 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLower.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneLower.java @@ -33,5 +33,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.Lower; public class LuceneLower extends Lower { - + /** + * + */ + public LuceneLower() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneNotEquals.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneNotEquals.java index 8eaf5350df..b50d8442b0 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneNotEquals.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneNotEquals.java @@ -38,7 +38,7 @@ public class LuceneNotEquals extends NotEquals */ public LuceneNotEquals() { - // TODO Auto-generated constructor stub + super(); } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LucenePropertyAccessor.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LucenePropertyAccessor.java index 87b9273f6b..18b4e120a8 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LucenePropertyAccessor.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LucenePropertyAccessor.java @@ -31,5 +31,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.PropertyAccessor; */ public class LucenePropertyAccessor extends PropertyAccessor { - + /** + * + */ + public LucenePropertyAccessor() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneScore.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneScore.java index 52a4d8cfa6..09c0c56328 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneScore.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneScore.java @@ -33,5 +33,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.Score; public class LuceneScore extends Score { - + /** + * + */ + public LuceneScore() + { + super(); + } } diff --git a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneUpper.java b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneUpper.java index 20c728eb58..e92cbc7b5b 100644 --- a/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneUpper.java +++ b/source/java/org/alfresco/repo/search/impl/querymodel/impl/lucene/functions/LuceneUpper.java @@ -32,5 +32,11 @@ import org.alfresco.repo.search.impl.querymodel.impl.functions.Upper; */ public class LuceneUpper extends Upper { - + /** + * + */ + public LuceneUpper() + { + super(); + } } diff --git a/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java b/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java index 16ebe35b82..4cbd9c9224 100644 --- a/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java +++ b/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java @@ -97,7 +97,7 @@ public interface DictionaryService /** * @param type - * @param follow true => follow up the super-class hierarchy, false => immediate sub types only + * @param follow true => all sub-type descendants, false => immediate sub-type children * @return the sub types of specified type */ @NotAuditable