blob: 3f3194f11e516a3829a071835cc61cd02e471964 [file] [log] [blame]
/*
* 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();
}
}