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.shared.dsmlv2.request; 021 022 023 import java.util.List; 024 025 import org.apache.directory.shared.dsmlv2.ParserUtils; 026 import org.apache.directory.shared.ldap.codec.AttributeValueAssertion; 027 import org.apache.directory.shared.ldap.codec.LdapConstants; 028 import org.apache.directory.shared.ldap.codec.MessageTypeEnum; 029 import org.apache.directory.shared.ldap.codec.search.AndFilter; 030 import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter; 031 import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter; 032 import org.apache.directory.shared.ldap.codec.search.Filter; 033 import org.apache.directory.shared.ldap.codec.search.NotFilter; 034 import org.apache.directory.shared.ldap.codec.search.OrFilter; 035 import org.apache.directory.shared.ldap.codec.search.PresentFilter; 036 import org.apache.directory.shared.ldap.codec.search.SearchRequestCodec; 037 import org.apache.directory.shared.ldap.codec.search.SubstringFilter; 038 import org.apache.directory.shared.ldap.entry.EntryAttribute; 039 import org.apache.directory.shared.ldap.filter.SearchScope; 040 import org.dom4j.Element; 041 import org.dom4j.Namespace; 042 import org.dom4j.QName; 043 044 045 /** 046 * DSML Decorator for SearchRequest 047 * 048 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 049 * @version $Rev$, $Date$ 050 */ 051 public class SearchRequestDsml extends AbstractRequestDsml 052 { 053 /** 054 * Creates a new instance of SearchRequestDsml. 055 */ 056 public SearchRequestDsml() 057 { 058 super( new SearchRequestCodec() ); 059 } 060 061 062 /** 063 * Creates a new instance of SearchRequestDsml. 064 * 065 * @param ldapMessage 066 * the message to decorate 067 */ 068 public SearchRequestDsml( SearchRequestCodec ldapMessage ) 069 { 070 super( ldapMessage ); 071 } 072 073 074 /** 075 * {@inheritDoc} 076 */ 077 public MessageTypeEnum getMessageType() 078 { 079 return instance.getMessageType(); 080 } 081 082 083 /** 084 * {@inheritDoc} 085 */ 086 public Element toDsml( Element root ) 087 { 088 Element element = super.toDsml( root ); 089 090 SearchRequestCodec request = ( SearchRequestCodec ) instance; 091 092 // DN 093 if ( request.getBaseObject() != null ) 094 { 095 element.addAttribute( "dn", request.getBaseObject().getName() ); 096 } 097 098 // Scope 099 SearchScope scope = request.getScope(); 100 if ( scope != null ) 101 { 102 if ( scope == SearchScope.OBJECT ) 103 { 104 element.addAttribute( "scope", "baseObject" ); 105 } 106 else if ( scope == SearchScope.ONELEVEL ) 107 { 108 element.addAttribute( "scope", "singleLevel" ); 109 } 110 else if ( scope == SearchScope.SUBTREE ) 111 { 112 element.addAttribute( "scope", "wholeSubtree" ); 113 } 114 } 115 116 // DerefAliases 117 int derefAliases = request.getDerefAliases(); 118 if ( derefAliases == LdapConstants.NEVER_DEREF_ALIASES ) 119 { 120 element.addAttribute( "derefAliases", "neverDerefAliases" ); 121 } 122 else if ( derefAliases == LdapConstants.DEREF_IN_SEARCHING ) 123 { 124 element.addAttribute( "derefAliases", "derefInSearching" ); 125 } 126 else if ( derefAliases == LdapConstants.DEREF_FINDING_BASE_OBJ ) 127 { 128 element.addAttribute( "derefAliases", "derefFindingBaseObj" ); 129 } 130 else if ( derefAliases == LdapConstants.DEREF_ALWAYS ) 131 { 132 element.addAttribute( "derefAliases", "derefAlways" ); 133 } 134 135 // SizeLimit 136 if ( request.getSizeLimit() != 0L ) 137 { 138 element.addAttribute( "sizeLimit", "" + request.getSizeLimit() ); 139 } 140 141 // TimeLimit 142 if ( request.getTimeLimit() != 0 ) 143 { 144 element.addAttribute( "timeLimit", "" + request.getTimeLimit() ); 145 } 146 147 // TypesOnly 148 if ( request.isTypesOnly() ) 149 { 150 element.addAttribute( "typesOnly", "true" ); 151 } 152 153 // Filter 154 Element filterElement = element.addElement( "filter" ); 155 toDsml( filterElement, request.getFilter() ); 156 157 // Attributes 158 List<EntryAttribute> attributes = request.getAttributes(); 159 if ( attributes.size() > 0 ) 160 { 161 Element attributesElement = element.addElement( "attributes" ); 162 163 for ( EntryAttribute entryAttribute : attributes ) 164 { 165 attributesElement.addElement( "attribute" ).addAttribute( "name", entryAttribute.getId() ); 166 } 167 } 168 169 return element; 170 } 171 172 173 /** 174 * Recursively converts the filter of the Search Request into a DSML representation and adds 175 * it to the XML Element corresponding to the Search Request 176 * 177 * @param element 178 * the parent Element 179 * @param filter 180 * the filter to convert 181 */ 182 private void toDsml( Element element, Filter filter ) 183 { 184 // AND FILTER 185 if ( filter instanceof AndFilter ) 186 { 187 Element newElement = element.addElement( "and" ); 188 189 List<Filter> filterList = ( ( AndFilter ) filter ).getAndFilter(); 190 for ( int i = 0; i < filterList.size(); i++ ) 191 { 192 toDsml( newElement, filterList.get( i ) ); 193 } 194 } 195 196 // OR FILTER 197 else if ( filter instanceof OrFilter ) 198 { 199 Element newElement = element.addElement( "or" ); 200 201 List<Filter> filterList = ( ( OrFilter ) filter ).getOrFilter(); 202 for ( int i = 0; i < filterList.size(); i++ ) 203 { 204 toDsml( newElement, filterList.get( i ) ); 205 } 206 } 207 208 // NOT FILTER 209 else if ( filter instanceof NotFilter ) 210 { 211 Element newElement = element.addElement( "not" ); 212 213 toDsml( newElement, ( ( NotFilter ) filter ).getNotFilter() ); 214 } 215 216 // SUBSTRING FILTER 217 else if ( filter instanceof SubstringFilter ) 218 { 219 Element newElement = element.addElement( "substrings" ); 220 221 SubstringFilter substringFilter = ( SubstringFilter ) filter; 222 223 newElement.addAttribute( "name", substringFilter.getType() ); 224 225 String initial = substringFilter.getInitialSubstrings(); 226 if ( ( initial != null ) && ( !"".equals( initial ) ) ) 227 { 228 newElement.addElement( "initial" ).setText( initial ); 229 } 230 231 List<String> anyList = substringFilter.getAnySubstrings(); 232 for ( int i = 0; i < anyList.size(); i++ ) 233 { 234 newElement.addElement( "any" ).setText( anyList.get( i ) ); 235 } 236 237 String finalString = substringFilter.getFinalSubstrings(); 238 if ( ( finalString != null ) && ( !"".equals( finalString ) ) ) 239 { 240 newElement.addElement( "final" ).setText( finalString ); 241 } 242 } 243 244 // APPROXMATCH, EQUALITYMATCH, GREATEROREQUALS & LESSOREQUAL FILTERS 245 else if ( filter instanceof AttributeValueAssertionFilter ) 246 { 247 AttributeValueAssertionFilter avaFilter = ( AttributeValueAssertionFilter ) filter; 248 249 Element newElement = null; 250 int filterType = avaFilter.getFilterType(); 251 if ( filterType == LdapConstants.APPROX_MATCH_FILTER ) 252 { 253 newElement = element.addElement( "approxMatch" ); 254 } 255 else if ( filterType == LdapConstants.EQUALITY_MATCH_FILTER ) 256 { 257 newElement = element.addElement( "equalityMatch" ); 258 } 259 else if ( filterType == LdapConstants.GREATER_OR_EQUAL_FILTER ) 260 { 261 newElement = element.addElement( "greaterOrEqual" ); 262 } 263 else if ( filterType == LdapConstants.LESS_OR_EQUAL_FILTER ) 264 { 265 newElement = element.addElement( "lessOrEqual" ); 266 } 267 268 AttributeValueAssertion assertion = avaFilter.getAssertion(); 269 if ( assertion != null ) 270 { 271 newElement.addAttribute( "name", assertion.getAttributeDesc() ); 272 273 Object value = assertion.getAssertionValue(); 274 if ( value != null ) 275 { 276 if ( ParserUtils.needsBase64Encoding( value ) ) 277 { 278 Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI ); 279 Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI ); 280 element.getDocument().getRootElement().add( xsdNamespace ); 281 element.getDocument().getRootElement().add( xsiNamespace ); 282 283 Element valueElement = newElement.addElement( "value" ).addText( 284 ParserUtils.base64Encode( value ) ); 285 valueElement 286 .addAttribute( new QName( "type", xsiNamespace ), "xsd:" + ParserUtils.BASE64BINARY ); 287 } 288 else 289 { 290 newElement.addElement( "value" ).setText( ( String ) value ); 291 } 292 } 293 } 294 } 295 296 // PRESENT FILTER 297 else if ( filter instanceof PresentFilter ) 298 { 299 Element newElement = element.addElement( "present" ); 300 301 newElement.addAttribute( "name", ( ( PresentFilter ) filter ).getAttributeDescription() ); 302 } 303 304 // EXTENSIBLEMATCH 305 else if ( filter instanceof ExtensibleMatchFilter ) 306 { 307 Element newElement = element.addElement( "extensibleMatch" ); 308 309 ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) filter; 310 311 Object value = extensibleMatchFilter.getMatchValue(); 312 if ( value != null ) 313 { 314 if ( ParserUtils.needsBase64Encoding( value ) ) 315 { 316 Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI ); 317 Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI ); 318 element.getDocument().getRootElement().add( xsdNamespace ); 319 element.getDocument().getRootElement().add( xsiNamespace ); 320 321 Element valueElement = newElement.addElement( "value" ).addText( ParserUtils.base64Encode( value ) ); 322 valueElement.addAttribute( new QName( "type", xsiNamespace ), "xsd:" + ParserUtils.BASE64BINARY ); 323 } 324 else 325 { 326 newElement.addElement( "value" ).setText( ( String ) value ); 327 } 328 } 329 330 if ( extensibleMatchFilter.isDnAttributes() ) 331 { 332 newElement.addAttribute( "dnAttributes", "true" ); 333 } 334 335 String matchingRule = extensibleMatchFilter.getMatchingRule(); 336 if ( ( matchingRule != null ) && ( "".equals( matchingRule ) ) ) 337 { 338 newElement.addAttribute( "matchingRule", matchingRule ); 339 } 340 } 341 } 342 }