1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.query.internal

File AbstractWhereQueryFilter.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

12
22
2
1
110
47
10
0.45
11
2
5

Classes

Class Line # Actions
AbstractWhereQueryFilter 34 22 0% 10 0
1.0100%
 

Contributing tests

This file is covered by 19 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.query.internal;
21   
22    import javax.inject.Inject;
23   
24    import org.slf4j.Logger;
25    import org.xwiki.query.Query;
26    import org.xwiki.query.QueryFilter;
27   
28    /**
29    * Make it easy to create a {@link QueryFilter} that adds a "where" clause.
30    *
31    * @version $Id: 4c83cd1ba30f7cdc9302d7d79659100f23a70883 $
32    * @since 5.1M2
33    */
 
34    public abstract class AbstractWhereQueryFilter implements QueryFilter
35    {
36    /**
37    * SQL where token.
38    */
39    private static final String WHERE = " where ";
40   
41    /**
42    * Used to log debug information.
43    */
44    @Inject
45    private Logger logger;
46   
47    /**
48    * @param statement statement to filter.
49    * @return true if the filter can be applied to the passed statement, false otherwise.
50    */
 
51  876 toggle protected boolean isFilterable(String statement)
52    {
53    // This could be replaced by the following regex: "xwikidocument(\\s)+(as)?(\\s)+doc"
54  876 return statement.indexOf("xwikidocument as doc") > -1 || statement.indexOf("xwikidocument doc") > -1;
55    }
56   
57    /**
58    * Inserts the passed where clause in the passed statement.
59    *
60    * @param whereClause the clause to insert
61    * @param statement the statement in which to insert the clause
62    * @param language the language of the statement
63    * @return the modified statement that includes the passed where clause
64    */
 
65  903 toggle protected String insertWhereClause(String whereClause, String statement, String language)
66    {
67  903 String result = statement.trim();
68  903 String lowerStatement = result.toLowerCase();
69  903 String original = result;
70   
71  903 if (Query.HQL.equals(language) && isFilterable(lowerStatement)) {
72   
73  899 int whereIdx = lowerStatement.indexOf(WHERE);
74  899 int orderByIdx = Math.min(lowerStatement.indexOf(" order by "), Integer.MAX_VALUE);
75  899 int groupByIdx = Math.min(lowerStatement.indexOf(" group by "), Integer.MAX_VALUE);
76    // We need to handle the case where there's only one of them and not both (ie. avoid -1)
77  899 orderByIdx = orderByIdx < 0 ? Integer.MAX_VALUE : orderByIdx;
78  899 groupByIdx = groupByIdx < 0 ? Integer.MAX_VALUE : groupByIdx;
79    // Get the index of the first or only one
80  899 int orderOrGroupByIdx = Math.min(orderByIdx, groupByIdx);
81   
82  899 if (whereIdx >= 0) {
83    // With 'WHERE'
84    // We need the index at the end of the " where " part
85  848 whereIdx = whereIdx + WHERE.length();
86  848 int whereEndIdx = Math.min(orderOrGroupByIdx, lowerStatement.length());
87  848 result = result.substring(0, whereEndIdx) + ")" + result.substring(whereEndIdx);
88  848 result =
89    result.substring(0, whereIdx) + whereClause + " and (" + result.substring(whereIdx);
90    } else {
91    // Without 'WHERE', look for 'ORDER BY' or 'GROUP BY'
92  51 if (orderOrGroupByIdx > 0 && orderOrGroupByIdx < Integer.MAX_VALUE) {
93    // Without 'WHERE', but with 'ORDER BY' and/or 'GROUP BY'
94  49 result = result.substring(0, orderOrGroupByIdx) + WHERE + whereClause
95    + result.substring(orderOrGroupByIdx);
96    } else {
97    // Without 'WHERE', 'ORDER BY' or 'GROUP BY'... This should not happen at all.
98  2 result = result + WHERE + whereClause;
99    }
100    // TODO: Take into account GROUP BY, HAVING and other keywords when there's no WHERE in the query
101    }
102    }
103   
104  903 if (!original.equals(result)) {
105  899 logger.debug("Query [{}] has been transformed into [{}]", original, result);
106    }
107   
108  903 return result;
109    }
110    }