| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.directory.shared.ldap.model.filter; |
| |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.regex.Pattern; |
| import java.util.regex.PatternSyntaxException; |
| |
| import org.apache.directory.shared.ldap.model.entry.StringValue; |
| import org.apache.directory.shared.ldap.model.exception.LdapException; |
| import org.apache.directory.shared.ldap.model.schema.AttributeType; |
| import org.apache.directory.shared.ldap.model.schema.Normalizer; |
| |
| |
| /** |
| * Filter expression tree node used to represent a substring assertion. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public class SubstringNode extends LeafNode |
| { |
| /** The initial fragment before any wildcard */ |
| private String initialPattern; |
| |
| /** The end fragment after wildcard */ |
| private String finalPattern; |
| |
| /** List of fragments between wildcard */ |
| private List<String> anyPattern; |
| |
| /** |
| * Creates a new SubstringNode object with only one wildcard and no internal |
| * any fragments between wildcards. |
| * |
| * @param attributeType the name of the attributeType to substring assert |
| * @param initialPattern the initial fragment |
| * @param finalPattern the final fragment |
| */ |
| public SubstringNode( AttributeType attributeType, String initialPattern, String finalPattern ) |
| { |
| super( attributeType, AssertionType.SUBSTRING ); |
| |
| anyPattern = new ArrayList<String>( 2 ); |
| this.finalPattern = finalPattern; |
| this.initialPattern = initialPattern; |
| } |
| |
| |
| /** |
| * Creates a new SubstringNode object with only one wildcard and no internal |
| * any fragments between wildcards. |
| * |
| * @param attribute the name of the attribute to substring assert |
| * @param initialPattern the initial fragment |
| * @param finalPattern the final fragment |
| */ |
| public SubstringNode( String attribute, String initialPattern, String finalPattern ) |
| { |
| super( attribute, AssertionType.SUBSTRING ); |
| |
| anyPattern = new ArrayList<String>( 2 ); |
| this.finalPattern = finalPattern; |
| this.initialPattern = initialPattern; |
| } |
| |
| |
| /** |
| * Creates a new SubstringNode object without any value |
| * |
| * @param attribute the name of the attribute to substring assert |
| */ |
| public SubstringNode( AttributeType attribute ) |
| { |
| super( attribute, AssertionType.SUBSTRING ); |
| |
| anyPattern = new ArrayList<String>( 2 ); |
| this.finalPattern = null; |
| this.initialPattern = null; |
| } |
| |
| |
| /** |
| * Creates a new SubstringNode object without any value |
| * |
| * @param attributeType the attributeType to substring assert |
| */ |
| public SubstringNode( String attributeType ) |
| { |
| super( attributeType, AssertionType.SUBSTRING ); |
| |
| anyPattern = new ArrayList<String>( 2 ); |
| this.finalPattern = null; |
| this.initialPattern = null; |
| } |
| |
| |
| /** |
| * Creates a new SubstringNode object more than one wildcard and an any |
| * list. |
| * |
| * @param anyPattern list of internal fragments between wildcards |
| * @param attributeType the attributeType to substring assert |
| * @param initialPattern the initial fragment |
| * @param finalPattern the final fragment |
| */ |
| public SubstringNode( List<String> anyPattern, AttributeType attributeType, String initialPattern, String finalPattern ) |
| { |
| super( attributeType, AssertionType.SUBSTRING ); |
| |
| this.anyPattern = anyPattern; |
| this.finalPattern = finalPattern; |
| this.initialPattern = initialPattern; |
| } |
| |
| |
| /** |
| * Creates a new SubstringNode object more than one wildcard and an any |
| * list. |
| * |
| * @param anyPattern list of internal fragments between wildcards |
| * @param attribute the name of the attribute to substring assert |
| * @param initialPattern the initial fragment |
| * @param finalPattern the final fragment |
| */ |
| public SubstringNode( List<String> anyPattern, String attribute, String initialPattern, String finalPattern ) |
| { |
| super( attribute, AssertionType.SUBSTRING ); |
| |
| this.anyPattern = anyPattern; |
| this.finalPattern = finalPattern; |
| this.initialPattern = initialPattern; |
| } |
| |
| /** |
| * Creates a regular expression from an LDAP substring assertion filter |
| * specification. |
| * |
| * @param initialPattern |
| * the initial fragment before wildcards |
| * @param anyPattern |
| * fragments surrounded by wildcards if any |
| * @param finalPattern |
| * the final fragment after last wildcard if any |
| * @return the regular expression for the substring match filter |
| * @throws java.util.regex.PatternSyntaxException |
| * if a syntactically correct regular expression cannot be |
| * compiled |
| */ |
| public static Pattern getRegex( String initialPattern, String[] anyPattern, String finalPattern ) |
| throws PatternSyntaxException |
| { |
| StringBuffer buf = new StringBuffer(); |
| |
| if ( initialPattern != null ) |
| { |
| buf.append( '^' ).append( Pattern.quote( initialPattern ) ); |
| } |
| |
| if ( anyPattern != null ) |
| { |
| for ( int i = 0; i < anyPattern.length; i++ ) |
| { |
| buf.append( ".*" ).append( Pattern.quote( anyPattern[i] ) ); |
| } |
| } |
| |
| if ( finalPattern != null ) |
| { |
| buf.append( ".*" ).append( Pattern.quote( finalPattern ) ); |
| } |
| else |
| { |
| buf.append( ".*" ); |
| } |
| |
| return Pattern.compile(buf.toString()); |
| } |
| |
| |
| /** |
| * Clone the Node |
| */ |
| @Override public ExprNode clone() |
| { |
| ExprNode clone = (ExprNode)super.clone(); |
| |
| if ( anyPattern != null ) |
| { |
| ((SubstringNode)clone).anyPattern = new ArrayList<String>(); |
| |
| for ( String any:anyPattern ) |
| { |
| ((SubstringNode)clone).anyPattern.add( any ); |
| } |
| } |
| |
| return clone; |
| } |
| |
| |
| /** |
| * Gets the initial fragment. |
| * |
| * @return the initial prefix |
| */ |
| public final String getInitial() |
| { |
| return initialPattern; |
| } |
| |
| |
| /** |
| * Set the initial pattern |
| * @param initialPattern The initial pattern |
| */ |
| public void setInitial( String initialPattern ) |
| { |
| this.initialPattern = initialPattern; |
| } |
| |
| |
| /** |
| * Gets the final fragment or suffix. |
| * |
| * @return the suffix |
| */ |
| public final String getFinal() |
| { |
| return finalPattern; |
| } |
| |
| |
| /** |
| * Set the final pattern |
| * @param finalPattern The final pattern |
| */ |
| public void setFinal( String finalPattern ) |
| { |
| this.finalPattern = finalPattern; |
| } |
| |
| |
| /** |
| * Gets the list of wildcard surrounded any fragments. |
| * |
| * @return the any fragments |
| */ |
| public final List<String> getAny() |
| { |
| return anyPattern; |
| } |
| |
| |
| /** |
| * Set the any patterns |
| * @param anyPattern The any patterns |
| */ |
| public void setAny( List<String> anyPattern ) |
| { |
| this.anyPattern = anyPattern; |
| } |
| |
| |
| /** |
| * Add an any pattern |
| * @param anyPattern The any pattern |
| */ |
| public void addAny( String anyPattern ) |
| { |
| this.anyPattern.add( anyPattern ); |
| } |
| |
| |
| /** |
| * Gets the compiled regular expression for the substring expression. |
| * |
| * @param normalizer the normalizer to use for pattern component normalization |
| * @return the equivalent compiled regular expression |
| * @throws LdapException if there are problems while normalizing |
| */ |
| public final Pattern getRegex( Normalizer normalizer ) throws LdapException |
| { |
| if ( ( anyPattern != null ) && ( anyPattern.size() > 0 ) ) |
| { |
| String[] any = new String[anyPattern.size()]; |
| |
| for ( int i = 0; i < any.length; i++ ) |
| { |
| any[i] = ( String ) normalizer.normalize( anyPattern.get( i ) ); |
| |
| if ( any[i].length() == 0 ) |
| { |
| any[i] = " "; |
| } |
| } |
| |
| String initialStr = null; |
| |
| if ( initialPattern != null ) |
| { |
| initialStr = ( String ) normalizer.normalize( initialPattern ); |
| } |
| |
| String finalStr = null; |
| |
| if ( finalPattern != null ) |
| { |
| finalStr = ( String ) normalizer.normalize( finalPattern ); |
| } |
| |
| return getRegex(initialStr, any, finalStr); |
| } |
| |
| String initialStr = null; |
| |
| if ( initialPattern != null ) |
| { |
| initialStr = ( String ) normalizer.normalize( initialPattern ); |
| } |
| |
| String finalStr = null; |
| |
| if ( finalPattern != null ) |
| { |
| finalStr = ( String ) normalizer.normalize( finalPattern ); |
| } |
| |
| return getRegex(initialStr, null, finalStr); |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public boolean equals( Object obj ) |
| { |
| if ( obj == this ) |
| { |
| return true; |
| } |
| |
| if ( ( obj == null ) || !( obj instanceof SubstringNode ) ) |
| { |
| return false; |
| } |
| SubstringNode that = ( SubstringNode ) obj; |
| |
| if ( initialPattern == null ) |
| { |
| if ( that.initialPattern != null ) |
| { |
| return false; |
| } |
| } |
| else |
| { |
| if ( !initialPattern.equals( that.initialPattern ) ) |
| { |
| return false; |
| } |
| } |
| |
| if ( finalPattern == null ) |
| { |
| if ( that.finalPattern != null ) |
| { |
| return false; |
| } |
| } |
| else |
| { |
| if ( !finalPattern.equals( that.finalPattern ) ) |
| { |
| return false; |
| } |
| } |
| |
| return super.equals( obj ); |
| } |
| |
| |
| /** |
| * @see Object#hashCode() |
| * @return the instance's hash code |
| */ |
| @Override |
| public int hashCode() |
| { |
| int h = 37; |
| |
| h = h*17 + super.hashCode(); |
| h = h*17 + ( initialPattern != null ? initialPattern.hashCode() : 0 ); |
| |
| if ( anyPattern != null ) |
| { |
| for ( String pattern:anyPattern ) |
| { |
| h = h*17 + pattern.hashCode(); |
| } |
| } |
| |
| h = h*17 + ( finalPattern != null ? finalPattern.hashCode() : 0 ); |
| |
| return h; |
| } |
| |
| |
| /** |
| * @see java.lang.Object#toString() |
| * @return A string representing the AndNode |
| */ |
| public String toString() |
| { |
| StringBuilder buf = new StringBuilder(); |
| |
| buf.append( '(' ); |
| |
| if ( attributeType != null ) |
| { |
| buf.append( attributeType.getName() ); |
| } |
| else |
| { |
| buf.append( attribute ); |
| } |
| |
| |
| buf.append( '=' ); |
| |
| if ( null != initialPattern ) |
| { |
| buf.append( escapeFilterValue( new StringValue( initialPattern ) ) ).append( '*' ); |
| } |
| else |
| { |
| buf.append( '*' ); |
| } |
| |
| if ( null != anyPattern ) |
| { |
| for ( String any:anyPattern ) |
| { |
| buf.append( escapeFilterValue( new StringValue( any ) ) ); |
| buf.append( '*' ); |
| } |
| } |
| |
| if ( null != finalPattern ) |
| { |
| buf.append( escapeFilterValue( new StringValue( finalPattern ) ) ); |
| } |
| |
| buf.append( super.toString() ); |
| |
| buf.append( ')' ); |
| |
| return buf.toString(); |
| } |
| } |