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 }