You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2013/10/28 20:46:25 UTC

svn commit: r1536494 - in /directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search: ./ BranchNode.java FilterNode.java FilterParser.java Operator.java TerminalNode.java

Author: kayyagari
Date: Mon Oct 28 19:46:24 2013
New Revision: 1536494

URL: http://svn.apache.org/r1536494
Log:
filter parser

Added:
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/BranchNode.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterNode.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterParser.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/Operator.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/TerminalNode.java

Added: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/BranchNode.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/BranchNode.java?rev=1536494&view=auto
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/BranchNode.java (added)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/BranchNode.java Mon Oct 28 19:46:24 2013
@@ -0,0 +1,90 @@
+/*
+ *   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.directory.scim.search;
+
+/**
+ * TODO BranchNode.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class BranchNode extends FilterNode
+{
+    private FilterNode leftNode;
+    
+    private FilterNode rightNode;
+    
+    public BranchNode( Operator operator )
+    {
+        super( operator );
+    }
+    
+    public void addNode( FilterNode node )
+    {
+        if( leftNode == null )
+        {
+            leftNode = node;
+        }
+        else if( rightNode == null )
+        {
+            rightNode = node;
+        }
+        else
+        {
+            throw new IllegalStateException( "A branch node can only hold two nodes" );
+        }
+    }
+
+    /**
+     * @return the leftNode
+     */
+    public FilterNode getLeftNode()
+    {
+        return leftNode;
+    }
+
+    /**
+     * @return the rightNode
+     */
+    public FilterNode getRightNode()
+    {
+        return rightNode;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        if( leftNode != null )
+        {
+            sb.append( leftNode );
+        }
+        
+        sb.append( " AND " );
+        
+        if( rightNode != null )
+        {
+            sb.append( rightNode );
+        }
+        
+        return sb.toString();
+    }
+    
+}

Added: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterNode.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterNode.java?rev=1536494&view=auto
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterNode.java (added)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterNode.java Mon Oct 28 19:46:24 2013
@@ -0,0 +1,44 @@
+/*
+ *   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.directory.scim.search;
+
+/**
+ * TODO FilterNode.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public abstract class FilterNode
+{
+    private Operator operator;
+    
+    public FilterNode( Operator operator )
+    {
+        this.operator = operator;
+    }
+
+    /**
+     * @return the operator
+     */
+    public Operator getOperator()
+    {
+        return operator;
+    }
+    
+}

