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            throw new IllegalStateException( I18n.err( I18n.ERR_04159 ) );
090        }
091
092        children.add( node );
093    }
094
095
096    /**
097     * Adds a child node to this NOT node at the head rather than the tail. 
098     * 
099     * @param node the child expression to add to this branch node
100     */
101    @Override
102    public void addNodeToHead( ExprNode node )
103    {
104        if ( !children.isEmpty() )
105        {
106            throw new IllegalStateException( I18n.err( I18n.ERR_04159 ) );
107        }
108
109        children.add( node );
110    }
111
112
113    /**
114     * Sets the list of children under this node.
115     * 
116     * @param childList the list of children to set.
117     */
118    @Override
119    public void setChildren( List<ExprNode> childList )
120    {
121        if ( ( childList != null ) && ( childList.size() > 1 ) )
122        {
123            throw new IllegalStateException( I18n.err( I18n.ERR_04159 ) );
124        }
125
126        children = childList;
127    }
128
129
130    /**
131     * Gets the operator for this branch node.
132     * 
133     * @return the operator constant.
134     */
135    public AssertionType getOperator()
136    {
137        return AssertionType.NOT;
138    }
139
140
141    /**
142     * Tests whether or not this node is a disjunction (a OR'ed branch).
143     * 
144     * @return true if the operation is a OR, false otherwise.
145     */
146    public boolean isDisjunction()
147    {
148        return false;
149    }
150
151
152    /**
153     * Tests whether or not this node is a conjunction (a AND'ed branch).
154     * 
155     * @return true if the operation is a AND, false otherwise.
156     */
157    public boolean isConjunction()
158    {
159        return false;
160    }
161
162
163    /**
164     * Tests whether or not this node is a negation (a NOT'ed branch).
165     * 
166     * @return true if the operation is a NOT, false otherwise.
167     */
168    public boolean isNegation()
169    {
170        return true;
171    }
172
173
174    /**
175     * @see ExprNode#printRefinementToBuffer(StringBuilder)
176     * 
177     * @param buf The buffer where we store the result
178     * @return The buffer in which the refinement has been appended
179     * @throws UnsupportedOperationException if this node isn't a part of a refinement.
180     */
181    @Override
182    public StringBuilder printRefinementToBuffer( StringBuilder buf )
183    {
184        buf.append( "not: " );
185
186        // There is only one item for a not refinement
187        children.get( 0 ).printRefinementToBuffer( buf );
188
189        return buf;
190    }
191
192
193    /**
194     * Gets the recursive prefix string represent of the filter from this node
195     * down.
196     * 
197     * @see java.lang.Object#toString()
198     * @return A string representing the AndNode
199     */
200    @Override
201    public String toString()
202    {
203        StringBuilder buf = new StringBuilder();
204        buf.append( "(!" );
205
206        buf.append( super.toString() );
207
208        buf.append( getFirstChild() );
209        buf.append( ')' );
210
211        return buf.toString();
212    }
213}