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 * https://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 */ 020package org.apache.directory.api.ldap.codec.actions.request.search; 021 022 023import java.util.ArrayList; 024import java.util.List; 025 026import org.apache.directory.api.asn1.DecoderException; 027import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 028import org.apache.directory.api.i18n.I18n; 029import org.apache.directory.api.ldap.codec.AttributeValueAssertion; 030import org.apache.directory.api.ldap.codec.api.LdapCodecConstants; 031import org.apache.directory.api.ldap.codec.api.LdapMessageContainer; 032import org.apache.directory.api.ldap.codec.search.AndFilter; 033import org.apache.directory.api.ldap.codec.search.AttributeValueAssertionFilter; 034import org.apache.directory.api.ldap.codec.search.ConnectorFilter; 035import org.apache.directory.api.ldap.codec.search.ExtensibleMatchFilter; 036import org.apache.directory.api.ldap.codec.search.Filter; 037import org.apache.directory.api.ldap.codec.search.OrFilter; 038import org.apache.directory.api.ldap.codec.search.PresentFilter; 039import org.apache.directory.api.ldap.codec.search.SubstringFilter; 040import org.apache.directory.api.ldap.model.entry.Value; 041import org.apache.directory.api.ldap.model.exception.LdapSchemaException; 042import org.apache.directory.api.ldap.model.filter.AndNode; 043import org.apache.directory.api.ldap.model.filter.ApproximateNode; 044import org.apache.directory.api.ldap.model.filter.BranchNode; 045import org.apache.directory.api.ldap.model.filter.EqualityNode; 046import org.apache.directory.api.ldap.model.filter.ExprNode; 047import org.apache.directory.api.ldap.model.filter.ExtensibleNode; 048import org.apache.directory.api.ldap.model.filter.GreaterEqNode; 049import org.apache.directory.api.ldap.model.filter.LeafNode; 050import org.apache.directory.api.ldap.model.filter.LessEqNode; 051import org.apache.directory.api.ldap.model.filter.NotNode; 052import org.apache.directory.api.ldap.model.filter.OrNode; 053import org.apache.directory.api.ldap.model.filter.PresenceNode; 054import org.apache.directory.api.ldap.model.filter.SubstringNode; 055import org.apache.directory.api.ldap.model.message.SearchRequest; 056import org.slf4j.Logger; 057import org.slf4j.LoggerFactory; 058 059 060/** 061 * The action used to initialize the AttributeDesc list 062 * <pre> 063 * SearchRequest ::= [APPLICATION 3] SEQUENCE { 064 * ... 065 * filter Filter, 066 * attributes AttributeDescriptionList } 067 * 068 * AttributeDescriptionList ::= SEQUENCE OF 069 * AttributeDescription 070 * </pre> 071 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 072 */ 073public class InitSearchRequestAttributeDescList extends GrammarAction<LdapMessageContainer<SearchRequest>> 074{ 075 /** The logger */ 076 private static final Logger LOG = LoggerFactory.getLogger( InitSearchRequestAttributeDescList.class ); 077 078 /** 079 * Instantiates a new init attribute desc list action. 080 */ 081 public InitSearchRequestAttributeDescList() 082 { 083 super( "Initialize AttributeDesc list" ); 084 } 085 086 087 /** 088 * Transform the Filter part of a SearchRequest to an ExprNode 089 * 090 * @param filter The filter to be transformed 091 * @return An ExprNode 092 * @throws LdapSchemaException If teh filter is invalid 093 */ 094 private ExprNode transform( Filter filter ) throws LdapSchemaException 095 { 096 if ( filter != null ) 097 { 098 // Transform OR, AND or NOT leaves 099 if ( filter instanceof ConnectorFilter ) 100 { 101 BranchNode branch; 102 103 if ( filter instanceof AndFilter ) 104 { 105 branch = new AndNode(); 106 } 107 else if ( filter instanceof OrFilter ) 108 { 109 branch = new OrNode(); 110 } 111 else 112 { 113 branch = new NotNode(); 114 } 115 116 List<Filter> filtersSet = ( ( ConnectorFilter ) filter ).getFilterSet(); 117 118 // Loop on all AND/OR children 119 if ( filtersSet != null ) 120 { 121 for ( Filter node : filtersSet ) 122 { 123 branch.addNode( transform( node ) ); 124 } 125 } 126 127 return branch; 128 } 129 else 130 { 131 // Transform PRESENT or ATTRIBUTE_VALUE_ASSERTION 132 LeafNode branch = null; 133 134 if ( filter instanceof PresentFilter ) 135 { 136 branch = new PresenceNode( ( ( PresentFilter ) filter ).getAttributeDescription() ); 137 } 138 else if ( filter instanceof AttributeValueAssertionFilter ) 139 { 140 AttributeValueAssertion ava = ( ( AttributeValueAssertionFilter ) filter ).getAssertion(); 141 142 // Transform =, >=, <=, ~= filters 143 int filterType = ( ( AttributeValueAssertionFilter ) filter ).getFilterType(); 144 145 switch ( filterType ) 146 { 147 case LdapCodecConstants.EQUALITY_MATCH_FILTER: 148 branch = new EqualityNode( ava.getAttributeDesc(), ava.getAssertion() ); 149 break; 150 151 case LdapCodecConstants.GREATER_OR_EQUAL_FILTER: 152 branch = new GreaterEqNode( ava.getAttributeDesc(), ava.getAssertion() ); 153 break; 154 155 case LdapCodecConstants.LESS_OR_EQUAL_FILTER: 156 branch = new LessEqNode( ava.getAttributeDesc(), ava.getAssertion() ); 157 break; 158 159 case LdapCodecConstants.APPROX_MATCH_FILTER: 160 branch = new ApproximateNode( ava.getAttributeDesc(), ava.getAssertion() ); 161 break; 162 163 default: 164 throw new IllegalArgumentException( I18n.err( I18n.ERR_05503_UNEXPECTED_FILTER_TYPE, filterType ) ); 165 } 166 167 } 168 else if ( filter instanceof SubstringFilter ) 169 { 170 // Transform Substring filters 171 SubstringFilter substrFilter = ( SubstringFilter ) filter; 172 String initialString = null; 173 String finalString = null; 174 List<String> anyString = null; 175 176 if ( substrFilter.getInitialSubstrings() != null ) 177 { 178 initialString = substrFilter.getInitialSubstrings(); 179 } 180 181 if ( substrFilter.getFinalSubstrings() != null ) 182 { 183 finalString = substrFilter.getFinalSubstrings(); 184 } 185 186 if ( substrFilter.getAnySubstrings() != null ) 187 { 188 anyString = new ArrayList<>(); 189 190 for ( String any : substrFilter.getAnySubstrings() ) 191 { 192 anyString.add( any ); 193 } 194 } 195 196 branch = new SubstringNode( anyString, substrFilter.getType(), initialString, finalString ); 197 } 198 else if ( filter instanceof ExtensibleMatchFilter ) 199 { 200 // Transform Extensible Match Filter 201 ExtensibleMatchFilter extFilter = ( ExtensibleMatchFilter ) filter; 202 String matchingRule = null; 203 204 Value value = extFilter.getMatchValue(); 205 206 if ( extFilter.getMatchingRule() != null ) 207 { 208 matchingRule = extFilter.getMatchingRule(); 209 } 210 211 branch = new ExtensibleNode( extFilter.getType(), value, matchingRule, extFilter.isDnAttributes() ); 212 } 213 214 return branch; 215 } 216 } 217 else 218 { 219 // We have found nothing to transform. Return null then. 220 return null; 221 } 222 } 223 224 225 /** 226 * {@inheritDoc} 227 */ 228 public void action( LdapMessageContainer<SearchRequest> container ) throws DecoderException 229 { 230 // Here, we have to inject the decoded filter into the SearchRequest 231 SearchRequest searchRequest = container.getMessage(); 232 233 try 234 { 235 searchRequest.setFilter( transform( container.getTopFilter() ) ); 236 } 237 catch ( LdapSchemaException lse ) 238 { 239 throw new DecoderException( lse.getMessage(), lse ); 240 } 241 242 // We can have an END transition 243 container.setGrammarEndAllowed( true ); 244 245 if ( LOG.isDebugEnabled() ) 246 { 247 LOG.debug( I18n.msg( I18n.MSG_05158_INITIALIZE_ATT_DESC_LIST ) ); 248 } 249 } 250}