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