Move adsal into its own subdirectory.
[controller.git] / opendaylight / adsal / northbound / commons / src / test / java / org / opendaylight / controller / northbound / commons / query / ExpresssionTest.java
1 /**
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.northbound.commons.query;
9
10 import java.lang.reflect.Field;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.List;
14 import java.util.regex.Pattern;
15
16 import org.junit.Assert;
17 import org.junit.BeforeClass;
18 import org.junit.Test;
19 import org.opendaylight.controller.northbound.commons.query.CompareExpression.OP;
20
21 public class ExpresssionTest {
22
23     private static final List<PersonBean> people = new ArrayList<PersonBean>();
24     private static final ArrayList<BookBean> books = new ArrayList<BookBean>();
25
26     public static void p(String msg) {
27         //System.out.println("======= " + msg);
28     }
29
30     public static boolean matches(Expression exp, final PersonBean person) throws Exception {
31
32         boolean result = exp.accept(new Visitor() {
33             @Override
34             public boolean visit(LogicalExpression le) throws QueryException {
35                 p("=== LE " + le.getOperator() + "|" + le.getFirst() + "|" + le.getSecond());
36                 return (le.getOperator() == LogicalExpression.OP.AND) ?
37                         le.getFirst().accept(this) && le.getSecond().accept(this) :
38                             le.getFirst().accept(this) || le.getSecond().accept(this);
39             }
40
41             @Override
42             public boolean visit(CompareExpression ce) {
43                 p("=== CE " + ce.getOperator() + "|" + ce.getSelector() + "|" + ce.getArgument());
44                 if (person == null) {
45                     return false;
46                 }
47                 try {
48                     // check if the selector matches any of the fields
49                     Field field = PersonBean.class.getDeclaredField(ce.getSelector());
50                     if (field == null) {
51                         p("No field found by name : " + ce.getSelector());
52                         return false;
53                     }
54                     Object value = field.get(person);
55                     if (value instanceof String) {
56                         p("Comparing [" + ce.getArgument() + "] "+ ce.getOperator() + " [" + value.toString() + "]");
57                         if (ce.getOperator() == OP.EQ) {
58                             return ce.getArgument().equals(value.toString());
59                         } else if (ce.getOperator() == OP.RE) {
60                             return Pattern.matches(ce.getArgument(), value.toString());
61                         } else if (ce.getOperator() == OP.NE) {
62                             return !ce.getArgument().equals(value.toString());
63                         } else {
64                             p("Comparator : " + ce.getOperator() + " cannot apply to Strings");
65                             return false;
66                         }
67                     } else {
68                         // assume its a #
69                         int valToMatch = Integer.parseInt(ce.getArgument());
70                         int actualValue = (Integer)value;
71                         p("Comparing: " + valToMatch + " " + ce.getOperator() + " " + actualValue);
72                         switch(ce.getOperator()) {
73                         case EQ :
74                         case RE :
75                             return actualValue == valToMatch;
76                         case NE :
77                             return actualValue != valToMatch;
78                         case GT :
79                             return actualValue > valToMatch;
80                         case GE :
81                             return actualValue >= valToMatch;
82                         case LT :
83                             return actualValue < valToMatch;
84                         case LE :
85                             return actualValue <= valToMatch;
86                         default:
87                             p("Unrecognized compare operator: " + ce.getOperator());
88                             return false;
89                         }
90                     }
91                 } catch (Exception e) {
92                     throw new IllegalStateException(e);
93                 }
94             }
95         });
96         p("RESULT: " + result);
97         return result;
98     }
99
100     @BeforeClass
101     public static void load() {
102         System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
103
104         people.add(new PersonBean(100, "John", "Doe", "San Jose"));
105         people.add(new PersonBean(200, "Foo", "Bar", "San Francisco"));
106         people.add(new PersonBean(300, "A", "B", "San Francisco"));
107         people.add(new PersonBean(400, "X", "Y", "New York"));
108
109         books.add(new BookBean("Book1", "A001", people.get(0)));
110         books.add(new BookBean("Book2", "A002", people.get(1)));
111         books.add(new BookBean("Book3", "A003", people.get(2)));
112
113         ReviewBean review1 = new ReviewBean("cool", people.get(2));
114         ReviewBean review2 = new ReviewBean("kewl", people.get(3));
115         ReviewBean review3 = new ReviewBean("+++", people.get(0));
116         ReviewBean review4 = new ReviewBean("---", people.get(1));
117
118         books.get(0).addReview(review1).addReview(review2).addReview(review3).addReview(review4);
119         books.get(1).addReview(review1).addReview(review2).addReview(review3).addReview(review4);
120         books.get(2).addReview(review1).addReview(review2).addReview(review3).addReview(review4);
121     }
122
123     @Test
124     public void testCXFQueries() throws Exception {
125         // following queries copied from apache cxf
126         Assert.assertFalse(matches(parseQuery("id=gt=100;name=Fred"), null));
127         Assert.assertFalse(matches(parseQuery("id=gt=100;name==Fred"), null));
128         Assert.assertFalse(matches(parseQuery("id=lt=123"), null));
129         Assert.assertFalse(matches(parseQuery("date=le=2010-03-11"), null));
130         Assert.assertFalse(matches(parseQuery("time=le=2010-03-11T18:00:00"), null));
131         Assert.assertFalse(matches(parseQuery("name==CXF;version=ge=2.2"), null));
132         Assert.assertFalse(matches(parseQuery("(age=lt=25,age=gt=35);city==London"), null));
133         Assert.assertFalse(matches(parseQuery("date=lt=2000-01-01;date=gt=1999-01-01;(sub==math,sub==physics)"), null));
134     }
135
136     public Expression parseQuery(String query) throws Exception {
137         p("PARSING query: " + query);
138         // FiqlParser is a parser generated by javacc
139         Expression exp = FiqlParser.parse(query);
140         p(exp.toString());
141         return exp;
142     }
143
144     public int find(String query) throws Exception {
145         int found = 0;
146         Expression exp = parseQuery(query);
147         TypeInfo.createRoot("person", PersonBean.class);
148         for (PersonBean person : people) {
149             if (matches(exp, person)) found++;
150         }
151         return found;
152     }
153
154     @Test
155     public void testPeopleQueries() throws Exception {
156         Assert.assertTrue(find("id==200") == 1);
157         Assert.assertTrue(find("id!=100;(city='San.*')") == 2);
158         Assert.assertTrue(find("id>200;(city='San.*')") == 1);
159         Assert.assertTrue(find("city='San.*'") == 3);
160     }
161
162     @Test
163     public void testTypeTree() throws Exception {
164         TypeInfo bookType = TypeInfo.createRoot("book", BookBean.class);
165         Assert.assertEquals("John", bookType.retrieve(books.get(0),
166                 "book.author.firstName".split("\\."), 1));
167         Object result = bookType.retrieve(books.get(0),
168                 "book.reviews.review.comment".split("\\."), 1);
169         Assert.assertTrue( result instanceof List);
170         List<Object> commentList = (List<Object>) result;
171         Assert.assertTrue(commentList.contains("cool"));
172     }
173
174     @Test
175     public void testQueryAPI() throws Exception {
176         QueryContext qc = new QueryContextImpl();
177
178         // find all books written by author with firstName "John"
179         Query q1 = qc.createQuery("book.author.firstName==John", BookBean.class);
180         Collection<BookBean> r1 = q1.find(books);
181         p("Filtered books: " + r1.size());
182         Assert.assertEquals(1, r1.size());
183
184         // find all books reviewed by people in a city "San*"
185         Query q2 = qc.createQuery("book.reviews.review.reviewer.city=San.*", BookBean.class);
186         Collection<BookBean> r2 = q2.find(books);
187
188         p("Filtered books: " + r2.size());
189         Assert.assertEquals(3, r2.size());
190
191         // find all books reviewed by people in a city "San*"
192         Query q3 = qc.createQuery("book==foo", BookBean.class);
193         Collection<BookBean> r3 = q3.find(books);
194         Assert.assertEquals(0, r3.size());
195     }
196
197     @Test
198     public void testFilter() throws Exception {
199         Library library = new Library((List)books.clone());
200         QueryContext qc = new QueryContextImpl();
201         // find all books written by author with firstName "John"
202         Query q1 = qc.createQuery("book.author.firstName==John", Library.class);
203         int sizeBefore = library.getList().size();
204         System.out.println(q1.filter(library, BookBean.class));
205         Assert.assertEquals(1, library.getList().size());
206     }
207 }