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 }