Added: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterParser.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterParser.java?rev=1536494&view=auto
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterParser.java (added)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/FilterParser.java Mon Oct 28 19:46:24 2013
@@ -0,0 +1,237 @@
+/*
+ *   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.directory.scim.search;
+
+import static org.apache.directory.scim.search.Operator.*;
+
+/**
+ * TODO FilterParser.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class FilterParser
+{
+    
+    private static class Position
+    {
+        int val;
+        private Position( int pos )
+        {
+            this.val = pos;
+        }
+        
+        private void increment()
+        {
+            val++;
+        }
+        
+        private void set( int pos )
+        {
+            this.val = pos;
+        }
+        
+        private void decrement()
+        {
+            val--;
+        }
+    }
+    
+    public static FilterNode parse( String filter )
+    {
+        Position pos = new Position( 0 );
+        
+        int len = filter.length();
+        
+        FilterNode node = null;
+        
+        char prevChar = ' ';
+        
+        while( pos.val < len )
+        {
+            char c = filter.charAt( pos.val );
+            
+            switch( c )
+            {
+                case '(':
+                    //FIXME handle groupings
+                    break;
+                
+                default:
+                    FilterNode next = parseNode( pos, filter );
+                    if( next instanceof BranchNode )
+                    {
+                        if( node != null )
+                        {
+                            ( ( BranchNode ) next ).addNode( node );
+                        }
+                        
+                        node = next;
+                    }
+                    else if ( node instanceof BranchNode )
+                    {
+                        ( ( BranchNode ) node ).addNode( next );
+                    }
+                    else
+                    {
+                        node = next;
+                    }
+            }
+            
+            prevChar = c;
+        }
+        
+        return node;
+    }
+    
+    private static FilterNode parseNode( Position pos, String filter )
+    {
+        FilterNode node = null;
+
+        String attribute = parseToken( pos, filter );
+        
+        Operator branchOperator = Operator.getByName( attribute );
+        
+        if( branchOperator != UNKNOWN )
+        {
+            switch ( branchOperator )
+            {
+                case AND:
+                case OR:
+                     return new BranchNode( branchOperator );
+
+                default:
+                    throw new IllegalArgumentException( "Invalid predicate in filter, expected an attribute or an operator token but found " + attribute );
+            }            
+        }
+        
+        
+        Operator operator = Operator.getByName( parseToken( pos, filter ) );
+        
+        int curPos = pos.val;
+        
+        String value = null;
+        
+        String valOrOperator = parseToken( pos, filter );
+        
+        if( Operator.getByName( valOrOperator ) != UNKNOWN )
+        {
+            // move back
+            pos.set( curPos );
+        }
+        else
+        {
+            value = valOrOperator;
+        }
+        
+        switch ( operator )
+        {
+            case AND:
+            case OR:
+                 //node = new BranchNode( operator );
+                throw new IllegalArgumentException( "Invalid predicate in filter, expected a non branching operator but found " + operator );
+
+            default:
+                TerminalNode tn= new TerminalNode( operator );
+                tn.setAttribute( attribute );
+                tn.setValue( value );
+                node = tn;
+                break;
+        }
+        
+        return node;
+    }
+    
+    private static String parseToken( Position pos, String filter )
+    {
+        boolean foundNonSpace = false;
+        
+        StringBuilder sb = new StringBuilder();
+        
+        char prevChar = ' ';
+        
+        boolean isEscaped = false;
+        
+//        boolean isEnclosed = false;
+        
+        boolean startQuote = false;
+        
+        boolean endQuote = false;
+        
+        while( pos.val < filter.length() )
+        {
+            char c = filter.charAt( pos.val );
+            pos.increment();
+            
+            if( ( prevChar == '\\' ) && ( c != '\\') )
+            {
+                isEscaped = true;
+            }
+            
+            if( c == '"' )
+            {
+//                isEnclosed = true;
+                
+                if( !isEscaped )
+                {
+                    if( startQuote )
+                    {
+                        endQuote = true;
+                    }
+                    else
+                    {
+                        startQuote = true;
+                    }
+                    
+                    continue;
+                }
+            }
+            
+            switch( c )
+            {
+                case ' ' :
+                    
+                    if( !foundNonSpace || ( startQuote && !endQuote ) )
+                    {
+                        continue;
+                    }
+                    else
+                    {
+                        return sb.toString();
+                    }
+                    
+                default:
+                    sb.append( c );
+                    foundNonSpace = true;
+            }
+            
+            prevChar = c;
+        }
+        
+        return sb.toString();
+    }
+    
+    public static void main( String[] args )
+    {
+        String filter = "(x eq y) and userName   eq \"bjensen\"";
+        
+        FilterNode node = parse( filter );
+        System.out.println( node );
+    }
+}

Added: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/Operator.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/Operator.java?rev=1536494&view=auto
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/Operator.java (added)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/Operator.java Mon Oct 28 19:46:24 2013
@@ -0,0 +1,159 @@
+/*
+ *   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.directory.scim.search;
+
+/**
+ * TODO Operator.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public enum Operator
+{
+    /**
+     * The attribute and operator values must be identical for a match.     
+     */
+    EQ("eq", "equal"),
+    
+    /**
+     * The entire operator value must be a substring of the attribute value for a match.                             
+     */
+    CO("co", "contains"),
+    
+    /**
+     *  The entire operator value must be a substring of the attribute value, 
+     *  starting at the beginning of the attribute value. This criterion is
+     *  satisfied if the two strings are identical.                          
+     */
+    SW("sw", "starts with"),
+    
+    /**
+     * If the attribute has a non-empty value, or if it contains a non-empty
+     * node for complex attributes there is a match.                             
+     */
+    PR("pr", "present (has value)"),
+    
+    /**
+     * If the attribute value is greater than operator value, there is a
+     * match. The actual comparison is dependent on the attribute type. For
+     * string attribute types, this is a lexicographical comparison and for
+     * DateTime types, it is a chronological comparison.                          
+     */
+    GT("gt", "greater than"),
+    
+    /**
+     * If the attribute value is greater than or equal to the operator value,
+     * there is a match. The actual comparison is dependent on the attribute 
+     * type. For string attribute types, this is a lexicographical comparison
+     * and for DateTime types, it is a chronological comparison.       
+     */
+    GE("ge", "greater than or equal"),
+    
+    /**
+     * If the attribute value is less than operator value, there is a match. The
+     * actual comparison is dependent on the attribute type.  For string attribute
+     * types, this is a lexicographical comparison and for DateTime types, it is a
+     * chronological comparison.       
+     */
+    LT("lt", "less than"),
+    
+    /**
+     * If the attribute value is less than or equal to the operator value, there
+     * is a match. The actual comparison is dependent on the attribute type. For
+     * string attribute types, this is a lexicographical comparison and for 
+     * DateTime types, it is a chronological comparison.                          
+     */
+    LE("le", "less than or equal"),
+    
+    /**
+     * The filter is only a match if both expressions evaluate to true  
+     */
+    AND("and", "logical and"),
+    
+    /**
+     * The filter is a match if either expression evaluates to true.  
+     */
+    OR("or", "logical or"),
+    
+    /** Unknown operator */
+    UNKNOWN("", "unknown operator");
+    
+    //LEFT_PARENTHESIS("(", "left parenthesis"),
+    
+    //RIGHT_PARENTHESIS(")", "right parenthesis");
+    
+    private String val;
+    
+    private String desc;
+    
+    private Operator( String val, String desc )
+    {
+        this.val = val;
+        this.desc = desc;
+    }
+    
+    
+    public static Operator getByName( String name )
+    {
+        name = name.toLowerCase();
+        
+        if( name.equals( EQ.val ) )
+        {
+            return EQ;
+        }
+        else if( name.equals( CO.val ) )
+        {
+            return CO;
+        }
+        else if( name.equals( SW.val ) )
+        {
+            return SW;
+        }
+        else if( name.equals( PR.val ) )
+        {
+            return PR;
+        }
+        else if( name.equals( GT.val ) )
+        {
+            return GT;
+        }
+        else if( name.equals( GE.val ) )
+        {
+            return GE;
+        }
+        else if( name.equals( LT.val ) )
+        {
+            return LT;
+        }
+        else if( name.equals( LE.val ) )
+        {
+            return LE;
+        }
+        else if( name.equals( AND.val ) )
+        {
+            return AND;
+        }
+        else if( name.equals( OR.val ) )
+        {
+            return OR;
+        }
+        
+        return UNKNOWN;
+    }
+}

Added: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/TerminalNode.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/TerminalNode.java?rev=1536494&view=auto
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/TerminalNode.java (added)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/search/TerminalNode.java Mon Oct 28 19:46:24 2013
@@ -0,0 +1,75 @@
+/*
+ *   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.directory.scim.search;
+
+/**
+ * TODO TerminalNode.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class TerminalNode extends FilterNode
+{
+    private String attribute;
+    
+    private String value;
+    
+    public TerminalNode( Operator operator )
+    {
+        super( operator );
+    }
+
+    /**
+     * @return the attribute
+     */
+    public String getAttribute()
+    {
+        return attribute;
+    }
+
+    /**
+     * @param attribute the attribute to set
+     */
+    public void setAttribute( String attribute )
+    {
+        this.attribute = attribute;
+    }
+
+    /**
+     * @return the value
+     */
+    public String getValue()
+    {
+        return value;
+    }
+
+    /**
+     * @param value the value to set
+     */
+    public void setValue( String value )
+    {
+        this.value = value;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "(" + attribute + " " + super.getOperator() + " " + value + ")";
+    }
+}