chemistry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fguilla...@apache.org
Subject svn commit: r980513 [2/15] - in /incubator/chemistry/opencmis/trunk/chemistry-opencmis-server: chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/dummy/ chemistry-opencmis-server-bindings/src/main/java/org/apache...
Date Thu, 29 Jul 2010 17:13:30 GMT
Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/query/InMemoryQueryProcessor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/query/InMemoryQueryProcessor.java?rev=980513&r1=980512&r2=980513&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/query/InMemoryQueryProcessor.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/query/InMemoryQueryProcessor.java Thu Jul 29 17:13:28 2010
@@ -1,862 +1,862 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.chemistry.opencmis.inmemory.query;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import org.antlr.runtime.RecognitionException;
-import org.antlr.runtime.tree.Tree;
-import org.apache.chemistry.opencmis.commons.data.ObjectData;
-import org.apache.chemistry.opencmis.commons.data.ObjectList;
-import org.apache.chemistry.opencmis.commons.data.PropertyData;
-import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
-import org.apache.chemistry.opencmis.commons.enums.Cardinality;
-import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
-import org.apache.chemistry.opencmis.commons.enums.PropertyType;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.DocumentVersion;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.Filing;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.Folder;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.ObjectStore;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoredObject;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.VersionedDocument;
-import org.apache.chemistry.opencmis.inmemory.storedobj.impl.ObjectStoreImpl;
-import org.apache.chemistry.opencmis.inmemory.types.PropertyCreationHelper;
-import org.apache.chemistry.opencmis.server.support.TypeManager;
-import org.apache.chemistry.opencmis.server.support.query.AbstractQueryConditionProcessor;
-import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictLexer;
-import org.apache.chemistry.opencmis.server.support.query.CmisQueryWalker;
-import org.apache.chemistry.opencmis.server.support.query.CmisSelector;
-import org.apache.chemistry.opencmis.server.support.query.ColumnReference;
-import org.apache.chemistry.opencmis.server.support.query.FunctionReference;
-import org.apache.chemistry.opencmis.server.support.query.QueryObject;
-import org.apache.chemistry.opencmis.server.support.query.QueryObject.SortSpec;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A processor for a CMIS query for the In-Memory server. During tree traversal conditions
- * are checked against the data contained in the central hash map with all objects. In a first 
- * pass one time setup is performed, in a custom walk across the query expression tree an object
- * is checked if it matches. In case of a match it is appended to a list of matching objects.
- * 
- * @author Jens
- *
- */
-public class InMemoryQueryProcessor extends AbstractQueryConditionProcessor {
-
-    private static Log LOG = LogFactory.getLog(InMemoryQueryProcessor.class);
-    
-    private List<StoredObject> matches = new ArrayList<StoredObject>();
-    private QueryObject queryObj;
-    private Tree whereTree;
-    
-    public InMemoryQueryProcessor() {
-    }
-    
-    /**
-     * Main entry function to process a query from discovery service
-     */
-    public ObjectList query(TypeManager tm, ObjectStore objectStore, String user, String repositoryId, String statement, Boolean searchAllVersions,
-            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
-            BigInteger maxItems, BigInteger skipCount) {
-
-        queryObj = new QueryObject(tm, this);
-        processQueryAndCatchExc(statement); // calls query processor
-
-        // iterate over all the objects and check for each if the query matches
-        for (String objectId : ((ObjectStoreImpl) objectStore).getIds()) {
-            StoredObject so = objectStore.getObjectById(objectId);
-            match(so, searchAllVersions==null ? true : searchAllVersions.booleanValue());
-        }
-
-        ObjectList objList = buildResultList(tm, user, includeAllowableActions, includeRelationships, renditionFilter,
-                maxItems, skipCount);
-        LOG.debug("Query result, number of matching objects: " + objList.getNumItems());
-        return objList;
-    }        
-
-    public CmisQueryWalker processQuery(String statement) throws UnsupportedEncodingException, IOException, RecognitionException {
-        CmisQueryWalker walker = AbstractQueryConditionProcessor.getWalker(statement);
-        walker.query(queryObj);
-        String errMsg = walker.getErrorMessageString();
-        if (null != errMsg) {
-            throw new RuntimeException("Walking of statement failed with error: \n   " + errMsg + 
-                    "\n   Statement was: " + statement);
-        }
-        /*CommonTree walkerTree = (CommonTree) */ walker.getTreeNodeStream().getTreeSource();
-        return walker;
-    }
-
-    public CmisQueryWalker processQueryAndCatchExc(String statement) {
-        try {
-            return processQuery(statement);
-        } catch (RecognitionException e) {
-            throw new RuntimeException("Walking of statement failed with RecognitionException error: \n   " + e); 
-        } catch (Exception e) {
-            throw new RuntimeException("Walking of statement failed with other exception: \n   " + e); 
-        }
-    }
-    
-    public void onStartProcessing(Tree node) {
-        // log.debug("onStartProcessing()");
-        // checkRoot(node);
-        whereTree = node;
-    }
-
-    public void onStopProcessing() {
-        // log.debug("onStopProcessing()");
-    }
-
-    public ObjectList buildResultList(TypeManager tm, String user, 
-            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
-            BigInteger maxItems, BigInteger skipCount) {
-        
-        sortMatches();
-
-        ObjectListImpl res = new ObjectListImpl();
-        res.setNumItems(BigInteger.valueOf(matches.size()));
-        int start = 0;
-        if (skipCount != null) 
-            start = (int)skipCount.longValue();
-        if (start < 0)
-            start = 0;
-        if (start > matches.size())
-            start = matches.size();
-        int stop = 0;
-        if (maxItems != null) 
-            stop = start + (int)maxItems.longValue();
-        if (stop <= 0 || stop > matches.size())
-            stop = matches.size();
-        res.setHasMoreItems(stop < matches.size());
-        if (start > 0 || stop > 0)
-            matches = matches.subList(start, stop);
-        List<ObjectData> objDataList = new ArrayList<ObjectData>();
-        Map<String, String> props = queryObj.getRequestedProperties();
-        Map<String, String> funcs = queryObj.getRequestedFuncs();
-        for (StoredObject so : matches) {
-            TypeDefinition td = tm.getTypeById(so.getTypeId()).getTypeDefinition();
-            ObjectData od = PropertyCreationHelper.getObjectDataQueryResult(td, so, user, 
-                    props, funcs, includeAllowableActions, includeRelationships, renditionFilter);
-            
-            objDataList.add(od); 
-        }
-        res.setObjects(objDataList);
-        return res;
-    }
-    
-    private boolean typeMatches(TypeDefinition td, StoredObject so) {
-        String typeId = so.getTypeId();
-        while (typeId != null) {
-            if (typeId.equals(td.getId())) {
-                return true;
-            }
-            // check parent type
-            TypeDefinition parentTD = queryObj.getParentType(typeId);
-            typeId = parentTD == null ? null : parentTD.getId();
-        }
-        return false;
-    }
-    
-    private void sortMatches() {
-        final List<SortSpec> orderBy = queryObj.getOrderBys();
-        if (orderBy.size() > 1)
-            LOG.warn("ORDER BY has more than one sort criterium, all but the first are ignored.");
-        class ResultComparator implements Comparator<StoredObject> {
-
-            @SuppressWarnings("unchecked")
-            public int compare(StoredObject so1, StoredObject so2) {
-                SortSpec s = orderBy.get(0);
-                CmisSelector sel = s.getSelector();
-                int result;
-                
-                if (sel instanceof ColumnReference) {
-                    String propId = ((ColumnReference)sel).getPropertyId();
-                    Object propVal1 = so1.getProperties().get(propId).getFirstValue();
-                    Object propVal2 = so2.getProperties().get(propId).getFirstValue();
-                    if (propVal1 == null && propVal2 == null)
-                        result = 0;
-                    else if (propVal1 == null)
-                        result = -1;
-                    else if (propVal2 == null)
-                        result = 1;
-                    else 
-                        result = ((Comparable)propVal1).compareTo(propVal2);                    
-                } else {
-                    String funcName = ((FunctionReference)sel).getName();
-                    // evaluate function here, currently ignore
-                    result = 0;
-                }
-                if (!s.isAscending())
-                    result = -result;
-                return result;
-            }
-        }
-
-        if (orderBy.size() > 0)
-            Collections.sort(matches, new ResultComparator());
-        
-    }
-
-    /**
-     * Check for each object contained in the in-memory repository if it matches the current query
-     * expression. If yes add it to the list of matched objects.
-     * 
-     * @param so
-     *      object stored in the in-memory repository
-     */
-    private void match(StoredObject so, boolean searchAllVersions) {
-        // log.debug("checkMatch() for object: " + so.getId());
-        // first check if type is matching...
-        String queryName = queryObj.getTypes().values().iterator().next(); // as we don't support JOINS take first type
-        TypeDefinition td = queryObj.getTypeDefinitionFromQueryName(queryName);
-        boolean skip = so instanceof VersionedDocument; // we are only interested in versions not in the series
-        boolean typeMatches = typeMatches(td, so);
-        if (!searchAllVersions && so instanceof DocumentVersion && ((DocumentVersion)so).getParentDocument().getLatestVersion(false) != so)
-            skip = true;
-        // ... then check expression...
-        if (typeMatches && !skip)
-            evalWhereTree(whereTree, so);        
-    }
-    
-    private void evalWhereTree(Tree node, StoredObject so) {
-        boolean match=true;
-        if (null != node)
-            match = evalWhereNode(so, node.getChild(0));
-        if (match)
-            matches.add(so); // add to list
-    }
-
-    // Standard expression evaluator for single pass walking. This is used as first
-    // pass walk in this object for one-time setup tasks (e.g. setup maps)
-    public void onEquals(Tree eqNode, Tree leftNode, Tree rightNode) {
-        
-    }
-    
-    public void onNotEquals(Tree neNode, Tree leftNode, Tree rightNode) {
-        
-    }
-    
-    public void onGreaterThan(Tree gtNode, Tree leftNode, Tree rightNode) {
-        
-    }
-    
-    public void onGreaterOrEquals(Tree geNode, Tree leftNode, Tree rightNode) {
-        
-    }
-    
-    public void onLessThan(Tree ltNode, Tree leftNode, Tree rightNode) {
-        
-    }
-    
-    public void onLessOrEquals(Tree leqNode, Tree leftNode, Tree rightNode) { 
-        
-    }
-
-    // Boolean operators
-    public void onNot(Tree opNode, Tree leftNode) {
-        
-    }
-    
-    public void onAnd(Tree opNode, Tree leftNode, Tree rightNode) {
-        
-    }
-    
-    public void onOr(Tree opNode, Tree leftNode, Tree rightNode) {
-        
-    }
-
-    // Multi-value:
-    public void onIn(Tree node, Tree colNode, Tree listNode) {
-        
-    }
-    
-    public void onNotIn(Tree nod, Tree colNode, Tree listNode) {
-        
-    }
-    
-    public void onNotInList(Tree node) {
-        
-    }
-    
-    public void onInAny(Tree node, Tree colNode, Tree listNode) {
-        
-    }
-    
-    public void onNotInAny(Tree node, Tree colNode, Tree listNode) {
-        
-    }
-    
-    public void onEqAny(Tree node, Tree literalNode, Tree colNode) {
-        
-    }
-
-    // Null comparisons:
-    public void onIsNull(Tree nullNode, Tree colNode) {
-        
-    }
-    
-    public void onIsNotNull(Tree notNullNode, Tree colNode) {
-        
-    }
-
-    // String matching:
-    public void onIsLike(Tree node, Tree colNode, Tree stringNode) {
-        
-    }
-    
-    public void onIsNotLike(Tree node, Tree colNode, Tree stringNode) {
-        
-    }
-
-    // Functions:
-    public void onContains(Tree node, Tree colNode, Tree paramNode) {
-        
-    }
-    
-    public void onInFolder(Tree node, Tree colNode, Tree paramNode) {
-        
-    }
-    
-    public void onInTree(Tree node, Tree colNode, Tree paramNode) {
-        
-    }
-    public void onScore(Tree node, Tree paramNode) { 
-        
-    }
-
-    /**
-     * For each object check if it matches and append it to match-list if it does.
-     * We do here our own walking mechanism so that we can pass additional parameters
-     * and define the return types.
-     *   
-     * @param node
-     *      node in where clause
-     * @return
-     *      true if it matches, false if it not matches
-     */
-    boolean evalWhereNode(StoredObject so, Tree node) {
-        boolean matches = true;
-
-        switch (node.getType()) {
-        case CmisQlStrictLexer.WHERE:
-            matches = evalWhereNode(so, node.getChild(0));
-            break; // ignore
-        case CmisQlStrictLexer.EQ:
-            matches = evalWhereEquals(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.NEQ:
-            matches = evalWhereNotEquals(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.GT:
-            matches = evalWhereGreaterThan(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.GTEQ:
-            matches = evalWhereGreaterOrEquals(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.LT:
-            matches = evalWhereLessThan(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.LTEQ:
-            matches = evalWhereLessOrEquals(so, node, node.getChild(0), node.getChild(1));
-            break;
-
-        case CmisQlStrictLexer.NOT:
-            matches = evalWhereNot(so, node, node.getChild(0));
-            break;
-        case CmisQlStrictLexer.AND:
-            matches = evalWhereAnd(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.OR:
-            matches = evalWhereOr(so, node, node.getChild(0), node.getChild(1));
-            break;
-
-        // Multi-value:
-        case CmisQlStrictLexer.IN:
-            matches = evalWhereIn(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.NOT_IN:
-            matches = evalWhereNotIn(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.IN_ANY:
-            matches = evalWhereInAny(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.NOT_IN_ANY:
-            matches = evalWhereNotInAny(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.EQ_ANY:
-            matches = evalWhereEqAny(so, node, node.getChild(0), node.getChild(1));
-            break;
-
-        // Null comparisons:
-        case CmisQlStrictLexer.IS_NULL:
-            matches = evalWhereIsNull(so, node, node.getChild(0));
-            break;
-        case CmisQlStrictLexer.IS_NOT_NULL:
-            matches = evalWhereIsNotNull(so, node, node.getChild(0));
-            break;
-
-        // String matching
-        case CmisQlStrictLexer.LIKE:
-            matches = evalWhereIsLike(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.NOT_LIKE:
-            matches = evalWhereIsNotLike(so, node, node.getChild(0), node.getChild(1));
-            break;
-
-        // Functions
-        case CmisQlStrictLexer.CONTAINS:
-            if (node.getChildCount() == 1)
-                matches = evalWhereContains(so, node, null, node.getChild(0));
-            else
-                matches = evalWhereContains(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.IN_FOLDER:
-            if (node.getChildCount() == 1)
-                matches = evalWhereInFolder(so, node, null, node.getChild(0));
-            else
-                matches = evalWhereInFolder(so, node, node.getChild(0), node.getChild(1));
-            break;
-        case CmisQlStrictLexer.IN_TREE:
-            if (node.getChildCount() == 1)
-                matches = evalWhereInTree(so, node, null, node.getChild(0));
-            else
-                matches = evalWhereInTree(so, node, node.getChild(0), node.getChild(1));
-            break;
-
-        default:
-            // do nothing;
-        }
-
-        return matches;
-    }
-
-    private boolean evalWhereEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        Integer cmp = compareTo(so, leftChild, rightChild);
-        if (null == cmp)
-            return false; // property is not set
-        else
-            return cmp == 0;
-    }
-
-    private boolean evalWhereNotEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        Integer cmp = compareTo(so, leftChild, rightChild);
-        if (null == cmp)
-            return false; // property is not set
-        else
-            return cmp != 0;
-    }
-
-    private boolean evalWhereGreaterThan(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        Integer cmp = compareTo(so, leftChild, rightChild);
-        if (null == cmp)
-            return false; // property is not set
-        else
-            return cmp > 0;
-    }
-
-    private boolean evalWhereGreaterOrEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        Integer cmp = compareTo(so, leftChild, rightChild);
-        if (null == cmp)
-            return false; // property is not set
-        else
-            return cmp >= 0;
-    }
-
-    private boolean evalWhereLessThan(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        Integer cmp = compareTo(so, leftChild, rightChild);
-        if (null == cmp)
-            return false; // property is not set
-        else
-            return cmp < 0;
-    }
-
-    private boolean evalWhereLessOrEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        Integer cmp = compareTo(so, leftChild, rightChild);
-        if (null == cmp)
-            return false; // property is not set
-        else
-            return cmp <= 0;
-    }
-
-    private boolean evalWhereNot(StoredObject so, Tree node, Tree child) {
-        boolean matches = evalWhereNode(so, child);
-        return !matches;
-    }
-
-    private boolean evalWhereAnd(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        boolean matches1 = evalWhereNode(so, leftChild);
-        boolean matches2 = evalWhereNode(so, rightChild);        
-        return matches1 && matches2;
-    }
-
-    private boolean evalWhereOr(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
-        boolean matches1 = evalWhereNode(so, leftChild);
-        boolean matches2 = evalWhereNode(so, rightChild);        
-        return matches1 || matches2;
-    }
-
-    private boolean evalWhereIn(StoredObject so, Tree node, Tree colNode, Tree listNode) {
-        ColumnReference colRef = getColumnReference(colNode);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
-        List<Object> literals = onLiteralList(listNode);
-        if (pd.getCardinality() != Cardinality.SINGLE)
-            throw new RuntimeException("Operator IN only is allowed on single-value properties ");
-        else if (lVal == null)
-            return false;
-        else {
-            Object prop= lVal.getFirstValue();
-            if (literals.contains(prop))
-                return true;
-            else
-                return false;
-        }
-    }
-
-    private boolean evalWhereNotIn(StoredObject so, Tree node, Tree colNode, Tree listNode) {
-        // Note just return !evalWhereIn(so, node, colNode, listNode) is wrong, because
-        // then it evaluates to true for null values (not set properties).
-        ColumnReference colRef = getColumnReference(colNode);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
-        List<Object> literals = onLiteralList(listNode);
-        if (pd.getCardinality() != Cardinality.SINGLE)
-            throw new RuntimeException("Operator IN only is allowed on single-value properties ");
-        else if (lVal == null)
-            return false;
-        else {
-            Object prop= lVal.getFirstValue();
-            if (literals.contains(prop))
-                return false;
-            else
-                return true;
-        }
-    }
-
-    private boolean evalWhereInAny(StoredObject so, Tree node, Tree colNode, Tree listNode) {
-        ColumnReference colRef = getColumnReference(colNode);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
-        List<Object> literals = onLiteralList(listNode);
-        if (pd.getCardinality() != Cardinality.MULTI)
-            throw new RuntimeException("Operator ANY...IN only is allowed on multi-value properties ");
-        else if (lVal == null)
-            return false;
-        else {
-            List<?> props= lVal.getValues();
-            for (Object prop : props) {
-                LOG.debug("comparing with: " + prop);
-                if (literals.contains(prop))
-                    return true;
-            }
-            return false;
-        }
-    }
-
-    private boolean evalWhereNotInAny(StoredObject so, Tree node, Tree colNode, Tree listNode) {
-        // Note just return !evalWhereInAny(so, node, colNode, listNode) is wrong, because
-        // then it evaluates to true for null values (not set properties).
-        ColumnReference colRef = getColumnReference(colNode);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
-        List<Object> literals = onLiteralList(listNode);
-        if (pd.getCardinality() != Cardinality.MULTI)
-            throw new RuntimeException("Operator ANY...IN only is allowed on multi-value properties ");
-        else if (lVal == null)
-            return false;
-        else {
-            List<?> props= lVal.getValues();
-            for (Object prop : props) {
-                LOG.debug("comparing with: " + prop);
-                if (literals.contains(prop))
-                    return false;
-            }
-            return true;
-        }    
-    }
-
-    private boolean evalWhereEqAny(StoredObject so, Tree node, Tree literalNode, Tree colNode) {
-        ColumnReference colRef = getColumnReference(colNode);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
-        Object literal = onLiteral(literalNode);
-        if (pd.getCardinality() != Cardinality.MULTI)
-            throw new RuntimeException("Operator = ANY only is allowed on multi-value properties ");
-        else if (lVal == null)
-            return false;
-        else {
-            List<?> props= lVal.getValues();
-            if (props.contains(literal))
-                return true;
-            else
-                return false;
-        }
-    }
-
-    private boolean evalWhereIsNull(StoredObject so, Tree node, Tree child) {
-       Object propVal = getPropertyValue(child, so);
-       return null == propVal;
-    }
-
-    private boolean evalWhereIsNotNull(StoredObject so, Tree node, Tree child) {
-        Object propVal = getPropertyValue(child, so);
-        return null != propVal;
-    }
-
-    private boolean evalWhereIsLike(StoredObject so, Tree node, Tree colNode, Tree StringNode) {
-        Object rVal = onLiteral(StringNode);
-        if (!(rVal instanceof String))
-                throw new RuntimeException("LIKE operator requires String literal on right hand side.");
-        
-        ColumnReference colRef = getColumnReference(colNode);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyType propType = pd.getPropertyType();
-        if (propType != PropertyType.STRING && propType != PropertyType.HTML &&  propType != PropertyType.ID &&
-                propType != PropertyType.URI)
-            throw new RuntimeException("Property type "+ propType.value() + " is not allowed FOR LIKE");
-        if (pd.getCardinality() != Cardinality.SINGLE)
-            throw new RuntimeException("LIKE is not allowed for multi-value properties ");
-        
-        String propVal = (String) so.getProperties().get(colRef.getPropertyId()).getFirstValue();
-        String pattern = translatePattern((String) rVal); // SQL to Java regex syntax
-        Pattern p = Pattern.compile(pattern);
-        return p.matcher(propVal).matches();
-    }
-
-    private boolean evalWhereIsNotLike(StoredObject so, Tree node, Tree colNode, Tree stringNode) {
-        return ! evalWhereIsLike(so, node, colNode, stringNode);
-    }
-
-    private boolean evalWhereContains(StoredObject so, Tree node, Tree colNode, Tree paramNode) {
-        throw new RuntimeException("Operator CONTAINS not supported in InMemory server.");
-    }
-
-    private boolean evalWhereInFolder(StoredObject so, Tree node, Tree colNode, Tree paramNode) {
-        if (null != colNode) {
-            getTableReference(colNode); 
-            // just for error checking we do not evaluate this, there is only one from without join support
-        }
-        Object lit = onLiteral(paramNode);
-        if (!(lit instanceof String))
-            throw new RuntimeException("Folder id in IN_FOLDER must be of type String");
-        String folderId = (String) lit;
-        
-        // check if object is in folder
-        if (so instanceof Filing)
-            return hasParent((Filing)so, folderId);
-        else
-            return false;
-    }
-
-    private boolean evalWhereInTree(StoredObject so, Tree node, Tree colNode, Tree paramNode) {
-        if (null != colNode) {
-            getTableReference(colNode); 
-            // just for error checking we do not evaluate this, there is only one from without join support
-        }
-        Object lit = onLiteral(paramNode);
-        if (!(lit instanceof String))
-            throw new RuntimeException("Folder id in IN_FOLDER must be of type String");
-        String folderId = (String) lit;
-        
-        // check if object is in folder
-        if (so instanceof Filing)
-            return hasAncestor((Filing) so, folderId);
-        else
-            return false;
-    }
-    
-    private boolean hasParent(Filing objInFolder, String folderId) {
-        List<Folder> parents = objInFolder.getParents();
-        
-        for (Folder folder : parents)
-            if (folderId.equals(folder.getId()))
-                return true;
-        return false;
-    }
-
-    private boolean hasAncestor(Filing objInFolder, String folderId) {
-        List<Folder> parents = objInFolder.getParents();
-        
-        for (Folder folder : parents)
-            if (folderId.equals(folder.getId()))
-                return true;
-        for (Folder folder : parents)
-            if (hasAncestor(folder, folderId))
-                return true;
-        return false;
-    }
-
-    private Integer compareTo(StoredObject so, Tree leftChild, Tree rightChild) {
-        Object rVal = onLiteral(rightChild);
-        
-        //log.debug("retrieve node from where: " + System.identityHashCode(leftChild) + " is " + leftChild);
-        ColumnReference colRef = getColumnReference(leftChild);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
-        if (lVal instanceof List<?>)
-            throw new RuntimeException("You can't query operators <, <=, ==, !=, >=, > on multi-value properties ");
-        else
-            return compareTo(pd, lVal, rVal);
-    }
-    
-    private int compareTo(PropertyDefinition<?> td, PropertyData<?> lVal, Object rVal) {
-        Object lValue = lVal.getFirstValue();
-        switch (td.getPropertyType()) {
-        case BOOLEAN:
-            if (rVal instanceof Boolean)
-                return ((Boolean)lValue).compareTo((Boolean)rVal);
-            else 
-                throwIncompatibleTypesException(lValue, rVal);
-            break;
-        case INTEGER: 
-        { 
-            Long lLongValue = ((BigInteger)lVal.getFirstValue()).longValue();
-            if (rVal instanceof Long)
-                return (lLongValue).compareTo((Long)rVal);
-            else if (rVal instanceof Double)
-                return Double.valueOf(((Integer)lValue).doubleValue()).compareTo((Double)rVal);
-            else 
-                throwIncompatibleTypesException(lValue, rVal);
-            break;
-        }
-        case DATETIME:
-            if (rVal instanceof GregorianCalendar) {
-                // LOG.debug("left:" + CalendarHelper.toString((GregorianCalendar)lValue) + " right: " + CalendarHelper.toString((GregorianCalendar)rVal));
-                return ((GregorianCalendar)lValue).compareTo((GregorianCalendar)rVal);
-            } else 
-                throwIncompatibleTypesException(lValue, rVal);
-            break;
-        case DECIMAL:
-        { 
-            Double lDoubleValue = ((BigDecimal)lVal.getFirstValue()).doubleValue();
-            if (rVal instanceof Double)
-                return lDoubleValue.compareTo((Double)rVal);
-            else if (rVal instanceof Long)
-                return Double.valueOf(((Integer)lValue).doubleValue()).compareTo((Double)rVal);
-            else 
-                throwIncompatibleTypesException(lValue, rVal);
-            break;
-        }
-        case HTML:
-        case STRING:
-        case URI:   
-        case ID: 
-            if (rVal instanceof String) {
-                LOG.debug("compare strings: " + lValue + " with " + rVal);
-                return ((String)lValue).compareTo((String)rVal);
-            } else 
-                throwIncompatibleTypesException(lValue, rVal);
-            break;
-        }
-        return 0;
-    }
-    
-    private ColumnReference getColumnReference(Tree columnNode) {
-        CmisSelector sel = queryObj.getColumnReference(columnNode.getTokenStartIndex());
-        if (null == sel)
-            throw new RuntimeException("Unknown property query name " + columnNode.getChild(0));
-        else if (sel instanceof ColumnReference)
-            return (ColumnReference) sel;
-        else
-            throw new RuntimeException("Unexpected numerical value function in where clause");
-    }
-    
-    private String getTableReference(Tree tableNode) {
-        String typeQueryName = queryObj.getTypeQueryName(tableNode.getText());
-        if (null == typeQueryName)
-            throw new RuntimeException("Inavlid type in IN_FOLDER() or IN_TREE(), must be in FROM list: " + tableNode.getText());
-        return typeQueryName;
-    }
-
-    private Object getPropertyValue(Tree columnNode, StoredObject so) {
-        ColumnReference colRef = getColumnReference(columnNode);
-        TypeDefinition td = colRef.getTypeDefinition();
-        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
-        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
-        if (null == lVal)
-            return null;
-        else {
-            if (pd.getCardinality() == Cardinality.SINGLE)
-                return null == lVal ? null : lVal.getFirstValue();
-            else
-                return lVal.getValues();
-        }                
-    }
-    
-    // translate SQL wildcards %, _ to Java regex syntax
-    public static String translatePattern(String wildcardString) {
-        int index = 0;
-        int start = 0;
-        StringBuffer res = new StringBuffer();
-        
-        while (index >= 0) {
-            index = wildcardString.indexOf('%', start);
-            if (index < 0) 
-                res.append(wildcardString.substring(start));
-            else if (index == 0 || index > 0 && wildcardString.charAt(index-1) != '\\') {
-                res.append(wildcardString.substring(start, index));
-                res.append(".*");
-            } else 
-                res.append(wildcardString.substring(start, index+1));
-            start = index+1;
-        }
-        wildcardString = res.toString();
-        
-        index = 0;
-        start = 0;
-        res = new StringBuffer();
-        
-        while (index >= 0) {
-            index = wildcardString.indexOf('_', start);
-            if (index < 0) 
-                res.append(wildcardString.substring(start));
-            else if (index == 0 || index > 0 && wildcardString.charAt(index-1) != '\\') {
-                res.append(wildcardString.substring(start, index));
-                res.append(".");
-            } else 
-                res.append(wildcardString.substring(start, index+1));
-            start = index+1;
-        }
-        return res.toString();
-    }
-    
-    private void throwIncompatibleTypesException(Object o1, Object o2) {
-        throw new RuntimeException("Incompatible Types to compare: " + o1 + " and " + o2);
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.inmemory.query;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.tree.Tree;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.data.ObjectList;
+import org.apache.chemistry.opencmis.commons.data.PropertyData;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.enums.Cardinality;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.enums.PropertyType;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.DocumentVersion;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.Filing;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.Folder;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.ObjectStore;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoredObject;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.VersionedDocument;
+import org.apache.chemistry.opencmis.inmemory.storedobj.impl.ObjectStoreImpl;
+import org.apache.chemistry.opencmis.inmemory.types.PropertyCreationHelper;
+import org.apache.chemistry.opencmis.server.support.TypeManager;
+import org.apache.chemistry.opencmis.server.support.query.AbstractQueryConditionProcessor;
+import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictLexer;
+import org.apache.chemistry.opencmis.server.support.query.CmisQueryWalker;
+import org.apache.chemistry.opencmis.server.support.query.CmisSelector;
+import org.apache.chemistry.opencmis.server.support.query.ColumnReference;
+import org.apache.chemistry.opencmis.server.support.query.FunctionReference;
+import org.apache.chemistry.opencmis.server.support.query.QueryObject;
+import org.apache.chemistry.opencmis.server.support.query.QueryObject.SortSpec;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A processor for a CMIS query for the In-Memory server. During tree traversal conditions
+ * are checked against the data contained in the central hash map with all objects. In a first 
+ * pass one time setup is performed, in a custom walk across the query expression tree an object
+ * is checked if it matches. In case of a match it is appended to a list of matching objects.
+ * 
+ * @author Jens
+ *
+ */
+public class InMemoryQueryProcessor extends AbstractQueryConditionProcessor {
+
+    private static Log LOG = LogFactory.getLog(InMemoryQueryProcessor.class);
+    
+    private List<StoredObject> matches = new ArrayList<StoredObject>();
+    private QueryObject queryObj;
+    private Tree whereTree;
+    
+    public InMemoryQueryProcessor() {
+    }
+    
+    /**
+     * Main entry function to process a query from discovery service
+     */
+    public ObjectList query(TypeManager tm, ObjectStore objectStore, String user, String repositoryId, String statement, Boolean searchAllVersions,
+            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
+            BigInteger maxItems, BigInteger skipCount) {
+
+        queryObj = new QueryObject(tm, this);
+        processQueryAndCatchExc(statement); // calls query processor
+
+        // iterate over all the objects and check for each if the query matches
+        for (String objectId : ((ObjectStoreImpl) objectStore).getIds()) {
+            StoredObject so = objectStore.getObjectById(objectId);
+            match(so, searchAllVersions==null ? true : searchAllVersions.booleanValue());
+        }
+
+        ObjectList objList = buildResultList(tm, user, includeAllowableActions, includeRelationships, renditionFilter,
+                maxItems, skipCount);
+        LOG.debug("Query result, number of matching objects: " + objList.getNumItems());
+        return objList;
+    }        
+
+    public CmisQueryWalker processQuery(String statement) throws UnsupportedEncodingException, IOException, RecognitionException {
+        CmisQueryWalker walker = AbstractQueryConditionProcessor.getWalker(statement);
+        walker.query(queryObj);
+        String errMsg = walker.getErrorMessageString();
+        if (null != errMsg) {
+            throw new RuntimeException("Walking of statement failed with error: \n   " + errMsg + 
+                    "\n   Statement was: " + statement);
+        }
+        /*CommonTree walkerTree = (CommonTree) */ walker.getTreeNodeStream().getTreeSource();
+        return walker;
+    }
+
+    public CmisQueryWalker processQueryAndCatchExc(String statement) {
+        try {
+            return processQuery(statement);
+        } catch (RecognitionException e) {
+            throw new RuntimeException("Walking of statement failed with RecognitionException error: \n   " + e); 
+        } catch (Exception e) {
+            throw new RuntimeException("Walking of statement failed with other exception: \n   " + e); 
+        }
+    }
+    
+    public void onStartProcessing(Tree node) {
+        // log.debug("onStartProcessing()");
+        // checkRoot(node);
+        whereTree = node;
+    }
+
+    public void onStopProcessing() {
+        // log.debug("onStopProcessing()");
+    }
+
+    public ObjectList buildResultList(TypeManager tm, String user, 
+            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
+            BigInteger maxItems, BigInteger skipCount) {
+        
+        sortMatches();
+
+        ObjectListImpl res = new ObjectListImpl();
+        res.setNumItems(BigInteger.valueOf(matches.size()));
+        int start = 0;
+        if (skipCount != null) 
+            start = (int)skipCount.longValue();
+        if (start < 0)
+            start = 0;
+        if (start > matches.size())
+            start = matches.size();
+        int stop = 0;
+        if (maxItems != null) 
+            stop = start + (int)maxItems.longValue();
+        if (stop <= 0 || stop > matches.size())
+            stop = matches.size();
+        res.setHasMoreItems(stop < matches.size());
+        if (start > 0 || stop > 0)
+            matches = matches.subList(start, stop);
+        List<ObjectData> objDataList = new ArrayList<ObjectData>();
+        Map<String, String> props = queryObj.getRequestedProperties();
+        Map<String, String> funcs = queryObj.getRequestedFuncs();
+        for (StoredObject so : matches) {
+            TypeDefinition td = tm.getTypeById(so.getTypeId()).getTypeDefinition();
+            ObjectData od = PropertyCreationHelper.getObjectDataQueryResult(td, so, user, 
+                    props, funcs, includeAllowableActions, includeRelationships, renditionFilter);
+            
+            objDataList.add(od); 
+        }
+        res.setObjects(objDataList);
+        return res;
+    }
+    
+    private boolean typeMatches(TypeDefinition td, StoredObject so) {
+        String typeId = so.getTypeId();
+        while (typeId != null) {
+            if (typeId.equals(td.getId())) {
+                return true;
+            }
+            // check parent type
+            TypeDefinition parentTD = queryObj.getParentType(typeId);
+            typeId = parentTD == null ? null : parentTD.getId();
+        }
+        return false;
+    }
+    
+    private void sortMatches() {
+        final List<SortSpec> orderBy = queryObj.getOrderBys();
+        if (orderBy.size() > 1)
+            LOG.warn("ORDER BY has more than one sort criterium, all but the first are ignored.");
+        class ResultComparator implements Comparator<StoredObject> {
+
+            @SuppressWarnings("unchecked")
+            public int compare(StoredObject so1, StoredObject so2) {
+                SortSpec s = orderBy.get(0);
+                CmisSelector sel = s.getSelector();
+                int result;
+                
+                if (sel instanceof ColumnReference) {
+                    String propId = ((ColumnReference)sel).getPropertyId();
+                    Object propVal1 = so1.getProperties().get(propId).getFirstValue();
+                    Object propVal2 = so2.getProperties().get(propId).getFirstValue();
+                    if (propVal1 == null && propVal2 == null)
+                        result = 0;
+                    else if (propVal1 == null)
+                        result = -1;
+                    else if (propVal2 == null)
+                        result = 1;
+                    else 
+                        result = ((Comparable)propVal1).compareTo(propVal2);                    
+                } else {
+                    String funcName = ((FunctionReference)sel).getName();
+                    // evaluate function here, currently ignore
+                    result = 0;
+                }
+                if (!s.isAscending())
+                    result = -result;
+                return result;
+            }
+        }
+
+        if (orderBy.size() > 0)
+            Collections.sort(matches, new ResultComparator());
+        
+    }
+
+    /**
+     * Check for each object contained in the in-memory repository if it matches the current query
+     * expression. If yes add it to the list of matched objects.
+     * 
+     * @param so
+     *      object stored in the in-memory repository
+     */
+    private void match(StoredObject so, boolean searchAllVersions) {
+        // log.debug("checkMatch() for object: " + so.getId());
+        // first check if type is matching...
+        String queryName = queryObj.getTypes().values().iterator().next(); // as we don't support JOINS take first type
+        TypeDefinition td = queryObj.getTypeDefinitionFromQueryName(queryName);
+        boolean skip = so instanceof VersionedDocument; // we are only interested in versions not in the series
+        boolean typeMatches = typeMatches(td, so);
+        if (!searchAllVersions && so instanceof DocumentVersion && ((DocumentVersion)so).getParentDocument().getLatestVersion(false) != so)
+            skip = true;
+        // ... then check expression...
+        if (typeMatches && !skip)
+            evalWhereTree(whereTree, so);        
+    }
+    
+    private void evalWhereTree(Tree node, StoredObject so) {
+        boolean match=true;
+        if (null != node)
+            match = evalWhereNode(so, node.getChild(0));
+        if (match)
+            matches.add(so); // add to list
+    }
+
+    // Standard expression evaluator for single pass walking. This is used as first
+    // pass walk in this object for one-time setup tasks (e.g. setup maps)
+    public void onEquals(Tree eqNode, Tree leftNode, Tree rightNode) {
+        
+    }
+    
+    public void onNotEquals(Tree neNode, Tree leftNode, Tree rightNode) {
+        
+    }
+    
+    public void onGreaterThan(Tree gtNode, Tree leftNode, Tree rightNode) {
+        
+    }
+    
+    public void onGreaterOrEquals(Tree geNode, Tree leftNode, Tree rightNode) {
+        
+    }
+    
+    public void onLessThan(Tree ltNode, Tree leftNode, Tree rightNode) {
+        
+    }
+    
+    public void onLessOrEquals(Tree leqNode, Tree leftNode, Tree rightNode) { 
+        
+    }
+
+    // Boolean operators
+    public void onNot(Tree opNode, Tree leftNode) {
+        
+    }
+    
+    public void onAnd(Tree opNode, Tree leftNode, Tree rightNode) {
+        
+    }
+    
+    public void onOr(Tree opNode, Tree leftNode, Tree rightNode) {
+        
+    }
+
+    // Multi-value:
+    public void onIn(Tree node, Tree colNode, Tree listNode) {
+        
+    }
+    
+    public void onNotIn(Tree nod, Tree colNode, Tree listNode) {
+        
+    }
+    
+    public void onNotInList(Tree node) {
+        
+    }
+    
+    public void onInAny(Tree node, Tree colNode, Tree listNode) {
+        
+    }
+    
+    public void onNotInAny(Tree node, Tree colNode, Tree listNode) {
+        
+    }
+    
+    public void onEqAny(Tree node, Tree literalNode, Tree colNode) {
+        
+    }
+
+    // Null comparisons:
+    public void onIsNull(Tree nullNode, Tree colNode) {
+        
+    }
+    
+    public void onIsNotNull(Tree notNullNode, Tree colNode) {
+        
+    }
+
+    // String matching:
+    public void onIsLike(Tree node, Tree colNode, Tree stringNode) {
+        
+    }
+    
+    public void onIsNotLike(Tree node, Tree colNode, Tree stringNode) {
+        
+    }
+
+    // Functions:
+    public void onContains(Tree node, Tree colNode, Tree paramNode) {
+        
+    }
+    
+    public void onInFolder(Tree node, Tree colNode, Tree paramNode) {
+        
+    }
+    
+    public void onInTree(Tree node, Tree colNode, Tree paramNode) {
+        
+    }
+    public void onScore(Tree node, Tree paramNode) { 
+        
+    }
+
+    /**
+     * For each object check if it matches and append it to match-list if it does.
+     * We do here our own walking mechanism so that we can pass additional parameters
+     * and define the return types.
+     *   
+     * @param node
+     *      node in where clause
+     * @return
+     *      true if it matches, false if it not matches
+     */
+    boolean evalWhereNode(StoredObject so, Tree node) {
+        boolean matches = true;
+
+        switch (node.getType()) {
+        case CmisQlStrictLexer.WHERE:
+            matches = evalWhereNode(so, node.getChild(0));
+            break; // ignore
+        case CmisQlStrictLexer.EQ:
+            matches = evalWhereEquals(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.NEQ:
+            matches = evalWhereNotEquals(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.GT:
+            matches = evalWhereGreaterThan(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.GTEQ:
+            matches = evalWhereGreaterOrEquals(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.LT:
+            matches = evalWhereLessThan(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.LTEQ:
+            matches = evalWhereLessOrEquals(so, node, node.getChild(0), node.getChild(1));
+            break;
+
+        case CmisQlStrictLexer.NOT:
+            matches = evalWhereNot(so, node, node.getChild(0));
+            break;
+        case CmisQlStrictLexer.AND:
+            matches = evalWhereAnd(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.OR:
+            matches = evalWhereOr(so, node, node.getChild(0), node.getChild(1));
+            break;
+
+        // Multi-value:
+        case CmisQlStrictLexer.IN:
+            matches = evalWhereIn(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.NOT_IN:
+            matches = evalWhereNotIn(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.IN_ANY:
+            matches = evalWhereInAny(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.NOT_IN_ANY:
+            matches = evalWhereNotInAny(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.EQ_ANY:
+            matches = evalWhereEqAny(so, node, node.getChild(0), node.getChild(1));
+            break;
+
+        // Null comparisons:
+        case CmisQlStrictLexer.IS_NULL:
+            matches = evalWhereIsNull(so, node, node.getChild(0));
+            break;
+        case CmisQlStrictLexer.IS_NOT_NULL:
+            matches = evalWhereIsNotNull(so, node, node.getChild(0));
+            break;
+
+        // String matching
+        case CmisQlStrictLexer.LIKE:
+            matches = evalWhereIsLike(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.NOT_LIKE:
+            matches = evalWhereIsNotLike(so, node, node.getChild(0), node.getChild(1));
+            break;
+
+        // Functions
+        case CmisQlStrictLexer.CONTAINS:
+            if (node.getChildCount() == 1)
+                matches = evalWhereContains(so, node, null, node.getChild(0));
+            else
+                matches = evalWhereContains(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.IN_FOLDER:
+            if (node.getChildCount() == 1)
+                matches = evalWhereInFolder(so, node, null, node.getChild(0));
+            else
+                matches = evalWhereInFolder(so, node, node.getChild(0), node.getChild(1));
+            break;
+        case CmisQlStrictLexer.IN_TREE:
+            if (node.getChildCount() == 1)
+                matches = evalWhereInTree(so, node, null, node.getChild(0));
+            else
+                matches = evalWhereInTree(so, node, node.getChild(0), node.getChild(1));
+            break;
+
+        default:
+            // do nothing;
+        }
+
+        return matches;
+    }
+
+    private boolean evalWhereEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        Integer cmp = compareTo(so, leftChild, rightChild);
+        if (null == cmp)
+            return false; // property is not set
+        else
+            return cmp == 0;
+    }
+
+    private boolean evalWhereNotEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        Integer cmp = compareTo(so, leftChild, rightChild);
+        if (null == cmp)
+            return false; // property is not set
+        else
+            return cmp != 0;
+    }
+
+    private boolean evalWhereGreaterThan(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        Integer cmp = compareTo(so, leftChild, rightChild);
+        if (null == cmp)
+            return false; // property is not set
+        else
+            return cmp > 0;
+    }
+
+    private boolean evalWhereGreaterOrEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        Integer cmp = compareTo(so, leftChild, rightChild);
+        if (null == cmp)
+            return false; // property is not set
+        else
+            return cmp >= 0;
+    }
+
+    private boolean evalWhereLessThan(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        Integer cmp = compareTo(so, leftChild, rightChild);
+        if (null == cmp)
+            return false; // property is not set
+        else
+            return cmp < 0;
+    }
+
+    private boolean evalWhereLessOrEquals(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        Integer cmp = compareTo(so, leftChild, rightChild);
+        if (null == cmp)
+            return false; // property is not set
+        else
+            return cmp <= 0;
+    }
+
+    private boolean evalWhereNot(StoredObject so, Tree node, Tree child) {
+        boolean matches = evalWhereNode(so, child);
+        return !matches;
+    }
+
+    private boolean evalWhereAnd(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        boolean matches1 = evalWhereNode(so, leftChild);
+        boolean matches2 = evalWhereNode(so, rightChild);        
+        return matches1 && matches2;
+    }
+
+    private boolean evalWhereOr(StoredObject so, Tree node, Tree leftChild, Tree rightChild) {
+        boolean matches1 = evalWhereNode(so, leftChild);
+        boolean matches2 = evalWhereNode(so, rightChild);        
+        return matches1 || matches2;
+    }
+
+    private boolean evalWhereIn(StoredObject so, Tree node, Tree colNode, Tree listNode) {
+        ColumnReference colRef = getColumnReference(colNode);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
+        List<Object> literals = onLiteralList(listNode);
+        if (pd.getCardinality() != Cardinality.SINGLE)
+            throw new RuntimeException("Operator IN only is allowed on single-value properties ");
+        else if (lVal == null)
+            return false;
+        else {
+            Object prop= lVal.getFirstValue();
+            if (literals.contains(prop))
+                return true;
+            else
+                return false;
+        }
+    }
+
+    private boolean evalWhereNotIn(StoredObject so, Tree node, Tree colNode, Tree listNode) {
+        // Note just return !evalWhereIn(so, node, colNode, listNode) is wrong, because
+        // then it evaluates to true for null values (not set properties).
+        ColumnReference colRef = getColumnReference(colNode);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
+        List<Object> literals = onLiteralList(listNode);
+        if (pd.getCardinality() != Cardinality.SINGLE)
+            throw new RuntimeException("Operator IN only is allowed on single-value properties ");
+        else if (lVal == null)
+            return false;
+        else {
+            Object prop= lVal.getFirstValue();
+            if (literals.contains(prop))
+                return false;
+            else
+                return true;
+        }
+    }
+
+    private boolean evalWhereInAny(StoredObject so, Tree node, Tree colNode, Tree listNode) {
+        ColumnReference colRef = getColumnReference(colNode);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
+        List<Object> literals = onLiteralList(listNode);
+        if (pd.getCardinality() != Cardinality.MULTI)
+            throw new RuntimeException("Operator ANY...IN only is allowed on multi-value properties ");
+        else if (lVal == null)
+            return false;
+        else {
+            List<?> props= lVal.getValues();
+            for (Object prop : props) {
+                LOG.debug("comparing with: " + prop);
+                if (literals.contains(prop))
+                    return true;
+            }
+            return false;
+        }
+    }
+
+    private boolean evalWhereNotInAny(StoredObject so, Tree node, Tree colNode, Tree listNode) {
+        // Note just return !evalWhereInAny(so, node, colNode, listNode) is wrong, because
+        // then it evaluates to true for null values (not set properties).
+        ColumnReference colRef = getColumnReference(colNode);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
+        List<Object> literals = onLiteralList(listNode);
+        if (pd.getCardinality() != Cardinality.MULTI)
+            throw new RuntimeException("Operator ANY...IN only is allowed on multi-value properties ");
+        else if (lVal == null)
+            return false;
+        else {
+            List<?> props= lVal.getValues();
+            for (Object prop : props) {
+                LOG.debug("comparing with: " + prop);
+                if (literals.contains(prop))
+                    return false;
+            }
+            return true;
+        }    
+    }
+
+    private boolean evalWhereEqAny(StoredObject so, Tree node, Tree literalNode, Tree colNode) {
+        ColumnReference colRef = getColumnReference(colNode);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
+        Object literal = onLiteral(literalNode);
+        if (pd.getCardinality() != Cardinality.MULTI)
+            throw new RuntimeException("Operator = ANY only is allowed on multi-value properties ");
+        else if (lVal == null)
+            return false;
+        else {
+            List<?> props= lVal.getValues();
+            if (props.contains(literal))
+                return true;
+            else
+                return false;
+        }
+    }
+
+    private boolean evalWhereIsNull(StoredObject so, Tree node, Tree child) {
+       Object propVal = getPropertyValue(child, so);
+       return null == propVal;
+    }
+
+    private boolean evalWhereIsNotNull(StoredObject so, Tree node, Tree child) {
+        Object propVal = getPropertyValue(child, so);
+        return null != propVal;
+    }
+
+    private boolean evalWhereIsLike(StoredObject so, Tree node, Tree colNode, Tree StringNode) {
+        Object rVal = onLiteral(StringNode);
+        if (!(rVal instanceof String))
+                throw new RuntimeException("LIKE operator requires String literal on right hand side.");
+        
+        ColumnReference colRef = getColumnReference(colNode);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyType propType = pd.getPropertyType();
+        if (propType != PropertyType.STRING && propType != PropertyType.HTML &&  propType != PropertyType.ID &&
+                propType != PropertyType.URI)
+            throw new RuntimeException("Property type "+ propType.value() + " is not allowed FOR LIKE");
+        if (pd.getCardinality() != Cardinality.SINGLE)
+            throw new RuntimeException("LIKE is not allowed for multi-value properties ");
+        
+        String propVal = (String) so.getProperties().get(colRef.getPropertyId()).getFirstValue();
+        String pattern = translatePattern((String) rVal); // SQL to Java regex syntax
+        Pattern p = Pattern.compile(pattern);
+        return p.matcher(propVal).matches();
+    }
+
+    private boolean evalWhereIsNotLike(StoredObject so, Tree node, Tree colNode, Tree stringNode) {
+        return ! evalWhereIsLike(so, node, colNode, stringNode);
+    }
+
+    private boolean evalWhereContains(StoredObject so, Tree node, Tree colNode, Tree paramNode) {
+        throw new RuntimeException("Operator CONTAINS not supported in InMemory server.");
+    }
+
+    private boolean evalWhereInFolder(StoredObject so, Tree node, Tree colNode, Tree paramNode) {
+        if (null != colNode) {
+            getTableReference(colNode); 
+            // just for error checking we do not evaluate this, there is only one from without join support
+        }
+        Object lit = onLiteral(paramNode);
+        if (!(lit instanceof String))
+            throw new RuntimeException("Folder id in IN_FOLDER must be of type String");
+        String folderId = (String) lit;
+        
+        // check if object is in folder
+        if (so instanceof Filing)
+            return hasParent((Filing)so, folderId);
+        else
+            return false;
+    }
+
+    private boolean evalWhereInTree(StoredObject so, Tree node, Tree colNode, Tree paramNode) {
+        if (null != colNode) {
+            getTableReference(colNode); 
+            // just for error checking we do not evaluate this, there is only one from without join support
+        }
+        Object lit = onLiteral(paramNode);
+        if (!(lit instanceof String))
+            throw new RuntimeException("Folder id in IN_FOLDER must be of type String");
+        String folderId = (String) lit;
+        
+        // check if object is in folder
+        if (so instanceof Filing)
+            return hasAncestor((Filing) so, folderId);
+        else
+            return false;
+    }
+    
+    private boolean hasParent(Filing objInFolder, String folderId) {
+        List<Folder> parents = objInFolder.getParents();
+        
+        for (Folder folder : parents)
+            if (folderId.equals(folder.getId()))
+                return true;
+        return false;
+    }
+
+    private boolean hasAncestor(Filing objInFolder, String folderId) {
+        List<Folder> parents = objInFolder.getParents();
+        
+        for (Folder folder : parents)
+            if (folderId.equals(folder.getId()))
+                return true;
+        for (Folder folder : parents)
+            if (hasAncestor(folder, folderId))
+                return true;
+        return false;
+    }
+
+    private Integer compareTo(StoredObject so, Tree leftChild, Tree rightChild) {
+        Object rVal = onLiteral(rightChild);
+        
+        //log.debug("retrieve node from where: " + System.identityHashCode(leftChild) + " is " + leftChild);
+        ColumnReference colRef = getColumnReference(leftChild);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
+        if (lVal instanceof List<?>)
+            throw new RuntimeException("You can't query operators <, <=, ==, !=, >=, > on multi-value properties ");
+        else
+            return compareTo(pd, lVal, rVal);
+    }
+    
+    private int compareTo(PropertyDefinition<?> td, PropertyData<?> lVal, Object rVal) {
+        Object lValue = lVal.getFirstValue();
+        switch (td.getPropertyType()) {
+        case BOOLEAN:
+            if (rVal instanceof Boolean)
+                return ((Boolean)lValue).compareTo((Boolean)rVal);
+            else 
+                throwIncompatibleTypesException(lValue, rVal);
+            break;
+        case INTEGER: 
+        { 
+            Long lLongValue = ((BigInteger)lVal.getFirstValue()).longValue();
+            if (rVal instanceof Long)
+                return (lLongValue).compareTo((Long)rVal);
+            else if (rVal instanceof Double)
+                return Double.valueOf(((Integer)lValue).doubleValue()).compareTo((Double)rVal);
+            else 
+                throwIncompatibleTypesException(lValue, rVal);
+            break;
+        }
+        case DATETIME:
+            if (rVal instanceof GregorianCalendar) {
+                // LOG.debug("left:" + CalendarHelper.toString((GregorianCalendar)lValue) + " right: " + CalendarHelper.toString((GregorianCalendar)rVal));
+                return ((GregorianCalendar)lValue).compareTo((GregorianCalendar)rVal);
+            } else 
+                throwIncompatibleTypesException(lValue, rVal);
+            break;
+        case DECIMAL:
+        { 
+            Double lDoubleValue = ((BigDecimal)lVal.getFirstValue()).doubleValue();
+            if (rVal instanceof Double)
+                return lDoubleValue.compareTo((Double)rVal);
+            else if (rVal instanceof Long)
+                return Double.valueOf(((Integer)lValue).doubleValue()).compareTo((Double)rVal);
+            else 
+                throwIncompatibleTypesException(lValue, rVal);
+            break;
+        }
+        case HTML:
+        case STRING:
+        case URI:   
+        case ID: 
+            if (rVal instanceof String) {
+                LOG.debug("compare strings: " + lValue + " with " + rVal);
+                return ((String)lValue).compareTo((String)rVal);
+            } else 
+                throwIncompatibleTypesException(lValue, rVal);
+            break;
+        }
+        return 0;
+    }
+    
+    private ColumnReference getColumnReference(Tree columnNode) {
+        CmisSelector sel = queryObj.getColumnReference(columnNode.getTokenStartIndex());
+        if (null == sel)
+            throw new RuntimeException("Unknown property query name " + columnNode.getChild(0));
+        else if (sel instanceof ColumnReference)
+            return (ColumnReference) sel;
+        else
+            throw new RuntimeException("Unexpected numerical value function in where clause");
+    }
+    
+    private String getTableReference(Tree tableNode) {
+        String typeQueryName = queryObj.getTypeQueryName(tableNode.getText());
+        if (null == typeQueryName)
+            throw new RuntimeException("Inavlid type in IN_FOLDER() or IN_TREE(), must be in FROM list: " + tableNode.getText());
+        return typeQueryName;
+    }
+
+    private Object getPropertyValue(Tree columnNode, StoredObject so) {
+        ColumnReference colRef = getColumnReference(columnNode);
+        TypeDefinition td = colRef.getTypeDefinition();
+        PropertyDefinition<?> pd = td.getPropertyDefinitions().get(colRef.getPropertyId());
+        PropertyData<?> lVal = so.getProperties().get(colRef.getPropertyId());
+        if (null == lVal)
+            return null;
+        else {
+            if (pd.getCardinality() == Cardinality.SINGLE)
+                return null == lVal ? null : lVal.getFirstValue();
+            else
+                return lVal.getValues();
+        }                
+    }
+    
+    // translate SQL wildcards %, _ to Java regex syntax
+    public static String translatePattern(String wildcardString) {
+        int index = 0;
+        int start = 0;
+        StringBuffer res = new StringBuffer();
+        
+        while (index >= 0) {
+            index = wildcardString.indexOf('%', start);
+            if (index < 0) 
+                res.append(wildcardString.substring(start));
+            else if (index == 0 || index > 0 && wildcardString.charAt(index-1) != '\\') {
+                res.append(wildcardString.substring(start, index));
+                res.append(".*");
+            } else 
+                res.append(wildcardString.substring(start, index+1));
+            start = index+1;
+        }
+        wildcardString = res.toString();
+        
+        index = 0;
+        start = 0;
+        res = new StringBuffer();
+        
+        while (index >= 0) {
+            index = wildcardString.indexOf('_', start);
+            if (index < 0) 
+                res.append(wildcardString.substring(start));
+            else if (index == 0 || index > 0 && wildcardString.charAt(index-1) != '\\') {
+                res.append(wildcardString.substring(start, index));
+                res.append(".");
+            } else 
+                res.append(wildcardString.substring(start, index+1));
+            start = index+1;
+        }
+        return res.toString();
+    }
+    
+    private void throwIncompatibleTypesException(Object o1, Object o2) {
+        throw new RuntimeException("Incompatible Types to compare: " + o1 + " and " + o2);
+    }
+
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/query/InMemoryQueryProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/AbstractServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/AbstractServiceImpl.java?rev=980513&r1=980512&r2=980513&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/AbstractServiceImpl.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/AbstractServiceImpl.java Thu Jul 29 17:13:28 2010
@@ -1,171 +1,171 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.chemistry.opencmis.inmemory.server;
-
-import org.apache.chemistry.opencmis.commons.PropertyIds;
-import org.apache.chemistry.opencmis.commons.data.Properties;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.DocumentVersion;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.ObjectStore;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoreManager;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoredObject;
-import org.apache.chemistry.opencmis.inmemory.storedobj.api.VersionedDocument;
-
-/**
- * Common functionality for all service implementations
- * 
- * @author Jens
- * 
- */
-public class AbstractServiceImpl {
-
-    protected StoreManager fStoreManager;
-
-    protected AbstractServiceImpl(StoreManager storeManager) {
-        fStoreManager = storeManager;
-    }
-
-    /**
-     * check if repository is known and that object exists. To avoid later calls
-     * to again retrieve the object from the id return the retrieved object for
-     * later use.
-     * 
-     * @param repositoryId
-     *            repository id
-     * @param objectId
-     *            object id
-     * @return object for objectId
-     */
-    protected StoredObject checkStandardParameters(String repositoryId, String objectId) {
-
-        ObjectStore objStore = fStoreManager.getObjectStore(repositoryId);
-
-        if (objStore == null)
-            throw new CmisObjectNotFoundException("Unknown repository id: " + repositoryId);
-
-        StoredObject so = objStore.getObjectById(objectId);
-
-        if (so == null)
-            throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
-        return so;
-    }
-
-    protected StoredObject checkExistingObjectId(ObjectStore objStore, String objectId) {
-
-        StoredObject so = objStore.getObjectById(objectId);
-
-        if (so == null)
-            throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
-        return so;
-    }
-
-    protected void checkRepositoryId(String repositoryId) {
-        ObjectStore objStore = fStoreManager.getObjectStore(repositoryId);
-
-        if (objStore == null)
-            throw new CmisObjectNotFoundException("Unknown repository id: " + repositoryId);
-    }
-
-    protected TypeDefinition getTypeDefinition(String repositoryId, Properties properties) {
-        String typeId = (String) properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID).getFirstValue();
-        TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, typeId);
-        if (typeDefC == null)
-            throw new RuntimeException("Cannot create object, a type with id " + typeId + " is unknown");
-
-        return typeDefC.getTypeDefinition();
-    }
-
-    protected TypeDefinition getTypeDefinition(String repositoryId, StoredObject obj) {
-
-        TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, obj.getTypeId());
-        return typeDefC.getTypeDefinition();
-    }
-
-    /**
-     * We allow checkin, cancel, checkout operations on a single version as well
-     * as on a version series This method returns the versioned document
-     * (version series) in each case
-     * 
-     * @param value
-     *            version or version series id of a document
-     * @return version series id
-     */
-    protected VersionedDocument getVersionedDocumentOfObjectId(StoredObject so) {
-
-        VersionedDocument verDoc;
-        if (so instanceof DocumentVersion) {
-            // get document the version is contained in to c
-            verDoc = ((DocumentVersion) so).getParentDocument();
-        } else {
-            verDoc = (VersionedDocument) so;
-        }
-
-        return verDoc;
-    }
-
-    protected VersionedDocument testIsNotCheckedOutBySomeoneElse(StoredObject so, String user) {
-        checkIsVersionableObject(so);
-        VersionedDocument verDoc = getVersionedDocumentOfObjectId(so);
-        if (verDoc.isCheckedOut())
-            testCheckedOutByCurrentUser(user, verDoc);
-
-        return verDoc;
-    }
-
-    protected VersionedDocument testHasProperCheckedOutStatus(StoredObject so, String user) {
-
-        checkIsVersionableObject(so);
-        VersionedDocument verDoc = getVersionedDocumentOfObjectId(so);
-
-        checkHasUser(user);
-
-        testIsCheckedOut(verDoc);
-        testCheckedOutByCurrentUser(user, verDoc);
-
-        return verDoc;
-    }
-
-    protected void checkIsVersionableObject(StoredObject so) {
-        if (!(so instanceof VersionedDocument || so instanceof DocumentVersion))
-            throw new RuntimeException(
-                    "Object is of a versionable type but not instance of VersionedDocument or DocumentVersion.");
-    }
-
-    protected void checkHasUser(String user) {
-        if (null == user || user.length() == 0)
-            throw new CmisUpdateConflictException("Object can't be checked-in, no user is given.");
-    }
-
-    protected void testCheckedOutByCurrentUser(String user, VersionedDocument verDoc) {
-        if (!user.equals(verDoc.getCheckedOutBy()))
-            throw new CmisUpdateConflictException("Object can't be checked-in, user " + verDoc.getCheckedOutBy()
-                    + " has checked out the document.");
-    }
-
-    protected void testIsCheckedOut(VersionedDocument verDoc) {
-        if (!verDoc.isCheckedOut())
-            throw new CmisUpdateConflictException("Canot check-in: Document " + verDoc.getId() + " is not checked out.");
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.inmemory.server;
+
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.Properties;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.DocumentVersion;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.ObjectStore;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoreManager;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoredObject;
+import org.apache.chemistry.opencmis.inmemory.storedobj.api.VersionedDocument;
+
+/**
+ * Common functionality for all service implementations
+ * 
+ * @author Jens
+ * 
+ */
+public class AbstractServiceImpl {
+
+    protected StoreManager fStoreManager;
+
+    protected AbstractServiceImpl(StoreManager storeManager) {
+        fStoreManager = storeManager;
+    }
+
+    /**
+     * check if repository is known and that object exists. To avoid later calls
+     * to again retrieve the object from the id return the retrieved object for
+     * later use.
+     * 
+     * @param repositoryId
+     *            repository id
+     * @param objectId
+     *            object id
+     * @return object for objectId
+     */
+    protected StoredObject checkStandardParameters(String repositoryId, String objectId) {
+
+        ObjectStore objStore = fStoreManager.getObjectStore(repositoryId);
+
+        if (objStore == null)
+            throw new CmisObjectNotFoundException("Unknown repository id: " + repositoryId);
+
+        StoredObject so = objStore.getObjectById(objectId);
+
+        if (so == null)
+            throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+        return so;
+    }
+
+    protected StoredObject checkExistingObjectId(ObjectStore objStore, String objectId) {
+
+        StoredObject so = objStore.getObjectById(objectId);
+
+        if (so == null)
+            throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+        return so;
+    }
+
+    protected void checkRepositoryId(String repositoryId) {
+        ObjectStore objStore = fStoreManager.getObjectStore(repositoryId);
+
+        if (objStore == null)
+            throw new CmisObjectNotFoundException("Unknown repository id: " + repositoryId);
+    }
+
+    protected TypeDefinition getTypeDefinition(String repositoryId, Properties properties) {
+        String typeId = (String) properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID).getFirstValue();
+        TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, typeId);
+        if (typeDefC == null)
+            throw new RuntimeException("Cannot create object, a type with id " + typeId + " is unknown");
+
+        return typeDefC.getTypeDefinition();
+    }
+
+    protected TypeDefinition getTypeDefinition(String repositoryId, StoredObject obj) {
+
+        TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, obj.getTypeId());
+        return typeDefC.getTypeDefinition();
+    }
+
+    /**
+     * We allow checkin, cancel, checkout operations on a single version as well
+     * as on a version series This method returns the versioned document
+     * (version series) in each case
+     * 
+     * @param value
+     *            version or version series id of a document
+     * @return version series id
+     */
+    protected VersionedDocument getVersionedDocumentOfObjectId(StoredObject so) {
+
+        VersionedDocument verDoc;
+        if (so instanceof DocumentVersion) {
+            // get document the version is contained in to c
+            verDoc = ((DocumentVersion) so).getParentDocument();
+        } else {
+            verDoc = (VersionedDocument) so;
+        }
+
+        return verDoc;
+    }
+
+    protected VersionedDocument testIsNotCheckedOutBySomeoneElse(StoredObject so, String user) {
+        checkIsVersionableObject(so);
+        VersionedDocument verDoc = getVersionedDocumentOfObjectId(so);
+        if (verDoc.isCheckedOut())
+            testCheckedOutByCurrentUser(user, verDoc);
+
+        return verDoc;
+    }
+
+    protected VersionedDocument testHasProperCheckedOutStatus(StoredObject so, String user) {
+
+        checkIsVersionableObject(so);
+        VersionedDocument verDoc = getVersionedDocumentOfObjectId(so);
+
+        checkHasUser(user);
+
+        testIsCheckedOut(verDoc);
+        testCheckedOutByCurrentUser(user, verDoc);
+
+        return verDoc;
+    }
+
+    protected void checkIsVersionableObject(StoredObject so) {
+        if (!(so instanceof VersionedDocument || so instanceof DocumentVersion))
+            throw new RuntimeException(
+                    "Object is of a versionable type but not instance of VersionedDocument or DocumentVersion.");
+    }
+
+    protected void checkHasUser(String user) {
+        if (null == user || user.length() == 0)
+            throw new CmisUpdateConflictException("Object can't be checked-in, no user is given.");
+    }
+
+    protected void testCheckedOutByCurrentUser(String user, VersionedDocument verDoc) {
+        if (!user.equals(verDoc.getCheckedOutBy()))
+            throw new CmisUpdateConflictException("Object can't be checked-in, user " + verDoc.getCheckedOutBy()
+                    + " has checked out the document.");
+    }
+
+    protected void testIsCheckedOut(VersionedDocument verDoc) {
+        if (!verDoc.isCheckedOut())
+            throw new CmisUpdateConflictException("Canot check-in: Document " + verDoc.getId() + " is not checked out.");
+    }
+
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/AbstractServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message