@@ -25,17 +25,11 @@ public class PagedQuery {
2525
2626 private static final Pattern LIMIT_OR_OFFSET = Pattern .compile ("((limit)|(offset))\\ s+\\ d+" , FLAGS );
2727
28- private static final Pattern SPLITTER = Pattern .compile ("\\ s" );
29-
30- private static final Pattern OFFSET_PATTERN = Pattern .compile ("\\ boffset\\ s+\\ d+\\ b" , FLAGS );
31-
32- private static final Pattern LIMIT_PATTERN = Pattern .compile ("\\ blimit\\ s+\\ d+\\ b" , FLAGS );
33-
3428 private static final Pattern SERQL_NAMESPACE = Pattern .compile ("\\ busing namespace\\ b" , FLAGS );
3529
3630 private final String modifiedQuery ;
3731
38- private final boolean hasLimitAndOffset ;
32+ private final boolean inlineLimitAndOffset ;
3933
4034 private int limitSubstitute , offsetSubstitute ;
4135
@@ -68,49 +62,27 @@ public PagedQuery(final String query, final QueryLanguage language, final int re
6862
6963 String rval = query ;
7064
65+ /*
66+ * the matcher on the pattern will have a group for "limit l#" as well as a group for l#, similarly
67+ * for "offset o#" and o#. If either exists, disable paging.
68+ */
69+ final Matcher matcher = LIMIT_OR_OFFSET .matcher (query );
7170 // requestLimit <= 0 actually means don't limit display
72- hasLimitAndOffset = requestLimit > 0 ;
73- if (hasLimitAndOffset ) {
74- /*
75- * the matcher on the pattern will have a group for "limit l#" as well as a group for l#,
76- * similarly for "offset o#" and o#. If either doesn't exist, it can be appended at the end.
77- */
78- int queryLimit = -1 ;
79- int queryOffset = -1 ;
80- final Matcher matcher = LIMIT_OR_OFFSET .matcher (query );
81- while (matcher .find ()) {
82- final String clause = matcher .group ().toLowerCase ();
83- final int value = Integer .parseInt (SPLITTER .split (clause )[1 ]);
84- if (clause .startsWith ("limit" )) {
85- if (query .indexOf ('}' , matcher .end ()) < 0 ) {
86- queryLimit = value ;
87- }
88- }
89- else {
90- queryOffset = value ;
91- }
92- }
93-
94- final boolean queryLimitExists = (queryLimit >= 0 );
95- final boolean queryOffsetExists = (queryOffset >= 0 );
96- final int maxQueryCount = getMaxQueryResultCount (queryLimit , queryOffset , queryLimitExists ,
97- queryOffsetExists );
98- // gracefully handle malicious value
99- final int offset = (requestOffset < 0 ) ? 0 : requestOffset ;
100- final int maxRequestCount = requestLimit + offset ;
101- limitSubstitute = (maxRequestCount < maxQueryCount ) ? requestLimit : queryLimit - offset ;
102- offsetSubstitute = queryOffsetExists ? queryOffset + offset : offset ;
103- rval = modifyLimit (language , rval , queryLimit , queryLimitExists , queryOffsetExists ,
104- limitSubstitute );
105- rval = modifyOffset (language , offset , rval , queryOffsetExists );
71+ inlineLimitAndOffset = requestLimit > 0 && !matcher .find ();
72+ // gracefully handle malicious value
73+ offsetSubstitute = (requestOffset < 0 ) ? 0 : requestOffset ;
74+ limitSubstitute = requestLimit ;
75+ if (inlineLimitAndOffset ) {
76+ rval = modifyLimit (language , rval , limitSubstitute );
77+ rval = modifyOffset (language , offsetSubstitute , rval );
10678 LOGGER .debug ("Modified Query: {}" , rval );
10779 }
10880
10981 this .modifiedQuery = rval ;
11082 }
11183
11284 public boolean isPaged () {
113- return this .hasLimitAndOffset ;
85+ return this .inlineLimitAndOffset ;
11486 }
11587
11688 public int getLimit () {
@@ -126,42 +98,19 @@ public String toString() {
12698 return this .modifiedQuery ;
12799 }
128100
129- private static int getMaxQueryResultCount (final int queryLimit , final int queryOffset ,
130- final boolean queryLimitExists , final boolean queryOffsetExists )
131- {
132- final int maxQueryCount = queryLimitExists ? (queryLimit + (queryOffsetExists ? queryOffset : 0 ))
133- : Integer .MAX_VALUE ;
134- return maxQueryCount ;
135- }
136-
137- private String modifyOffset (final QueryLanguage language , final int offset , final String query ,
138- final boolean queryOffsetExists )
139- {
101+ private String modifyOffset (final QueryLanguage language , final int offset , final String query ) {
140102 String rval = query ;
141- if (queryOffsetExists ) {
142- if (offsetSubstitute != offset ) {
143- // do a clause replacement
144- final Matcher offsetMatcher = OFFSET_PATTERN .matcher (rval );
145- final StringBuffer buffer = new StringBuffer ();
146- offsetMatcher .find ();
147- offsetMatcher .appendReplacement (buffer , "offset " + offsetSubstitute );
148- offsetMatcher .appendTail (buffer );
149- rval = buffer .toString ();
103+ final String newOffsetClause = "offset " + offset ;
104+ if (QueryLanguage .SPARQL == language ) {
105+ if (offset > 0 ) {
106+ rval = ensureNewlineAndAppend (rval , newOffsetClause );
150107 }
151108 }
152109 else {
153- final String newOffsetClause = "offset " + offset ;
154- if (QueryLanguage .SPARQL == language ) {
155- if (offset > 0 ) {
156- rval = ensureNewlineAndAppend (rval , newOffsetClause );
157- }
158- }
159- else {
160- /*
161- * SeRQL, add the clause before before the namespace section
162- */
163- rval = insertAtMatchOnOwnLine (SERQL_NAMESPACE , rval , newOffsetClause );
164- }
110+ /*
111+ * SeRQL, add the clause before before the namespace section
112+ */
113+ rval = insertAtMatchOnOwnLine (SERQL_NAMESPACE , rval , newOffsetClause );
165114 }
166115 return rval ;
167116 }
@@ -176,8 +125,8 @@ private static String ensureNewlineAndAppend(final String original, final String
176125 return buffer .append (append ).toString ();
177126 }
178127
179- private static String modifyLimit (final QueryLanguage language , final String query , final int queryLimit ,
180- final boolean queryLimitExists , final boolean queryOffsetExists , final int limitSubstitute )
128+ private static String modifyLimit (final QueryLanguage language , final String query ,
129+ final int limitSubstitute )
181130 {
182131 String rval = query ;
183132
@@ -187,29 +136,11 @@ private static String modifyLimit(final QueryLanguage language, final String que
187136 * and LIMIT must precede OFFSET. This code makes no attempt to correct if the user places them out of
188137 * order in the query.
189138 */
190- if (queryLimitExists ) {
191- if (limitSubstitute != queryLimit ) {
192- // do a clause replacement
193- final Matcher limitMatcher = LIMIT_PATTERN .matcher (rval );
194- final StringBuffer buffer = new StringBuffer ();
195- limitMatcher .find ();
196- limitMatcher .appendReplacement (buffer , "limit " + limitSubstitute );
197- limitMatcher .appendTail (buffer );
198- rval = buffer .toString ();
199- }
139+ if (QueryLanguage .SPARQL == language ) {
140+ rval = ensureNewlineAndAppend (rval , "limit " + limitSubstitute );
200141 }
201142 else {
202- final String newLimitClause = "limit " + limitSubstitute ;
203- if (QueryLanguage .SPARQL == language ) {
204- rval = ensureNewlineAndAppend (rval , newLimitClause );
205- }
206- else {
207- /*
208- * SeRQL, add the clause before any offset clause or the namespace section
209- */
210- final Pattern pattern = queryOffsetExists ? OFFSET_PATTERN : SERQL_NAMESPACE ;
211- rval = insertAtMatchOnOwnLine (pattern , rval , newLimitClause );
212- }
143+ rval = insertAtMatchOnOwnLine (SERQL_NAMESPACE , rval , "limit " + limitSubstitute );
213144 }
214145 return rval ;
215146 }
0 commit comments