001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.server.core.event;
021    
022    
023    import java.util.regex.Pattern;
024    import java.util.regex.PatternSyntaxException;
025    
026    import org.apache.directory.server.i18n.I18n;
027    import org.apache.directory.shared.ldap.entry.EntryAttribute;
028    import org.apache.directory.shared.ldap.entry.ServerEntry;
029    import org.apache.directory.shared.ldap.entry.Value;
030    import org.apache.directory.shared.ldap.exception.LdapException;
031    import org.apache.directory.shared.ldap.exception.LdapInvalidSearchFilterException;
032    import org.apache.directory.shared.ldap.filter.ExprNode;
033    import org.apache.directory.shared.ldap.filter.SubstringNode;
034    import org.apache.directory.shared.ldap.schema.AttributeType;
035    import org.apache.directory.shared.ldap.schema.MatchingRule;
036    import org.apache.directory.shared.ldap.schema.Normalizer;
037    import org.apache.directory.shared.ldap.schema.SchemaManager;
038    
039    
040    /**
041     * Evaluates substring filter assertions on an entry.
042     * 
043     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
044     * @version $Rev: 927146 $
045     */
046    public class SubstringEvaluator implements Evaluator
047    {
048        /** SchemaManager needed for normalizing and comparing values */
049        private SchemaManager schemaManager;
050    
051    
052        /**
053         * Creates a new SubstringEvaluator for substring expressions.
054         *
055         * @param oidRegistry the OID registry for name to OID mapping
056         * @param attributeTypeRegistry the attributeType registry
057         */
058        public SubstringEvaluator( SchemaManager schemaManager )
059        {
060            this.schemaManager = schemaManager;
061        }
062    
063    
064        /**
065         * @see Evaluator#evaluate( ExprNode, String, ServerEntry )
066         */
067        public boolean evaluate( ExprNode node, String dn, ServerEntry entry ) throws LdapException
068        {
069            Pattern regex = null;
070            SubstringNode snode = (SubstringNode)node;
071            String oid = schemaManager.getAttributeTypeRegistry().getOidByName( snode.getAttribute() );
072            AttributeType type = schemaManager.lookupAttributeTypeRegistry( oid );
073            MatchingRule matchingRule = type.getSubstring();
074            
075            if ( matchingRule == null )
076            {
077                matchingRule = type.getEquality();
078            }
079            
080            Normalizer normalizer = matchingRule.getNormalizer();
081            
082    
083            // get the attribute
084            EntryAttribute attr = entry.get( snode.getAttribute() );
085    
086            // if the attribute does not exist just return false
087            if ( null == attr )
088            {
089                return false;
090            }
091    
092            // compile the regular expression to search for a matching attribute
093            try
094            {
095                regex = snode.getRegex( normalizer );
096            }
097            catch ( PatternSyntaxException pse )
098            {
099                LdapInvalidSearchFilterException ne = new LdapInvalidSearchFilterException( I18n.err( I18n.ERR_248, node ) );
100                ne.initCause( pse );
101                throw ne;
102            }
103    
104            /*
105             * Cycle through the attribute values testing normalized version 
106             * obtained from using the substring matching rule's normalizer.
107             * The test uses the comparator obtained from the appropriate 
108             * substring matching rule.
109             */
110    
111            for ( Value<?> value: attr )
112            {
113                String normValue = normalizer.normalize( value.getString() );
114    
115                // Once match is found cleanup and return true
116    
117                if ( regex.matcher( normValue ).matches() )
118                {
119                    return true;
120                }
121            }
122    
123            // we fell through so a match was not found - assertion was false.
124            return false;
125        }
126    }