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, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.security.visibility;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertTrue;
022import static org.junit.Assert.fail;
023
024import org.apache.hadoop.hbase.HBaseClassTestRule;
025import org.apache.hadoop.hbase.security.visibility.expression.ExpressionNode;
026import org.apache.hadoop.hbase.security.visibility.expression.LeafExpressionNode;
027import org.apache.hadoop.hbase.security.visibility.expression.NonLeafExpressionNode;
028import org.apache.hadoop.hbase.security.visibility.expression.Operator;
029import org.apache.hadoop.hbase.testclassification.SecurityTests;
030import org.apache.hadoop.hbase.testclassification.SmallTests;
031import org.junit.ClassRule;
032import org.junit.Test;
033import org.junit.experimental.categories.Category;
034
035@Category({ SecurityTests.class, SmallTests.class })
036public class TestExpressionParser {
037
038  @ClassRule
039  public static final HBaseClassTestRule CLASS_RULE =
040    HBaseClassTestRule.forClass(TestExpressionParser.class);
041
042  private ExpressionParser parser = new ExpressionParser();
043
044  @Test
045  public void testPositiveCases() throws Exception {
046    // abc -> (abc)
047    ExpressionNode node = parser.parse("abc");
048    assertTrue(node instanceof LeafExpressionNode);
049    assertEquals("abc", ((LeafExpressionNode) node).getIdentifier());
050
051    // a&b|c&d -> (((a & b) | c) & )
052    node = parser.parse("a&b|c&d");
053    assertTrue(node instanceof NonLeafExpressionNode);
054    NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
055    assertEquals(Operator.AND, nlNode.getOperator());
056    assertEquals(2, nlNode.getChildExps().size());
057    assertEquals("d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
058    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
059    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
060    assertEquals(Operator.OR, nlNode.getOperator());
061    assertEquals(2, nlNode.getChildExps().size());
062    assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
063    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
064    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
065    assertEquals(Operator.AND, nlNode.getOperator());
066    assertEquals(2, nlNode.getChildExps().size());
067    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
068    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
069
070    // (a) -> (a)
071    node = parser.parse("(a)");
072    assertTrue(node instanceof LeafExpressionNode);
073    assertEquals("a", ((LeafExpressionNode) node).getIdentifier());
074
075    // (a&b) -> (a & b)
076    node = parser.parse(" ( a & b )");
077    assertTrue(node instanceof NonLeafExpressionNode);
078    nlNode = (NonLeafExpressionNode) node;
079    assertEquals(Operator.AND, nlNode.getOperator());
080    assertEquals(2, nlNode.getChildExps().size());
081    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
082    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
083
084    // ((((a&b)))) -> (a & b)
085    node = parser.parse("((((a&b))))");
086    assertTrue(node instanceof NonLeafExpressionNode);
087    nlNode = (NonLeafExpressionNode) node;
088    assertEquals(Operator.AND, nlNode.getOperator());
089    assertEquals(2, nlNode.getChildExps().size());
090    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
091    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
092
093    // (a|b)&(cc|def) -> ((a | b) & (cc | def))
094    node = parser.parse("( a | b ) & (cc|def)");
095    assertTrue(node instanceof NonLeafExpressionNode);
096    nlNode = (NonLeafExpressionNode) node;
097    assertEquals(Operator.AND, nlNode.getOperator());
098    assertEquals(2, nlNode.getChildExps().size());
099    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
100    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
101    NonLeafExpressionNode nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
102    NonLeafExpressionNode nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
103    assertEquals(Operator.OR, nlNodeLeft.getOperator());
104    assertEquals(2, nlNodeLeft.getChildExps().size());
105    assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
106    assertEquals("b", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(1)).getIdentifier());
107    assertEquals(Operator.OR, nlNodeRight.getOperator());
108    assertEquals(2, nlNodeRight.getChildExps().size());
109    assertEquals("cc", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
110    assertEquals("def", ((LeafExpressionNode) nlNodeRight.getChildExps().get(1)).getIdentifier());
111
112    // a&(cc|de) -> (a & (cc | de))
113    node = parser.parse("a&(cc|de)");
114    assertTrue(node instanceof NonLeafExpressionNode);
115    nlNode = (NonLeafExpressionNode) node;
116    assertEquals(Operator.AND, nlNode.getOperator());
117    assertEquals(2, nlNode.getChildExps().size());
118    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
119    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
120    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
121    assertEquals(Operator.OR, nlNode.getOperator());
122    assertEquals(2, nlNode.getChildExps().size());
123    assertEquals("cc", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
124    assertEquals("de", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
125
126    // (a&b)|c -> ((a & b) | c)
127    node = parser.parse("(a&b)|c");
128    assertTrue(node instanceof NonLeafExpressionNode);
129    nlNode = (NonLeafExpressionNode) node;
130    assertEquals(Operator.OR, nlNode.getOperator());
131    assertEquals(2, nlNode.getChildExps().size());
132    assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
133    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
134    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
135    assertEquals(Operator.AND, nlNode.getOperator());
136    assertEquals(2, nlNode.getChildExps().size());
137    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
138    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
139
140    // (a&b&c)|d -> (((a & b) & c) | d)
141    node = parser.parse("(a&b&c)|d");
142    assertTrue(node instanceof NonLeafExpressionNode);
143    nlNode = (NonLeafExpressionNode) node;
144    assertEquals(Operator.OR, nlNode.getOperator());
145    assertEquals(2, nlNode.getChildExps().size());
146    assertEquals("d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
147    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
148    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
149    assertEquals(Operator.AND, nlNode.getOperator());
150    assertEquals(2, nlNode.getChildExps().size());
151    assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
152    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
153    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
154    assertEquals(Operator.AND, nlNode.getOperator());
155    assertEquals(2, nlNode.getChildExps().size());
156    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
157    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
158
159    // a&(b|(c|d)) -> (a & (b | (c | d)))
160    node = parser.parse("a&(b|(c|d))");
161    assertTrue(node instanceof NonLeafExpressionNode);
162    nlNode = (NonLeafExpressionNode) node;
163    assertEquals(Operator.AND, nlNode.getOperator());
164    assertEquals(2, nlNode.getChildExps().size());
165    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
166    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
167    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
168    assertEquals(Operator.OR, nlNode.getOperator());
169    assertEquals(2, nlNode.getChildExps().size());
170    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
171    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
172    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
173    assertEquals(Operator.OR, nlNode.getOperator());
174    assertEquals(2, nlNode.getChildExps().size());
175    assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
176    assertEquals("d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
177
178    // (!a) -> (!a)
179    node = parser.parse("(!a)");
180    assertTrue(node instanceof NonLeafExpressionNode);
181    nlNode = (NonLeafExpressionNode) node;
182    assertEquals(Operator.NOT, nlNode.getOperator());
183    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
184
185    // a&(!b) -> (a & (!b))
186    node = parser.parse("a&(!b)");
187    assertTrue(node instanceof NonLeafExpressionNode);
188    nlNode = (NonLeafExpressionNode) node;
189    assertEquals(Operator.AND, nlNode.getOperator());
190    assertEquals(2, nlNode.getChildExps().size());
191    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
192    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
193    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
194    assertEquals(Operator.NOT, nlNode.getOperator());
195    assertEquals(1, nlNode.getChildExps().size());
196    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
197
198    // !a&b -> ((!a) & b)
199    node = parser.parse("!a&b");
200    assertTrue(node instanceof NonLeafExpressionNode);
201    nlNode = (NonLeafExpressionNode) node;
202    assertEquals(Operator.AND, nlNode.getOperator());
203    assertEquals(2, nlNode.getChildExps().size());
204    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
205    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
206    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
207    assertEquals(Operator.NOT, nlNode.getOperator());
208    assertEquals(1, nlNode.getChildExps().size());
209    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
210
211    // !a&(!b) -> ((!a) & (!b))
212    node = parser.parse("!a&(!b)");
213    assertTrue(node instanceof NonLeafExpressionNode);
214    nlNode = (NonLeafExpressionNode) node;
215    assertEquals(Operator.AND, nlNode.getOperator());
216    assertEquals(2, nlNode.getChildExps().size());
217    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
218    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
219    nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
220    nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
221    assertEquals(Operator.NOT, nlNodeLeft.getOperator());
222    assertEquals(1, nlNodeLeft.getChildExps().size());
223    assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
224    assertEquals(Operator.NOT, nlNodeRight.getOperator());
225    assertEquals(1, nlNodeRight.getChildExps().size());
226    assertEquals("b", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
227
228    // !a&!b -> ((!a) & (!b))
229    node = parser.parse("!a&!b");
230    assertTrue(node instanceof NonLeafExpressionNode);
231    nlNode = (NonLeafExpressionNode) node;
232    assertEquals(Operator.AND, nlNode.getOperator());
233    assertEquals(2, nlNode.getChildExps().size());
234    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
235    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
236    nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
237    nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
238    assertEquals(Operator.NOT, nlNodeLeft.getOperator());
239    assertEquals(1, nlNodeLeft.getChildExps().size());
240    assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
241    assertEquals(Operator.NOT, nlNodeRight.getOperator());
242    assertEquals(1, nlNodeRight.getChildExps().size());
243    assertEquals("b", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
244
245    // !(a&b) -> (!(a & b))
246    node = parser.parse("!(a&b)");
247    assertTrue(node instanceof NonLeafExpressionNode);
248    nlNode = (NonLeafExpressionNode) node;
249    assertEquals(Operator.NOT, nlNode.getOperator());
250    assertEquals(1, nlNode.getChildExps().size());
251    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
252    assertEquals(Operator.AND, nlNode.getOperator());
253    assertEquals(2, nlNode.getChildExps().size());
254    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
255    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
256
257    // a&!b -> (a & (!b))
258    node = parser.parse("a&!b");
259    assertTrue(node instanceof NonLeafExpressionNode);
260    nlNode = (NonLeafExpressionNode) node;
261    assertEquals(Operator.AND, nlNode.getOperator());
262    assertEquals(2, nlNode.getChildExps().size());
263    assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
264    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
265    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
266    assertEquals(Operator.NOT, nlNode.getOperator());
267    assertEquals(1, nlNode.getChildExps().size());
268    assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
269
270    // !((a|b)&!(c&!b)) -> (!((a | b) & (!(c & (!b)))))
271    node = parser.parse("!((a | b) & !(c & !b))");
272    assertTrue(node instanceof NonLeafExpressionNode);
273    nlNode = (NonLeafExpressionNode) node;
274    assertEquals(Operator.NOT, nlNode.getOperator());
275    assertEquals(1, nlNode.getChildExps().size());
276    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
277    assertEquals(Operator.AND, nlNode.getOperator());
278    assertEquals(2, nlNode.getChildExps().size());
279    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
280    assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
281    nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
282    nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
283    assertEquals(Operator.OR, nlNodeLeft.getOperator());
284    assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
285    assertEquals("b", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(1)).getIdentifier());
286    assertEquals(Operator.NOT, nlNodeRight.getOperator());
287    assertEquals(1, nlNodeRight.getChildExps().size());
288    nlNodeRight = (NonLeafExpressionNode) nlNodeRight.getChildExps().get(0);
289    assertEquals(Operator.AND, nlNodeRight.getOperator());
290    assertEquals(2, nlNodeRight.getChildExps().size());
291    assertEquals("c", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
292    assertTrue(nlNodeRight.getChildExps().get(1) instanceof NonLeafExpressionNode);
293    nlNodeRight = (NonLeafExpressionNode) nlNodeRight.getChildExps().get(1);
294    assertEquals(Operator.NOT, nlNodeRight.getOperator());
295    assertEquals(1, nlNodeRight.getChildExps().size());
296    assertEquals("b", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
297  }
298
299  @Test
300  public void testNegativeCases() throws Exception {
301    executeNegativeCase("(");
302    executeNegativeCase(")");
303    executeNegativeCase("()");
304    executeNegativeCase("(a");
305    executeNegativeCase("a&");
306    executeNegativeCase("a&|b");
307    executeNegativeCase("!");
308    executeNegativeCase("a!");
309    executeNegativeCase("a!&");
310    executeNegativeCase("&");
311    executeNegativeCase("|");
312    executeNegativeCase("!(a|(b&c)&!b");
313    executeNegativeCase("!!a");
314    executeNegativeCase("( a & b ) | ( c & d e)");
315    executeNegativeCase("! a");
316  }
317
318  @Test
319  public void testNonAsciiCases() throws Exception {
320    ExpressionNode node =
321      parser.parse(CellVisibility.quote("\u0027") + "&" + CellVisibility.quote("\u002b") + "|"
322        + CellVisibility.quote("\u002d") + "&" + CellVisibility.quote("\u003f"));
323    assertTrue(node instanceof NonLeafExpressionNode);
324    NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
325    assertEquals(Operator.AND, nlNode.getOperator());
326    assertEquals(2, nlNode.getChildExps().size());
327    assertEquals("\u003f", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
328    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
329    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
330    assertEquals(Operator.OR, nlNode.getOperator());
331    assertEquals(2, nlNode.getChildExps().size());
332    assertEquals("\u002d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
333    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
334    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
335    assertEquals(Operator.AND, nlNode.getOperator());
336    assertEquals(2, nlNode.getChildExps().size());
337    assertEquals("\u002b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
338    assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
339
340    node = parser.parse(CellVisibility.quote("\u0027") + "&" + CellVisibility.quote("\u002b") + "|"
341      + CellVisibility.quote("\u002d") + "&" + CellVisibility.quote("\u003f"));
342    assertTrue(node instanceof NonLeafExpressionNode);
343    nlNode = (NonLeafExpressionNode) node;
344    assertEquals(Operator.AND, nlNode.getOperator());
345    assertEquals(2, nlNode.getChildExps().size());
346    assertEquals("\u003f", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
347    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
348    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
349    assertEquals(Operator.OR, nlNode.getOperator());
350    assertEquals(2, nlNode.getChildExps().size());
351    assertEquals("\u002d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
352    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
353    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
354    assertEquals(Operator.AND, nlNode.getOperator());
355    assertEquals(2, nlNode.getChildExps().size());
356    assertEquals("\u002b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
357    assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
358  }
359
360  @Test
361  public void testCasesSeperatedByDoubleQuotes() throws Exception {
362    ExpressionNode node = null;
363    try {
364      node = parser.parse("\u0027&\"|\u002b&\u003f");
365      fail("Excpetion must be thrown as there are special characters without quotes");
366    } catch (ParseException e) {
367    }
368    node = parser.parse(CellVisibility.quote("\u0027") + "&" + CellVisibility.quote("\"") + "|"
369      + CellVisibility.quote("\u002b" + "&" + "\u003f"));
370    assertTrue(node instanceof NonLeafExpressionNode);
371    NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
372    assertEquals(Operator.OR, nlNode.getOperator());
373    assertEquals(2, nlNode.getChildExps().size());
374    assertEquals("\u002b" + "&" + "\u003f",
375      ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
376    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
377    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
378    assertEquals(Operator.AND, nlNode.getOperator());
379    assertEquals(2, nlNode.getChildExps().size());
380    assertEquals("\"", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
381    assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
382    try {
383      node = parser.parse(CellVisibility.quote("\u0027&\\") + "|"
384        + CellVisibility.quote("\u002b" + "&" + "\\") + CellVisibility.quote("$$\""));
385      fail("Excpetion must be thrown as there is not operator");
386    } catch (ParseException e) {
387    }
388    node = parser.parse(CellVisibility.quote("\u0027" + "&" + "\\") + "|"
389      + CellVisibility.quote("\u003f" + "&" + "\\") + "&" + CellVisibility.quote("$$\""));
390    assertTrue(node instanceof NonLeafExpressionNode);
391    nlNode = (NonLeafExpressionNode) node;
392    assertEquals(Operator.AND, nlNode.getOperator());
393    assertEquals(2, nlNode.getChildExps().size());
394    assertEquals("$$\"", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
395    assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
396    nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
397    assertEquals(Operator.OR, nlNode.getOperator());
398    assertEquals(2, nlNode.getChildExps().size());
399    assertEquals("\u0027" + "&" + "\\",
400      ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
401    assertEquals("\u003f" + "&" + "\\",
402      ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
403    try {
404      node = parser.parse(
405        CellVisibility.quote("\u002b&\\") + "|" + CellVisibility.quote("\u0027&\\") + "&" + "\"$$");
406      fail("Excpetion must be thrown as there is no end quote");
407    } catch (ParseException e) {
408    }
409  }
410
411  private void executeNegativeCase(String exp) {
412    try {
413      parser.parse(exp);
414      fail("Expected ParseException for expression " + exp);
415    } catch (ParseException e) {
416    }
417  }
418}