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
021package org.apache.directory.api.ldap.model.filter;
022
023
024import java.util.List;
025
026import org.apache.directory.api.i18n.I18n;
027
028
029/**
030 * Node representing an Not connector in a filter operation
031 * 
032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
033 */
034public class NotNode extends BranchNode
035{
036    /**
037     * Creates a NotNode using a logical NOT operator and a list of children.
038     * 
039     * A Not node could contain only one child
040     * 
041     * @param childList the child nodes under this branch node.
042     */
043    public NotNode( List<ExprNode> childList )
044    {
045        super( AssertionType.NOT );
046
047        if ( childList != null )
048        {
049            setChildren( childList );
050        }
051    }
052
053
054    /**
055     * Creates a NotNode using a logical NOT operator and the given child.
056     * 
057     * @param child the child node under this branch node.
058     */
059    public NotNode( ExprNode child )
060    {
061        super( AssertionType.NOT );
062
063        if ( child != null )
064        {
065            addNode( child );
066        }
067    }
068
069
070    /**
071     * Creates an empty NotNode
072     */
073    public NotNode()
074    {
075        this( ( ExprNode ) null );
076    }
077
078
079    /**
080     * Adds a child node to this NOT node node
081     * 
082     * @param node the child expression to add to this NOT node
083     */
084    @Override
085    public void addNode( ExprNode node )
086    {
087        if ( ( children != null ) && children.isEmpty() )
088        {
089            children.add( node );
090        }
091        else
092        {
093            throw new IllegalStateException( I18n.err( I18n.ERR_13317_NO_MORE_THAN_ONE_ELEM_IN_NOT ) );
094        }
095    }
096
097
098    /**
099     * Adds a child node to this NOT node at the head rather than the tail. 
100     * 
101     * @param node the child expression to add to this branch node
102     */
103    @Override
104    public void addNodeToHead( ExprNode node )
105    {
106        if ( ( children != null ) && children.isEmpty() )
107        {
108            children.add( node );
109        }
110        else
111        {
112            throw new IllegalStateException( I18n.err( I18n.ERR_13317_NO_MORE_THAN_ONE_ELEM_IN_NOT ) );
113        }
114    }
115
116
117    /**
118     * Sets the list of children under this node.
119     * 
120     * @param childList the list of children to set.
121     */
122    @Override
123    public void setChildren( List<ExprNode> childList )
124    {
125        if ( ( childList != null ) && ( childList.size() > 1 ) )
126        {
127            throw new IllegalStateException( I18n.err( I18n.ERR_13317_NO_MORE_THAN_ONE_ELEM_IN_NOT ) );
128        }
129
130        children = childList;
131    }
132
133
134    /**
135     * Gets the operator for this branch node.
136     * 
137     * @return the operator constant.
138     */
139    public AssertionType getOperator()
140    {
141        return AssertionType.NOT;
142    }
143
144
145    /**
146     * Tests whether or not this node is a disjunction (a OR'ed branch).
147     * 
148     * @return true if the operation is a OR, false otherwise.
149     */
150    public boolean isDisjunction()
151    {
152        return false;
153    }
154
155
156    /**
157     * Tests whether or not this node is a conjunction (a AND'ed branch).
158     * 
159     * @return true if the operation is a AND, false otherwise.
160     */
161    public boolean isConjunction()
162    {
163        return false;
164    }
165
166
167    /**
168     * Tests whether or not this node is a negation (a NOT'ed branch).
169     * 
170     * @return true if the operation is a NOT, false otherwise.
171     */
172    public boolean isNegation()
173    {
174        return true;
175    }
176
177
178    /**
179     * @see ExprNode#printRefinementToBuffer(StringBuilder)
180     * 
181     * @return The buffer in which the refinement has been appended
182     * @throws UnsupportedOperationException if this node isn't a part of a refinement.
183     */
184    @Override
185    public StringBuilder printRefinementToBuffer( StringBuilder buf )
186    {
187        buf.append( "not: " );
188
189        // There is only one item for a not refinement
190        children.get( 0 ).printRefinementToBuffer( buf );
191
192        return buf;
193    }
194
195
196    /**
197     * Gets the recursive prefix string represent of the filter from this node
198     * down.
199     * 
200     * @see java.lang.Object#toString()
201     * @return A string representing the AndNode
202     */
203    @Override
204    public String toString()
205    {
206        StringBuilder buf = new StringBuilder();
207        buf.append( "(!" );
208
209        buf.append( super.toString() );
210
211        buf.append( getFirstChild() );
212        buf.append( ')' );
213
214        return buf.toString();
215    }
216}