pax_global_header00006660000000000000000000000064115774365150014530gustar00rootroot0000000000000052 comment=0d8231b9663d2e31487326ccecb761f9239f9c0b josql-2.2/000077500000000000000000000000001157743651500125235ustar00rootroot00000000000000josql-2.2/LICENSE-2.0.txt000066400000000000000000000261361157743651500146530ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. josql-2.2/README000066400000000000000000000012441157743651500134040ustar00rootroot00000000000000Read the http://josql.sourceforge.net/manual/introduction.html user manual for details on how to use JoSQL. See: http://josql.sourceforge.net/manual/version-changes.html for details of the latest changes, improvements and fixes. Usage, ensure that JoSQL-X.Y.jar and 3rd-party-jars/gentlyWEB-utils-X.Y.jar are in your classpath. Also, please note that JoSQL falls under the Apache V2.0 license (a copy of which is found in this distribution), as does the gentlyWEB software (the jar is in 3rd-party-jars). Please contact me: barrygently at users.sourceforge.net (Gary) for a copy of the source. It will soon be released on sourceforge as well (one thing at a time!). josql-2.2/build.xml000066400000000000000000000202051157743651500143430ustar00rootroot00000000000000
josql-2.2/data/000077500000000000000000000000001157743651500134345ustar00rootroot00000000000000josql-2.2/data/classTemplate.java000066400000000000000000000014561157743651500171060ustar00rootroot00000000000000/* * Copyright 2004-2005 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql; /** *

* Last Modified By: $Author: barrygently $
* Last Modified On: $Date: 2004/12/20 16:25:12 $
* Current Revision: $Revision: 1.1 $
*/ public class { } josql-2.2/data/javadocsStyle.css000066400000000000000000000047271157743651500167730ustar00rootroot00000000000000pre a code { font-size: small; font-family: courier; } pre { font-size: small; } code b a { font-size: small; font-family: courier; } code { font-size: small; } a code { font-size: small; text-decoration: none; color: #1f5ba4; font-family: courier; font-weight: bold; } a { text-decoration: none; color: #1f5ba4; font-family: Verdana, Helvetica, sans-serif; font-weight: bold; font-size: 10pt; } h2 { font-family: Verdana, Helvetica, sans-serif; font-weight: bold; font-size: medium; color: black; } h3 { font-family: Verdana, Helvetica, sans-serif; font-weight: bold; font-size: medium; color: #16408b } h4 { font-family: Verdana, Helvetica, sans-serif; font-weight: bold; font-size: medium; color: #aa0600; } h4 a { font-family: Verdana, Helvetica, sans-serif; font-weight: bold; font-size: medium; color: #aa0600; } h5 { font-family: Verdana, Helvetica, sans-serif; font-weight: bold; font-size: small; color: #aa0600; } h5 a { font-family: Verdana, Helvetica, sans-serif; font-weight: bold; font-size: small; color: #aa0600; } th { background-color: #f3f1eb; color: #545454; padding-left: 3px; font-weight: bold; font-family: "Trebuchet MS", arial, verdana, arial, helvetica; font-size: 14pt; } th a { font-weight: bold; font-family: "Trebuchet MS", arial, verdana, arial, helvetica; font-size: 14pt; } td { font-family: Verdana, Helvetica, sans-serif; font-size: small; } li { font-family: Verdana, Helvetica, sans-serif; font-size: small; } dd { font-family: Verdana, Helvetica, sans-serif; font-size: small; } dt { font-family: Verdana, Helvetica, sans-serif; font-size: small; } p { font-family: Verdana, Helvetica, sans-serif; font-size: small; } span { font-family: Verdana, Helvetica, sans-serif; font-weight: bold; } .pi { color: blue; } .attr { color: #a27a0d; } .attrValue { color: #5394b5; } .comment { color: #c73822; } .element { color: #2a4abc; } .content { color: #5f5e5a; } .namespace { color: #9b9841; } tr.TableHeadingColor { background-color: #f3f1eb; } td.NavBarCell1 { background-color: #f3f1eb; } font.FrameHeadingFont { font-family: Verdana, Helvetica, sans-serif; font-size: medium; }josql-2.2/data/josql-taglib.tld000066400000000000000000000023331157743651500165320ustar00rootroot00000000000000 2.0 1.2 josql josqltaglib JoSQL Allows a JoSQL statement to be used in JSPs. query org.josql.contrib.JoSQLJSPQueryTag JSP inputList true true Can either be a "string" that is the name of the attribute that holds the input list (i.e. the list to execute the query against). Or can be a "java.util.List" that will be the list to execute the query against. results true true The name of the attribute that the results should be stored in. Will be an instance of: org.josql.QueryResults. josql-2.2/data/josql.jj000066400000000000000000000625651157743651500151270ustar00rootroot00000000000000/* * Copyright 2004-2005 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ options{ IGNORE_CASE=true ; STATIC=false; JAVA_UNICODE_ESCAPE=true; // DEBUG_LOOKAHEAD= true ; // FORCE_LA_CHECK=true; // DEBUG_TOKEN_MANAGER=true; } PARSER_BEGIN(JoSQLParser) package org.josql.parser; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.HashMap; import org.josql.Query; import org.josql.internal.OrderBy; import org.josql.internal.Limit; import org.josql.internal.Utilities; import org.josql.internal.ColumnReference; import org.josql.expressions.*; /** * The parser generated by JavaCC */ public class JoSQLParser { } PARSER_END(JoSQLParser) SKIP: { " " | "\t" | "\r" | "\n" } TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | " > } /* Old Keywords, not really used and prevent use of "value" and "key" as accessors which would be common. See: http://www.idevelopment.info/data/Programming/java/JavaCC/The_JavaCC_FAQ.htm#tth_sEc4.19 for potential ways of getting around this when these keywords are needed. | | */ TOKEN: { < S_IDENTIFIER: ( )+ ( | |)* > | < #LETTER: ["a"-"z", "A"-"Z"] > | < #SPECIAL_CHARS: "$" | "_"> | | } TOKEN : /* Numeric Constants */ { < S_DOUBLE: ()? "." ( ["e","E"] ([ "-","+"])? )? > | < S_INTEGER: ( )+ > | < #DIGIT: ["0" - "9"] > } SPECIAL_TOKEN: { | } BindVariable BindVariable(): { Token t = null; BindVariable result = new BindVariable (); String prefix = ""; String acc = null; } { (":" t = KeywordName() { result.setName (t.image); } | ":_" t = { prefix = "_"; result.setName (prefix + t.image); } | "?" { result.setAnonymous (true); } ) [ "." acc = Name() { result.setAccessor (acc); } ] { return result; } } SaveValue SaveValue(): { Token t = null; SaveValue result = new SaveValue (); String v = null; String acc = null; } { "@" t = KeywordName() [ "." acc = Name() { result.setAccessor (acc); } ] { result.setName (t.image); return result; } } void parseQuery(Query q): { } { Query(q) [";"] } String Name(): { StringBuffer v = new StringBuffer (); Token val = null; } { // Is in form... name.name.name val = KeywordName() { v.append (val.image); } ( "." { v.append ("."); } val = KeywordName() { v.append (val.image); } )* { return v.toString (); } } Token KeywordName(): { Token t = null; } { ( t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = /*| t = */ | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = ) { return t; } } /* String MultiName(): { StringBuffer v = new StringBuffer (); Token val = null; } { // Is in form... name[name.name] val = Name() [ "[" [ | ] val = PrimaryExpression() "]" { v.append (val.image); } ] { return v.toString (); } } */ String RelObjectName(): { Token tk = null; } { ( tk=KeywordName() | tk= | tk= ) { return tk.image; } } void Query(Query q): { List cols = null; List fromItems = null; List joins = null; Expression where = null; List orderBys = null; List groupOrderBys = null; List groupBys = null; Expression having = null; Limit limit = null; Limit grpLimit = null; Expression from = null; Map execute = null; boolean distinct = false; } { [ LOOKAHEAD(2) { q.setWantDistinctResults (true); } ] cols = SelectItemsList(q) from = From() [ where = WhereClause() ] [ LOOKAHEAD(2) groupBys = GroupBys() ] [ having = Having() ] [ LOOKAHEAD(GroupOrderBys()) groupOrderBys = GroupOrderBys() ] [ orderBys = OrderBys() ] [ LOOKAHEAD(GroupLimit()) grpLimit = GroupLimit() ] [ limit = Limit() ] [ execute = ExecuteOn() ] { // We set all the values since they are all dependent on the class // being available. q.setFrom (from); q.setColumns (cols); q.setWhere (where); q.setHaving (having); q.setGroupByOrderColumns (groupOrderBys); q.setOrderByColumns (orderBys); q.setGroupByColumns (groupBys); q.setGroupByLimit (grpLimit); q.setLimit (limit); q.setExecuteOnFunctions (execute); } } Map ExecuteOn(): { Map et = new HashMap (); } { ( et = ExecuteOnType(et))+ { return et; } } Map ExecuteOnType(Map execOn): { List el = null; String type = null; } { ( { type = Query.ALL; } | { type = Query.RESULTS; } | { type = Query.RESULTS; } | { type = Query.HAVING_RESULTS; } | { type = Query.GROUP_BY_RESULTS; } ) el = AliasedSQLExpressionList() { List fs = (List) execOn.get (type); if (fs != null) { fs.addAll (el); } else { execOn.put (type, el); } } { return execOn; } } List SelectItemsList(Query q): { List selectItemsList = new ArrayList(); SelectItemExpression si = null; } { si = SelectItem(q) { if (si != null) { selectItemsList.add (si); } } ("," si = SelectItem(q) { if (si != null) { selectItemsList.add (si); }} )* { return selectItemsList; } } List FunctionList(): { List fList = new ArrayList(); AliasedFunction f = null; String alias = null; } { f = AliasedFunction() { fList.add (f); } ("," f = AliasedFunction() { fList.add (f); } )* { return fList; } } AliasedFunction AliasedFunction(): { AliasedFunction af = new AliasedFunction (); String alias = null; Function f = null; } { (f = Function() [ alias = Alias() ]) { af.setAlias (alias); af.setExpression (f); return af; } } SelectItemExpression SelectItem(Query q): { String alias = null; SelectItemExpression csei = null; Expression expression = null; boolean addItemsFromColl = false; Token addItemType = null; } { ( "*" { q.setWantObjects (true); return null; } | /* OLD [ "[" "*" [ "," addItemType = ] "]" { addItemsFromColl = true; } ] expression = OrExpression() { csei = new SelectItemExpression (); csei.setExpression (expression); } */ [ LOOKAHEAD(2) "[" "*" [ "," addItemType = KeywordName() ] "]" { addItemsFromColl = true; } ] expression = ExpressionList() { csei = new SelectItemExpression (); csei.setExpression (expression); } [ LOOKAHEAD(2) alias=Alias() { csei.setAlias (alias); } ] ) { if (addItemsFromColl) { csei.setAddItemsType (java.util.Collection.class); if (addItemType != null) { csei.setAddMapType (addItemType.image); csei.setAddItemsType (java.util.Map.class); } } return csei; } } NewObjectExpression NewObjectExpression(): { String setterName = null; String className = null; List conArgs = null; Expression expression = null; NewObjectExpression noe = new NewObjectExpression (); } { { noe = new NewObjectExpression (); } className = Name() { noe.setClassName (className); } "(" [ conArgs = SQLExpressionList() { noe.setConstructorArgs (conArgs); } ] ")" [ "{" expression = ExpressionList() "->" setterName = Name() { noe.addIntoExpression (expression, setterName); } ( "," expression = ExpressionList() "->" setterName = Name() { noe.addIntoExpression (expression, setterName); } )* "}" ] { return noe; } } String Alias(): { String retval = null; } { [LOOKAHEAD(2) ] retval=RelObjectName() { return retval; } } Expression From(): { String cn = null; Expression from = null; } { (from = BindVariable () | from = SaveValue () | LOOKAHEAD(3) ( { cn = "null"; } | cn = Name() ) { ConstantExpression ce = new ConstantExpression (); from = ce; ce.setValue (cn); } | LOOKAHEAD(3) from = Function () ) { return from; } } Expression WhereClause(): { Expression retval = null; } { retval = ExpressionList() { return retval; } } List GroupBys(): { List groupBys = new ArrayList(); OrderBy ob = null; } { ob = OrderBy() { groupBys.add (ob); } ("," ob = OrderBy() { groupBys.add (ob); } )* { return groupBys; } } Expression Having(): { Expression having = null; } { having = ExpressionList() { return having; } } List OrderBys(): { List orderBys = new ArrayList (); OrderBy ob = null; } { ob = OrderBy() { orderBys.add (ob); } ("," ob = OrderBy() { orderBys.add (ob); } )* { return orderBys; } } List GroupOrderBys(): { List orderBys = new ArrayList (); OrderBy ob = null; } { ob = OrderBy() { orderBys.add (ob); } ("," ob = OrderBy() { orderBys.add (ob); } )* { return orderBys; } } OrderBy OrderBy(): { OrderBy oe = new OrderBy (); String acc = null; Token ci = null; int cInt = -1; Expression exp = null; } { (LOOKAHEAD(2) ci = { cInt = Integer.parseInt (ci.image); oe.setIndex (cInt); } | exp = ExpressionList() { oe.setExpression (exp); } ) [ { oe.setType (OrderBy.ASC); } | { oe.setType (OrderBy.DESC); } ] { return oe; } } Limit Limit(): { Limit limit = new Limit (); Token token = null; Expression start = null; Expression rows = null; } { [ LOOKAHEAD(2) start = SimpleExpression() "," ] rows = SimpleExpression() { if ((start != null) && (!(start instanceof ValueExpression)) ) { throw new ParseException ("Only expressions that return a numeric value are supported as the start value for the LIMIT part of the query."); } if (!(rows instanceof ValueExpression)) { throw new ParseException ("Only expressions that return a numeric value are supported as the rows value for the LIMIT part of the query."); } limit.setStart ((ValueExpression) start); limit.setRowsCount ((ValueExpression) rows); return limit; } } Limit GroupLimit(): { Limit limit = new Limit (); Token token = null; Expression start = null; Expression rows = null; } { [ LOOKAHEAD(2) start = SimpleExpression() "," ] rows = SimpleExpression() { if ((start != null) && (!(start instanceof ValueExpression)) ) { throw new ParseException ("Only expressions that return a numeric value are supported as the start value for the LIMIT part of the query."); } if (!(rows instanceof ValueExpression)) { throw new ParseException ("Only expressions that return a numeric value are supported as the rows value for the LIMIT part of the query."); } limit.setStart ((ValueExpression) start); limit.setRowsCount ((ValueExpression) rows); return limit; } } ColumnReference ColumnReference(): { ColumnReference retval = new ColumnReference (); String name = null; int index = -1; } { (name = Name() { retval.setName (name); } | index = ColumnIndex() { retval.setIndex (index); } ) { return retval; } } int ColumnIndex(): { Token index = null; } { index= { return Integer.parseInt(index.image); } } Expression ExpressionList(): { ExpressionList el = null; Expression expr = null; } { expr = OrExpression() { return expr; } | "[" expr = ExpressionList() { el = new ExpressionList (); el.addExpression (expr); } ( "," expr = ExpressionList() { el.addExpression (expr); } )* "]" { return el; } } Expression OrExpression(): { Expression left; Expression right; Expression result; } { left = AndExpression () { result = left; } ( LOOKAHEAD() right = ExpressionList() { result = new AndOrExpression (); BinaryExpression be = (BinaryExpression) result; be.setLeft (left); be.setRight (right); } )* { return result; } } Expression AndExpression() : { Expression left; Expression right; Expression result; } { left = Condition() { result = left; } ( LOOKAHEAD() right = ExpressionList() { result = new AndOrExpression (); AndOrExpression aoe = (AndOrExpression) result; aoe.setLeft (left); aoe.setRight (right); aoe.setAnd (true); } )* { return result; } } Expression Condition(): { Expression result; } { (LOOKAHEAD(SQLCondition()) result = SQLCondition() | result = RegularCondition()) { return result; } } Expression RegularCondition(): { Expression result = null; Expression left = null; Expression right = null; boolean ignoreCase = false; } { left = SimpleExpression() { result = left; } [ // Allows $ before any of the following. ["$" { ignoreCase = true; } ] ( ">" { result = new GTLTExpression (); GTLTExpression lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.GT); } | "<" { result = new GTLTExpression (); lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.LT); } | "=" { result = new EqualsExpression (); EqualsExpression ee = (EqualsExpression) result; ee.setIgnoreCase (ignoreCase); } | ">=" { result = new GTLTExpression (); lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.GTE); } | "<=" { result = new GTLTExpression (); lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.LTE); } | ("<>" | "!=") { result = new EqualsExpression (); ee = (EqualsExpression) result; ee.setNot (true); ee.setIgnoreCase (ignoreCase); } ) right = SimpleExpression() { BinaryExpression be = (BinaryExpression) result; be.setLeft (left); be.setRight (right); } ] { return result; } } Expression SQLCondition(): { Expression result; } { ( LOOKAHEAD(InExpression()) result = InExpression () | LOOKAHEAD(BetweenExpression()) result = BetweenExpression () | LOOKAHEAD(IsNullExpression()) result = IsNullExpression () | result = LikeExpression () ) { return result; } } InExpression InExpression(): { InExpression result = new InExpression(); List items = null; Expression left = null; } { left = SimpleExpression() [ { result.setNot(true); } ] [ "$" { result.setIgnoreCase (true); } ] [ "$" { result.setIgnoreCase (true); } ] [ { result.setDoLike (true); } ] [ { result.setAll (true); } ] "(" items = SQLExpressionList() ")" { if (!(left instanceof ValueExpression)) { throw new ParseException ("The left-hand side of an [NOT] IN clause must be a value expression."); } result.setLeft ((ValueExpression) left); for (int i = 0; i < items.size (); i++) { if (!(items.get (i) instanceof ValueExpression)) { throw new ParseException ("Item: " + (i + 1) + " from the [NOT] IN clause is NOT a value expression, is: \"" + items.get (i).toString () + "\""); } } result.setItems (items); return result; } } BetweenExpression BetweenExpression(): { BetweenExpression result = new BetweenExpression (); Expression left = null; Expression start = null; Expression end = null; } { left = SimpleExpression() [ { result.setNot(true); }] start = SimpleExpression() end = SimpleExpression() { if (!(left instanceof ValueExpression)) { throw new ParseException ("The left-hand side of an [NOT] BETWEEN clause must be a value expression, is: \"" + left + "\""); } if (!(start instanceof ValueExpression)) { throw new ParseException ("The START value of an [NOT] BETWEEN clause must be a value expression, is: \"" + start + "\""); } if (!(end instanceof ValueExpression)) { throw new ParseException ("The END value of an [NOT] BETWEEN clause must be a value expression, is: \"" + end + "\""); } result.setLeft ((ValueExpression) left); result.setStart ((ValueExpression) start); result.setEnd ((ValueExpression) end); return result; } } LikeExpression LikeExpression() : { LikeExpression result = new LikeExpression (); Expression left = null; Expression right = null; } { left = SimpleExpression() [ { result.setNot (true); } ] [ "$" { result.setIgnoreCase (true); } ] right = SimpleExpression() { result.setLeft (left); result.setRight (right); return result; } } IsNullExpression IsNullExpression(): { IsNullExpression result = new IsNullExpression (); Expression left = null; } { left = SimpleExpression() [ { result.setNot (true); } ] { result.setLeft (left); return result; } } List SQLExpressionList(): { List expressions = new ArrayList(); Expression expr = null; ExpressionList eList = null; List exprList = null; } { expr = ExpressionList() { expressions.add(expr); } ("," expr = ExpressionList() { expressions.add(expr); })* { return expressions; } } List AliasedSQLExpressionList(): { List expressions = new ArrayList(); AliasedExpression aexp = null; Expression expr = null; String alias = null; } { expr = ExpressionList() { aexp = new AliasedExpression (); aexp.setExpression (expr); expressions.add (aexp); } [ LOOKAHEAD(2) alias = Alias() { aexp.setAlias (alias); } ] ("," expr = ExpressionList() { aexp = new AliasedExpression (); aexp.setExpression (expr); expressions.add (aexp); } [ LOOKAHEAD(2) alias = Alias() { aexp.setAlias (alias); } ] )* { return expressions; } } Expression SimpleExpression(): { Expression result = null; } { (LOOKAHEAD(3) result = AdditiveExpression() | LOOKAHEAD(3) result = MultiplicativeExpression() | LOOKAHEAD(3) result = PrimaryExpression() ) { return result; } } Expression AdditiveExpression(): { Expression result = null; Expression left = null; Expression right = null; int type = -1; } { left = MultiplicativeExpression() { result = left; } ( LOOKAHEAD(2) ("+" { type = ArithmeticExpression.ADDITION; } | "-" { type = ArithmeticExpression.SUBTRACT; } ) right = AdditiveExpression() { if (!(left instanceof ValueExpression)) { throw new ParseException ("The left-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression."); } if (!(right instanceof ValueExpression)) { throw new ParseException ("The right-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression."); } ArithmeticExpression ae = new ArithmeticExpression (); ae.setLeft ((ValueExpression) left); ae.setRight ((ValueExpression) right); result = ae; ae.setType (type); } )* { return result; } } Expression MultiplicativeExpression(): { Expression result = null; Expression left = null; Expression right = null; int type = -1; } { left = PrimaryExpression() { result = left; } ( LOOKAHEAD(2) ("*" { type = ArithmeticExpression.MULTIPLY; } | "/" { type = ArithmeticExpression.DIVIDE; } | "%" { type = ArithmeticExpression.MODULUS; } ) right = AdditiveExpression() { if (!(left instanceof ValueExpression)) { throw new ParseException ("The left-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression."); } if (!(right instanceof ValueExpression)) { throw new ParseException ("The right-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression."); } ArithmeticExpression ae = new ArithmeticExpression (); ae.setLeft ((ValueExpression) left); ae.setRight ((ValueExpression) right); result = ae; ae.setType (type); } )* { return result; } } Expression PrimaryExpression(): { Expression retval = null; Token token = null; boolean isInverse = false; String tmp = ""; String accName = null; } { ( LOOKAHEAD(2) retval = NewObjectExpression() | LOOKAHEAD(2) retval = SubQueryExpression() | { retval = new ConstantExpression (); ConstantExpression ce = (ConstantExpression) retval; ce.setValue (null); } | LOOKAHEAD(2) { retval = new BooleanExpression (); BooleanExpression be = (BooleanExpression) retval; be.setValue (Boolean.TRUE); } | LOOKAHEAD(2) { retval = new BooleanExpression (); BooleanExpression be = (BooleanExpression) retval; be.setValue (Boolean.FALSE); } | retval = BindVariable() | retval = SaveValue() | LOOKAHEAD([ "+" | "-"] Function()) [ "+" | "-" { isInverse = true; }] retval = Function() | LOOKAHEAD([ "+" | "-"] ) [ "+" | "-" { tmp = "-"; }] token= { retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (new Double (tmp+token.image)); } | LOOKAHEAD([ "+" | "-"] ) [ "+" | "-" { tmp = "-"; }] token= { retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (new Double (tmp+token.image)); } | LOOKAHEAD(2) [ "+" | "-" { isInverse = true; }] accName = Name() {retval= new Accessor (); Accessor a = (Accessor) retval; a.setAccessor (accName); } /* | LOOKAHEAD(2) [ "+" | "-" { isInverse = true; }] accName = MultiName() {retval= new MultiAccessor (); MultiAccessor a = (MultiAccessor) retval; a.setAccessor (accName); } */ | LOOKAHEAD(2) [ "+" | "-" { isInverse = true; }] "(" retval = ExpressionList() ")" { retval.setBracketed (true); } | token= { retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (token.image.substring (1,token.image.length () - 1)); } | token= { retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (token.image.substring (1,token.image.length () - 1)); } ) { return retval; } } Function Function(): { Function retval = new Function (); String funcName = null; String tmp = null; List params = null; String acc = null; } { funcName = Name() "(" [ (params = SQLExpressionList()) ] ")" [ "." acc = Name() ] { retval.setParameters (params); retval.setName (funcName); retval.setAccessor (acc); return retval; } } SubQueryExpression SubQueryExpression (): { Query q = new Query (); SubQueryExpression exp = new SubQueryExpression (q); String acc = null; } { "(" Query(q) ")" [ "." acc = Name() { exp.setAccessor (acc); } ] { return exp; } } josql-2.2/src/000077500000000000000000000000001157743651500133125ustar00rootroot00000000000000josql-2.2/src/org/000077500000000000000000000000001157743651500141015ustar00rootroot00000000000000josql-2.2/src/org/josql/000077500000000000000000000000001157743651500152315ustar00rootroot00000000000000josql-2.2/src/org/josql/Query.java000066400000000000000000002040461157743651500172070ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql; import java.io.StringReader; import java.io.BufferedReader; import java.util.Map; import java.util.HashMap; import java.util.SortedMap; import java.util.LinkedHashMap; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashSet; import java.util.Collection; import org.josql.parser.JoSQLParser; import org.josql.expressions.*; import org.josql.functions.*; import org.josql.internal.*; import org.josql.events.*; /** * This class provides the ability for a developer to apply an arbitrary SQL statement * (using suitable syntax) to a collection of Java objects. *

* Basic usage: *

 *   Query q = new Query ();
 *   q.parse (myStatement);
 *   List results = q.execute (myObjects);
 * 
*

* An example statement would look like: *

 *   SELECT lastModified,
 *          name
 *   FROM   java.io.File
 *   WHERE  name LIKE '%.html'
 * 
*

* The JoSQL functionality is large and complex, whilst basic queries like the one above are * perfectly possible, very complex queries are also possible, for example: *

 *   SELECT name,
 *          formatDate(lastModified),
 *          formatNumber(length),
 *          formatNumber(length - @avg_length),
 *          formatTimeDuration(@max_last_modified - lastModified)
 *   FROM   java.io.File
 *   WHERE  lastModified > @avg_last_modified
 *   AND    length > @avg_length
 *   AND    lower(name) LIKE '%.html'
 *   GROUP BY path
 *   ORDER BY name, lastModified DESC
 *   EXECUTE ON ALL avg (:_allobjs, length) avg_length,
 *                  avg (:_allobjs, lastModified) avg_last_modified,
 *                  max (:_allobjs, lastModified) max_last_modified
 * 
*

* Note: the "EXECUTE ON ALL" syntax is an extension used by JoSQL because it has no notion * of "aggregate functions". *

* For full details of how a query works and what is possible, see the * JoSQL User Manual. *

* Please note that the package structure for JoSQL is deliberate, JoSQL is designed to be a * black box and lightweight thus only the Query object and associated exceptions * are exposed in the main package. Also, the class structure for JoSQL is not designed to * exactly represent the SQL statement passed to it, rather the classes are optimised for * ease of execution of the statement. If you wish to have a completely accurate Java object * view of ANY SQL statement then please see: * JSqlParser * which will provide what you need. */ public class Query { public static String QUERY_BIND_VAR_NAME = "_query"; public static String PARENT_BIND_VAR_NAME = "_parent"; public static String CURR_OBJ_VAR_NAME = "_currobj"; public static String ALL_OBJS_VAR_NAME = "_allobjs"; public static String GRPBY_OBJ_VAR_NAME = "_grpby"; public static String GRPBY_OBJ_VAR_NAME_SYNONYM = "_groupby"; public static final String INT_BIND_VAR_PREFIX = "^^^"; public static final String ALL = "ALL"; public static final String RESULTS = "RESULTS"; public static final String GROUP_BY_RESULTS = "GROUP_BY_RESULTS"; public static final String WHERE_RESULTS = "WHERE_RESULTS"; public static final String HAVING_RESULTS = "HAVING_RESULTS"; public static final String ORDER_BY_ASC = "ASC"; public static final String ORDER_BY_DESC = "DESC"; public static final List nullQueryList = new ArrayList (); static { Query.nullQueryList.add (new Object ()); } private List bfhs = new ArrayList (); private Map bfhsMap = new HashMap (); private char wildcardChar = '%'; private Map aliases = new HashMap (); private List groupBys = null; private Comparator orderByComp = null; private Comparator groupOrderByComp = null; private Grouper grouper = null; private List orderBys = null; private List groupOrderBys = null; private List cols = null; private boolean retObjs = false; private Expression where = null; private Expression having = null; private Map bindVars = null; private String query = null; private boolean wantTimings = false; private List functionHandlers = null; private int anonVarIndex = 1; private Expression from = null; private Class objClass = null; private Limit limit = null; private Limit groupByLimit = null; private Map executeOn = null; private boolean isParsed = false; private boolean distinctResults = false; private ClassLoader classLoader = null; private Query parent = null; private Map listeners = new HashMap (); private Comparator userComparator = null; // Execution data. private transient Object currentObject = null; private transient List allObjects = null; private transient List currGroupBys = null; private QueryResults qd = null; /** * Return the WHERE clause expression. * * @return The WHERE clause as an expression. */ public Expression getWhereClause () { return this.where; } /** * Return the HAVING clause expression. * * @return The HAVING clause as an expression. */ public Expression getHavingClause () { return this.having; } /** * Return the {@link Comparator} we will use to do the ordering of the results, may be null. * * @return The Comparator. */ public Comparator getOrderByComparator () { return this.orderByComp; } public FunctionHandler getFunctionHandler (String id) { if (this.parent != null) { return this.parent.getFunctionHandler (id); } return (FunctionHandler) this.bfhsMap.get (id); } private void initFunctionHandlers () { FunctionHandler o = new CollectionFunctions (); o.setQuery (this); this.bfhsMap.put (CollectionFunctions.HANDLER_ID, o); this.bfhs.add (o); o = new StringFunctions (); o.setQuery (this); this.bfhsMap.put (StringFunctions.HANDLER_ID, o); this.bfhs.add (o); o = new ConversionFunctions (); o.setQuery (this); this.bfhsMap.put (ConversionFunctions.HANDLER_ID, o); this.bfhs.add (o); o = new FormattingFunctions (); o.setQuery (this); this.bfhsMap.put (FormattingFunctions.HANDLER_ID, o); this.bfhs.add (o); o = new GroupingFunctions (); o.setQuery (this); this.bfhsMap.put (GroupingFunctions.HANDLER_ID, o); this.bfhs.add (o); o = new MiscellaneousFunctions (); o.setQuery (this); this.bfhsMap.put (MiscellaneousFunctions.HANDLER_ID, o); this.bfhs.add (o); } public Map getExecuteOnFunctions () { return this.executeOn; } public void setExecuteOnFunctions (Map ex) { this.executeOn = ex; } public String getAnonymousBindVariableName () { if (this.parent != null) { return this.parent.getAnonymousBindVariableName (); } String n = Query.INT_BIND_VAR_PREFIX + this.anonVarIndex; this.anonVarIndex++; return n; } public List getDefaultFunctionHandlers () { if (this.parent != null) { return this.parent.getDefaultFunctionHandlers (); } return new ArrayList (this.bfhs); } public List getFunctionHandlers () { if (this.parent != null) { return this.parent.getFunctionHandlers (); } return this.functionHandlers; } public void addFunctionHandler (Object o) { if (this.parent != null) { this.parent.addFunctionHandler (o); } if (this.functionHandlers == null) { this.functionHandlers = new ArrayList (); } if (o instanceof FunctionHandler) { FunctionHandler fh = (FunctionHandler) o; fh.setQuery (this); } this.functionHandlers.add (o); } public void setFrom (Expression exp) { this.from = exp; } public Expression getFrom () { return this.from; } public void setClassName (String n) { ConstantExpression ce = new ConstantExpression (); this.from = ce; ce.setValue (n); } public void setOrderByColumns (List cols) { this.orderBys = cols; } public void setGroupByLimit (Limit g) { this.groupByLimit = g; } public void setGroupByOrderColumns (List cols) { this.groupOrderBys = cols; } public List getGroupByColumns () { return this.groupBys; } public void setGroupByColumns (List cols) { this.groupBys = cols; } public List getColumns () { return this.cols; } public void setColumns (List cols) { this.cols = cols; } /** * Set the expression for the HAVING clause. * Caution: do NOT use this method unless you are sure about what you are doing! * * @param be The expression. */ public void setHaving (Expression be) { this.having = be; } /** * Set the expression for the WHERE clause. * Caution: do NOT use this method unless you are sure about what you are doing! * * @param be The expression. */ public void setWhere (Expression be) { this.where = be; } /** * Create a new blank Query object. */ public Query () { this.initFunctionHandlers (); } public void setWantTimings (boolean v) { this.wantTimings = v; } protected void addTiming (String id, double time) { if (this.wantTimings) { if (this.qd == null) { return; } if (this.qd.timings == null) { this.qd.timings = new LinkedHashMap (); } this.qd.timings.put (id, new Double (time)); } } /** * Get the value of an indexed bind variable. * * @param index The index. * @return The value. */ public Object getVariable (int index) { if (this.parent != null) { return this.parent.getVariable (index); } return this.getVariable (Query.INT_BIND_VAR_PREFIX + index); } /** * Get the class that the named variable has. * * @param name The name of the variable. * @return The Class. */ public Class getVariableClass (String name) { String n = name.toLowerCase (); if (n.equals (Query.QUERY_BIND_VAR_NAME)) { // Return the query itself! return Query.class; } if (n.equals (Query.PARENT_BIND_VAR_NAME)) { // Return the query itself! return Query.class; } if (n.equals (Query.CURR_OBJ_VAR_NAME)) { // May be null if we aren't processing a while/having expression. return this.objClass; } if (n.equals (Query.ALL_OBJS_VAR_NAME)) { // May change depending upon when it is called. return List.class; } if (this.parent != null) { return this.parent.getVariableClass (n); } if (this.bindVars == null) { return Object.class; } Object v = (Object) this.bindVars.get (n); if (v == null) { return Object.class; } return v.getClass (); } /** * Get the value of a group by variable from the current group bys. * * @param ind The variable index. * @return The value. */ public Object getGroupByVariable (int ind) { // Get the current group bys. if (this.currGroupBys != null) { return this.currGroupBys.get (ind - 1); } return null; } /** * Get the value of a named bind variable. * * @param name The name of the bind variable. * @return The value. */ public Object getVariable (String name) { String n = name.toLowerCase (); if (n.startsWith (":")) { n = n.substring (1); } if (n.equals (Query.QUERY_BIND_VAR_NAME)) { // Return the query itself! return this; } if (n.equals (Query.PARENT_BIND_VAR_NAME)) { // Return the parent query. return this.parent; } if (n.equals (Query.CURR_OBJ_VAR_NAME)) { // May be null if we aren't processing a while/having expression. return this.currentObject; } if (n.equals (Query.ALL_OBJS_VAR_NAME)) { // May change depending upon when it is called. return this.allObjects; } if (this.parent != null) { return this.parent.getVariable (name); } if (this.bindVars == null) { return null; } return this.bindVars.get (n); } /** * Set the value of a named bind variable. * * @param name The name. * @param v The value. */ public void setVariable (String name, Object v) { if (this.parent != null) { this.parent.setVariable (name, v); return; } if (this.bindVars == null) { this.bindVars = new HashMap (); } if (name.startsWith (":")) { name = name.substring (1); } this.bindVars.put (name.toLowerCase (), v); } /** * Set the value of an indexed bind variable. * * @param index The index. * @param v The value. */ public void setVariable (int index, Object v) { if (this.parent != null) { this.parent.setVariable (index, v); return; } this.setVariable (Query.INT_BIND_VAR_PREFIX + index, v); } /** * Get all the bind variables as a Map. * * @return The name/value mappings of the bind variables. */ public Map getVariables () { if (this.parent != null) { return this.parent.getVariables (); } return this.bindVars; } /** * A helper method that will evaluate the WHERE clause for the object passed in. * * @param o The object to evaluate the WHERE clause against. * @return The result of calling: Expression.isTrue(Object,Query) for the WHERE clause. */ public boolean isWhereTrue (Object o) throws QueryExecutionException { if (this.where == null) { // A null where means yes! return true; } return this.where.isTrue (o, this); } /** * Set the bind variables in one go. * * @param bVars The bind variable name/value mappings. */ public void setVariables (Map bVars) { if (this.parent != null) { this.parent.setVariables (bVars); return; } Iterator iter = bVars.entrySet ().iterator (); while (iter.hasNext ()) { Map.Entry item = (Map.Entry) iter.next (); Object k = item.getKey (); Object v = item.getValue (); if (k instanceof Number) { this.setVariable (((Number) k).intValue (), v); } else { this.setVariable (k.toString (), v); } } } /** * Execute all the expressions for the specified type, either: {@link #ALL} or: * {@link #RESULTS}. If the expressions are aliased then the results will be * available in the save results upon completion. * * @param l The List of objects to execute the functions on. * @param t The type of expressions to execute. * @throws QueryExecutionException If there is an issue with executing one of the * expressions or if the Query hasn't been inited yet. */ public void doExecuteOn (List l, String t) throws QueryExecutionException { if (this.executeOn == null) { // Do nothing. return; } if (!this.isParsed) { throw new QueryExecutionException ("Query has not been initialised."); } if (this.executeOn != null) { // Set the "all objects". this.allObjects = l; long s = System.currentTimeMillis (); List fs = (List) this.executeOn.get (t); if (fs != null) { // Execute each one in turn. int si = fs.size (); for (int i = 0; i < si; i++) { AliasedExpression f = (AliasedExpression) fs.get (i); Object o = f.getValue (null, this); String af = f.getAlias (); if (af != null) { this.setSaveValue (af, o); } } this.addTiming ("Total time to execute: " + si + " expression(s) on " + t + " objects", System.currentTimeMillis () - s); } } } /** * This method will be called at the end of a query execution to clean up the * transient objects used throughout execution. */ private void clearResults () { this.qd = null; this.currentObject = null; this.allObjects = null; this.currGroupBys = null; } /** * Execute this query on the specified objects provided by the iterator. It should be noted that the iterator * is first traversed and the objects it returns converted to a List and then passed to the {@link #execute(List)} method for execution. * * @param iter The iterator to use to get the objects. * @return The list of objects that match the query. * @throws QueryExecutionException If the query cannot be executed. */ public QueryResults execute (Iterator iter) throws QueryExecutionException { if ((iter == null) && (this.objClass != null) ) { throw new QueryExecutionException ("Iterator must be non-null when an object class is specified."); } List l = new ArrayList (); while (iter.hasNext ()) { l.add (iter.next ()); } return this.execute (l); } /** * Execute this query on the specified objects. It should be noted that the collection * is first converted to a List and then passed to the {@link #execute(List)} method for execution. * * @param objs The collection of objects to execute the query on. * @return The list of objects that match the query. * @throws QueryExecutionException If the query cannot be executed. */ public QueryResults execute (Collection objs) throws QueryExecutionException { if ((objs == null) && (this.objClass != null) ) { throw new QueryExecutionException ("Collection of objects must be non-null when an object class is specified."); } List l = new ArrayList (objs.size ()); l.addAll (objs); return this.execute (l); } /** * Execute this query on the specified objects. * * @param objs The list of objects to execute the query on. * @return The list of objects that match the query. * @throws QueryExecutionException If the query cannot be executed. */ public QueryResults execute (List objs) throws QueryExecutionException { if ((objs == null) && (this.objClass != null) ) { throw new QueryExecutionException ("List of objects must be non-null when an object class is specified."); } this.qd = new QueryResults (); if ((this.objClass == null) && (objs == null) ) { objs = Query.nullQueryList; } this.allObjects = objs; // See if we have any expressions that are to be executed on // the complete set. this.doExecuteOn (objs, Query.ALL); this.evalWhereClause (); // See if we have any functions that are to be executed on // the results... this.doExecuteOn (this.qd.results, Query.RESULTS); // If we have a "having" clause execute it here... this.evalHavingClause (); // Now perform the group by operation. if (this.grouper != null) { this.evalGroupByClause (); return this.qd; } // Now perform the order by. this.evalOrderByClause (); // Finally, if we have a limit clause, restrict the set of objects returned... this.evalLimitClause (); this.evalSelectClause (); try { return this.qd; } finally { // Clean up ;) this.clearResults (); } } private void evalSelectClause () throws QueryExecutionException { boolean retNewObjs = false; // See if we are a single column of new objects. if (!this.retObjs) { if (this.cols.size () == 1) { SelectItemExpression sei = (SelectItemExpression) this.cols.get (0); if (sei.getExpression () instanceof NewObjectExpression) { retNewObjs = true; } } } long s = System.currentTimeMillis (); // Now get the columns if necessary, we do this here to get the minimum // set of objects required. if ((!this.retObjs) && (!retNewObjs) ) { Collection resC = null; if (!this.distinctResults) { resC = new ArrayList (this.qd.results.size ()); } else { resC = new LinkedHashSet (this.qd.results.size ()); } // Get the column values. this.getColumnValues (this.qd.results, resC); if (this.distinctResults) { this.qd.results = new ArrayList (resC); } else { this.qd.results = (List) resC; } this.addTiming ("Collection of results took", (double) (System.currentTimeMillis () - s)); } else { if (this.retObjs) { if (this.distinctResults) { s = System.currentTimeMillis (); this.qd.results = ((CollectionFunctions) this.getFunctionHandler (CollectionFunctions.HANDLER_ID)).unique (this.qd.results); this.addTiming ("Collecting unique results took", (double) (System.currentTimeMillis () - s)); } } // If we want a single column of new objects... if (retNewObjs) { this.qd.results = this.getNewObjectSingleColumnValues (this.qd.results); } } } private void evalOrderByClause () throws QueryExecutionException { if ((this.qd.results.size () > 1) && (this.orderByComp != null) ) { long s = System.currentTimeMillis (); // It should be noted here that the comparator will set the // "current object" so that it can be used in the order by // clause. Collections.sort (this.qd.results, this.orderByComp); this.addTiming ("Total time to order results", System.currentTimeMillis () - s); } if (this.orderByComp != null) { ListExpressionComparator lec = (ListExpressionComparator) this.orderByComp; if (lec.getException () != null) { throw new QueryExecutionException ("Unable to order results", lec.getException ()); } lec.clearCache (); } } private void evalGroupByClause () throws QueryExecutionException { long s = System.currentTimeMillis (); // Need to handle the fact that this will return a Map of Lists... try { s = System.currentTimeMillis (); // Group the objects. Map mres = this.grouper.group (this.qd.results); this.qd.groupByResults = mres; List grpBys = new ArrayList (mres.keySet ()); // Convert the keys in the group by to a List. Map origSvs = this.qd.saveValues; Map nres = new LinkedHashMap (); int gs = grpBys.size (); // Now for each "group by" list, do: // 1. Execute the functions for the GROUP_BY_RESULTS type. // 2. Sort the group by results according to the ORDER BY clause. // 3. Limit the group by results according to the LIMIT clause. for (int i = 0; i < gs; i++) { List l = (List) grpBys.get (i); List lr = (List) mres.get (l); this.allObjects = lr; this.currGroupBys = l; // Now set the save values for the group bys. if (this.qd.groupBySaveValues == null) { this.qd.groupBySaveValues = new HashMap (); } this.qd.saveValues = new HashMap (); if (origSvs != null) { this.qd.saveValues.putAll (origSvs); } this.qd.groupBySaveValues.put (l, this.qd.saveValues); // Now execute all (any) group by results functions. this.doExecuteOn (lr, Query.GROUP_BY_RESULTS); // Now sort these according to the order by (if any). if ((lr.size () > 1) && (this.orderByComp != null) ) { Collections.sort (lr, this.orderByComp); ListExpressionComparator lec = (ListExpressionComparator) this.orderByComp; if (lec.getException () != null) { throw new QueryExecutionException ("Unable to order group by results", lec.getException ()); } lec.clearCache (); } if (!this.retObjs) { // Now collect the values... Collection res = null; if (!this.distinctResults) { res = new ArrayList (); } else { res = new LinkedHashSet (); } this.getColumnValues (lr, res); if (this.distinctResults) { lr = new ArrayList (res); } else { lr = (List) res; } } else { if (this.distinctResults) { this.qd.results = ((CollectionFunctions) this.getFunctionHandler (CollectionFunctions.HANDLER_ID)).unique (this.qd.results); } } nres.put (l, lr); } // Restore the save values. this.qd.saveValues = origSvs; // Set the group by results. this.qd.groupByResults = nres; long t = System.currentTimeMillis (); this.addTiming ("Group column collection and sort took", (double) (t - s)); s = t; // Now order the group bys, if present. if (this.groupOrderByComp != null) { origSvs = this.qd.saveValues; Collections.sort (grpBys, this.groupOrderByComp); // "Restore" the save values. this.qd.saveValues = origSvs; GroupByExpressionComparator lec = (GroupByExpressionComparator) this.groupOrderByComp; if (lec.getException () != null) { throw new QueryExecutionException ("Unable to order group bys, remember that the current object here is a java.util.List, not the class defined in the FROM clause, you may need to use the org.josq.functions.CollectionFunctions.get(java.util.List,Number) function to get access to the relevant value from the List.", lec.getException ()); } lec.clearCache (); } // Now limit the group bys, if required. if (this.groupByLimit != null) { s = System.currentTimeMillis (); List oGrpBys = grpBys; grpBys = this.groupByLimit.getSubList (grpBys, this); // Now trim out from the group by results any list that isn't in the current grpbys. for (int i = 0; i < oGrpBys.size (); i++) { List l = (List) oGrpBys.get (i); if (!grpBys.contains (l)) { // Remove. this.qd.groupByResults.remove (l); } } this.addTiming ("Total time to limit group by results size", System.currentTimeMillis () - s); } this.addTiming ("Group operation took", (double) (System.currentTimeMillis () - s)); // "Restore" the save values. this.qd.saveValues = origSvs; this.qd.results = grpBys; // NOW limit the group by results to a certain size, this needs // to be done last so that the group by limit clause can make use of the size of the // results. if (this.limit != null) { for (int i = 0; i < this.qd.results.size (); i++) { List l = (List) this.qd.results.get (i); List lr = (List) this.qd.groupByResults.get (l); this.allObjects = lr; this.currGroupBys = l; this.qd.saveValues = (Map) this.qd.groupBySaveValues.get (l); this.qd.groupByResults.put (l, this.limit.getSubList (lr, this)); } } this.qd.saveValues = origSvs; } catch (Exception e) { throw new QueryExecutionException ("Unable to perform group by operation", e); } } private void evalHavingClause () throws QueryExecutionException { if (this.having != null) { int si = this.qd.results.size (); this.qd.havingResults = new ArrayList (si); for (int i = 0; i < si; i++) { Object o = this.qd.results.get (i); this.currentObject = o; if (this.having.isTrue (o, this)) { this.qd.havingResults.add (o); } } this.qd.results = this.qd.havingResults; // Future proofing... this.allObjects = this.qd.results; } } private void evalLimitClause () throws QueryExecutionException { if (this.limit != null) { long s = System.currentTimeMillis (); this.qd.results = this.limit.getSubList (this.qd.results, this); this.addTiming ("Total time to limit results size", System.currentTimeMillis () - s); } } private void evalWhereClause () throws QueryExecutionException { long s = System.currentTimeMillis (); int si = this.allObjects.size (); if (this.where != null) { // Create the where results with "about" half the size of the input collection. // Further optimizations may be possible here if some statistics are collected // about how many objects match/fail the where clause and then increase the // capacity of the where results list as required, i.e. to cut down on the number // of array copy and allocation operations performed. For now though half will do ;) this.qd.whereResults = new ArrayList (si / 2); for (int i = 0; i < si; i++) { Object o = this.allObjects.get (i); this.currentObject = o; boolean res = this.where.isTrue (o, this); if (res) { this.qd.whereResults.add (o); } } } else { // No limiting where clause so what's passed in is what comes out. this.qd.whereResults = this.allObjects; } double wet = (double) System.currentTimeMillis () - (double) s; this.addTiming ("Total time to execute Where clause on all objects", wet); this.addTiming ("Where took average over: " + si + " objects", wet / (double) si); this.allObjects = this.qd.whereResults; // The results here are the result of executing the where clause, if present. this.qd.results = this.qd.whereResults; } public void setCurrentGroupByObjects (List objs) { this.currGroupBys = objs; } /** * Get the current list of objects in context (value of the :_allobjs special bind variable). * Note: the value of the :_allobjs bind variable will change depending upon where the query execution * is up to. * * @return The list of objects in context. */ public List getAllObjects () { return this.allObjects; } public void setAllObjects (List objs) { this.allObjects = objs; } public void setCurrentObject (Object o) { this.currentObject = o; } /** * Get the current object (value of the :_currobj special bind variable). Note: the value * of the :_currobj bind variable will change depending upon where the query execution is up to. * * @return The current object in context. */ public Object getCurrentObject () { return this.currentObject; } private void getColumnValues (List res, Collection rs) throws QueryExecutionException { int s = res.size (); int cs = this.cols.size (); boolean addItems = false; for (int i = 0; i < s; i++) { Object o = res.get (i); this.currentObject = o; List sRes = new ArrayList (cs); for (int j = 0; j < cs; j++) { SelectItemExpression v = (SelectItemExpression) this.cols.get (j); try { if (v.isAddItemsFromCollectionOrMap ()) { addItems = true; } // Get the value from the object... Object ov = v.getValue (o, this); if (addItems) { rs.addAll (v.getAddItems (ov)); } else { sRes.add (ov); } // Now since the expression can set the current object, put it // back to rights after the call... this.currentObject = o; } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for column: " + j + " for: " + v.toString () + " from result: " + i + " (" + o + ")", e); } } if (!addItems) { rs.add (sRes); } } } private List getNewObjectSingleColumnValues (List rows) throws QueryExecutionException { int s = rows.size (); SelectItemExpression nsei = (SelectItemExpression) this.cols.get (0); List res = new ArrayList (s); for (int i = 0; i < s; i++) { Object o = rows.get (i); this.currentObject = o; try { res.add (nsei.getValue (o, this)); // Now since the expression can set the current object, put it // back to rights after the call... this.currentObject = o; } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for column: " + 1 + " for: " + nsei.toString () + " from result: " + i + " (" + o + ")", e); } } return res; } public void setSaveValues (Map s) { if (this.parent != null) { this.parent.qd.saveValues.putAll (s); return; } this.qd.saveValues = s; } public void setSaveValue (Object id, Object value) { if (this.parent != null) { this.parent.setSaveValue (id, value); return; } if (this.qd == null) { return; } if (id instanceof String) { id = ((String) id).toLowerCase (); } Object old = this.qd.saveValues.get (id); this.qd.saveValues.put (id, value); if (old != null) { this.fireSaveValueChangedEvent (id, old, value); } } protected void fireSaveValueChangedEvent (Object id, Object from, Object to) { List l = (List) this.listeners.get ("svs"); if ((l == null) || (l.size () == 0) ) { return; } SaveValueChangedEvent svce = new SaveValueChangedEvent (this, id.toString ().toLowerCase (), from, to); for (int i = 0; i < l.size (); i++) { SaveValueChangedListener svcl = (SaveValueChangedListener) l.get (i); svcl.saveValueChanged (svce); } } protected void fireBindVariableChangedEvent (String name, Object from, Object to) { List l = (List) this.listeners.get ("bvs"); if ((l == null) || (l.size () == 0) ) { return; } BindVariableChangedEvent bvce = new BindVariableChangedEvent (this, name, from, to); for (int i = 0; i < l.size (); i++) { BindVariableChangedListener bvcl = (BindVariableChangedListener) l.get (i); bvcl.bindVariableChanged (bvce); } } /** * Get the save value for a particular key and group by list. * * @param id The id of the save value. * @param gbs The group by list key. * @return The object the key maps to. */ public Object getGroupBySaveValue (Object id, List gbs) { if (this.parent != null) { return this.parent.getGroupBySaveValue (id, gbs); } Map m = this.getGroupBySaveValues (gbs); if (m == null) { return null; } return m.get (id); } /** * Get the save values for the specified group bys. * * @param gbs The group bys. * @return The save values (name/value pairs). */ public Map getGroupBySaveValues (List gbs) { if (this.parent != null) { return this.parent.getGroupBySaveValues (gbs); } if ((this.qd == null) || (this.qd.groupBySaveValues == null) ) { return null; } return (Map) this.qd.groupBySaveValues.get (gbs); } /** * Get the save values for a particular key. * * @return The object the key maps to. */ public Object getSaveValue (Object id) { if (this.parent != null) { return this.parent.getSaveValue (id); } if ((this.qd == null) || (this.qd.saveValues == null) ) { return null; } if (id instanceof String) { id = ((String) id).toLowerCase (); } return this.qd.saveValues.get (id); } /** * Get the query string that this Query object represents. * * @return The query string. */ public String getQuery () { return this.query; } /** * Sets the custom comparator to use to perform per object comparisons. * * @param c The comparator. */ public void setObjectComparator (Comparator c) { this.userComparator = c; } public Comparator getObjectComparator () { return this.userComparator; } /** * Will cause the order by comparator used to order the results * to be initialized. This is generally only useful if you are specifying the * the order bys yourself via: {@link #setOrderByColumns(List)}. Usage of * this method is NOT supported, so don't use unless you really know what * you are doing! */ public void initOrderByComparator () throws QueryParseException { if (this.orderBys != null) { // No caching, this may need to change in the future. this.orderByComp = new ListExpressionComparator (this, this.userComparator, false); ListExpressionComparator lec = (ListExpressionComparator) this.orderByComp; // Need to check the type of each order by, if we have // any "column" indexes check to see if they are an accessor... int si = this.orderBys.size (); for (int i = 0; i < si; i++) { OrderBy ob = (OrderBy) this.orderBys.get (i); // Get the expression... Expression e = (Expression) ob.getExpression (); if (e == null) { // Now expect an integer that refers to a column // in the select... int ci = ob.getIndex (); if (ci == 0) { throw new QueryParseException ("Order by column indices should start at 1."); } if (this.retObjs) { throw new QueryParseException ("Cannot sort on a select column index when the objects are to be returned."); } if (ci > this.cols.size ()) { throw new QueryParseException ("Invalid order by column index: " + ci + ", only: " + this.cols.size () + " columns are selected to be returned."); } // Get the SelectItemExpression. SelectItemExpression sei = (SelectItemExpression) this.cols.get (ci - 1); // Get the expression... e = sei.getExpression (); } else { // Init the expression... e.init (this); } // Check to see if the expression returns a fixed result, if so // there's no point adding it. if (!e.hasFixedResult (this)) { lec.addSortItem (e, ob.getType ()); } } } } /** * Re-order the objects according to the columns supplied in the dirs Map. * The Map should be keyed on an Integer and map to a String value, the String value should * be either: {@link #ORDER_BY_ASC} for the column to be in ascending order or: * {@link #ORDER_BY_DESC} for the column to be in descending order. The Integer refers * to a column in the SELECT part of the statement. *

* For example: *

*

     *   SELECT name,
     *          directory,
     *          file
     *          length
     *   FROM   java.io.File
     * 
* Can be (re)ordered via the following code: *
     *   Query q = new Query ();
     *   q.parse (sql);
     *   
     *   Map reorderBys = new TreeMap ();
     *   reorderBys.put (new Integer (2), Query.ORDER_BY_ASC);
     *   reorderBys.put (new Integer (3), Query.ORDER_BY_DESC);
     *   reorderBys.put (new Integer (1), Query.ORDER_BY_ASC);
     *   reorderBys.put (new Integer (4), Query.ORDER_BY_DESC);
     *
     *   // Note: this call will cause the entire statement to be executed.
     *   q.reorder (myFiles,
     *              reorderBys);
     * 
* * @param objs The objects you wish to reorder. * @param dirs The order bys. * @return The QueryResults. * @throws QueryParseException If the statement can be parsed, i.e. if any of the order by * columns is out of range. * @throws QueryExecutionException If the call to: {@link #execute(List)} fails. * @see #reorder(List,String) */ public QueryResults reorder (List objs, SortedMap dirs) throws QueryExecutionException, QueryParseException { if (this.isWantObjects ()) { throw new QueryParseException ("Only SQL statements that return columns (not the objects passed in) can be re-ordered."); } List obs = new ArrayList (); Iterator iter = dirs.entrySet ().iterator (); while (iter.hasNext ()) { Map.Entry item = (Map.Entry) iter.next (); Integer in = (Integer) item.getKey (); // See if we have a column for it. if (in.intValue () > this.cols.size ()) { throw new QueryParseException ("Cannot reorder: " + dirs.size () + " columns, only: " + this.cols.size () + " are present in the SQL statement."); } String dir = (String) item.getValue (); int d = OrderBy.ASC; if (dir.equals (Query.ORDER_BY_DESC)) { d = OrderBy.DESC; } OrderBy ob = new OrderBy (); ob.setIndex (in.intValue ()); ob.setType (d); obs.add (ob); } this.orderBys = obs; this.initOrderByComparator (); // Execute the query. return this.execute (objs); } /** * Allows the re-ordering of the results via a textual representation of the order bys. * This is effectively like providing a new ORDER BY clause to the sql. *

* For example: *

*

     *   SELECT name,
     *          directory,
     *          file
     *          length
     *   FROM   java.io.File
     * 
* Can be (re)ordered via the following code: *
     *   Query q = new Query ();
     *   q.parse (sql);
     *   
     *   // Note: this call will cause the entire statement to be executed.
     *   q.reorder (myFiles,
     *              "name DESC, 3 ASC, length, 1 DESC");
     * 
* * @param objs The objects you wish to re-order. * @param orderBys The order bys. * @return The execution results. * @throws QueryParseException If the statement can be parsed, i.e. if any of the order by * columns is out of range or the order bys cannot be parsed. * @throws QueryExecutionException If the call to: {@link #execute(List)} fails. * @see #reorder(List,SortedMap) */ public QueryResults reorder (List objs, String orderBys) throws QueryParseException, QueryExecutionException { String sql = ""; if (!orderBys.toLowerCase ().startsWith ("order by")) { sql = sql + " ORDER BY "; } sql = sql + orderBys; BufferedReader sr = new BufferedReader (new StringReader (sql)); JoSQLParser parser = new JoSQLParser (sr); List ors = null; try { ors = parser.OrderBys (); } catch (Exception e) { throw new QueryParseException ("Unable to parse order bys: " + orderBys, e); } this.orderBys = ors; this.initOrderByComparator (); // Execute the query. return this.execute (objs); } public void setClassLoader (ClassLoader cl) { this.classLoader = cl; } public ClassLoader getClassLoader () { if (this.classLoader == null) { // No custom classloader specified, use the one that loaded // this class. this.classLoader = Thread.currentThread ().getContextClassLoader (); if (this.classLoader == null) { this.classLoader = this.getClass ().getClassLoader (); } } return this.classLoader; } public Class loadClass (String name) throws Exception { return this.getClassLoader ().loadClass (name); } /** * Parse the JoSQL query. * * @param q The query string. * @throws QueryParseException If the query cannot be parsed and/or {@link #init() inited}. */ public void parse (String q) throws QueryParseException { this.query = q; BufferedReader sr = new BufferedReader (new StringReader (q)); long s = System.currentTimeMillis (); JoSQLParser parser = new JoSQLParser (sr); this.addTiming ("Time to init josql parser object", System.currentTimeMillis () - s); s = System.currentTimeMillis (); try { parser.parseQuery (this); } catch (Exception e) { throw new QueryParseException ("Unable to parse query: " + q, e); } this.isParsed = true; this.addTiming ("Time to parse query into object form", System.currentTimeMillis () - s); // Init the query. this.init (); } private void initFromObjectClass () throws QueryParseException { if (this.parent == null) { if (!(this.from instanceof ConstantExpression)) { throw new QueryParseException ("The FROM clause of the outer-most Query must be a string that denotes a fully-qualified class name, expression: " + this.from + " is not valid."); } // See if the class name is the special "null". String cn = null; try { // Should be safe to use a null value here (especially since we know // how ConstantExpression works ;) cn = (String) this.from.getValue (null, this); } catch (Exception e) { throw new QueryParseException ("Unable to determine FROM clause of the outer-most Query from expression: " + this.from + ", note: this exception shouldn't be able to happen, so something has gone SERIOUSLY wrong!", e); } if (!cn.equalsIgnoreCase ("null")) { // Load the class that we are dealing with... try { this.objClass = this.loadClass (cn); } catch (Exception e) { throw new QueryParseException ("Unable to load FROM class: " + cn, e); } } } } public void init () throws QueryParseException { long s = System.currentTimeMillis (); // If we don't have a parent, then there must be an explicit class name. this.initFromObjectClass (); // Now if we have any columns, init those as well... this.initSelect (); // Now init the where clause (where possible)... if (this.where != null) { this.where.init (this); } // Now init the having clause (where possible)... if (this.having != null) { this.having.init (this); } // See if we have order by columns, if so init the comparator. this.initOrderByComparator (); // See if we have order by columns, if so init the comparator. if (this.groupBys != null) { this.initGroupBys (); } this.initGroupOrderBys (); if (this.groupByLimit != null) { this.groupByLimit.init (this); } if (this.limit != null) { this.limit.init (this); } this.initExecuteOn (); this.addTiming ("Time to init Query objects", System.currentTimeMillis () - s); } private void initSelect () throws QueryParseException { if (this.retObjs) { // Nothing to do. return; } int aic = 0; int si = this.cols.size (); this.aliases = new HashMap (); for (int i = 0; i < si; i++) { SelectItemExpression exp = (SelectItemExpression) this.cols.get (i); exp.init (this); if (exp.isAddItemsFromCollectionOrMap ()) { aic++; } String alias = exp.getAlias (); if (alias != null) { this.aliases.put (alias, Integer.valueOf (i + 1)); } this.aliases.put ((i + 1) + "", Integer.valueOf (i + 1)); } if ((aic > 0) && (aic != si) ) { throw new QueryParseException ("If one or more SELECT clause columns is set to add the items returned from a: " + Map.class.getName () + " or: " + java.util.Collection.class.getName () + " then ALL columns must be marked to return the items as well."); } } private void initGroupBys () throws QueryParseException { this.grouper = new Grouper (this); int si = this.groupBys.size (); for (int i = 0; i < si; i++) { OrderBy ob = (OrderBy) this.groupBys.get (i); // Get the expression... Expression e = (Expression) ob.getExpression (); if (e == null) { // Now expect an integer that refers to a column // in the select... int ci = ob.getIndex (); if (ci == 0) { throw new QueryParseException ("Order by column indices should start at 1."); } if (this.retObjs) { throw new QueryParseException ("Cannot sort on a select column index when the objects are to be returned."); } if (ci > this.cols.size ()) { throw new QueryParseException ("Invalid order by column index: " + ci + ", only: " + this.cols.size () + " columns are selected to be returned."); } // Get the SelectItemExpression. SelectItemExpression sei = (SelectItemExpression) this.cols.get (ci - 1); // Get the expression... e = sei.getExpression (); } else { // Init the expression... e.init (this); } this.grouper.addExpression (e); } } private void initExecuteOn () throws QueryParseException { if (this.executeOn == null) { return; } // Get the supported types. List allF = (List) this.executeOn.get (Query.ALL); if (allF != null) { // We have some, so init them... int si = allF.size (); for (int i = 0; i < si; i++) { AliasedExpression f = (AliasedExpression) allF.get (i); f.init (this); } } List resultsF = (List) this.executeOn.get (Query.RESULTS); if (resultsF != null) { // We have some, so init them... int si = resultsF.size (); for (int i = 0; i < si; i++) { AliasedExpression f = (AliasedExpression) resultsF.get (i); f.init (this); } } resultsF = (List) this.executeOn.get (Query.GROUP_BY_RESULTS); if (resultsF != null) { // We have some, so init them... int si = resultsF.size (); for (int i = 0; i < si; i++) { AliasedExpression f = (AliasedExpression) resultsF.get (i); f.init (this); } } } private void initGroupOrderBys () throws QueryParseException { if (this.groupOrderBys == null) { // Nothing to do. return; } if (this.grouper == null) { throw new QueryParseException ("Group Order Bys are only valid if 1 or more Group By columns have been specified."); } // Here we "override" the from class because when dealing with the order bys the // current object will be a List, NOT the class defined in the FROM clause. Class c = this.objClass; this.objClass = List.class; // No caching, this may need to change in the future. this.groupOrderByComp = new GroupByExpressionComparator (this, this.userComparator, false); GroupByExpressionComparator lec = (GroupByExpressionComparator) this.groupOrderByComp; List grouperExps = this.grouper.getExpressions (); // Need to check the type of each order by, if we have // any "column" indexes check to see if they are an accessor... int si = this.groupOrderBys.size (); for (int i = 0; i < si; i++) { OrderBy ob = (OrderBy) this.groupOrderBys.get (i); if (ob.getIndex () > -1) { int ci = ob.getIndex (); if (ci == 0) { throw new QueryParseException ("Group Order by column indices should start at 1."); } if (ci > grouperExps.size ()) { throw new QueryParseException ("Invalid Group Order By column index: " + ci + ", only: " + grouperExps.size () + " Group By columns are selected to be returned."); } lec.addSortItem (null, // Remember the -1! Column indices start at 1 but // List indices start at 0 ;) ci - 1, ob.getType ()); continue; } // Get the expression... Expression e = (Expression) ob.getExpression (); // See if the expression is a "direct" match for any of the // group by columns. boolean cont = true; for (int j = 0; j < grouperExps.size (); j++) { Expression exp = (Expression) grouperExps.get (j); if (e.equals (exp)) { // This is a match, add to the comparator. lec.addSortItem (null, j, ob.getType ()); cont = false; } } if (!cont) { continue; } if ((e instanceof Function) || (e instanceof BindVariable) || (e instanceof SaveValue) ) { e.init (this); lec.addSortItem (e, -1, ob.getType ()); continue; } // If we are here then we haven't been able to deal with the // order by... so barf. throw new QueryParseException ("If the Group Order By: " + ob + " is not a function, a bind variable or a save value then it must be present in the Group By list."); } // Restore the FROM object class. this.objClass = c; } /** * Set the "FROM" object class. It is advised that you NEVER call this method, do so * at your own risk, dragons will swoop from the sky and crisp your innards if you do so!!! * Seriously though ;), this method should ONLY be called by those who know what they * are doing, whatever you think you know about how this method operates is irrelevant * which is why the dangers of calling this method are not documented... *

* YOU HAVE BEEN WARNED!!! NO BUGS WILL BE ACCEPTED THAT ARISE FROM THE CALLING OF * THIS METHOD!!! * * @param c The FROM class. */ public void setFromObjectClass (Class c) { this.objClass = c; } public Class getFromObjectClass () { return this.objClass; } public void removeBindVariableChangedListener (BindVariableChangedListener bvl) { List l = (List) this.listeners.get ("bvs"); if (l == null) { return; } l.remove (bvl); } public void addBindVariableChangedListener (BindVariableChangedListener bvl) { List l = (List) this.listeners.get ("bvs"); if (l == null) { l = new ArrayList (); this.listeners.put ("bvs", l); } if (!l.contains (bvl)) { l.add (bvl); } } public void removeSaveValueChangedListener (SaveValueChangedListener svl) { List l = (List) this.listeners.get ("svs"); if (l == null) { return; } l.remove (svl); } public void addSaveValueChangedListener (SaveValueChangedListener svl) { List l = (List) this.listeners.get ("svs"); if (l == null) { l = new ArrayList (); this.listeners.put ("svs", l); } if (!l.contains (svl)) { l.add (svl); } } public Map getAliases () { return this.aliases; } /** * Return whether the query should return objects. * * @return true if the query should return objects. */ public boolean isWantObjects () { return this.retObjs; } /** * Set whether the query should return objects (use true). * Caution: Do NOT use unless you are sure about what you are doing! * * @param v Set to true to indicate that the query should return objects. */ public void setWantObjects (boolean v) { this.retObjs = v; } /** * Get the character that represents a wildcard in LIKE searches. * * @return The char. */ public char getWildcardCharacter () { return this.wildcardChar; } /** * Set the character that represents a wildcard in LIKE searches. * * @param c The char. */ public void setWildcardCharacter (char c) { this.wildcardChar = c; } /** * Set the object that represents the limit clause. * Caution: Do NOT use unless you are sure about what you are doing! * * @param l The object. */ public void setLimit (Limit l) { this.limit = l; } /** * Get the object that represents the limit clause. * * @return The object. */ public Limit getLimit () { return this.limit; } /** * Return whether this Query object has had a statement applied to it * and has been parsed. * * @return Whether the query is associated with a statement. */ public boolean parsed () { return this.isParsed; } /** * Indicate whether "distinct" results are required. * * @param v Set to true to make the results distinct. */ public void setWantDistinctResults (boolean v) { this.distinctResults = v; } /** * Get the results of {@link #execute(java.util.List) executing} this query. * * @return The query results. */ public QueryResults getQueryResults () { return this.qd; } /** * Get the "order bys". This will return a List of {@link OrderBy} objects. * This is generally only useful when you want to {@link #reorder(List,String)} * the search and wish to get access to the textual representation of the order bys. *

* It is therefore possible to modify the orderbys in place, perhaps by using a different * expression or changing the direction (since the objects are not cloned before being * returned). However do so at YOUR OWN RISK. If you do so, then ensure you * call: {@link #setOrderByColumns(List)}, then: {@link #initOrderByComparator()} * before re-executing the statement, otherwise nothing will happen! * * @return The order bys. */ public List getOrderByColumns () { return new ArrayList (this.orderBys); } /** * Set the parent query. * Caution: Do NOT use unless you are sure about what you are doing! * * @param q The parent query. */ public void setParent (Query q) { this.parent = q; } /** * Get the parent query. * * @return The query, will be null if there is no parent. */ public Query getParent () { return this.parent; } /** * Get the top level query if "this" is a sub-query, the query chain is traversed until * the top level query is found, i.e. when {@link #getParent()} returns null. * * @return The top level query, will be null if there is no parent. */ public Query getTopLevelQuery () { Query q = this; Query par = null; while (true) { par = q.getParent (); if (par == null) { break; } q = par; } return q; } /** * Get a string version of this query suitable for debugging. This will reconstruct the query * based on the objects it holds that represent the various clauses. * * @return The reconstructed query. */ public String toString () { StringBuffer buf = new StringBuffer ("SELECT "); if (this.distinctResults) { buf.append ("DISTINCT "); } if (this.retObjs) { buf.append ("*"); } else { for (int i = 0; i < this.cols.size (); i++) { buf.append (" "); buf.append (this.cols.get (i)); if (i < (this.cols.size () - 1)) { buf.append (","); } } } buf.append (" FROM "); buf.append (this.from); if (this.where != null) { buf.append (" WHERE "); buf.append (this.where); } return buf.toString (); } public static QueryResults parseAndExec (String query, List objs) throws QueryParseException, QueryExecutionException { Query q = new Query (); q.parse (query); return q.execute (objs); } } josql-2.2/src/org/josql/QueryExecutionException.java000066400000000000000000000017511157743651500227500ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql; /** * The exception that is thrown during the execution part of the Query * execution. */ public class QueryExecutionException extends Exception { public QueryExecutionException (String message, Throwable cause) { super (message, cause); } public QueryExecutionException (String message) { super (message); } } josql-2.2/src/org/josql/QueryParseException.java000066400000000000000000000017461157743651500220630ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql; /** * The exception that is thrown during the parse and init * parts of the Query execution. */ public class QueryParseException extends Exception { public QueryParseException (String message, Throwable cause) { super (message, cause); } public QueryParseException (String message) { super (message); } } josql-2.2/src/org/josql/QueryResults.java000066400000000000000000000056741157743651500205770ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql; import java.util.List; import java.util.Map; import java.util.HashMap; /** * This class holds all the "result" information about the execution of a particular * Query. It should be noted that this class holds no reference to the Query object * so that a query can be executed, the results "processed" in some way and then the * results can be cleaned up by the GC. *

* @see org.josql.Query#execute(List) */ public class QueryResults { // Execution data. Map saveValues = new HashMap (); Map timings = null; List results = null; List whereResults = null; List havingResults = null; Map groupByResults = null; Map groupBySaveValues = null; public QueryResults () { } public Map getGroupBySaveValues (List k) { if (this.groupBySaveValues == null) { return null; } return (Map) this.groupBySaveValues.get (k); } /** * Get the save values. * * @return The save values. */ public Map getSaveValues () { return this.saveValues; } /** * Get a particular save value for the passed in key. * * @param id The key of the save value. * @return The value it maps to. */ public Object getSaveValue (Object id) { if (this.saveValues == null) { return null; } if (id instanceof String) { id = ((String) id).toLowerCase (); } return this.saveValues.get (id); } /** * Get the results of executing the query, this is the "final" results, i.e. * of executing ALL of the query. * * @return The results. */ public List getResults () { return this.results; } /** * Get the timing information, is a Map of string to double values. * * @return The timings. */ public Map getTimings () { return this.timings; } /** * Get the group by results. * * @return The group by results. */ public Map getGroupByResults () { return this.groupByResults; } /** * Get the having results. * * @return The having results. */ public List getHavingResults () { return this.havingResults; } /** * Get the where results. * * @return The where results. */ public List getWhereResults () { return this.whereResults; } } josql-2.2/src/org/josql/contrib/000077500000000000000000000000001157743651500166715ustar00rootroot00000000000000josql-2.2/src/org/josql/contrib/JoSQLAntFileSelector.java000066400000000000000000000136141157743651500234350ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.io.File; import org.apache.tools.ant.types.selectors.ExtendFileSelector; import org.apache.tools.ant.types.Parameter; import org.apache.tools.ant.BuildException; import org.josql.Query; /** * A custom file selector for use with Ant. *

* See: Custom Ant Selectors for more details. *

* Allows a JoSQL WHERE clause * to be applied to each file passed to the selector {@link #isSelected(File,String,File)}. *

* An obvious question to ask here is "why do I need this when Ant has lots of custom file selectors". * Well, in short, you don't "need" this selector, but I've found that trying to remember all the * custom elements and their attributes can be painful and doesn't give me all the power needed to * select the files I want. This custom selector however does. *

* The selector supports the following "param"s. *

*

* Usage: *

* A typical usage may be: *

*

 *   <fileset dir="myDir" 
 *            includes="**">
 *     <custom classpath="[PATH_TO_JOSQL]/JoSQL-1.0.jar:[PATH_TO_JOSQL]/3rd-party-jars/gentlyWEB-utils-1.1.jar"
 *             classname="org.josql.contrib.JoSQLAntFileSelector">
 *       <param name="debug" value="on" />
 *       <param name="where" value="toDate (lastModified) > toDate ('22/Sep/2005')" />
 *       <param name="where" value="AND length > 10000" />
 *     </custom>
 *   </fileset>
 * 
*

* This will create a file set containing all the files modified after 22/Sep/2005 and have a length greater * than 10000 bytes. *

* Compare this to how it would be "normally" be done with standard Ant fileset selectors: *

 *   <fileset dir="myDir" 
 *            includes="**">
 *     <date datetime="22/Sep/2005"
 *           pattern="dd/MMM/yyyy"
 *           when="after" />
 *     <size value="10000"
 *           when="more" />
 *   </fileset>
 * 
*

* Of course it is perfectly possible to mix and match this selector and other custom selectors or * the built-in selectors. */ public class JoSQLAntFileSelector extends Query implements ExtendFileSelector { private static String sqlPrefix = "SELECT * FROM java.io.File WHERE "; public static final String WHERE = "where"; public static final String DEBUG = "debug"; private Exception parseExp = null; private boolean configured = false; private String where = null; private boolean debug = false; private boolean shownWhere = false; public JoSQLAntFileSelector () { } public void setParameters (Parameter[] parms) { if (parms != null) { StringBuffer buf = new StringBuffer (); for (int i = 0; i < parms.length; i++) { Parameter p = parms[i]; if (p.getName ().toLowerCase ().equals (JoSQLAntFileSelector.DEBUG)) { if (p.getValue ().toLowerCase ().equals ("on")) { this.debug = true; } } if (p.getName ().toLowerCase ().equals (JoSQLAntFileSelector.WHERE)) { if (buf.length () > 0) { buf.append (" "); } buf.append (p.getValue ().trim ()); } } if (buf.length () > 0) { try { this.where = buf.toString (); this.parse (JoSQLAntFileSelector.sqlPrefix + buf.toString ()); this.configured = true; } catch (Exception e) { this.parseExp = e; } } } } public boolean isSelected (File basedir, String filename, File file) throws BuildException { if (!this.configured) { if (this.parseExp != null) { throw new BuildException ("Unable to init query with where clause: " + this.where + ", reason: " + this.parseExp.getMessage (), this.parseExp); } throw new BuildException ("Selector is not configured, expected to find a parameter with name: " + JoSQLAntFileSelector.WHERE + " that provides the where clause to evaluate against each file."); } if (this.debug) { if (!this.shownWhere) { System.out.println ("Using WHERE clause: " + this.where); this.shownWhere = true; } } try { boolean v = this.getWhereClause ().isTrue (file, this); if (this.debug) { System.out.println ("WHERE = " + v + " for file: " + file); } return v; } catch (Exception e) { //e.printStackTrace (); throw new BuildException ("Unable to execute where clause: " + this.getWhereClause () + " on file: " + file + ", reason: " + e.getMessage (), e); } } } josql-2.2/src/org/josql/contrib/JoSQLFreeChartCategoryDataset.java000066400000000000000000000210271157743651500252560ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.util.List; import java.util.ArrayList; import java.util.Arrays; import org.jfree.data.category.CategoryDataset; import org.jfree.data.DomainOrder; import org.jfree.data.general.DatasetGroup; import org.jfree.data.general.DatasetChangeListener; import org.jfree.data.general.DatasetChangeEvent; import org.josql.Query; import org.josql.QueryResults; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; import org.josql.expressions.SelectItemExpression; public class JoSQLFreeChartCategoryDataset extends Query implements CategoryDataset { private QueryResults results = null; private int xCol = 0; private List yCols = null; private List listeners = new ArrayList (); private DatasetGroup group = null; public JoSQLFreeChartCategoryDataset () { } public void addChangeListener (DatasetChangeListener l) { this.listeners.add (l); } public void removeChangeListener (DatasetChangeListener l) { this.listeners.remove (l); } public DatasetGroup getGroup () { return this.group; } /** * Get any results, will be null unless {@link #execute(List)} has been called. * * @return The results. */ public QueryResults getResults () { return this.results; } /** * Clear any results. */ public void clearResults () { this.results = null; } public void setGroup (DatasetGroup g) { this.group = g; } public void define (int xCol, Object[] yCols) throws IllegalArgumentException, IllegalStateException, QueryParseException { this.define (xCol, Arrays.asList (yCols)); } public void define (int xCol, int[] yCols) throws IllegalArgumentException, IllegalStateException, QueryParseException { List l = new ArrayList (yCols.length); for (int i = 0; i < yCols.length; i++) { l.add (Integer.valueOf (yCols[i])); } this.define (xCol, l); } public void define (int xCol, List yCols) throws IllegalArgumentException, IllegalStateException, QueryParseException { if (!this.parsed ()) { throw new IllegalStateException ("Cannot add a series until a query has been specified and parsed."); } if (xCol < 1) { throw new IllegalArgumentException ("X column index must be a minimum of 1."); } for (int i = 0; i < yCols.size (); i++) { Object o = yCols.get (i); if (o instanceof String) { try { yCols.set (i, Integer.valueOf ((String) o)); continue; } catch (Exception e) { throw new IllegalArgumentException ("Unable to convert y column indicator: " + o + " to an integer."); } } if (o instanceof Number) { yCols.set (i, Integer.valueOf (((Number) o).intValue ())); continue; } if (!(o instanceof Integer)) { throw new IllegalArgumentException ("Expected y column indicator: " + o + " to be either a number or a string representing a number."); } } List cols = this.getColumns (); for (int i = 0; i < yCols.size (); i++) { Integer in = (Integer) yCols.get (i); if (in.intValue () < 1) { throw new IllegalArgumentException ("Y column index must be a minimum of 1."); } if (in.intValue () > cols.size ()) { throw new IllegalArgumentException ("Y column index must be a maximum of " + cols.size () + "."); } SelectItemExpression yexp = (SelectItemExpression) cols.get (in.intValue () - 1); if (yexp.getAlias () == null) { throw new IllegalArgumentException ("Y column: " + yexp + " must have an alias."); } Class yc = yexp.getExpectedReturnType (this); if (!Utilities.isNumber (yc)) { throw new IllegalArgumentException ("Y column: " + yexp + " will evaluate to an instance of type: " + yc.getName () + ", but only columns that return numbers are allowed."); } } if (xCol > cols.size ()) { throw new IllegalArgumentException ("X column index must be a maximum of " + cols.size () + "."); } SelectItemExpression xexp = (SelectItemExpression) cols.get (xCol - 1); Class xc = xexp.getExpectedReturnType (this); xc = Utilities.getObjectClass (xc); if (!(Comparable.class.isAssignableFrom (xc))) { throw new IllegalArgumentException ("X column: " + xexp + " will evaluate to an instance of type: " + xc.getName () + ", but only columns that implement: " + Comparable.class.getName () + " can be used."); } this.yCols = yCols; } /** * Exectute the query and return the results. A reference to the results is also held to * allow them to be iterated over. If you plan on re-using this data source then * you should call: {@link #clearResults()} to free up the references to the results. * * @param l The List of objects to execute the query on. * @return The results. * @throws QueryExecutionException If the query cannot be executed, or if the query * is set to return objects rather than "columns". */ public QueryResults executeQuery (List l) throws QueryExecutionException { if (this.isWantObjects ()) { throw new QueryExecutionException ("Only SQL statements that return columns (not the objects passed in) can be used."); } this.results = super.execute (l); // Notify our listeners. DatasetChangeEvent dce = new DatasetChangeEvent (this, this); for (int i = 0; i < this.listeners.size (); i++) { DatasetChangeListener d = (DatasetChangeListener) this.listeners.get (i); d.datasetChanged (dce); } return this.results; } public DomainOrder getDomainOrder () { return DomainOrder.ASCENDING; } public int getRowCount () { return this.results.getResults ().size (); } public int getColumnCount () { return this.yCols.size (); } public Number getValue (int row, int col) { List l = (List) this.results.getResults ().get (row); return (Number) l.get (col); } public List getRowKeys () { List ks = new ArrayList (); for (int i = 0; i < this.results.getResults ().size (); i++) { List l = (List) this.results.getResults ().get (i); ks.add (l.get (this.xCol)); } return ks; } public Number getValue (Comparable row, Comparable col) { int rk = this.getRowIndex (row); int ck = this.getColumnIndex (col); List l = (List) this.results.getResults ().get (rk); return (Number) l.get (ck); } public Comparable getColumnKey (int c) { return (Comparable) this.getColumnKeys ().get (c); } public List getColumnKeys () { List ks = new ArrayList (); for (int i = 0; i < this.yCols.size (); i++) { Integer in = (Integer) this.yCols.get (i); SelectItemExpression sei = (SelectItemExpression) this.getColumns ().get (in.intValue () - 1); ks.add (sei.getAlias ()); } return ks; } public int getColumnIndex (Comparable c) { List ck = this.getColumnKeys (); for (int i = 0; i < ck.size (); i++) { if (((Comparable) ck.get (i)).compareTo (c) == 0) { return i; } } return -1; } public int getRowIndex (Comparable c) { List rk = this.getRowKeys (); for (int i = 0; i < rk.size (); i++) { if (((Comparable) rk.get (i)).compareTo (c) == 0) { return i; } } return -1; } public Comparable getRowKey (int k) { return (Comparable) this.getRowKeys ().get (k); } } josql-2.2/src/org/josql/contrib/JoSQLFreeChartPieDataset.java000066400000000000000000000144621157743651500242230ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.LinkedHashMap; import java.util.Iterator; import org.jfree.data.general.PieDataset; import org.jfree.data.general.DatasetGroup; import org.jfree.data.general.DatasetChangeListener; import org.jfree.data.general.DatasetChangeEvent; import org.josql.Query; import org.josql.QueryResults; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; import org.josql.expressions.SelectItemExpression; public class JoSQLFreeChartPieDataset extends Query implements PieDataset { private Map values = new LinkedHashMap (); private int key = 0; private int value = 0; private List listeners = new ArrayList (); private DatasetGroup group = null; public JoSQLFreeChartPieDataset () { } public void addChangeListener (DatasetChangeListener l) { this.listeners.add (l); } public void removeChangeListener (DatasetChangeListener l) { this.listeners.remove (l); } public DatasetGroup getGroup () { return this.group; } public void setGroup (DatasetGroup g) { this.group = g; } public void setKeyValue (int keyCol, int valueCol) throws IllegalArgumentException, IllegalStateException, QueryParseException { if (!this.parsed ()) { throw new IllegalStateException ("Cannot specify the key and value columns until a query has been specified and parsed."); } if (keyCol < 1) { throw new IllegalArgumentException ("Key column index must be a minimum of 1."); } if (valueCol < 1) { throw new IllegalArgumentException ("Value column index must be a minimum of 1."); } List cols = this.getColumns (); if (keyCol > cols.size ()) { throw new IllegalArgumentException ("Key column index must be a minimum of " + cols.size () + "."); } if (valueCol > cols.size ()) { throw new IllegalArgumentException ("Value column index must be a minimum of " + cols.size () + "."); } SelectItemExpression vexp = (SelectItemExpression) cols.get (valueCol - 1); Class vc = vexp.getExpectedReturnType (this); if (!Utilities.isNumber (vc)) { throw new IllegalArgumentException ("Value column: " + valueCol + " will evaluate to an instance of type: " + vc.getName () + ", but only columns that return numbers are allowed."); } this.key = keyCol; this.value = valueCol; } /** * Exectute the query and return the results. A reference to the results is also held to * allow them to be iterated over. If you plan on re-using this data source then * you should call: {@link #clearResults()} to free up the references to the results. * * @param l The List of objects to execute the query on. * @return The results. * @throws QueryExecutionException If the query cannot be executed, or if the query * is set to return objects rather than "columns". */ public QueryResults executeQuery (List l) throws QueryExecutionException { if (this.isWantObjects ()) { throw new QueryExecutionException ("Only SQL statements that return columns (not the objects passed in) can be used."); } if ((this.key == 0) || (this.value == 0) ) { throw new IllegalStateException ("Key and/or value columns not specified."); } QueryResults qr = super.execute (l); List res = qr.getResults (); Map nValues = new LinkedHashMap (); for (int i = 0; i < res.size (); i++) { List resR = (List) res.get (i); // Get the key. Object k = resR.get (this.key - 1); // Get the value. Object v = resR.get (this.value - 1); String kv = null + ""; if (k == null) { nValues.put (kv, v); } // See if the key is "comparable". if (k instanceof Comparable) { nValues.put (k, v); } else { kv = k.toString (); nValues.put (kv, v); } } // Just switch them, this way enables any client of the data to // still iterate over them without fear of a ConcurrentModificationException // occuring. this.values = nValues; // Notify our listeners. DatasetChangeEvent dce = new DatasetChangeEvent (this, this); for (int i = 0; i < this.listeners.size (); i++) { DatasetChangeListener d = (DatasetChangeListener) this.listeners.get (i); d.datasetChanged (dce); } return qr; } public int getItemCount () { return this.values.size (); } public Number getValue (int index) { int c = 0; Iterator iter = this.values.keySet ().iterator (); while (iter.hasNext ()) { Object k = iter.next (); if (index == c) { return (Number) this.values.get (k); } c++; } return new Double (-1); } public int getIndex (Comparable k) { int c = 0; Iterator iter = this.values.keySet ().iterator (); while (iter.hasNext ()) { Comparable ko = (Comparable) iter.next (); if (ko.compareTo (k) == 0) { return c; } c++; } return -1; } public Comparable getKey (int index) { int c = 0; Iterator iter = this.values.keySet ().iterator (); while (iter.hasNext ()) { Object k = iter.next (); if (index == c) { return (Comparable) k; } c++; } return null; } public Number getValue (Comparable key) { return (Number) this.values.get (key); } public List getKeys () { return new ArrayList (this.values.keySet ()); } } josql-2.2/src/org/josql/contrib/JoSQLFreeChartXYDataset.java000066400000000000000000000153521157743651500240450ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import org.jfree.data.xy.XYDataset; import org.jfree.data.DomainOrder; import org.jfree.data.general.DatasetGroup; import org.jfree.data.general.DatasetChangeListener; import org.jfree.data.general.DatasetChangeEvent; import org.josql.Query; import org.josql.QueryResults; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; import org.josql.expressions.SelectItemExpression; public class JoSQLFreeChartXYDataset extends Query implements XYDataset { private List results = null; private Map series = new HashMap (); private List listeners = new ArrayList (); private DatasetGroup group = null; public JoSQLFreeChartXYDataset () { } public void addChangeListener (DatasetChangeListener l) { this.listeners.add (l); } public void removeChangeListener (DatasetChangeListener l) { this.listeners.remove (l); } public DatasetGroup getGroup () { return this.group; } public void setGroup (DatasetGroup g) { this.group = g; } public int indexOf (Comparable c) { // Must be an integer. return ((Integer) c).intValue (); } public Comparable getSeriesKey (int series) { return Integer.valueOf (series); } public int getSeriesCount () { return this.series.size (); } public void removeSeries (int series) { this.series.remove (Integer.valueOf (series)); } public void addSeries (int series, int xCol, int yCol) throws IllegalArgumentException, IllegalStateException, QueryParseException { if (!this.parsed ()) { throw new IllegalStateException ("Cannot add a series until a query has been specified and parsed."); } if (xCol < 1) { throw new IllegalArgumentException ("X column index must be a minimum of 1."); } if (yCol < 1) { throw new IllegalArgumentException ("Y column index must be a minimum of 1."); } List cols = this.getColumns (); if (xCol > cols.size ()) { throw new IllegalArgumentException ("X column index must be a minimum of " + cols.size () + "."); } if (yCol > cols.size ()) { throw new IllegalArgumentException ("Y column index must be a minimum of " + cols.size () + "."); } SelectItemExpression xexp = (SelectItemExpression) cols.get (xCol - 1); Class xc = xexp.getExpectedReturnType (this); if (!Utilities.isNumber (xc)) { throw new IllegalArgumentException ("X column: " + xexp + " will evaluate to an instance of type: " + xc.getName () + ", but only columns that return numbers are allowed."); } SelectItemExpression yexp = (SelectItemExpression) cols.get (yCol - 1); Class yc = yexp.getExpectedReturnType (this); if (!Utilities.isNumber (yc)) { throw new IllegalArgumentException ("Y column: " + yexp + " will evaluate to an instance of type: " + yc.getName () + ", but only columns that return numbers are allowed."); } this.series.put (Integer.valueOf (series), new Series (xCol, yCol)); } /** * Exectute the query and return the results. A reference to the results is also held to * allow them to be iterated over. If you plan on re-using this data source then * you should call: {@link #clearResults()} to free up the references to the results. * * @param l The List of objects to execute the query on. * @return The results. * @throws QueryExecutionException If the query cannot be executed, or if the query * is set to return objects rather than "columns". */ public QueryResults executeQuery (List l) throws QueryExecutionException { if (this.isWantObjects ()) { throw new QueryExecutionException ("Only SQL statements that return columns (not the objects passed in) can be used."); } QueryResults qr = super.execute (l); this.results = qr.getResults (); // Notify our listeners. DatasetChangeEvent dce = new DatasetChangeEvent (this, this); for (int i = 0; i < this.listeners.size (); i++) { DatasetChangeListener d = (DatasetChangeListener) this.listeners.get (i); d.datasetChanged (dce); } return qr; } public List getResults () { return this.results; } public void clearResults () { this.results = null; } public int getItemCount (int series) { if (this.results == null) { return 0; } return this.results.size (); } public double getXValue (int series, int item) { // Bad man! return ((Double) this.getX (series, item)).doubleValue (); } public double getYValue (int series, int item) { // Bad man! return ((Double) this.getY (series, item)).doubleValue (); } public Number getX (int series, int item) { if (this.results == null) { return new Double (0); } List l = (List) this.results.get (item); Series s = (Series) this.series.get (Integer.valueOf (series)); if (s == null) { return new Double (0); } Number n = (Number) l.get (s.xCol - 1); if (n instanceof Double) { return n; } else { return new Double (n.doubleValue ()); } } public Number getY (int series, int item) { if (this.results == null) { return new Double (0); } List l = (List) this.results.get (item); Series s = (Series) this.series.get (Integer.valueOf (series)); if (s == null) { return new Double (0); } Number n = (Number) l.get (s.yCol - 1); if (n instanceof Double) { return n; } else { return new Double (n.doubleValue ()); } } public DomainOrder getDomainOrder () { return DomainOrder.ASCENDING; } private class Series { public int xCol = 0; public int yCol = 0; public Series (int x, int y) { this.xCol = x; this.yCol = y; } } } josql-2.2/src/org/josql/contrib/JoSQLJRDataSource.java000066400000000000000000000074241157743651500227020ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.util.List; import net.sf.jasperreports.engine.JRRewindableDataSource; import net.sf.jasperreports.engine.JRField; import org.josql.QueryExecutionException; import org.josql.Query; import org.josql.QueryResults; /** * A data source suitable for use with JasperReports. * This is basically just an extension to {@link Query} that allows the * results to be iterated over, thereby providing the ability for objects to be reported on * that are held in memory. *

* One limitation here is that the SQL query must return columns rather than the objects * since the values need to be mapped by JasperReports. For example: *

 *   SELECT lastModified,
 *          name
 *   FROM   java.io.File
 *   WHERE  name LIKE '%.html'
 * 
*

* This query would work but it should be noted that the select "columns" (since they do not have * aliases assigned) will be labeled 1, 2, X and so on. * You can assign aliases to the "columns" and then use them in the report definition file. *

* Please note: due to my bewilderment (and the fact that I can't get the examples to work ;) * I haven't been able to adequately test this implementation, in the rudementary tests I * performed it seemed to work. If it doesn't please send me an example so that I can try * it! */ public class JoSQLJRDataSource extends Query implements JRRewindableDataSource { private int row = 0; private List results = null; public JoSQLJRDataSource () { } /** * Exectute the query and return the results. A reference to the results is also held to * allow them to be iterated over. If you plan on re-using this data source then * you should call: {@link #clearResults()} to free up the references to the results. * * @param l The List of objects to execute the query on. * @return The results. * @throws QueryExecutionException If the query cannot be executed, or if the query * is set to return objects rather than "columns". */ public QueryResults executeQuery (List l) throws QueryExecutionException { if (this.isWantObjects ()) { throw new QueryExecutionException ("Only SQL statements that return columns (not the objects passed in) can be used."); } QueryResults qr = super.execute (l); this.results = qr.getResults (); return qr; } public List getResults () { return this.results; } public void clearResults () { this.results = null; } public Object getFieldValue (JRField field) { // Get the row of objects. List res = (List) this.results.get (this.row); Integer ind = (Integer) this.getAliases ().get (field.getName ()); int i = -1; if (ind != null) { i = ind.intValue (); if (i > (res.size () - 1)) { return null; } } // Get the index for the field name. return res.get (i); } public boolean next () { if (this.row < (this.results.size () - 1)) { this.row++; return true; } return false; } public void moveFirst () { this.row = 0; } } josql-2.2/src/org/josql/contrib/JoSQLJSPQueryTag.java000066400000000000000000000126061157743651500225300ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.util.List; import javax.servlet.jsp.tagext.BodyTagSupport; import javax.servlet.jsp.tagext.Tag; import javax.servlet.jsp.JspException; import org.josql.Query; import org.josql.QueryResults; /** * Allows a JoSQL Query to be used in a JSP. *

* Example: *

 *   <%@ page import="java.util.Arrays" %>
 *   <%@ page import="java.io.File" %>
 *
 *   <%@ tablib prefix="josql" uri="josqltaglib" %>
 *
 *   <josql:query inputList='<%= Arrays.asList (new File ("/home/me/").listFiles ()) %>'
 *                results="queryResults">
 *     SELECT *
 *     FROM   java.io.File
 *     WHERE  name = '.bashrc'
 *   </josql:query>
 * 
*

* The body of the tag is taken as the statement to execute. *

* Note: this class deliberately does NOT extend {@link Query} since doing so would then * prevent the query from being released via the {@link #release()} method. *

* The following attributes are supported: *

*/ public class JoSQLJSPQueryTag extends BodyTagSupport { private Object inputList = null; private String results = null; private Query query = null; /** * Set the name of the attribute that should hold the results. * * @param r The name. */ public void setResults (String r) { this.results = r; } /** * Set the input list, i.e. the list of objects to execute the JoSQL * statement against. Can be either a "java.lang.String" which will * indicate the name of an attribute to use, or a "java.util.List" * which will be the list of objects of use. * The list of objects is not gained until the {@link #doEndTag()} method * is called. * * @param l The name or list of objects to execute the statement against. */ public void setInputList (Object l) { this.inputList = l; } /** * When called will parse the tag body into a JoSQL statement. * * @return {@link Tag#SKIP_BODY} is returned. * @throws JspException If the tag body cannot be parsed into a JoSQL statement. */ public int doAfterBody () throws JspException { this.query = new Query (); String st = this.getBodyContent ().getString (); try { this.query.parse (st); } catch (Exception e) { throw new JspException ("Unable to parse statement: " + st, e); } return Tag.SKIP_BODY; } /** * Execute the statement parsed in {@link #doAfterBody()}. * The list of objects to execute the statement against is first retrieved * using the value specified in {@link #setInputList(Object)}. The list must * not be null and must be a list otherwise an exception is thrown. *

* Once executed the results are set as an attribute specified by: * {@link #setResults(String)}. * * @return {@link Tag#EVAL_PAGE} always. * @throws JspException If the list is null, not a list or the statement cannot * be executed against the list of objects. */ public int doEndTag () throws JspException { List l = null; if (this.inputList instanceof String) { String ln = (String) this.inputList; // Get the list. Object o = this.pageContext.findAttribute (ln); if (o == null) { throw new JspException ("No list with name: " + ln + " can be found"); } if (!(o instanceof List)) { throw new JspException ("Attribute: " + ln + " is not an instance of: " + List.class.getName () + ", is: " + o.getClass ().getName ()); } l = (List) o; } if (this.inputList instanceof List) { l = (List) this.inputList; } if (l == null) { throw new JspException ("No input list specified."); } try { QueryResults qr = this.query.execute (l); // Set the query results as an attribute. this.pageContext.setAttribute (this.results, qr); } catch (Exception e) { throw new JspException ("Unable to execute query with list: " + this.inputList, e); } return Tag.EVAL_PAGE; } /** * Release the objects we have references to and then call: super.release (). */ public void release () { this.inputList = null; this.results = null; this.query = null; super.release (); } } josql-2.2/src/org/josql/contrib/JoSQLSwingTableModel.java000066400000000000000000000222061157743651500234270ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.util.List; import java.util.ArrayList; import java.util.SortedMap; import javax.swing.table.TableModel; import javax.swing.event.TableModelListener; import javax.swing.event.TableModelEvent; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.Query; import org.josql.QueryResults; import org.josql.internal.Utilities; import org.josql.expressions.SelectItemExpression; /** * A table model suitable for use with Swing JTable. * * This is basically just an extension to {@link Query} that allows the * results to be iterated over, thereby providing the ability for objects to be reported on * that are held in memory. *

* One limitation here is that the SQL query must return columns rather than the objects * since the values need to be mapped by the renderer and editor. For example: *

 *   SELECT lastModified,
 *          name
 *   FROM   java.io.File
 *   WHERE  name LIKE '%.html'
 * 
*

* This query would work but it should be noted that the select "columns" (since they do not have * aliases assigned) will be labeled 1, 2, X and so on. * You can assign aliases to the "columns" and then use them in the report definition file. */ public class JoSQLSwingTableModel extends Query implements TableModel { private QueryResults results = null; private List listeners = new ArrayList (); public JoSQLSwingTableModel () { } /** * Parse the SQL. Note: this will cause a TableModelEvent to be fired to all * registered listeners indicating that the table header has changed. * * @param sql The SQL. * @throws QueryParseException If the sql cannot be parsed or if the query will not return * columns. */ public void parse (String sql) throws QueryParseException { this.results = null; super.parse (sql); if (this.isWantObjects ()) { throw new QueryParseException ("Only SQL statements that return columns (not the objects passed in) can be used."); } this.notifyListeners (new TableModelEvent (this, TableModelEvent.HEADER_ROW)); } private void notifyListeners (TableModelEvent ev) { for (int i = 0; i < this.listeners.size (); i++) { TableModelListener l = (TableModelListener) this.listeners.get (i); l.tableChanged (ev); } } /** * Re-order the columns according to the column indices provided in dirs. * * @param objs The objects to reorder. * @param dirs The columns to order by. * @return The results. * @throws QueryExecutionException If something goes wrong during execution of the * query. * @throws QueryParseException If the column indices are out of range for the statement. * @see Query#reorder(List,SortedMap) */ public QueryResults reorder (List objs, SortedMap dirs) throws QueryExecutionException, QueryParseException { // Get the order bys. this.results = super.reorder (objs, dirs); // Notify the listeners that the data has changed. this.notifyListeners (new TableModelEvent (this)); return this.results; } /** * Re-order the columns according to the string representation provided by orderBys. * * @param objs The objects to reorder. * @param orderBys The columns to order by. * @return The results. * @throws QueryExecutionException If something goes wrong during execution of the * query. * @throws QueryParseException If the column indices are out of range for the statement. * @see Query#reorder(List,String) */ public QueryResults reorder (List objs, String orderBys) throws QueryParseException, QueryExecutionException { this.results = super.reorder (objs, orderBys); // Notify the listeners that the data has changed. this.notifyListeners (new TableModelEvent (this)); return this.results; } /** * Exectute the query and return the results. A reference to the results is also held to * allow them to be iterated over. Note: this will cause a TableModelEvent to be fired to all * registered listeners indicating that ALL the table data has changed. * * @param l The List of objects to execute the query on. * @return The results. * @throws QueryExecutionException If the query cannot be executed, or if the query * is set to return objects rather than "columns". */ public QueryResults execute (List l) throws QueryExecutionException { this.results = super.execute (l); // Notify the listeners that the data has changed. this.notifyListeners (new TableModelEvent (this)); return this.results; } /** * Get any results, will be null unless {@link #execute(List)} has been called. * * @return The results. */ public QueryResults getResults () { return this.results; } /** * Clear any results. */ public void clearResults () { this.results = null; } /** * Get the name of the column, if the query has not yet been parsed then null is returned, * if the column does not have an alias then "ind + 1" is returned. * * @return The column name. */ public String getColumnName (int ind) { List cs = this.getColumns (); if ((cs == null) || (ind > (cs.size () - 1)) ) { return null; } SelectItemExpression s = (SelectItemExpression) cs.get (ind); String al = s.getAlias (); if (al == null) { return (ind + 1) + ""; } return al; } /** * The expected class of the object at column i. * * @return The class of the column. */ public Class getColumnClass (int i) { List cs = this.getColumns (); if ((cs == null) || (i > (cs.size () - 1)) ) { return null; } SelectItemExpression s = (SelectItemExpression) cs.get (i); try { return Utilities.getObjectClass (s.getExpectedReturnType (this)); } catch (Exception e) { // Painful, but not much we can do. return null; } } /** * Get the object at row r, column c. * * @param r The row. * @param c The column. * @return The object at that location. */ public Object getValueAt (int r, int c) { if ((this.results == null) || (r > (this.results.getResults ().size () - 1)) ) { return null; } Object o = this.results.getResults ().get (r); if (o instanceof List) { List l = (List) o; if (c > (l.size () - 1)) { return null; } return l.get (c); } if (c > 0) { return null; } return o; } /** * Not supported, always throws a: {@link UnsupportedOperationException}. * * @param v The object to set at the location. * @param r The row. * @param c The column. * @throws UnsupportedOperationException Not supported. */ public void setValueAt (Object v, int r, int c) throws UnsupportedOperationException { // Do nothing for now... throw new UnsupportedOperationException ("This method not supported for: " + this.getClass ().getName ()); } /** * Cells are not editable since we do not store the results separately. * * @param r The row. * @param c The columns. * @return Always returns false. */ public boolean isCellEditable (int r, int c) { // Not sure what's best here... for now make them non-editable. return false; } /** * Number of rows. * * @return The row count. */ public int getRowCount () { if (this.results == null) { return 0; } return this.results.getResults ().size (); } /** * Get the number of columns. * * @return The column count, returns 0 if the query has not yet been parsed. */ public int getColumnCount () { // See if we have any columns. if (this.getColumns () == null) { return 0; } return this.getColumns ().size (); } public void removeTableModelListener (TableModelListener l) { this.listeners.remove (l); } public void addTableModelListener (TableModelListener l) { if (this.listeners.contains (l)) { return; } this.listeners.add (l); } } josql-2.2/src/org/josql/contrib/JoSQLVelocityExecuteTool.java000066400000000000000000000062651157743651500243750ustar00rootroot00000000000000/* * Copyright 2004-2008 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.contrib; import java.util.Collection; import java.util.List; import java.util.Iterator; //import org.apache.velocity.tools.config.ValidScope; //import org.apache.velocity.tools.config.DefaultKey; import org.josql.Query; // Annotations to tell the Tools framework that the default key should be "josql" and that the tool // should be in the "request" scope. //@DefaultKey(value="josql") //@ValidScope(value="request") /** * A custom tool for use with Velocity. *

* Usage: *

* A typical usage may be: *

*

 *   #foreach ($v in $josql.filter ("name LIKE '/opt/%' order by dir, name", $files))
 * 
*/ public class JoSQLVelocityExecuteTool { private Exception excep = null; public JoSQLVelocityExecuteTool () { } public Exception getException () { return this.excep; } public void clearException () { this.excep = null; } public List filter (String st, Collection items) { // Build up our statement. Iterator iter = items.iterator (); Object o = null; // Get the object, determine the class, build the query. while (iter.hasNext ()) { o = iter.next (); if (o != null) { break; } } // Default to object. Class c = Object.class; if (o != null) { c = o.getClass (); } String t = "SELECT * FROM " + c.getName (); String sst = st.trim ().toLowerCase (); if ((!sst.startsWith ("order by")) && (!sst.startsWith ("limit")) ) { t = " WHERE "; } t = t + st; Query q = new Query (); try { q.parse (t); } catch (Exception e) { this.excep = e; // As per the tool contract. return null; } try { return q.execute (items).getResults (); } catch (Exception e) { this.excep = e; // As per the tool contract. return null; } } } josql-2.2/src/org/josql/events/000077500000000000000000000000001157743651500165355ustar00rootroot00000000000000josql-2.2/src/org/josql/events/BindVariableChangedEvent.java000066400000000000000000000013161157743651500241770ustar00rootroot00000000000000package org.josql.events; import java.util.EventObject; import org.josql.Query; public class BindVariableChangedEvent extends EventObject { private Query q = null; private String name = null; private Object from = null; private Object to = null; public BindVariableChangedEvent (Query q, String name, Object from, Object to) { super (q); this.q = q; this.name = name; this.from = from; this.to = to; } public Object getTo () { return this.to; } public Object getFrom () { return this.from; } public String getName () { return this.name; } public Query getQuery () { return this.q; } }josql-2.2/src/org/josql/events/BindVariableChangedListener.java000066400000000000000000000002201157743651500246740ustar00rootroot00000000000000package org.josql.events; public interface BindVariableChangedListener { public void bindVariableChanged (BindVariableChangedEvent ev); }josql-2.2/src/org/josql/events/SaveValueChangedEvent.java000066400000000000000000000012771157743651500235560ustar00rootroot00000000000000package org.josql.events; import java.util.EventObject; import org.josql.Query; public class SaveValueChangedEvent extends EventObject { private Query q = null; private String name = null; private Object from = null; private Object to = null; public SaveValueChangedEvent (Query q, String name, Object from, Object to) { super (q); this.q = q; this.name = name; this.from = from; this.to = to; } public Object getTo () { return this.to; } public Object getFrom () { return this.from; } public String getName () { return this.name; } public Query getQuery () { return this.q; } }josql-2.2/src/org/josql/events/SaveValueChangedListener.java000066400000000000000000000002071157743651500242520ustar00rootroot00000000000000package org.josql.events; public interface SaveValueChangedListener { public void saveValueChanged (SaveValueChangedEvent ev); }josql-2.2/src/org/josql/expressions/000077500000000000000000000000001157743651500176135ustar00rootroot00000000000000josql-2.2/src/org/josql/expressions/Accessor.java000066400000000000000000000066071157743651500222310ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import com.gentlyweb.utils.Getter; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; /** * Represents an "accessor" into an object. An accessor is basically a dot separated list * of method names, such as: myObj.id.name. *

* All of the methods referenced must have no arguments and be "public" in the referring class. * You can use either the actual method name or the JavaBean naming convention. * Thus: myObj.id.name might also be represented as: getMyObj.getId.getName. */ public class Accessor extends ValueExpression { private String acc = null; private Getter get = null; public Class getExpectedReturnType (Query q) throws QueryParseException { return this.get.getType (); } public void init (Query q) throws QueryParseException { // Now init the getter. try { this.get = new Getter (this.acc, q.getFromObjectClass ()); } catch (Exception e) { throw new QueryParseException ("Unable to create getter: " + this.acc, e); } } public String getAccessor () { return this.acc; } public void setAccessor (String a) { this.acc = a; } public Getter getGetter () { return this.get; } public void setName (String name) { this.acc = name; } public boolean isTrue (Object o, Query q) throws QueryExecutionException { o = this.evaluate (o, q); if (o == null) { return false; } if (Utilities.isNumber (o)) { return Utilities.getDouble (o) > 0; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue (); } // Not null so return true... return true; } public boolean hasFixedResult (Query q) { // Well duh... return false; } public Object evaluate (Object o, Query q) throws QueryExecutionException { try { return this.get.getValue (o); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value from: " + this + " passed in object type: " + o.getClass ().getName () + " expecting: " + this.get.getType ().getName (), e); } } public boolean equals (Object o) { if (o == null) { return false; } if (!(o instanceof Accessor)) { return false; } Accessor a = (Accessor) o; return this.acc.equals (a.getAccessor ()); } public String toString () { if (this.isBracketed ()) { return "(" + this.acc + ")"; } return this.acc + "[detail: " + this.get + "]"; } } josql-2.2/src/org/josql/expressions/AliasedExpression.java000066400000000000000000000105711157743651500241040ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; /** * Represents an expression that also has an alias. SELECT columns may have aliases * as may the functions in the "EXECUTE ON" clause. */ public class AliasedExpression extends Expression { private String alias = null; protected Expression exp = null; private boolean fixedResult = false; /** * Return whether this expression has a fixed result. * See: {@link Expression#hasFixedResult(Query)} for more details. * * @param q The Query object. * @return true if the expression returns a fixed result, false otherwise. */ public boolean hasFixedResult (Query q) { return this.fixedResult; } /** * Get the expected return type for the expression. * * @param q The Query object. * @return The class of the return type. * @throws QueryParseException If an error occurs whilst trying to determine the * return type. */ public Class getExpectedReturnType (Query q) throws QueryParseException { return this.exp.getExpectedReturnType (q); } /** * Init this expression. All that occurs here is that the aliased expression is * inited via: {@link Expression#init(Query)}. * * @param q The Query object. * @throws QueryParseException If an error occurs during the initialisation of the * expression. */ public void init (Query q) throws QueryParseException { this.exp.init (q); this.fixedResult = this.exp.hasFixedResult (q); } /** * Get the alias for the expression. * * @return The alias. */ public String getAlias () { return this.alias; } public void setAlias (String a) { this.alias = Utilities.stripQuotes (a); } /** * Get the expression being aliased. * * @return The expression. */ public Expression getExpression () { return this.exp; } public void setExpression (Expression exp) { this.exp = exp; } /** * Indicate whether the expression evaluates to true. * * @param o The object to perform the expression on. * @param q The Query object. * @return true if the expression evaulates to true, false * otherwise. * @throws QueryExecutionException If something goes wrong during execution of the: * {@link Expression#isTrue(Object,Query)} method. * @see Expression#isTrue(Object,Query) */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { return this.exp.isTrue (o, q); } /** * Get the value for this expression. * * @param o The object to perform the expression on. * @param q The Query object. * @return The result of calling: {@link Expression#getValue(Object,Query)}. * @throws QueryExecutionException If something goes wrong with the execution of the * expression. */ public Object getValue (Object o, Query q) throws QueryExecutionException { return this.exp.getValue (o, q); } /** * Return a string representation of the aliased expression. * Returns in the form: Expression AS Alias. * * @return The result of calling: {@link Expression#toString()} + AS + {@link #getAlias()}. */ public String toString () { return this.exp.toString () + " AS " + this.alias; } } josql-2.2/src/org/josql/expressions/AliasedFunction.java000066400000000000000000000017141157743651500235310ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; /** * A function that also has an alias. This generally occurs in the "EXECUTE ON" * clause. */ public class AliasedFunction extends AliasedExpression { /** * Get the function that is aliased. * * @return The function. */ public Function getFunction () { return (Function) this.exp; } } josql-2.2/src/org/josql/expressions/AndOrExpression.java000066400000000000000000000104751157743651500235500ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; /** * Represents either an AND expression or a OR expression. * Lazy evaluation is employed here such if the expression is: LHS OR RHS * and LHS = true then the RHS is NOT evaluated, if the expression is: LHS AND RHS * and LHS = false then the RHS is NOT evaluated (see {@link #isTrue(Object,Query)}). This is important to note if you expect * side-effects to occur in the RHS (bad practice anyway so don't do it!). */ public class AndOrExpression extends BinaryExpression { private boolean and = false; public boolean isAnd () { return this.and; } public void setAnd (boolean v) { this.and = v; } /** * Evaulates the expression and returns true if the expression evaulates to true. *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TypeLHSRHSResultNotes
ANDtruetruetrueBoth LHS and RHS are evaulated.
ANDtruefalsefalseBoth LHS and RHS are evaulated.
ANDfalseunknown or falsefalseOnly the LHS is evaulated.
ORtrueunknowntrueOnly the LHS is evaulated.
ORfalsetruetrueBoth the LHS and RHS are evaulated.
ORfalsefalsefalseBoth the LHS and RHS are evaulated.
*

* In general what this means is that you should "left-weight" your expressions so that * the expression that returns true most often (or more likely to return * true) should be on the LHS. * * @param o The current object to perform the expression on. * @param q The query object. * @return true if the expression evaulates to true, false * otherwise. * @throws QueryExecutionException If the expression cannot be evaulated. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { // Execute left first. boolean l = this.left.isTrue (o, q); // See what our predicate is... if (this.and) { if (!l) { return false; } boolean r = this.right.isTrue (o, q); return l && r; } if (l) { return true; } boolean r = this.right.isTrue (o, q); return r; } /** * Return a string version of this expression. * Note: any formatting of the statement (such as line breaks) will be removed. * * @return A string version of the expression. */ public String toString () { String pred = " OR "; if (this.and) { pred = " AND "; } if (this.isBracketed ()) { return "(" + this.left.toString () + pred + this.right.toString () + ")"; } return this.left.toString () + pred + this.right.toString (); } } josql-2.2/src/org/josql/expressions/ArithmeticExpression.java000066400000000000000000000161161157743651500246340ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; /** * Represents the arithmetic expressions: *, +, /, - and %. * It should be noted that ALL numbers in JoSQL are represented as double values, this * allows for easy arithmetic operations without the fear of losing precision or casting * issues. */ public class ArithmeticExpression extends ValueExpression { public static final int MULTIPLY = 0; public static final int ADDITION = 1; public static final int SUBTRACT = 2; public static final int DIVIDE = 3; public static final int MODULUS = 4; private int type = -1; private ValueExpression left = null; private ValueExpression right = null; private boolean fixedResult = false; /** * Return the expected return type. This just returns the result of calling this * method on the LHS. * * @param q The Query object. * @return The expected return type class. * @throws QueryParseException If something goes wrong in determining the return type. */ public Class getExpectedReturnType (Query q) throws QueryParseException { return this.left.getExpectedReturnType (q); } /** * Determine whether this arithmetic expression evaluates to true. * Whilst this seems a little bizarre this method is needed to allow * artithmetic expressions to be used in the columns part of the SELECT. *

* Thus the following could be performed: *

     *   SELECT 10 + 20
     *   FROM   java.lang.Object
     * 
* * The rules are as follows: * * * @param o The object to perform the expression on. * @param q The Query object. * @return As according to the rules above. * @throws QueryExecutionException If something goes wrong during the evaluation of the * expression. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { o = this.evaluate (o, q); if (o == null) { return false; } if (o instanceof Number) { return ((Number) o).doubleValue () > 0; } return true; } /** * Return whether this expression has a fixed result. * * @param q The Query object. * @return {@link Expression#hasFixedResult(Query) LHS.hasFixedResult(Query)} * && * {@link Expression#hasFixedResult(Query) RHS.hasFixedResult(Query)} */ public boolean hasFixedResult (Query q) { return this.fixedResult; } public void init (Query q) throws QueryParseException { this.left.init (q); this.right.init (q); this.fixedResult = this.left.hasFixedResult (q) && this.right.hasFixedResult (q); } /** * Get the RHS value expression. * * @return The RHS. */ public ValueExpression getRight () { return this.right; } /** * Get the LHS value expression. * * @return The LHS. */ public ValueExpression getLeft () { return this.left; } public void setLeft (ValueExpression exp) { this.left = exp; } public void setRight (ValueExpression exp) { this.right = exp; } public int getType () { return this.type; } public void setType (int t) { this.type = t; } /** * Evaulate this expression. Apart from the special cases the LHS and RHS must evaluate * to an instance of java.lang.Number otherwise a QueryExecutionException is * thrown. *

* Special cases: *

* * @param o The object to perform the expression on. * @param q The Query object. * @return The result of the expression, see the "special cases" for the exceptions to what would * be the intuitive result. * @throws QueryExecutionException If an error occurs during processing. */ public Object evaluate (Object o, Query q) throws QueryExecutionException { Object l = this.left.getValue (o, q); Object r = this.right.getValue (o, q); // Special case for addition. if ((this.type == ArithmeticExpression.ADDITION) && (!(l instanceof Number) || !(r instanceof Number) ) ) { StringBuffer b = new StringBuffer (); b.append (l); b.append (r); return b.toString (); } if (l == null) { l = new Double (0); } if (r == null) { r = new Double (0); } double ld = Utilities.getDouble (l); double rd = Utilities.getDouble (r); if (this.type == ArithmeticExpression.ADDITION) { return new Double (ld + rd); } if (this.type == ArithmeticExpression.SUBTRACT) { return new Double (ld - rd); } if (this.type == ArithmeticExpression.MULTIPLY) { return new Double (ld * rd); } if (this.type == ArithmeticExpression.MODULUS) { return new Double (ld % rd); } if (this.type == ArithmeticExpression.DIVIDE) { if (rd == 0) { return new Double (0); } return new Double (ld / rd); } return null; } public String toString () { String pred = "+"; if (this.type == ArithmeticExpression.MULTIPLY) { pred = "*"; } if (this.type == ArithmeticExpression.SUBTRACT) { pred = "-"; } if (this.type == ArithmeticExpression.MODULUS) { pred = "%"; } if (this.type == ArithmeticExpression.DIVIDE) { pred = "/"; } String exp = this.left.toString () + " " + pred + " " + this.right.toString (); if (this.isBracketed ()) { exp = "(" + exp + ")"; } return exp; } } josql-2.2/src/org/josql/expressions/BetweenExpression.java000066400000000000000000000115431157743651500241330ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; /** * Represents a "BETWEEN x AND y" expression. */ public class BetweenExpression extends BinaryExpression { private ValueExpression start = null; private ValueExpression end = null; private boolean not = false; private boolean leftFR = false; private boolean startFR = false; private boolean endFR = false; private Object leftFRVal = null; private Object startFRVal = null; private Object endFRVal = null; /** * Inits the expression. * * @param q The Query object. * @throws QueryParseException If the LHS, start or end cannot be inited. */ public void init (Query q) throws QueryParseException { this.left.init (q); this.start.init (q); this.end.init (q); this.leftFR = this.left.hasFixedResult (q); this.startFR = this.start.hasFixedResult (q); this.endFR = this.end.hasFixedResult (q); } /** * Get the start expression. * * @return The start expression, is an instance of {@link ValueExpression}. */ public Expression getStart () { return this.start; } /** * Get the end expression. * * @return The end expression, is an instance of {@link ValueExpression}. */ public Expression getEnd () { return this.end; } public void setEnd (ValueExpression e) { this.end = e; } public void setStart (ValueExpression s) { this.start = s; } public boolean isNot () { return this.not; } public void setNot (boolean v) { this.not = v; } /** * Return whether this expression evaluates to true. * * Is equivalent to: LHS >= START AND LHS <= END. And of course if the * expression is NOTed then it returns !(LHS >= START AND LHS <= END). * * @param o The object to perform the expression on. * @param q The Query object. * @return true if the LHS is between the start and end values. * @throws QueryExecutionException If the expression cannot be executed. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { Object l = null; if (this.leftFR) { if (this.leftFRVal == null) { l = this.left.getValue (o, q); this.leftFRVal = l; } else { l = this.leftFRVal; } } else { l = this.left.getValue (o, q); if (this.leftFR) { this.leftFRVal = l; } } Object s = null; if (this.startFR) { if (this.startFRVal == null) { s = this.start.getValue (o, q); this.startFRVal = s; } else { s = this.startFRVal; } } else { s = this.start.getValue (o, q); if (this.startFR) { this.startFRVal = s; } } Object e = null; if (this.endFR) { if (this.endFRVal == null) { e = this.end.getValue (o, q); this.endFRVal = e; } else { e = this.endFRVal; } } else { e = this.end.getValue (o, q); if (this.endFR) { this.endFRVal = e; } } // See if the LHS is >= s. boolean sb = Utilities.isGTEquals (l, s); boolean eb = Utilities.isLTEquals (l, e); if (!this.not && sb && eb ) { return true; } if (this.not && (!sb || !eb ) ) { return true; } return false; } /** * Returns a string version of this expression. * Will return the form: *

*

     *   {@link Expression#toString() Expression} [ NOT ] BETWEEN {@link Expression#toString() Expression} AND {@link Expression#toString() Expression}
     * 
* * @return A string version of the expression. */ public String toString () { StringBuffer buf = new StringBuffer (this.left.toString ()); if (this.not) { buf.append (" NOT"); } buf.append (" BETWEEN "); buf.append (this.start); buf.append (" AND "); buf.append (this.end); if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } } josql-2.2/src/org/josql/expressions/BinaryExpression.java000066400000000000000000000067521157743651500237740ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; /** * Super-class of Expressions that return a binary result. *

* A binary expression must always have a LHS. The RHS is optional. */ public abstract class BinaryExpression extends Expression { protected Expression left = null; protected Expression right = null; /** * Return whether this expression, and more specifically the left and right parts of * the expression return a fixed result. * Sub-classes may override this method for more tailored results, especially if the * binary expression does not demand a RHS. * * @param q The Query object. * @return true if the expression has a fixed result. */ public boolean hasFixedResult (Query q) { boolean fr = true; if (this.right != null) { fr = this.right.hasFixedResult (q); } return this.left.hasFixedResult (q) && fr; } /** * Return the expected return type from this expression. * * @param q The Query object. * @return The class of the return type, this method ALWAYS returns Boolean.class. */ public Class getExpectedReturnType (Query q) { return Boolean.class; } /** * Init the expression. Sub-classes will often override this method. * This method just calls: {@link Expression#init(Query)} on the LHS and RHS (if present) of the * expression. * * @param q The Query object. * @throws QueryParseException If the LHS and/or RHS cannot be inited. */ public void init (Query q) throws QueryParseException { this.left.init (q); // There isn't always a RHS, for example IN expressions. if (this.right != null) { this.right.init (q); } } /** * Get the value of this expression. This will always return an instance of: * java.lang.Boolean created as the result of a call to: * {@link Expression#getValue(Object,Query)}. * * @param o The object to evaluate the expression on. * @param q The Query object. * @return An instance of Boolean. * @throws QueryExecutionException If the expression cannot be evaluated. */ public Object getValue (Object o, Query q) throws QueryExecutionException { return Boolean.valueOf (this.isTrue (o, q)); } /** * Get the RHS. * * @return The RHS of the expression. */ public Expression getRight () { return this.right; } /** * Get the LHS. * * @return The LHS of the expression. */ public Expression getLeft () { return this.left; } public void setLeft (Expression exp) { this.left = exp; } public void setRight (Expression exp) { this.right = exp; } } josql-2.2/src/org/josql/expressions/BindVariable.java000066400000000000000000000353571157743651500230150ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.List; import java.util.Map; import java.util.HashMap; import com.gentlyweb.utils.Getter; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; /** * This class represents a "bind variable" used within a SQL statement. * A bind variable can be either: *

*

Examples

*
 *   SELECT :_query,
 *          :_allobjs,
 *          :_currobj
 *   FROM java.lang.Object
 *
 *   SELECT name
 *   FROM   java.io.File
 *   WHERE  length(:_currobj, name) > :length
 *   AND    length > avg(:_query,:_allobjs,length)
 *   AND    path LIKE '%' + ?
 * 
*

Accessors

*

* It is also possible for bind variables (including the special variables) to have accessors. * For example: *

 *   SELECT :_query.variables
 *   FROM   java.lang.Object
 * 
*

* Would cause all the bind variables in the query to be returned. * Also, if the ? in the next query is an instance of java.lang.String. *

 *   SELECT ?.length
 *   FROM   java.lang.Object
 * 
*/ public class BindVariable extends ValueExpression { public static final String SPECIAL_NAME_PREFIX = "_"; private static Map SPECIAL_VAR_NAMES; static { BindVariable.SPECIAL_VAR_NAMES = new HashMap (); BindVariable.SPECIAL_VAR_NAMES.put (Query.QUERY_BIND_VAR_NAME, ""); BindVariable.SPECIAL_VAR_NAMES.put (Query.CURR_OBJ_VAR_NAME, ""); BindVariable.SPECIAL_VAR_NAMES.put (Query.ALL_OBJS_VAR_NAME, ""); BindVariable.SPECIAL_VAR_NAMES.put (Query.GRPBY_OBJ_VAR_NAME, ""); BindVariable.SPECIAL_VAR_NAMES.put (Query.GRPBY_OBJ_VAR_NAME_SYNONYM, ""); BindVariable.SPECIAL_VAR_NAMES.put (Query.PARENT_BIND_VAR_NAME, ""); } private String name = null; private Object val = null; private boolean anon = false; private String acc = null; private Getter get = null; private boolean groupByVar = false; private int groupByInd = 0; public boolean equals (Object o) { if (o == null) { return false; } if (!(o instanceof BindVariable)) { return false; } BindVariable b = (BindVariable) o; if ((b.getName () != null) && (this.name != null) && (b.getName ().equals (this.name)) ) { if ((this.acc != null) && (b.getAccessor () != null) && (b.getAccessor ().equals (this.acc)) ) { return true; } } return false; } public String getAccessor () { return this.acc; } public void setAccessor (String a) { this.acc = a; } /** * Get the expected return type. * The exact class returned here is dependent (obviously) on what the bind variable * represents. Wherever possible it attempts to get the most specific class for the * variable. It is generally better to set the variables prior to executing the: * {@link Query#parse(String)} method to ensure that the correct class is returned here. * * @param q The Query object. * @return The return type class or java.lang.Object.class if the class * cannot be determined. * @throws QueryParseException If the type cannot be determined. */ public Class getExpectedReturnType (Query q) throws QueryParseException { if (this.get != null) { return this.get.getType (); } if (this.val != null) { return this.val.getClass (); } return q.getVariableClass (this.name); } private void initForGroupByName (String n, Query q) throws QueryParseException { List grpBys = q.getGroupByColumns (); // This is a group by... check for a group by clause. if (grpBys == null) { throw new QueryParseException ("Use of special group by object bind variable: " + name + " is not valid when there are no GROUP BY clauses defined."); } String rest = ""; // Trim it down to see if there is a number. if (n.startsWith (Query.GRPBY_OBJ_VAR_NAME)) { rest = n.substring (Query.GRPBY_OBJ_VAR_NAME.length ()); } if (n.startsWith (Query.GRPBY_OBJ_VAR_NAME_SYNONYM)) { rest = n.substring (Query.GRPBY_OBJ_VAR_NAME_SYNONYM.length ()); } int grpbyind = 1; if (rest.length () > 0) { // Should be a number. try { grpbyind = Integer.parseInt (rest); } catch (Exception e) { throw new QueryParseException ("Special bind variable name: " + this.name + " is not valid, expected an integer number at end of name for indexing into GROUP BYs."); } if (grpbyind < 1) { throw new QueryParseException ("Special bind variable name: " + this.name + " is not valid, integer to index GROUP BYs must be a minimum of 1."); } if (grpbyind > (grpBys.size ())) { throw new QueryParseException ("Special bind variable name: " + this.name + " is not valid, integer references GROUP BY: " + grpbyind + " however there are only: " + grpBys.size () + " GROUP BYs defined."); } } this.groupByVar = true; this.groupByInd = grpbyind; } /** * Initialises this bind variable. * If the bind variable is "anonymous" then a name is gained for it from the * Query object. If there is a value then it is gained from the Query object and * cached. Also, if there is an accessor defined then it is inited where possible. * * @param q The Query object. * @throws QueryParseException If the bind variable cannot be inited. */ public void init (Query q) throws QueryParseException { if (this.anon) { this.name = q.getAnonymousBindVariableName (); } String n = this.name.toLowerCase (); if ((n.startsWith (Query.GRPBY_OBJ_VAR_NAME)) || (n.startsWith (Query.GRPBY_OBJ_VAR_NAME_SYNONYM)) ) { this.initForGroupByName (n, q); } else { if (n.startsWith (BindVariable.SPECIAL_NAME_PREFIX)) { // Make sure it's valid. if (!BindVariable.SPECIAL_VAR_NAMES.containsKey (n)) { throw new QueryParseException ("Bind variable name: " + name + " is not valid, bind variable names starting with: " + BindVariable.SPECIAL_NAME_PREFIX + " are reserved, and must be one of: " + BindVariable.SPECIAL_VAR_NAMES.keySet ()); } } } // See if we already have this bind variable set... this.val = q.getVariable (this.name); // See if we have a "trailing" accessor. if ((this.val != null) && (this.acc != null) ) { this.initGetter (this.val); try { this.val = this.get.getValue (this.val); } catch (Exception e) { throw new QueryParseException ("Unable to get value from accessor: " + this.acc + " and class: " + this.val.getClass ().getName () + " from bind variable: " + this.name, e); } } // See if we can init the getter... there are times when it // is possible even if the bind variable isn't available yet. if ((this.acc != null) && (this.get == null) ) { // Not over keen on this method but it will do for now... // It precludes the init occurring if we are working on java.lang.Object // objects... but how many times will that happen? Class c = q.getVariableClass (this.name); if (!c.isInstance (new Object ())) { // Init the getter. this.initGetter (c); } } } public String getName () { return this.name; } public boolean isAnonymous () { return this.anon; } public void setAnonymous (boolean v) { this.anon = v; } public void setName (String name) { this.name = name; } private void initGetter (Object o) { // Get the class for the value. Class c = o.getClass (); this.initGetter (c); } private void initGetter (Class c) { this.get = new Getter (this.acc, c); } /** * Gets the value of this bind variable. * * @param o The current object. Note that this variable isn't used in this method. * @param q The Query object. * @return The value. * @throws QueryExecutionException If something goes wrong during the accessing * of the value. */ public Object getValue (Object o, Query q) throws QueryExecutionException { if (this.groupByVar) { o = q.getGroupByVariable (this.groupByInd); } else { o = q.getVariable (this.name); } if ((this.acc != null) && (this.get == null) && (o != null) ) { // Unable to get the accessor... this.initGetter (o); } if (this.get != null) { try { o = this.get.getValue (o); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for accessor: " + this.acc + ", class: " + this.get.getBaseClass ().getName () + " from bind variable: " + this.name, e); } } return o; } /** * Returns whether the value of this bind variable represents a true * value. See: {@link ArithmeticExpression#isTrue(Object,Query)} for details of how * the return value is determined. * * @param o The current object. Not used in this method. * @param q The Query object. * @return true if the bind variable evaluates to true. * @throws QueryExecutionException If a problem occurs during evaluation. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { o = this.getValue (o, q); if (o == null) { return false; } if (Utilities.isNumber (o)) { return Utilities.getDouble (o) > 0; } // Not null so return true... return true; } /** * Evaluates the value of this bind variable. This is just a thin-wrapper around: * {@link #getValue(Object,Query)}. * * @param o The current object, not used in this method. * @param q The Query object. * @return The value of this bind variable. * @throws QueryExecutionException If there is a problem getting the value. */ public Object evaluate (Object o, Query q) throws QueryExecutionException { return this.getValue (o, q); } /** * Returns a string version of this bind variable. * Returns in the form: ? | ":" [ "_" ] Name * * @return A string version of the bind variable. */ public String toString () { StringBuffer buf = new StringBuffer (); if (this.anon) { buf.append ("?"); } else { buf.append (":"); buf.append (this.name); } if (this.acc != null) { buf.append ("."); buf.append (this.acc); } if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } /** * Will always return false since a bind variable cannot be fixed. * * @param q The Query object. * @return false always. */ public boolean hasFixedResult (Query q) { // A bind variable cannot have a fixed result. return false; } } josql-2.2/src/org/josql/expressions/BooleanExpression.java000066400000000000000000000056751157743651500241320ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; /** * This class represents a "boolean" expression, either true or false. */ public class BooleanExpression extends ValueExpression { private Boolean value = null; public BooleanExpression () { } /** * Always returns true since it represents a constant. * * @param q The Query object. * @return true always. */ public boolean hasFixedResult (Query q) { return true; } /** * Returns a string version of this expression. * Basically returns: true | false. * * @return A string version of this expression. */ public String toString () { if (this.isBracketed ()) { return "(" + this.value.toString () + ")"; } return this.value.toString (); } /** * Get the expected return type. * * @param q The Query object. * @return Always returns: java.lang.Boolean.TYPE. */ public Class getExpectedReturnType (Query q) { return Boolean.TYPE; } /** * Init this expression. Actually does nothing since it is a constant. * * @param q The Query object. */ public void init (Query q) { // Nothing to do... } public void setValue (Boolean b) { this.value = b; } /** * Returns whether this expression is true or false. * * @param o The current object, not used in this method. * @param q The Query object, not used in this method. * @return The value of this expression. */ public boolean isTrue (Object o, Query q) { return this.value.booleanValue (); } /** * Get the value of this boolean. * * @param o The current object, not used in this method. * @param q The Query object, not used in this method. * @return The value of this expression. */ public Object getValue (Object o, Query q) { return this.value; } /** * Get the value of this boolean. * * @param o The current object, not used in this method. * @param q The Query object, not used in this method. * @return The value of this expression. */ public Object evaluate (Object o, Query q) { return this.value; } } josql-2.2/src/org/josql/expressions/ConstantExpression.java000066400000000000000000000075401157743651500243350ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; /** * This class represents a constant String or number. * ALL numbers in JoSQL are represented by double. */ public class ConstantExpression extends ValueExpression { private Object val = null; /** * Get the expected return type. * Will be either: java.lang.String.class * or: java.lang.Double.class. * * @param q The Query object. * @return The expected class. */ public Class getExpectedReturnType (Query q) { if (this.val == null) { return Object.class; } return this.val.getClass (); } /** * Inits the expression, in reality does nothing here, can't init a constant! * * @param q The Query object. */ public void init (Query q) { // Nothing to do... } public void setValue (Object v) { this.val = v; } /** * Returns whether the value of this constant represents a true * value. See: {@link ArithmeticExpression#isTrue(Object,Query)} for details of how * the return value is determined. * * @param o The current object. Not used in this method. * @param q The Query object. * @return true if the constant evaluates to true. */ public boolean isTrue (Object o, Query q) { if (this.val == null) { return false; } if (this.val instanceof Boolean) { return ((Boolean) this.val).booleanValue (); } if (this.val instanceof Number) { return ((Number) this.val).doubleValue () > 0; } return true; } /** * Get the value of this constant. * * @param o The current object, not used in this method. * @param q The Query object, not used in this method. * @return The constant value. */ public Object getValue (Object o, Query q) { return this.val; } /** * Get the value of this constant. * * @param o The current object, not used in this method. * @param q The Query object, not used in this method. * @return The constant value. */ public Object evaluate (Object o, Query q) { return this.val; } /** * Always returns true, well duh! * * @param q The Query object. * @return true always. */ public boolean hasFixedResult (Query q) { // Well duh... return true; } /** * Returns a string representation of this constant. * If the constant is a String then it should be noted that the original * quoting character is not kept in this class and the output of this method * will contain the character "'" instead. * If the constant is a number then "toString" is called on it, so any "," * or other number formatting will have been lost. * * @return A string representation of this constant. */ public String toString () { String v = null; if (this.val == null) { v = val + ""; } else { if (this.val instanceof String) { v = "'" + this.val.toString () + "'"; } else { v = this.val.toString (); } } if (this.isBracketed ()) { v = "(" + v + ")"; } return v; } } josql-2.2/src/org/josql/expressions/EqualsExpression.java000066400000000000000000000126511157743651500237750ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.internal.Utilities; /** * This class represents an "=" or "!=" expression. This class also provides the * ability for the developer to prefix the "=" or "!=" with "$" to indicate that a * case-insensitive comparison should be made, in which case the LHS and RHS * are converted to strings first. */ public class EqualsExpression extends BinaryExpression { private boolean not = false; public boolean ignoreCase = false; public void setIgnoreCase (boolean v) { this.ignoreCase = v; } public boolean isIgnoreCase () { return this.ignoreCase; } public boolean isNot () { return this.not; } public void setNot (boolean v) { this.not = v; } /** * Return whether this expression evaluates to true. * * @param o The current object to perform the expression on. * @param q The Query object. * @return true if the expression evaluates to true, false * otherwise. * @throws QueryExecutionException If the expression cannot be evaluated. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { // Get the value for the lhs. Object l = null; try { l = this.left.getValue (o, q); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for LHS of expression: " + this, e); } Object r = null; try { r = this.right.getValue (o, q); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for RHS of expression: " + this, e); } if ((l == null) && (r == null) ) { // Debatable about whether 2 nulls make a true... if (this.not) { return false; } return true; } if ((l == null) || (r == null) ) { if (this.not) { return true; } // One of them is null, can't do any checking... return false; } // If we are here then both are NOT NULL. return Utilities.matches (l, r, this.ignoreCase, 4, this.not); /* if (this.ignoreCase) { // This means that we convert to a String for both and // compare case-insensitive. String ls = l.toString (); String rs = r.toString (); if ((ls == null) || (rs == null) ) { // Can't compare nulls. return false; } boolean eq = ls.equalsIgnoreCase (rs); if ((this.not) && (!eq) ) { return true; } if (eq) { return true; } return false; } // See if one of the sides is a number. boolean ln = Utilities.isNumber (l); boolean rn = Utilities.isNumber (r); if (ln && rn ) { // They are numbers... double ld = Utilities.getDouble (l); double rd = Utilities.getDouble (r); if (ld == rd) { if (this.not) { return false; } return true; } if (this.not) { return true; } return false; } // See if the 2 sides are "comparable". // Need to check to see if they are the "same" type... otherwise a CCE will result. if ((l instanceof Comparable) && (r instanceof Comparable) && (l.getClass ().isAssignableFrom (r.getClass ())) ) { Comparable lc = (Comparable) l; Comparable rc = (Comparable) r; boolean eq = lc.compareTo (rc) == 0; if ((this.not) && (!eq) ) { return true; } if (eq) { return true; } return false; } // If we are here then one or more of the items does NOT implement Comparable. // Force a string comparison. String ls = l.toString (); String rs = r.toString (); if (ls == null) { ls = ""; } if (rs == null) { rs = ""; } boolean eq = false; if (this.ignoreCase) { eq = ls.equalsIgnoreCase (rs); } else { eq = ls.equals (rs); } if (eq) { if (this.not) { return false; } return true; } else { if (this.not) { return true; } return false; } */ } /** * Return a string version of the expression. * In the form: {@link Expression#toString() Expression} [ $ ] [ ! ] = {@link Expression#toString() Expression} * * @return The string version. */ public String toString () { String pred = "="; if (this.not) { pred = "!="; } if (this.ignoreCase) { pred = "$" + pred; } if (this.isBracketed ()) { return "(" + this.left.toString () + " " + pred + " " + this.right.toString () + ")"; } return this.left.toString () + " " + pred + " " + this.right.toString (); } } josql-2.2/src/org/josql/expressions/Expression.java000066400000000000000000000110501157743651500226120ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; /** * The base class for all expressions. */ public abstract class Expression { private boolean bracketed = false; /** * This method allows ANY expression (including those that extend {@link ValueExpression}) * to be used in the WHERE and HAVING clauses but ensuring that a boolean value is * available for every expression. * * @param o The current object to evaluate the expression on. * @param q The Query object. * @return true if the expression evaluates to true (well duh...). * @throws QueryExecutionException If there is a problem with the execution of the * expression. */ public abstract boolean isTrue (Object o, Query q) throws QueryExecutionException; /** * Return whether the expression will evaluate to a fixed/constant result. * This allows certain optimisations to be performed when an expression is * evaluated. A "fixed result" is basically one in which multiple calls to * either the: {@link #isTrue(Object,Query)} or {@link #getValue(Object,Query)} * methods will return the same object (or that o1.equals (o2) == true) * regardless of the object passed to the method. * * @param q The Query object. * @return true if the expression evaluates to a fixed/constant result. */ public abstract boolean hasFixedResult (Query q); public void setBracketed (boolean v) { this.bracketed = v; } public boolean isBracketed () { return this.bracketed; } /** * Return the class of the object that "should" be returned from a call to the: * {@link #getValue(Object,Query)} method. It may be that repeated executions * of a query will return different classes from this method. In general * sub-classes should take this variance into account. * * @param q The Query object. * @return The expected type that will be returned from the {@link #getValue(Object,Query)} * method. * @throws QueryParseException If something goes wrong with determining the type. */ public abstract Class getExpectedReturnType (Query q) throws QueryParseException; /** * Perform the necessary initialisation for this expression. * The exact operations performed are defined by the sub-class. * * @param q The Query object. * @throws QueryParseException If something goes wrong with the initialisation. */ public abstract void init (Query q) throws QueryParseException; /** * Get the value for this expression based upon the object passed in. In general * sub-classes should perform some operation on the object to generate their result. * The Query object is provided so that sub-classes can gain access to the * bind variables (if required), save values and so on. * Whilst it may seem better to have the Query object as a member of this class * this would then prevent the expression from being used separately from the Query * (a design goal of JoSQL, i.e. independent processing). * * @param o The current object that the expression should be evaluated on. * @param q The Query object. * @return The value of the expression. * @throws QueryExecutionException If something goes wrong with gaining the value. */ public abstract Object getValue (Object o, Query q) throws QueryExecutionException; /** * Return a string representation of the expression, making this abstract forces * sub-classes to provide an implementation. * * @return A string representation of the expression. */ public abstract String toString (); } josql-2.2/src/org/josql/expressions/ExpressionList.java000066400000000000000000000153511157743651500234560ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.List; import java.util.ArrayList; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; /** * This class represents a list of expressions used within a SQL statement. *

* Expressions lists are created using pairs of "[]" brackets, i.e. *

 *  [toString, 10, true]
 * 
* Would create a list of expressions that should be treated as a unit. *

* Since expression lists are also expressions it is possible to nest them to the nth degree, if desired. * i.e. *

 *  [toString, [1, 2, 3, 4], [true, true]]
 * 
*/ public class ExpressionList extends ValueExpression { private List expressions = null; /** * Get the expected return type, which is {@link List}. * * @param q The Query object. * @return {@link List}. */ public Class getExpectedReturnType (Query q) { return List.class; } /** * Initialises this expression list, each expression in the list is inited. * * @param q The Query object. * @throws QueryParseException If one of the expressions cannot be inited. */ public void init (Query q) throws QueryParseException { for (int i = 0; i < this.expressions.size (); i++) { Expression exp = (Expression) this.expressions.get (i); exp.init (q); } } /** * Returns the expressions, a list of {@link Expression} objects. * * @return The expressions. */ public List getExpressions () { return this.expressions; } /** * Add an expression to the list. * * @param expr The expression. */ public void addExpression (Expression expr) { if (this.expressions == null) { this.expressions = new ArrayList (); } this.expressions.add (expr); } /** * Set the expressions. * * @param exprs The expressions. */ public void setExpressions (List exprs) { this.expressions = exprs; } /** * Gets the value of the expressions, this will return a list of the values for * each of the expressions in the list. In essence {@link Expression#getValue(Object,Query)} * is called on each of the expressions. * * @param o The current object. * @param q The Query object. * @return A list of the values, if there are no expressions in the list then an empty list is returned. * @throws QueryExecutionException If something goes wrong the acquisition of the values. */ public Object getValue (Object o, Query q) throws QueryExecutionException { List ret = new ArrayList (); for (int i = 0; i < this.expressions.size (); i++) { Expression exp = (Expression) this.expressions.get (i); ret.add (exp.getValue (o, q)); } return ret; } /** * Returns true if one of the expression values is non-null. * Note: for efficiency this method calls {@link Expression#getValue(Object,Query)} * on each expression directly and returns true for the first non-null * value found, as such if any of your expressions triggers side-effects then this * method should not be used. * * @param o The current object. * @param q The Query object. * @return true if one of the expression values is non-null. * @throws QueryExecutionException If a problem occurs during evaluation. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { for (int i = 0; i < this.expressions.size (); i++) { Expression exp = (Expression) this.expressions.get (i); if (exp.getValue (o, q) != null) { return true; } } return false; } /** * Evaluates the value of this expression list. This is just a thin-wrapper around: * {@link #getValue(Object,Query)}. * * @param o The current object. * @param q The Query object. * @return The value of this expression list. * @throws QueryExecutionException If there is a problem getting the values. */ public Object evaluate (Object o, Query q) throws QueryExecutionException { return this.getValue (o, q); } /** * Returns a string version of this expression list. * Returns in the form: "[" Expression [ , Expression ]* "]". * * @return A string version of the expression list. */ public String toString () { StringBuffer buf = new StringBuffer ("["); for (int i = 0; i < this.expressions.size (); i++) { buf.append (this.expressions.get (i)); if (i < this.expressions.size () - 1) { buf.append (", "); } } buf.append ("]"); return buf.toString (); } /** * Returns true if this expression list is empty (no expressions) or * if ALL of the expressions have a fixed result. * * @param q The Query object. * @return See description. */ public boolean hasFixedResult (Query q) { if (this.expressions.size () == 0) { return true; } for (int i = 0; i < this.expressions.size (); i++) { Expression exp = (Expression) this.expressions.get (i); if (!exp.hasFixedResult (q)) { return false; } } return true; } } josql-2.2/src/org/josql/expressions/Function.java000066400000000000000000000414171157743651500222520ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.List; import java.util.Arrays; import java.util.Map; import java.util.TreeMap; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import com.gentlyweb.utils.Getter; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; import org.josql.functions.NotFixedResults; /** * This class represents a Function that can be "called" in JoSQL. */ public class Function extends ValueExpression { private String name = null; private List params = null; private Method function = null; private Object handler = null; private boolean fixedResult = true; private Object fixedValue = null; private String acc = null; private Getter get = null; public Getter getGetter () { return this.get; } public String getAccessor () { return this.acc; } public void setAccessor (String acc) { this.acc = acc; } /** * Get the expected return type from the function. The exact class returned is * dependent upon the function (Java method) that is being called. * * @param q The Query object. * @return The class of the expected return type. */ public Class getExpectedReturnType (Query q) { if (this.get != null) { return this.get.getType (); } return this.function.getReturnType (); } /** * This is a complex method that will initialise the function. * Firstly all of the "arguments" to the function are inited and then * their expected return types gained from calling: {@link Function#getExpectedReturnType(Query)}. * Then the function handlers, user-defined and then built-in are searched until they * find a match for the function name, ensure that it's a public method and that all the * arguments match, widening the match where necessary. * * @param q The Query object. * @throws QueryParseException If something goes wrong whilst initing the arguments to the * function or if the function cannot be found. */ public void init (Query q) throws QueryParseException { // Need to init the params (if present) first because the expected type may not be // present otherwise. if (this.params != null) { int s = this.params.size (); for (int i = 0; i < s; i++) { Expression exp = (Expression) this.params.get (i); exp.init (q); } } // Try and find the relevant method, first in the user-defined function handler (if present) // or the built-in handlers. this.findMethod (q); if (this.function == null) { Class[] ps = null; if (this.params != null) { int s = params.size (); ps = new Class[s]; for (int i = 0; i < s; i++) { // Need to get the expected return type. Expression exp = (Expression) params.get (i); ps[i] = exp.getExpectedReturnType (q); } } // Can't find the function. throw new QueryParseException ("Unable to find function (method): \"" + Utilities.formatSignature (this.name, ps) + "\" in any user-defined function handlers or the default function handler"); } // Now see if we have an accessor for the function. if (this.acc != null) { this.initAccessor (); } // A function has/can have a fixed result if all it's arguments // also have a fixed result, if there aren't any args then assume // it won't have a fixed result. if ((this.params != null) && (!NotFixedResults.class.isAssignableFrom (this.function.getDeclaringClass ())) ) { for (int i = 0; i < this.params.size (); i++) { Expression exp = (Expression) this.params.get (i); if (!exp.hasFixedResult (q)) { this.fixedResult = false; break; } } } else { this.fixedResult = false; } } private void initAccessor () throws QueryParseException { // We have an accessor, see what the functions return type is. Class retType = this.function.getReturnType (); // Ensure that the function DOES have a return type. if (Void.TYPE.isAssignableFrom (retType)) { // The return type is void, barf! throw new QueryParseException ("Function: " + this + " maps to method: " + this.function + " however methods return type is \"void\" and an accessor: " + this.acc + " has been defined."); } // See if the return type is an object. If it is then defer trying to // get the accessor until run-time. Have to do it this way since // type comparisons are a little pointless. if (!retType.getName ().equals (Object.class.getName ())) { // The return type is NOT java.lang.Object, so now try and get the // accessor. try { this.get = new Getter (this.acc, retType); } catch (Exception e) { throw new QueryParseException ("Function: " + this + " maps to method: " + this.function + " and has accessor: " + this.acc + " however no valid accessor has been found in return type: " + retType.getName (), e); } } } private void getMethodFromHandlers (Query q, List handlers) throws QueryParseException { int s = handlers.size (); TreeMap ms = new TreeMap (); for (int i = 0; i < s; i++) { Object fh = handlers.get (i); this.getMethods (fh.getClass (), q, ms); } // Get the one with the highest score. if (ms.size () > 0) { this.function = (Method) ms.get (ms.lastKey ()); Class c = this.function.getDeclaringClass (); // What a pain! for (int i = 0; i < s; i++) { Object o = handlers.get (i); if (o.getClass ().isAssignableFrom (c)) { this.handler = o; } } } } private void findMethod (Query q) throws QueryParseException { List fhs = q.getFunctionHandlers (); if (fhs != null) { this.getMethodFromHandlers (q, fhs); } if (this.function == null) { List dfhs = q.getDefaultFunctionHandlers (); if (dfhs != null) { this.getMethodFromHandlers (q, dfhs); } } } /** * Return the List of {@link Expression} objects that constitute the arguments * to the function, no guarantee is made here as to whether they have been inited. * * @return The List of {@link Expression} objects. */ public List getParameters () { return this.params; } public void setParameters (List ps) { this.params = ps; } public void setName (String name) { this.name = name; } public String getName () { return this.name; } /** * Evaluate this function on the current object. It should be noted that not * all functions will use the current object in their execution, functions from the * {@link org.josql.functions.GroupingFunctions} class are notable exceptions. * * @param o The current object. * @param q The Query object. * @return The result of evaluating the function. * @throws QueryExecutionException If something goes wrong during execution of the * function or gaining the values to be used as arguments. */ public Object evaluate (Object o, Query q) throws QueryExecutionException { // See if we have a fixed result. if (this.fixedResult) { // Evaluated once... if (this.fixedValue != null) { return this.fixedValue; } } // Get the values for the parameters... if any... Object[] ps = null; if (this.params != null) { int s = this.params.size (); ps = new Object[s]; for (int i = 0; i < s; i++) { Expression exp = (Expression) this.params.get (i); if (Expression.class.isAssignableFrom (this.function.getParameterTypes ()[i])) { // Leave this one alone. ps[i] = exp; } else { // Eval this expression. try { ps[i] = exp.getValue (o, q); } catch (Exception e) { throw new QueryExecutionException ("Unable to get parameter: " + i + " (\"" + exp.toString () + "\") for function: " + this.name, e); } } } } Object v = null; try { v = this.function.invoke (this.handler, ps); } catch (Exception e) { throw new QueryExecutionException ("Unable to execute function: " + this.name + " (\"" + this.toString () + "\") with values: " + Arrays.asList (ps), e); } if (v != null) { // See if we have an accessor. if (this.acc != null) { // See if we have a Getter. if (this.get == null) { // No getter, so now try and init it. This assumes that the return // type won't ever change! try { this.get = new Getter (this.acc, v.getClass ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to create accessor for: " + this.acc + " from return type: " + v.getClass ().getName () + " after execution of function: " + this, e); } } try { v = this.get.getValue (v); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for accessor: " + this.acc + " from return type: " + v.getClass ().getName () + " after execution of function: " + this, e); } } } if (this.fixedResult) { this.fixedValue = v; } return v; } /** * Return whether the evaluation of this function (see: {@link #evaluate(Object,Query)}) * will result in a true value. * See: {@link ArithmeticExpression#isTrue(Object,Query)} for details of how this is * determined. * * @param o The current object. * @param q The Query object. * @return true if the function return value evaluates to true. * @throws QueryExecutionException If something goes wrong with evaluating the function. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { o = this.evaluate (o, q); if (o == null) { return false; } if (Utilities.isNumber (o)) { return Utilities.getDouble (o) > 0; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue (); } // Not null so return true... return true; } /** * Return a string representation of the function. * In the form: Name ( {@link Expression} [ , {@link Expression} ] ) * * @return A string representation of the function. */ public String toString () { StringBuffer buf = new StringBuffer (); buf.append (this.name); buf.append ("("); if (this.params != null) { for (int i = 0; i < this.params.size (); i++) { Expression p = (Expression) this.params.get (i); buf.append (p); if (i < (this.params.size () - 1)) { buf.append (","); } } } buf.append (")"); if (this.acc != null) { buf.append ("."); buf.append (this.acc); } if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } /** * Return whether the function will return a fixed result, this only * occurs iff all the arguments to the function also return a fixed result. * * @param q The Query object. */ public boolean hasFixedResult (Query q) { return this.fixedResult; } private int matchMethodArgs (Class[] methArgs, Query q) throws QueryParseException { // The score here helps in argument resolution, a more specific argument // match (that is NOT expression in the method args) will score higher and // thus is a better match. int score = 0; for (int i = 0; i < methArgs.length; i++) { Class c = methArgs[i]; Expression exp = (Expression) this.params.get (i); // See if the arg is object, which means "I can accept any type". if (c.getClass ().getName ().equals (Object.class.getName ())) { score += 1; continue; } // Now try and get the expected return type... Class expC = exp.getExpectedReturnType (q); if (expC == null) { // Can't match this arg. continue; } else { if (c.isAssignableFrom (expC)) { score += 2; continue; } } if (Expression.class.isAssignableFrom (c)) { score += 1; // This is a match... i.e. the arg is an expression and thus supported // in a "special" way. continue; } if ((Utilities.isNumber (expC)) && ((Utilities.isNumber (c)) || (c.getName ().equals (Object.class.getName ())) ) ) { score += 1; // This matches... continue; } if ((Utilities.isPrimitiveClass (c)) && (Utilities.isPrimitiveClass (expC)) ) { // It is a primitive class as well, so now see if they are compatible. if (Utilities.getPrimitiveClass (c).isAssignableFrom (Utilities.getPrimitiveClass (expC))) { score += 1; // They are assignable... continue; } } // See if the expression return type is an object... this "may" mean // that we can match and it may not, it will be determined at runtime. if (expC.getName ().equals (Object.class.getName ())) { score += 1; continue; } // If we are here then we can't match this arg type... // No point checking any further... return 0; } // All args can be matched. return score; } private void getMethods (Class c, Query q, Map matches) throws QueryParseException { Method[] meths = c.getMethods (); for (int i = 0; i < meths.length; i++) { Method m = meths[i]; if (!m.getName ().equals (this.name)) { continue; } // Make sure it's public... if (!Modifier.isPublic (m.getModifiers ())) { continue; } // Now check the args... sigh... Class[] mpt = m.getParameterTypes (); int ps = 0; int fps = 0; if (mpt != null) { ps = mpt.length; } if (this.params != null) { fps = this.params.size (); } if (ps != fps) { continue; } if (ps == 0) { matches.put (Integer.valueOf (0), m); return; } int score = this.matchMethodArgs (mpt, q); if (score > 0) { matches.put (Integer.valueOf (score), m); } } } } josql-2.2/src/org/josql/expressions/GTLTExpression.java000066400000000000000000000066331157743651500233200ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.internal.Utilities; /** * This class represents one of the following: * *

* You can also force a "string" comparison by prefixing with "$". This will force * both sides to be strings via the toString method. */ public class GTLTExpression extends BinaryExpression { private int type = -1; private boolean ignoreCase = false; public int getType () { return this.type; } /** * Type is an integer here for speed purposes, however one of the constants * should be used. * * @param t The type of expression. */ public void setType (int t) { this.type = t; } public void setIgnoreCase (boolean v) { this.ignoreCase = v; } public boolean isIgnoreCase () { return this.ignoreCase; } /** * Return whether this expression evaluates to true. The actual comparison * is performed by: {@link Utilities#compare(Object,Object)} which copes with * the object types. * * @param o The current object to evaluate the expression on. * @param q The Query object. * @return true if the expression evaluates to true. * @throws QueryExecutionException If the expression cannot be evaluated. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { // Get the lhs. Object l = this.left.getValue (o, q); Object r = this.right.getValue (o, q); if ((l == null) && (r == null) ) { if ((this.type == 1) || (this.type == 3) ) { return true; } } if ((l == null) || (r == null) ) { return false; } return Utilities.matches (l, r, this.ignoreCase, this.type, false); } /** * Return a string version of the expression. * In the form: {@link Expression#toString() Expression} [ $ ] <|> [ = ] {@link Expression#toString() Expression} * * @return A string version of the expression. */ public String toString () { String pred = "<"; if (this.type == Utilities.GT) { pred = ">"; } if (this.type == Utilities.GTE) { pred = ">="; } if (this.type == Utilities.LTE) { pred = "<="; } if (this.ignoreCase) { pred = "$" + pred; } if (this.isBracketed ()) { return "(" + this.left.toString () + " " + pred + " " + this.right.toString () + ")"; } return this.left.toString () + " " + pred + " " + this.right.toString (); } } josql-2.2/src/org/josql/expressions/InExpression.java000066400000000000000000000216621157743651500231130ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.List; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.Iterator; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; /** * This class represents in [ NOT ] IN [ LIKE ] [ ALL ] expression. * If any of the values listed are Maps or Collections then they are iterated over to see if a match * is found. For Maps only the key values are checked. If you pass a list then it is iterated over * using a for construct rather than an Iterator since it's much faster. *

* Note: due to the way that the expression is designed it is POSSIBLE to have a binary expression * in the in list, however at this time that is not supported since it can lead to an ambiguous result, * for example: true IN (true, false) has no sensible meaning. */ public class InExpression extends BinaryExpression { private List items = new ArrayList (); private boolean not = false; private boolean doLike = false; private boolean all = false; private boolean ignoreCase = false; /** * Initialise the IN expression. Init the LHS and then all of the values in the brackets. * * @param q The Query object. * @throws QueryParseException If something goes wrong with the init. */ public void init (Query q) throws QueryParseException { this.left.init (q); int s = this.items.size (); for (int i = 0; i < s; i++) { Expression exp = (Expression) this.items.get (i); exp.init (q); } } public void setIgnoreCase (boolean v) { this.ignoreCase = v; } public boolean isIgnoreCase () { return this.ignoreCase; } public boolean isAll () { return this.all; } public void setAll (boolean v) { this.all = v; } public boolean isDoLike () { return this.doLike; } public void setDoLike (boolean d) { this.doLike = d; } public void setItems (List items) { this.items = items; } public List getItems () { return this.items; } public void addItem (Expression e) { this.items.add (e); } public boolean isNot () { return this.not; } public void setNot (boolean v) { this.not = v; } /** * Return whether this expression evaulates to true. If any of the values on RHS are Maps (keys * only) or Collections then they are iterated over and checked against the LHS. * * @param o The current object to perform the expression on. * @param q The Query object. * @return true if the LHS is "equal" (as determined by: {@link Utilities#isEquals(Object,Object)}) * to any of the values in the brackets. If this is a NOT expression then the result is negated. * @throws QueryExecutionException If the expression cannot be evaluated. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { // Get the LHS. Object l = this.left.getValue (o, q); String v = null; String wc = String.valueOf (q.getWildcardCharacter ()); if (this.doLike) { if (l != null) { v = l.toString (); if (this.ignoreCase) { v = v.toLowerCase (); } } } int count = 0; // Cycle over our items. int s = this.items.size (); for (int i = 0; i < s; i++) { Expression exp = (Expression) this.items.get (i); // Evaluate it. Object eo = exp.getValue (o, q); boolean eq = false; boolean proc = false; if (eo instanceof Collection) { Collection col = (Collection) eo; eq = this.compareCollection (l, col, v, wc); proc = true; } if (eo instanceof Map) { eq = this.compareMap (l, (Map) eo, v, wc); proc = true; } if (!proc) { // See if the objects are equivalent. eq = this.compareItem (l, eo, v, wc); } if (eq) { count++; if (this.not) { return false; } if (!this.all) { return true; } } } if ((this.all) && (!this.not) && (count == s) ) { return true; } if ((this.all) && (this.not) && (count == 0) ) { return true; } if (this.not) { return true; } return false; } private boolean compareCollection (Object o, Collection c, String v, String wc) { if (c instanceof List) { return this.compareList (o, (List) c, v, wc); } Iterator i = c.iterator (); int count = 0; while (i.hasNext ()) { Object n = i.next (); if (this.compareItem (o, n, v, wc)) { count++; if (!this.all) { return true; } } } if ((this.all) && (!this.not) && (count == c.size ()) ) { return true; } if ((this.all) && (this.not) && (count == 0) ) { return true; } return false; } private boolean compareList (Object o, List l, String v, String wc) { int s = l.size (); int count = 0; for (int i = 0; i < s; i++) { Object n = l.get (i); if (this.compareItem (o, n, v, wc)) { count++; if (!this.all) { return true; } } } if ((this.all) && (!this.not) && (count == s) ) { return true; } if ((this.all) && (this.not) && (count == 0) ) { return true; } return false; } private boolean compareItem (Object o, Object n, String v, String wc) { boolean eq = true; if (this.doLike) { if ((v == null) && (n == null) ) { return true; } if (n == null) { return false; } String vn = n.toString (); if (this.ignoreCase) { vn = vn.toLowerCase (); } List pat = Utilities.getLikePattern (vn, wc); eq = Utilities.matchLikePattern (pat, v); } else { if (this.ignoreCase) { if (o == null) { return (n == null); } else { if (n == null) { return false; } } return o.toString ().equalsIgnoreCase (n.toString ()); } eq = Utilities.isEquals (o, n); } return eq; } private boolean compareMap (Object o, Map m, String v, String wc) { Iterator i = m.keySet ().iterator (); int count = 0; while (i.hasNext ()) { Object n = i.next (); if (this.compareItem (o, n, v, wc)) { count++; if (!this.all) { return true; } } } if ((this.all) && (!this.not) && (count == m.size ()) ) { return true; } if ((this.all) && (this.not) && (count == 0) ) { return true; } return false; } /** * Return a string representation of this expression. * In the form: {@link Expression#toString() Expression} [ NOT ] [$]IN [ LIKE ] [ ALL ] * ( {@link Expression#toString() Expression} [ , {@link Expression#toString() Expression}* ] ) * * @return A string representation of this expression. */ public String toString () { StringBuffer buf = new StringBuffer (this.left.toString ()); buf.append (" "); if (this.isNot ()) { buf.append ("NOT "); } if (this.ignoreCase) { buf.append ("$"); } buf.append ("IN "); if (this.doLike) { buf.append ("LIKE "); } if (this.all) { buf.append ("ALL "); } buf.append ("("); for (int i = 0; i < this.items.size (); i++) { buf.append (this.items.get (i)); if (i < (this.items.size () - 1)) { buf.append (","); } } buf.append (")"); if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } } josql-2.2/src/org/josql/expressions/IsNullExpression.java000066400000000000000000000043371157743651500237530ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; /** * Represents an "IS NULL" (or "IS NOT NULL") expression. */ public class IsNullExpression extends BinaryExpression { private boolean not = false; public boolean isNot () { return this.not; } public void setNot (boolean v) { this.not = v; } /** * Return a string representation of this expression. * In the form: {@link Expression#toString()} IS [ NOT ] NULL * * @return A string representation of this expression. */ public String toString () { StringBuffer buf = new StringBuffer ("IS "); if (this.not) { buf.append ("NOT "); } buf.append (this.left.toString ()); if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } /** * Determine whether the LHS of this expression is or is not null. * Note that this is equivalent to: LHS = null or: * LHS != null. * * @param o The current object to perform the expression on. * @param q The Query object. * @return true if the LHS is null (or not null is specified). * @throws QueryExecutionException If the expression cannot be evaluated. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { // Get the left... o = this.left.getValue (o, q); if (o == null) { if (this.not) { return false; } return true; } if (this.not) { return true; } return false; } } josql-2.2/src/org/josql/expressions/LikeExpression.java000066400000000000000000000132621157743651500234260ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.List; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; /** * Represents a LHS [ NOT ] [ $ ] LIKE RHS expression. * It should be noted that unlike "normal" SQL the "." character is not supported since in * practice it tends to be redundant. *

* It is possible to use: $ in front of the "LIKE" to indicate that a case insensitive * comparison should be performed, for example: *

 *   SELECT *
 *   FROM   java.lang.String
 *   WHERE  toString $LIKE '%value'
 * 
*

* Also, the LHS or RHS can be built up using the "+" operator to concatenate a string, thus: *

 *   SELECT *
 *   FROM   java.lang.String
 *   WHREE  toString $LIKE '%' + :myValue
 * 
*

* In this way (using the {@link BindVariable named bind variable}) you don't have to provide * the wildcard. *

* It is also possible to specify your own "wildcard" character in the Query object using: * {@link Query#setWildcardCharacter(char)}. *

* Note: the implementation is a modified version of that provided by: Kevin Stannard * (http://www.jzoo.com/java/wildcardfilter/). */ public class LikeExpression extends BinaryExpression { private boolean not = false; private boolean ignoreCase = false; private List pattern = null; public boolean isIgnoreCase () { return this.ignoreCase; } /** * Init the expression, we over-ride here so that if the RHS is fixed we can * init the pattern that will be used to match the expression. * * @param q The Query object. * @throws QueryParseException If the LHS and/or RHS cannot be inited. */ public void init (Query q) throws QueryParseException { // Call our parent first. super.init (q); if (this.right.hasFixedResult (q)) { // It does have a fixed result so get the value and init the pattern. Object r = null; try { r = this.right.getValue (null, q); } catch (Exception e) { throw new QueryParseException ("Unable to get RHS value from: \"" + this.right + "\", expected to RHS to have fixed result.", e); } if (r == null) { // Return since we can't do anything useful now. return; } String rs = r.toString (); if (this.ignoreCase) { rs = rs.toLowerCase (); } char wc = q.getWildcardCharacter (); this.pattern = Utilities.getLikePattern (rs, String.valueOf (wc)); } } public void setIgnoreCase (boolean v) { this.ignoreCase = v; } public boolean isNot () { return this.not; } public void setNot (boolean v) { this.not = v; } /** * Returns whether the LHS is "LIKE" the RHS. * A special case here is that if the LHS and RHS are both null then true * is returned. Also, if either the LHS or RHS is not null and one is null then false * is returned. * * @param o The object to evaluate the expression on. * @param q The Query object. * @return true if the LHS is "LIKE" the RHS, false if not. And using * "NOT" will invert the result. * @throws QueryExecutionException If the expression cannot be evaluated. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { // Get the left... Object l = this.left.getValue (o, q); if (this.pattern != null) { return Utilities.matchLikePattern (this.pattern, l, this.not, this.ignoreCase); } Object r = this.right.getValue (o, q); if ((l == null) && (r == null) ) { // Special case... if (this.not) { return false; } return true; } if ((l == null) || (r == null) ) { if (this.not) { return true; } return false; } // Convert RHS to a string. String rs = r.toString (); if (this.ignoreCase) { rs = rs.toLowerCase (); } // Now see if rs contains the wildcard character. char wc = q.getWildcardCharacter (); List pat = Utilities.getLikePattern (rs, String.valueOf (wc)); return Utilities.matchLikePattern (pat, l, this.not, this.ignoreCase); } /** * Returns a string version of the expression. * Returns in the form: *

     *   {@link Expression#toString() Expression} [ NOT ] [ $ ]LIKE {@link Expression#toString() Expression}
     * 
* * @return A string representation of the expression. */ public String toString () { StringBuffer buf = new StringBuffer (this.left.toString ()); if (this.isNot ()) { buf.append (" NOT"); } buf.append (" "); if (this.ignoreCase) { buf.append ("$"); } buf.append ("LIKE "); buf.append (this.right); if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } } josql-2.2/src/org/josql/expressions/NewObjectExpression.java000066400000000000000000000167551157743651500244340ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.*; import java.lang.reflect.Constructor; import org.josql.internal.Setter; import org.josql.internal.Utilities; import org.josql.Query; import org.josql.QueryParseException; import org.josql.QueryExecutionException; public class NewObjectExpression extends ValueExpression { private String cn = null; private Class clazz = null; private List constructorArgs = null; private Map intoExps = null; private Constructor constructor = null; private Object[] conParms = null; private int argsSize = -1; public void addIntoExpression (Expression exp, String setter) { if (this.intoExps == null) { this.intoExps = new LinkedHashMap (); } this.intoExps.put (exp, setter); } public void setConstructorArgs (List exps) { this.constructorArgs = exps; this.argsSize = exps.size () - 1; } public void setClassName (String c) { this.cn = c; } public boolean hasFixedResult (Query q) { return false; } public Class getExpectedReturnType (Query q) throws QueryParseException { return this.clazz; } public void init (Query q) throws QueryParseException { // Load the class. try { // Load via the custom (if present) classloader. this.clazz = q.getClassLoader ().loadClass (this.cn); } catch (Exception e) { throw new QueryParseException ("Unable to load class: " + this.cn, e); } Class[] conTypes = null; // Init all the constructor arg expressions, if provided. if (this.constructorArgs != null) { conTypes = new Class [this.constructorArgs.size ()]; this.conParms = new Object[this.constructorArgs.size ()]; for (int i = 0; i < this.constructorArgs.size (); i++) { Expression exp = (Expression) this.constructorArgs.get (i); exp.init (q); conTypes[i] = exp.getExpectedReturnType (q); } } TreeMap tm = new TreeMap (); Constructor[] cons = this.clazz.getConstructors (); for (int i = 0; i < cons.length; i++) { int score = Utilities.matchMethodArgs (cons[i].getParameterTypes (), conTypes); if (score > 0) { tm.put (Integer.valueOf (score), cons[i]); } } if (tm.size () > 0) { this.constructor = (Constructor) tm.get (tm.lastKey ()); } // Now try and find the constructor. if (this.constructor == null) { throw new QueryParseException ("Unable to find constructor: " + Utilities.formatSignature (this.clazz.getName (), conTypes)); } // Now init any setters. if (this.intoExps != null) { Iterator iter = this.intoExps.keySet ().iterator (); Class[] pts = new Class[1]; while (iter.hasNext ()) { Expression exp = (Expression) iter.next (); String setName = (String) this.intoExps.get (exp); exp.init (q); pts[0] = exp.getExpectedReturnType (q); // Create the Setter. Setter set = null; try { set = new Setter (setName, this.clazz, pts); } catch (Exception e) { throw new QueryParseException ("Unable to create setter for: " + setName, e); } this.intoExps.put (exp, set); } } } /** * Always return true because a new object is being created and thus * will be unequal to null. * * @param o The object currently in "scope". * @param q The Query object. * @return true always. */ public boolean isTrue (Object o, Query q) { return true; } public Object evaluate (Object o, Query q) throws QueryExecutionException { return this.getValue (o, q); } public Object getValue (Object o, Query q) throws QueryExecutionException { // Need to create a new object. if (this.constructorArgs != null) { for (int i = this.argsSize; i > -1; i--) { Expression exp = (Expression) this.constructorArgs.get (i); try { this.conParms[i] = exp.getValue (o, q); } catch (Exception e) { throw new QueryExecutionException ("Unable to evaluate constructor argument expression: " + exp, e); } } } // Execute the constructor. Object obj = null; try { obj = this.constructor.newInstance (Utilities.convertArgs (this.conParms, this.constructor.getParameterTypes ())); } catch (Exception e) { throw new QueryExecutionException ("Unable to create new instance of: " + this.clazz.getName () + " using constructor: " + this.constructor + ", passing parameters: " + Arrays.toString (this.conParms), e); } // See if we have any setters. if (this.intoExps != null) { Iterator iter = this.intoExps.keySet ().iterator (); while (iter.hasNext ()) { Expression exp = (Expression) iter.next (); Setter set = (Setter) this.intoExps.get (exp); Object so = null; // Eval the expression. try { so = exp.getValue (o, q); } catch (Exception e) { throw new QueryExecutionException ("Unable to evaluate expression: " + exp + " for setter: " + set + " on class: " + this.clazz.getName (), e); } try { set.setValue (obj, so); } catch (Exception e) { String cn = null + ""; if (so != null) { cn = so.getClass ().getName (); } throw new QueryExecutionException ("Unable to set value of type: " + cn + " in object of type: " + this.clazz.getName () + " using setter: " + set + " (value is result of expression: " + exp + ")", e); } } } return obj; } public String toString () { StringBuffer b = new StringBuffer ("new "); b.append (this.clazz.getName ()); b.append (" ("); if (this.constructorArgs != null) { for (int i = 0; i < this.constructorArgs.size (); i++) { Expression exp = (Expression) this.constructorArgs.get (i); b.append (exp); if (i < this.constructorArgs.size () - 1) { b.append (", "); } } } b.append (")"); if (this.intoExps != null) { b.append (" {"); Iterator iter = this.intoExps.keySet ().iterator (); while (iter.hasNext ()) { Expression exp = (Expression) iter.next (); b.append (exp); b.append (" -> "); Object obj = this.intoExps.get (exp); if (obj instanceof Setter) { Setter set = (Setter) obj; b.append (set); } if (obj instanceof String) { b.append ((String) obj); } if (iter.hasNext ()) { b.append (", "); } } b.append ("}"); } return b.toString (); } } josql-2.2/src/org/josql/expressions/SaveValue.java000066400000000000000000000077421157743651500223630ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import com.gentlyweb.utils.Getter; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; public class SaveValue extends ValueExpression { private String name = null; private String acc = null; private Getter get = null; public Class getExpectedReturnType (Query q) throws QueryParseException { // See if the save value is already present. Object sv = q.getSaveValue (this.name); if (sv != null) { if (this.acc != null) { // Init the getter. try { this.get = new Getter (this.acc, sv.getClass ()); } catch (Exception e) { throw new QueryParseException ("Unable to create dynamic getter from instance of type: " + sv.getClass ().getName () + " for save value: " + this.name + " using accessor: " + this.acc, e); } return this.get.getType (); } return sv.getClass (); } // No idea what it could be... return Object.class; } public void init (Query q) { // Nothing to do... } public String getName () { return this.name; } public void setName (String name) { this.name = name; } public Object getValue (Object o, Query q) throws QueryExecutionException { Object v = q.getSaveValue (this.name); if (v == null) { return v; } // See if we have an accessor... if ((this.acc != null) && (this.get == null) ) { try { this.get = new Getter (this.acc, v.getClass ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to create dynamic getter from instance of type: " + v.getClass ().getName () + " for save value: " + this.name + " using accessor: " + this.acc, e); } } if (this.get != null) { try { v = this.get.getValue (v); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value from instance of type: " + v.getClass ().getName () + " for save value: " + this.name + " using accessor: " + this.acc, e); } } return v; } public boolean isTrue (Object o, Query q) throws QueryExecutionException { o = this.getValue (o, q); if (o == null) { return false; } if (Utilities.isNumber (o)) { return Utilities.getDouble (o) > 0; } // Not null so return true... return true; } public String getAccessor () { return this.acc; } public void setAccessor (String acc) { this.acc = acc; } public Object evaluate (Object o, Query q) throws QueryExecutionException { return this.getValue (o, q); } public String toString () { StringBuffer buf = new StringBuffer (); buf.append ("@"); buf.append (this.name); if (this.acc != null) { buf.append ("."); buf.append (this.acc); } if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } public boolean hasFixedResult (Query q) { // A save value cannot have a fixed result. return false; } } josql-2.2/src/org/josql/expressions/SelectItemExpression.java000066400000000000000000000076111157743651500246010ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.Map; import java.util.Collection; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.internal.Utilities; public class SelectItemExpression extends Expression { public static final String KEY = "key"; public static final String VALUE = "value"; private Expression exp = null; private boolean fixedResult = false; private Class addItemsType = null; private String addItemsMapType = null; private String alias = null; public String getAlias () { return this.alias; } public void setAlias (String a) { this.alias = Utilities.stripQuotes (a); } public boolean hasFixedResult (Query q) { return this.fixedResult; } public Class getExpectedReturnType (Query q) throws QueryParseException { return this.exp.getExpectedReturnType (q); } public void init (Query q) throws QueryParseException { this.exp.init (q); this.fixedResult = this.exp.hasFixedResult (q); /* if (this.isAddItemsFromCollectionOrMap ()) { // Get the expected return type. Class expC = this.getExpectedReturnType (q); if (expC.getName ().equals (Object.class.getName ())) { // Defer until later. return; } if (!this.addItemsType.isAssignableFrom (expC)) { throw new QueryParseException ("Expected return type from select clause column will be: " + expC.getName () + ", however expecting to add items to results from type: " + this.addItemsType.getName ()); } } */ } public void setAddMapType (String t) { this.addItemsMapType = t; } public Collection getAddItems (Object v) { if (Map.class.isAssignableFrom (this.addItemsType)) { boolean k = this.addItemsMapType.equals (SelectItemExpression.KEY); Map m = (Map) v; if (k) { return m.keySet (); } return m.values (); } if (v instanceof Collection) { return (Collection) v; } // This is a nasty hack but is "ok" for now, fix in a later version... java.util.List l = new java.util.ArrayList (); l.add (v); return l; } public boolean isAddItemsFromCollectionOrMap () { return this.addItemsType != null; } public void setAddItemsType (Class c) { this.addItemsType = c; } public Expression getExpression () { return this.exp; } public void setExpression (Expression exp) { this.exp = exp; } public boolean isTrue (Object o, Query q) throws QueryExecutionException { return this.exp.isTrue (o, q); } public Object getValue (Object o, Query q) throws QueryExecutionException { return this.exp.getValue (o, q); } public String toString () { StringBuffer b = new StringBuffer (); if (this.isAddItemsFromCollectionOrMap ()) { b.append ("[*"); if (this.addItemsMapType != null) { b.append (", "); b.append (this.addItemsMapType); } b.append ("] "); } b.append (this.exp); if (this.alias != null) { b.append (" "); b.append (this.alias); } return b.toString (); } } josql-2.2/src/org/josql/expressions/SubQueryExpression.java000066400000000000000000000276421157743651500243300ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import java.util.List; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import com.gentlyweb.utils.Getter; import org.josql.Query; import org.josql.QueryResults; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.events.*; public class SubQueryExpression extends ValueExpression implements BindVariableChangedListener, SaveValueChangedListener { private Query q = null; private boolean inited = false; private String acc = null; private Getter get = null; private boolean nullQuery = false; public SubQueryExpression (Query q) { this.q = q; this.q.addBindVariableChangedListener (this); this.q.addSaveValueChangedListener (this); } public void bindVariableChanged (BindVariableChangedEvent ev) { if (this.q.getFrom () instanceof BindVariable) { BindVariable bv = (BindVariable) this.q.getFrom (); if (bv.getName ().equalsIgnoreCase (ev.getName ())) { this.inited = false; } } } public void saveValueChanged (SaveValueChangedEvent ev) { if (this.q.getFrom () instanceof SaveValue) { SaveValue sv = (SaveValue) this.q.getFrom (); if (sv.getName ().equalsIgnoreCase (ev.getName ())) { this.inited = false; } } } public Getter getGetter () { return this.get; } public void setAccessor (String acc) { this.acc = acc; } public String getAccessor () { return this.acc; } public Query getQuery () { return this.q; } public boolean hasFixedResult (Query q) { return false; } public Class getExpectedReturnType (Query q) throws QueryParseException { if (this.get != null) { return this.get.getType (); } return List.class; } public void init (Query q) throws QueryParseException { // Now see if we have an accessor for the function. if (this.acc != null) { try { this.get = new Getter (this.acc, ArrayList.class); } catch (Exception e) { throw new QueryParseException ("Sub-query: " + this + " has accessor: " + this.acc + " however no valid accessor has been found in return type: " + ArrayList.class.getName (), e); } } } public boolean isTrue (Object o, Query q) throws QueryExecutionException { List l = (List) this.getValue (o, q); return l.size () > 0; } private Object innerInitFromFunction (Expression from, Object o, Query q) throws QueryExecutionException { try { from.init (q); } catch (Exception e) { throw new QueryExecutionException ("Unable to init FROM clause: " + from + " for sub-query: " + q, e); } // Need to pass the parent query here to ensure that if we are using any // special bind variables they are gained from the correct place. return this.q.getFrom ().getValue (o, q); } private Object innerInitFromConstantExpression (Expression from, Object o, Query q) throws QueryExecutionException { Object obj = null; // Assume this is a getter. String g = (String) from.getValue (null, this.q); // See if it's the "special" null. if (!g.equalsIgnoreCase ("null")) { Accessor acc = new Accessor (); acc.setAccessor (g); this.q.setFrom (acc); try { // Init the accessor (from) but with our parent. acc.init (q); } catch (Exception e) { throw new QueryExecutionException ("Unable to init accessor: " + g + " from class: " + o.getClass () + " for FROM clause, for sub-query: \"" + this.q + "\"", e); } // Get the value, this will constitute the class for our query. obj = this.q.getFrom ().getValue (o, this.q); } else { // This is a "null" query. List l = new ArrayList (); l.add (new Object ()); obj = l; this.nullQuery = true; } return obj; } private Object innerInitFromBindVariable (Expression from, Object o, Query q) throws QueryExecutionException { // Need to init the bind variable. try { from.init (q.getTopLevelQuery ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to init FROM clause: " + from + " for sub-query: " + this.q, e); } return from.getValue (o, q.getTopLevelQuery ()); } private Object innerInitFromAccessor (Expression from, Object o, Query q) throws QueryExecutionException { try { from.init (q); } catch (Exception e) { throw new QueryExecutionException ("Unable to init FROM clause: " + from + " for sub-query: " + this.q, e); } // Get the value, this will constitute the class for our query. return from.getValue (o, this.q); } private void innerInit (Object o, Query q) throws QueryExecutionException { Object obj = null; Expression from = this.q.getFrom (); if (from instanceof ConstantExpression) { obj = this.innerInitFromConstantExpression (from, o, q); } if (from instanceof Accessor) { obj = this.innerInitFromAccessor (from, o, q); } if (from instanceof Function) { obj = this.innerInitFromFunction (from, o, q); } if (from instanceof SaveValue) { obj = from.getValue (o, q.getTopLevelQuery ()); } if (from instanceof BindVariable) { obj = this.innerInitFromBindVariable (from, o, q); } if (obj == null) { return; } // Need to ensure that obj is an instance of Collection. if (!(obj instanceof Collection)) { throw new QueryExecutionException ("Expected FROM clause: " + this.q.getFrom () + " for sub-query: " + this.q + " to evaluate to an instance of: " + Collection.class.getName () + ", instead evaluates to: " + obj.getClass ().getName () + " using from expression: " + from); } Collection col = (Collection) obj; // Now peek at the top of the collection. Iterator iter = col.iterator (); if (!iter.hasNext ()) { return; } Object io = iter.next (); // Get the class... if (io == null) { // Crapola! Now need to iterate down the collection until we find // an item that is not null. while (iter.hasNext ()) { io = iter.next (); if (io != null) { break; } } } if (io == null) { // Just return, no elements. return; } this.q.setFromObjectClass (io.getClass ()); try { this.q.init (); } catch (Exception e) { throw new QueryExecutionException ("Unable to init sub-query: " + this.q + " with class: " + io.getClass ().getName (), e); } this.inited = true; } private List innerGetValue (Object o) throws QueryExecutionException { if (this.nullQuery) { return Query.nullQueryList; } Object obj = null; try { obj = this.q.getFrom ().getValue (o, this.q.getTopLevelQuery ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to evaluate FROM clause accessor: " + this.q.getFrom () + " for sub-query: " + this.q, e); } if (obj == null) { return new ArrayList (); } if (!(obj instanceof Collection)) { throw new QueryExecutionException ("Evaluation of FROM clause for sub-query: " + this.q + " returns an instance of: " + obj.getClass ().getName () + " however only sub-classes of: " + Collection.class.getName () + " are supported."); } List l = null; // Now, co-erce the collection to a List. if (obj instanceof List) { l = (List) obj; } else { l = new ArrayList ((Collection) obj); } return l; } public Object evaluate (Object o, Query q) throws QueryExecutionException { this.q.setParent (q); if (!this.inited) { this.innerInit (o, q); } if (this.inited) { List l = this.innerGetValue (o); QueryResults qr = this.q.execute (l); if (this.get != null) { try { return this.get.getValue (qr.getResults ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for accessor: " + this.acc + " from return type: " + ArrayList.class.getName () + " after execution of sub-query: " + this, e); } } return qr.getResults (); } return new ArrayList (); } public String toString () { return "(" + this.q.toString () + ")"; } } josql-2.2/src/org/josql/expressions/ValueExpression.java000066400000000000000000000020761157743651500236170ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.expressions; import org.josql.Query; import org.josql.QueryExecutionException; public abstract class ValueExpression extends Expression { public Object getValue (Object o, Query q) throws QueryExecutionException { return this.evaluate (o, q); } public abstract Object evaluate (Object o, Query q) throws QueryExecutionException; } josql-2.2/src/org/josql/filters/000077500000000000000000000000001157743651500167015ustar00rootroot00000000000000josql-2.2/src/org/josql/filters/AbstractJoSQLFilter.java000066400000000000000000000120371157743651500233310ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.filters; import org.josql.Query; import org.josql.QueryParseException; /** * This class just provides a base-abstract implementation that allow "Filters" to be * built on top of it. */ public abstract class AbstractJoSQLFilter { protected Query q = null; protected Exception exp = null; protected boolean badQuery = false; /** * Protected constructor to allow sub-classes to init the query when they are ready. */ protected AbstractJoSQLFilter () { } /** * Init this filter with the query. * * @param q The query. * @throws QueryParseException If there is an issue with the parsing of the query, * or if the FROM class is not equal to the expected class. */ public AbstractJoSQLFilter (String q) throws QueryParseException { this.setQuery (q); } /** * Should sub-classes should return the type that they expect to be present in * a Query. * * @return The class that should be used in the Query for the filter. */ public abstract Class getExpectedClass (); /** * Init this file filter with the query already built and parsed. * * @param q The query. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not as expected. */ public AbstractJoSQLFilter (Query q) throws IllegalStateException, QueryParseException { this.setQuery (q); } private void checkFrom () throws QueryParseException { if (!this.getExpectedClass ().isAssignableFrom (this.q.getFromObjectClass ())) { throw new QueryParseException ("Query FROM class is: " + this.q.getFromObjectClass ().getName () + ", however only: " + this.getExpectedClass ().getName () + " or sub-classes are supported."); } } /* * Optional operation that allows a "generic" filter to be created. Sub-classes that do not * wish to support this operation should throw an instance of: {@link UnsupportedOperationException}. * * @param o The object to evaluate the WHERE clause against. * @return true if the WHERE clause evaluates to true for the specified * object. */ public abstract boolean accept (Object o) throws UnsupportedOperationException; /** * Clear any exception stored. */ public void clearException () { this.exp = null; this.badQuery = false; } /** * Most "filter accept" methods do not allow for any exceptions to be thrown however since * the execution of the WHERE clause on the object can cause the throwing of a * {@link QueryParseException} it should be captured. If the exception is thrown then * this method will return it. * * @return The exception thrown by the execution of the WHERE clause in {@link #accept(Object)} * or by sub-class/interface specific methods, this may be null if no exception was thrown. */ public Exception getException () { return this.exp; } /** * Set a new Query (string form) for use in this filter. * * @param q The Query to use. * @throws QueryParseException If there is an issue with the parsing of the query, * or if the FROM class is not as expected. */ public void setQuery (String q) throws QueryParseException { this.q = new Query (); this.q.parse (q); this.badQuery = false; this.exp = null; this.checkFrom (); } /** * Set a new Query object for use in this filter. * * @param q The Query to use. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not as expected. */ public void setQuery (Query q) throws IllegalStateException, QueryParseException { if (!q.parsed ()) { throw new IllegalStateException ("Query has not yet been parsed."); } this.q = q; this.checkFrom (); this.badQuery = false; this.exp = null; } /** * Get the Query we are using to process objects. * * @return The Query. */ public Query getQuery () { return this.q; } } josql-2.2/src/org/josql/filters/DefaultObjectFilter.java000066400000000000000000000071571157743651500234370ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.filters; import com.gentlyweb.utils.StringUtils; import org.josql.Query; import org.josql.QueryParseException; /** * A general purpose object filter that uses a JoSQL statement to provide the filtering. * The value returned by the {@link #accept(Object)} method is determined by executing the * JoSQL WHERE clause passed in. A "wrapper" is created around the WHERE clause to make it * a fully-formed JoSQL statement. */ public class DefaultObjectFilter extends AbstractJoSQLFilter { private static String qWrapper = "SELECT * FROM [[CLASS]] WHERE [[WHERE]]"; private static String CLASS_TAG = "[[CLASS]]"; private static String WHERE_TAG = "[[WHERE]]"; private Class c = null; /** * Init this filter with the where clause, note the class specified will be used in the * FROM clause. * * @param w The where clause. * @param c The class of the objects to filter. * @throws QueryParseException If there is an issue with the parsing of the query. */ public DefaultObjectFilter (String w, Class c) throws QueryParseException { if (c == null) { throw new QueryParseException ("Class must be specified"); } this.c = c; String q = StringUtils.replaceString (qWrapper, DefaultObjectFilter.CLASS_TAG, c.getName ()); w = w.trim (); if (w.toLowerCase ().startsWith ("where")) { w = w.substring (5); } q = StringUtils.replaceString (q, DefaultObjectFilter.WHERE_TAG, w); this.setQuery (q); } /** * Init this file filter with the query already built and parsed. * * @param q The query. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not {@link File}. */ public DefaultObjectFilter (Query q) throws IllegalStateException, QueryParseException { this.c = q.getFromObjectClass (); this.setQuery (q); } /** * Apply the WHERE clause of the statement to the object passed in. * If an exception is thrown by the execution of the WHERE clause the Query * is marked as "dirty" and the where clause is no longer executed on the passed in * objects (since it is likely that the WHERE clause will fail for all objects). * You can get access to exception by using: {@link #getException()}. * * @param o The object to evaluate the WHERE on. * @return true if the WHERE clause evaluates to true. */ public boolean accept (Object o) { if (this.badQuery) { return false; } try { return this.q.getWhereClause ().isTrue (o, this.q); } catch (Exception e) { this.badQuery = true; this.exp = e; } return false; } /** * Get the class the Query expects to operate on. * * @return The class. */ public Class getExpectedClass () { return this.c; } } josql-2.2/src/org/josql/filters/JoSQLFileFilter.java000066400000000000000000000074371157743651500224550ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.filters; import java.io.FileFilter; import java.io.File; import org.josql.Query; import org.josql.QueryParseException; /** * A {@link FileFilter} that uses a JoSQL statement to provide the filtering. * The value returned by the {@link #accept(File)} method is determined by executing the * WHERE clause of a JoSQL statement on each File passed in. *

* Since this uses a sub-set of the JoSQL functionality certain restrictions apply: *

* Examples: *

*

 *   SELECT *
 *   FROM   {@link File java.io.File}
 *   WHERE  name $LIKE '%.html'
 *   AND    lastModified > {@link org.josql.functions.ConversionFunctions#toDateMillis(String,String) toDateMillis}('12-04-2004')
 *   AND    file
 * 
*/ public class JoSQLFileFilter extends AbstractJoSQLFilter implements FileFilter { /** * Init this file filter with the query. * * @param q The query. * @throws QueryParseException If there is an issue with the parsing of the query, * or if the FROM class is not {@link File}. */ public JoSQLFileFilter (String q) throws QueryParseException { super (q); } /** * Init this file filter with the query already built and parsed. * * @param q The query. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not {@link File}. */ public JoSQLFileFilter (Query q) throws IllegalStateException, QueryParseException { super (q); } public boolean accept (Object o) { if (!(o instanceof File)) { throw new IllegalArgumentException ("Expected object to be of type: " + File.class.getName () + ", got: " + o.getClass ().getName ()); } return this.accept ((File) o); } /** * Apply the WHERE clause of the statement to the {@link File} passed in. * If an exception is thrown by the execution of the WHERE clause the Query * is marked as "dirty" and the where clause is no longer executed on the passed in * files (since it is likely that the WHERE clause will fail for all File objects). * You can get access to exception by using: {@link #getException()}. * * @param f The file to evaluate the WHERE on. * @return true if the WHERE clause evaluates to true. */ public boolean accept (File f) { if (this.badQuery) { return false; } try { return this.q.getWhereClause ().isTrue (f, this.q); } catch (Exception e) { this.badQuery = true; this.exp = e; } return false; } /** * Always returns {@link File}. * * @return The file class. */ public Class getExpectedClass () { return File.class; } } josql-2.2/src/org/josql/filters/JoSQLLogRecordFilter.java000066400000000000000000000105201157743651500234410ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.filters; import java.util.logging.Filter; import java.util.logging.LogRecord; import org.josql.Query; import org.josql.QueryParseException; /** * A {@link Filter} that uses a JoSQL statement to provide the filtering. * The value returned by the {@link #isLoggable(LogRecord)} method is determined by executing the * WHERE clause of a JoSQL statement on each {@link LogRecord} passed in. *

* Since this uses a sub-set of the JoSQL functionality certain restrictions apply: *

* Examples: *

*

 *   SELECT *
 *   FROM   {@link LogRecord java.tuil.logging.LogRecord}
 *   WHERE  name $LIKE '%.html'
 *   AND    millis > {@link org.josql.functions.ConversionFunctions#toDateMillis(String,String) toDateMillis}('12-04-2004')
 *   AND    sequenceNumber BETWEEN (10000 AND 20000)
 *   AND    message $LIKE '%internal%'
 *   AND    loggerName = 'internal_logger'
 *   AND    level.name IN ('SEVERE', 'WARNING')
 * 
*

* If you are using a custom log record then you can always just extend this class and override * the {@link #getExpectedClass()} method to return your specific sub-class. */ public class JoSQLLogRecordFilter extends DefaultObjectFilter { protected Class expected = LogRecord.class; /** * Init this filter with the query. * * @param q The query. * @throws QueryParseException If there is an issue with the parsing of the query, * or if the FROM class is not {@link LogRecord}. */ public JoSQLLogRecordFilter (String q) throws QueryParseException { super (q, LogRecord.class); } /** * Init this filter with the query already built and parsed. * * @param q The query. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not {@link LogRecord}. */ public JoSQLLogRecordFilter (Query q) throws IllegalStateException, QueryParseException { super (q); } public boolean accept (Object o) { if (!(o instanceof LogRecord)) { throw new IllegalArgumentException ("Expected object to be of type: " + LogRecord.class.getName () + ", got: " + o.getClass ().getName ()); } return super.accept ((LogRecord) o); } /** * Apply the WHERE clause of the statement to the {@link LogRecord} passed in. * If an exception is thrown by the execution of the WHERE clause the Query * is marked as "dirty" and the where clause is no longer executed on the passed in * files (since it is likely that the WHERE clause will fail for all LogRecord objects). * You can get access to exception by using: {@link #getException()}. * * @param l The log record to evaluate the WHERE on. * @return true if the WHERE clause evaluates to true. */ public boolean isLoggable (LogRecord l) { if (this.badQuery) { return false; } try { return this.q.getWhereClause ().isTrue (l, this.q); } catch (Exception e) { this.badQuery = true; this.exp = e; } return false; } /** * Always returns {@link LogRecord}. * * @return The log record class. */ public Class getExpectedClass () { return LogRecord.class; } } josql-2.2/src/org/josql/filters/JoSQLSwingFileFilter.java000066400000000000000000000066531157743651500234640ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.filters; import java.io.File; import javax.swing.filechooser.FileFilter; import org.josql.Query; import org.josql.QueryParseException; /** * A {@link FileFilter} that uses a JoSQL statement to provide the filtering. * The value returned by the {@link #accept(File)} method is determined by executing the * WHERE clause of a JoSQL statement on each File passed in. This just uses an instance of: * {@link JoSQLFileFilter} to do it's job, see that class for details of usage. */ public class JoSQLSwingFileFilter extends FileFilter { // Like I'm gonna re-invent the wheel! private JoSQLFileFilter ff = null; private String d = null; /** * Init this file filter with the query. * * @param q The query. * @throws QueryParseException If there is an issue with the parsing of the query, * or if the FROM class is not {@link File}. */ public JoSQLSwingFileFilter (String q) throws QueryParseException { this.ff = new JoSQLFileFilter (q); } /** * Init this file filter with the query already built and parsed. * * @param q The query. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not {@link File}. */ public JoSQLSwingFileFilter (Query q) throws IllegalStateException, QueryParseException { this.ff = new JoSQLFileFilter (q); } /** * Set the JoSQLFileFilter that should be used to handle the {@link #accept(File)} method. * * @param ff The file filter. */ public void setJoSQLFileFilter (JoSQLFileFilter ff) { this.ff = ff; } /** * Set the description that should be used. * * @param d The description. */ public void setDescription (String d) { this.d = d; } /** * Return the description for the filter. * * @return The description. */ public String getDescription () { return this.d; } /** * Get the file filter being used "under the hoodie" in the {@link #accept(File)} method. * You should also check that file filter to see if an exception has occurred. * * @return The JoSQLFileFilter that is being used to perform the match. */ public JoSQLFileFilter getJoSQLFileFilter () { return this.ff; } /** * Apply the WHERE clause of the statement to the {@link File} passed in. * This is just a wrapper call to: {@link JoSQLFileFilter#accept(File)}. * * @param f The file to evaluate the WHERE on. * @return true if the WHERE clause evaluates to true. */ public boolean accept (File f) { return this.ff.accept (f); } } josql-2.2/src/org/josql/filters/StackTraceElementFilter.java000066400000000000000000000127171157743651500242600ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.filters; import java.util.List; import java.util.ArrayList; import org.josql.Query; import org.josql.QueryParseException; import org.josql.QueryExecutionException; /** * This class allows you to filter the stack trace of a Throwable, so cutting down * on the (sometimes) pointless long stack traces. *

* Usage: *

 *    SELECT *
 *    FROM   java.lang.StackTraceElement
 *    WHERE  className LIKE 'org.josql.%'
 * 
* And then to use in code: *
 *    StackTraceElementFilter f = new StackTraceElementFilter (sql);
 *    f.filter (new Throwable ());
 * 
*/ public class StackTraceElementFilter extends AbstractJoSQLFilter { /** * Init this filter with the query. * * @param q The query. * @throws QueryParseException If there is an issue with the parsing of the query, * or if the FROM class is not equal to the expected class. */ public StackTraceElementFilter (String q) throws QueryParseException { super (q); } /** * Get the expected class. * * @return {@link StackTraceElement}. */ public Class getExpectedClass () { return StackTraceElement.class; } /** * Init this file filter with the query already built and parsed. * * @param q The query. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not as expected. */ public StackTraceElementFilter (Query q) throws IllegalStateException, QueryParseException { super (q); } /* * Returns true if the where clause evaluates to true for the * passed in StackTraceElement. * * @param o The object to evaluate the WHERE clause against. * @return true if the WHERE clause evaluates to true for the specified * object. */ public boolean accept (Object o) { try { return this.accept ((StackTraceElement) o); } catch (Exception e) { this.exp = e; return false; } } /** * Returns true if the where clause evaluates to true for the * passed in StackTraceElement. * * @param s The object to evaluate the WHERE clause against. * @return true if the WHERE clause evaluates to true for the specified * object. */ public boolean accept (StackTraceElement s) throws QueryExecutionException { return this.q.getWhereClause ().isTrue (s, this.q); } /** * Filter the specified stack trace and return the new stack trace * that can then be set in the throwable. * * @param s The stack trace. * @return The new stack trace, filtered. * @throws QueryExecutionException If the where clause cannot be * executed against a particular element. */ public StackTraceElement[] filterStackTrace (StackTraceElement[] s) throws QueryExecutionException { if (s == null) { return s; } List l = new ArrayList (); for (int i = 0; i < s.length; i++) { if (this.accept (s[i])) { l.add (s[i]); } } // Can't believe I have to fricking do this... can't just cast to // StackTraceElement[]... grr... StackTraceElement[] a = new StackTraceElement[l.size ()]; for (int i = 0; i < l.size (); i++) { a[i] = (StackTraceElement) l.get (i); } return a; } /** * Filter the throwable, but will also filter any causes (right up the cause chain) * as well. Equivalent to calling: {@link #filter(Throwable,boolean)} with the * boolean set to true. * * @param t The throwable instance to filter. * @throws QueryExecutionException If the where clause cannot be executed. */ public void filter (Throwable t) throws QueryExecutionException { this.filter (t, true); } /** * Filter the throwable, but will also filter any causes (right up the cause chain) * as well if the filterCause boolean is set to true. * * @param t The throwable instance to filter. * @param filterCause When set to true will also filter the cause * chain as well. * @throws QueryExecutionException If the where clause cannot be executed. */ public void filter (Throwable t, boolean filterCause) throws QueryExecutionException { if (filterCause) { Throwable c = t.getCause (); if (c != null) { this.filter (c, filterCause); } } t.setStackTrace (this.filterStackTrace (t.getStackTrace ())); } } josql-2.2/src/org/josql/functions/000077500000000000000000000000001157743651500172415ustar00rootroot00000000000000josql-2.2/src/org/josql/functions/AbstractFunctionHandler.java000066400000000000000000000022351157743651500246550ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import org.josql.Query; /** * Defines a basic function handler. * A function handler object does NOT have to extend this class, this is here purely * as an easy way to have the required {@link Query} object be available for * sub-classes. */ public abstract class AbstractFunctionHandler implements FunctionHandler { protected Query q = null; /** * Set the Query object that the function handler should use. * * @param q The Query object. */ public void setQuery (Query q) { this.q = q; } } josql-2.2/src/org/josql/functions/CollectionFunctions.java000066400000000000000000000622371157743651500241020ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Collections; import java.util.Comparator; import com.gentlyweb.utils.GeneralComparator; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.expressions.Expression; import org.josql.internal.Utilities; /** * Defines a set of functions that operate on "collections" of objects in some way. */ public class CollectionFunctions extends AbstractFunctionHandler { private Map foreachQueryCache = null; /** * The id that can be used to get the "CollectionFunctions" handler object from * the Query object. */ public static final String HANDLER_ID = "_internal_collection"; /** * Sort a list according to it's "natural" ordering (see {@link Collections#sort(List)}). * * @param objs The list of objects to sort. * @return The sorted list, according to their natural ordering. */ public List sort (List objs) { Collections.sort (objs); return objs; } /** * Sort a Map by the keys in ascending order (for more optionality in the sort and ordering * see: {@link #sort(Map,String,String)}). * * @param m The map to sort. * @return A List sorted according to the key in ascending order. */ public List sort (Map m) { return this.sort (m, "key", GeneralComparator.ASC); } /** * Sort a Map by it's keys or values in ascending order (for more optionality in the sort and ordering * see: {@link #sort(Map,String,String)}). * * @param m The map to sort. * @param type Should be either: "key" or "value" to indicate which item to sort on. * Use null for key. * @return A List sorted according to the key in ascending order. */ public List sort (Map m, String type) { return this.sort (m, type, GeneralComparator.ASC); } /** * Sort a Map by either it's key or value. * * @param m The map to sort. * @param type Should be either: "key" or "value" to indicate which item to sort on. * Use null for key. * @param dir The direction you want to sort on, either "asc" or "desc". Use null * for "asc". * @return A List sorted according to the key or value. */ public List sort (Map m, String type, String dir) { String acc = "key"; if ((type != null) && (type.equalsIgnoreCase ("value")) ) { acc = "value"; } String d = GeneralComparator.ASC; if (dir != null) { dir = dir.toUpperCase (); if (dir.equals (GeneralComparator.DESC)) { d = GeneralComparator.DESC; } } GeneralComparator gc = new GeneralComparator (Map.Entry.class); gc.addField (acc, d); List l = new ArrayList (m.entrySet ()); Collections.sort (l, gc); return l; } /** * Get a value from the specified Map. * * @param m The map of objects. * @param exp The expression is evaluated (in the context of the current object) and the * value returned used as the key to the Map, the value it maps to * (which may be null) is returned. * @return The value that the exp value maps to, may be null. */ public Object get (Map m, Expression exp) throws QueryExecutionException { // Evaluate the expression. // Get the current object. return m.get (exp.getValue (this.q.getCurrentObject (), this.q)); } /** * Get a value from the specified List. * * @param l The list of objects. * @param n The index, indices start at 0. * @return The value of the ith element from the list of objects. Return null * if n is out of range. */ public Object get (List l, Number n) { int i = n.intValue (); if ((i > l.size ()) || (i < 0) ) { return null; } return l.get (i); } /** * For each of the objects in the objs List get the value from each one * using the accessor and compare it to the value parameter. The value * param is converted to a string and then to a Boolean value using: {@link Boolean#valueOf(String)}. * * @param objs The list of objects to iterate over. * @param exp The expression to use to get the value from the object in the List. * @param value The value to compare the result of the accessor against. If the parm is null * then it defaults to {@link Boolean#FALSE}. * @return A count of how many times the accessor evaluated to the same value of the * value parm. * @throws QueryExecutionException If the value from the accessor cannot be gained or if * the compare cannot be performed. */ public int count (List objs, Expression exp, Object value) throws QueryExecutionException { Boolean b = Boolean.FALSE; if (value != null) { b = Boolean.valueOf (value.toString ()); } int count = 0; Object currobj = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); Comparator uc = this.q.getObjectComparator (); this.q.setAllObjects (objs); int size = objs.size (); for (int i = 0; i < size; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); try { int c = 0; if (uc != null) { c = uc.compare (exp.getValue (o, this.q), b); } else { c = Utilities.compare (exp.getValue (o, this.q), b); } if (c == 0) { count++; } } catch (Exception e) { // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for item: " + i + " from the list of objects.", e); } } // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return count; } public int count (Expression exp) throws QueryExecutionException { return this.count ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public int count (List allobjs, Expression exp) throws QueryExecutionException { int count = 0; Object currobj = this.q.getCurrentObject (); List currall = this.q.getAllObjects (); this.q.setAllObjects (allobjs); int size = allobjs.size (); for (int i = 0; i < size; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); try { if (exp.isTrue (o, this.q)) { count++; } } catch (Exception e) { // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (currall); throw new QueryExecutionException ("Unable to determine whether expression: \"" + exp + "\" is true for object at index: " + i + " from the list of objects.", e); } } // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (currall); return count; } public List toList (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { return this.collect (allobjs, exp, saveValueName); } public List unique (List objs) { /** Strangely the method below is consistently slower than the method employed! return new ArrayList (new java.util.LinkedHashSet (objs)); */ Map m = new LinkedHashMap (); int s = objs.size (); for (int i = 0; i < s; i++) { m.put (objs.get (i), null); } return new ArrayList (m.keySet ()); } public List unique (Expression exp) throws QueryExecutionException { return this.unique ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public List unique (List objs, Expression exp) throws QueryExecutionException { /** Strangely the method below is consistently slower than the method employed! return new ArrayList (new java.util.LinkedHashSet (objs)); */ Map m = new HashMap (); Object currobj = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); this.q.setAllObjects (objs); int s = objs.size (); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); o = exp.getValue (o, this.q); m.put (o, null); } // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return new ArrayList (m.keySet ()); } public List collect (List objs, Expression exp, String saveValueName) throws QueryExecutionException { if (saveValueName != null) { Object o = this.q.getSaveValue (saveValueName); if (o != null) { return (List) o; } } List retVals = new ArrayList (); int s = objs.size (); List allobjs = this.q.getAllObjects (); Object co = this.q.getCurrentObject (); this.q.setAllObjects (objs); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); // Execute the function. try { retVals.add (exp.getValue (o, this.q)); } catch (Exception e) { // Reset the current object. this.q.setCurrentObject (co); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to execute expression: \"" + exp + " on object at index: " + i + " from the list of objects.", e); } } if (saveValueName != null) { this.q.setSaveValue (saveValueName, retVals); } // Reset the current object. this.q.setCurrentObject (co); this.q.setAllObjects (allobjs); return retVals; } public List collect (Expression exp) throws QueryExecutionException { return this.collect ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public List collect (List allobjs, Expression exp) throws QueryExecutionException { return this.collect (allobjs, exp, null); } public List toList (Expression exp) throws QueryExecutionException { return this.toList ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public List toList (List allobjs, Expression exp) throws QueryExecutionException { return this.collect (allobjs, exp, null); } public List foreach (Expression exp) throws QueryExecutionException { return this.foreach ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public List foreach (List allobjs, Expression exp) throws QueryExecutionException { if (allobjs == null) { return null; } Object currobj = this.q.getCurrentObject (); this.q.setAllObjects (allobjs); List res = new ArrayList (); int s = allobjs.size (); for (int i = 0; i < s; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); res.add (exp.getValue (o, this.q)); } // Reset the current object. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return res; } /** * Given a list of objects, execute the expression against each one and return * those objects that return a true value for the expression. * In effect this is equivalent to executing the WHERE clause of a JoSQL statement * against each object (which in fact is what happens internally). The class * for the objects if found by examining the list passed in. * * @param objs The list of objects. * @param exp The expression (basically a where clause, it is ok for the expression * to start with "WHERE", case-insensitive) to execute for each of the * objects. * @return The list of matching objects. */ public List foreach (List objs, String exp) throws QueryExecutionException { List l = new ArrayList (); if ((objs == null) || (objs.size () == 0) ) { return l; } Query q = null; // See if we have the expression in our cache. if (this.foreachQueryCache != null) { q = (Query) this.foreachQueryCache.get (exp); } if (q == null) { // Init our query. Class c = null; Object o = objs.get (0); if (o == null) { int s = objs.size () - 1; // Bugger now need to cycle until we get a class. for (int i = s; s > -1; i--) { o = objs.get (i); if (o != null) { c = o.getClass (); break; } } } else { c = o.getClass (); } if (exp.toLowerCase ().trim ().startsWith ("where")) { exp = exp.trim ().substring (5); } String query = "SELECT * FROM " + c.getName () + " WHERE " + exp; q = new Query (); try { q.parse (query); } catch (Exception e) { throw new QueryExecutionException ("Unable to create statement using WHERE clause: " + exp + " and class: " + c.getName () + " (gained from objects in list passed in)", e); } // Cache it. if (this.foreachQueryCache == null) { this.foreachQueryCache = new HashMap (); } this.foreachQueryCache.put (exp, q); } return q.execute (objs).getResults (); } public List foreach (Expression listFunction, Expression exp) throws QueryExecutionException { // Execute the list function. Object o = listFunction.getValue (this.q.getCurrentObject (), this.q); if (!(o instanceof List)) { throw new QueryExecutionException ("Expected expression: " + listFunction + " to return instance of: " + List.class.getName () + " but returned instance of: " + o.getClass ().getName ()); } List l = (List) o; return this.foreach (l, exp); } /** * Find objects from the List based upon the expression passed in. If * the expression evaluates to true then the object will * be returned. * Note: in accordance with the general operating methodology for the Query * object, the ":_allobjs" special bind variable will be set to the * the List passed in and the "_currobj" will be set to the relevant * object in the List. * * @param objs The List of objects to search. * @param exp The expression to evaulate against each object in the List. * @return The List of matching objects, if none match then an empty list is returned. * @throws QueryExecutionException If the expression cannot be evaulated against each * object. */ public List find (List objs, Expression exp) throws QueryExecutionException { // Get the current object, it's important that we leave the Query in the // same state at the end of this function as when we started! Object currobj = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); this.q.setAllObjects (objs); List r = new ArrayList (); int s = objs.size (); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); try { if (exp.isTrue (o, this.q)) { r.add (o); } } catch (Exception e) { // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to evaulate expression: " + exp + " against object: " + i + " (class: " + o.getClass ().getName () + ")", e); } } // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return r; } /** * Group objects from the List based upon the expression passed in. The expression * is evaulated for each object, by calling: {@link Expression#getValue(Object,Query)} * and the return value used as the key to the Map. All objects with that value are * added to a List held against the key. To maintain the ordering of the keys (if * desirable) a {@link LinkedHashMap} is used as the return Map. * * Note: in accordance with the general operating methodology for the Query * object, the ":_allobjs" special bind variable will be set to the * the List passed in and the "_currobj" will be set to the relevant * object in the List. * * @param objs The List of objects to search. * @param exp The expression to evaulate against each object in the List. * @return The LinkedHashMap of matching objects, grouped according to the return value * of executing the expression against each object in the input List. * @throws QueryExecutionException If the expression cannot be evaulated against each * object. */ public Map grp (List objs, Expression exp) throws QueryExecutionException { // Get the current object, it's important that we leave the Query in the // same state at the end of this function as when we started! Object currobj = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); this.q.setAllObjects (objs); Map r = new LinkedHashMap (); int s = objs.size (); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); try { Object v = exp.getValue (o, this.q); List vs = (List) r.get (v); if (vs == null) { vs = new ArrayList (); r.put (v, vs); } vs.add (v); } catch (Exception e) { // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to evaulate expression: " + exp + " against object: " + i + " (class: " + o.getClass ().getName () + ")", e); } } // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return r; } /** * Create a map of the objects passed in, the key will be the object in the list and * the value will be the result of calling the expression on the object. * * The expression is evaulated for each object, by calling: {@link Expression#getValue(Object,Query)} * and the return value used as the value to the Map. To maintain the ordering of the keys (if * desirable) a {@link LinkedHashMap} is used as the return Map. * * Note: in accordance with the general operating methodology for the Query * object, the ":_allobjs" special bind variable will be set to the * the List passed in and the "_currobj" will be set to the relevant * object in the List. * * @param objs The List of objects to map. * @param exp The expression to evaulate against each object in the List. * @return The LinkedHashMap of mapped objects. * @throws QueryExecutionException If the expression cannot be evaulated against each * object. */ public Map map (List objs, Expression exp) throws QueryExecutionException { // Get the current object, it's important that we leave the Query in the // same state at the end of this function as when we started! Object currobj = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); this.q.setAllObjects (objs); Map r = new LinkedHashMap (); int s = objs.size (); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); try { Object v = exp.getValue (o, this.q); r.put (o, v); } catch (Exception e) { // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to evaulate expression: " + exp + " against object: " + i + " (class: " + o.getClass ().getName () + ")", e); } } // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return r; } /** * Create a map of the objects passed in, the key will be the result of calling the keyExp expression * on the object in the list and the value will be the result of calling the valExp expression on the object. * * The expression is evaulated for each object, by calling: {@link Expression#getValue(Object,Query)} * and the return value used as the value to the Map. To maintain the ordering of the keys (if * desirable) a {@link LinkedHashMap} is used as the return Map. * * Note: in accordance with the general operating methodology for the Query * object, the ":_allobjs" special bind variable will be set to the * the List passed in and the "_currobj" will be set to the relevant * object in the List. * * @param objs The List of objects to map. * @param exp The expression to evaulate against each object in the List. * @return The LinkedHashMap of mapped objects. * @throws QueryExecutionException If the expression cannot be evaulated against each * object. */ public Map map (List objs, Expression keyExp, Expression valExp) throws QueryExecutionException { // Get the current object, it's important that we leave the Query in the // same state at the end of this function as when we started! Object currobj = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); this.q.setAllObjects (objs); Map r = new LinkedHashMap (); int s = objs.size (); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); Object k = null; Object v = null; try { k = keyExp.getValue (o, this.q); } catch (Exception e) { // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to evaulate key expression: " + keyExp + " against object: " + i + " (class: " + o.getClass ().getName () + ")", e); } try { v = valExp.getValue (o, this.q); } catch (Exception e) { // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to evaulate value expression: " + valExp + " against object: " + i + " (class: " + o.getClass ().getName () + ")", e); } r.put (k, v); } // Restore the currobj and allobjs. this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return r; } } josql-2.2/src/org/josql/functions/ConversionFunctions.java000066400000000000000000000217711157743651500241320ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import java.util.Map; import java.util.HashMap; import java.util.Date; import java.util.GregorianCalendar; import java.util.Calendar; import java.text.SimpleDateFormat; import org.josql.QueryExecutionException; /** * Note: creating new instances of SimpleDateFormat objects are VERY costly over * large(ish) numbers of objects therefore a cache of objects is provided. */ public class ConversionFunctions extends AbstractFunctionHandler { public static final String HANDLER_ID = "_internal_conversion"; /** * Represents the {@link Calendar#MINUTE} field, is: mi. */ public static final String MINUTE = "mi"; /** * Represents the {@link Calendar#DATE} field, is: d. */ public static final String DAY = "d"; /** * Represents the {@link Calendar#YEAR} field, is: y. */ public static final String YEAR = "y"; /** * Represents the {@link Calendar#SECOND} field, is: s. */ public static final String SECOND = "s"; /** * Represents the {@link Calendar#HOUR_OF_DAY} field, is: h. */ public static final String HOUR = "h"; /** * Represents the {@link Calendar#MONTH} field, is: m. */ public static final String MONTH = "m"; /** * Represents the {@link Calendar#WEEK_OF_YEAR} field, is: w. */ public static final String WEEK = "w"; public static String DEFAULT_DATE_FORMAT_SPEC = "dd/MMM/yyyy"; public static String DEFAULT_DATE_FORMAT_SPEC_2 = "dd-MMM-yyyy"; public static String DEFAULT_DATE_FORMAT_SPEC_3 = "dd MMM yyyy"; private Map sdfs = new HashMap (); private Calendar cal = Calendar.getInstance (); public ConversionFunctions () { this.sdfs.put (ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC, new SimpleDateFormat (ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC)); this.sdfs.put (ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC_2, new SimpleDateFormat (ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC_2)); this.sdfs.put (ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC_3, new SimpleDateFormat (ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC_3)); } /** * This method (function) will return the associated field from a * {@link Calendar} instance. The type parm should be one of the * constants from this class. The default {@link java.util.TimeZone} is used. * * @param d If the type is a long value then it is first converted to a Date. * Or a {@link Date} should be used. * @param type The type of field to get. * @return The field from {@link Calendar}. * @throws QueryExecutionException If the d parm isn't an instance of * {@link Long} or {@link Date}. */ public int timeField (Object d, String type) throws QueryExecutionException { if ((!(d instanceof Date)) && (!(d instanceof Long)) ) { throw new QueryExecutionException ("Value passed in is of type: " + d.getClass ().getName () + " only: " + Long.class.getName () + " or: " + Date.class.getName () + " are supported."); } Date date = null; if (d instanceof Long) { date = new Date (((Long) d).longValue ()); } if (d instanceof Date) { date = (Date) d; } this.cal.setTime (date); type = type.toLowerCase (); if (type.equals (ConversionFunctions.SECOND)) { return this.cal.get (Calendar.SECOND); } if (type.equals (ConversionFunctions.MINUTE)) { return this.cal.get (Calendar.MINUTE); } if (type.equals (ConversionFunctions.HOUR)) { return this.cal.get (Calendar.HOUR_OF_DAY); } if (type.equals (ConversionFunctions.DAY)) { return this.cal.get (Calendar.DATE); } if (type.equals (ConversionFunctions.WEEK)) { return this.cal.get (Calendar.WEEK_OF_YEAR); } if (type.equals (ConversionFunctions.MONTH)) { return this.cal.get (Calendar.MONTH); } if (type.equals (ConversionFunctions.YEAR)) { return this.cal.get (Calendar.YEAR); } // None of the above... return -1; } public Date addTime (Date d, Double amount, String type) { int a = amount.intValue (); long v = d.getTime (); if (type.equals (ConversionFunctions.SECOND)) { v += (a * 1000L); return new Date (v); } if (type.equals (ConversionFunctions.MINUTE)) { v += (a * 60000L); return new Date (v); } if (type.equals (ConversionFunctions.HOUR)) { v += (a * 3600000L); return new Date (v); } if (type.equals (ConversionFunctions.DAY)) { v += (a * 24L * 3600000L); return new Date (v); } if (type.equals (ConversionFunctions.WEEK)) { v += (a * 7L * 24L * 3600000L); return new Date (v); } if (type.equals (ConversionFunctions.MONTH)) { // Need something a bit more sophisticated now... GregorianCalendar gc = new GregorianCalendar (); gc.setTime (d); gc.add (Calendar.MONTH, a); return gc.getTime (); } if (type.equals (ConversionFunctions.YEAR)) { // Need something a bit more sophisticated now... GregorianCalendar gc = new GregorianCalendar (); gc.setTime (d); gc.add (Calendar.YEAR, a); return gc.getTime (); } // None of the above... return d; } public Date toDate (Object value) throws QueryExecutionException { if (value == null) { return null; } if (value instanceof Number) { return new Date (((Number) value).longValue ()); } if (value instanceof String) { return this.toDate ((String) value, null); } if (value instanceof Date) { return (Date) value; } throw new QueryExecutionException ("Type: " + value.getClass ().getName () + " is not supported."); } public Date to_date (Object value) throws QueryExecutionException { return this.toDate (value); } public Date to_date (String value, String spec) throws QueryExecutionException { return this.toDate (value, spec); } public Date toDate (String value, String spec) throws QueryExecutionException { if (spec == null) { spec = ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC; } SimpleDateFormat df = (SimpleDateFormat) this.sdfs.get (spec); if (df == null) { df = new SimpleDateFormat (spec); this.sdfs.put (spec, df); } try { return df.parse (value); } catch (Exception e) { throw new QueryExecutionException ("Unable to parse date value: " + value + " using spec: " + spec, e); } } public Long toMillis (Date d) { return new Long (d.getTime ()); } public Long toDateMillis (String value, String spec) throws QueryExecutionException { if (spec == null) { spec = ConversionFunctions.DEFAULT_DATE_FORMAT_SPEC; } SimpleDateFormat df = (SimpleDateFormat) this.sdfs.get (spec); if (df == null) { df = new SimpleDateFormat (spec); this.sdfs.put (spec, df); } try { Date d = df.parse (value); return new Long (d.getTime ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to parse date value: " + value + " using spec: " + spec, e); } } public String upper (Object o) { if (o == null) { return null; } return o.toString ().toUpperCase (); } public String lower (Object o) { if (o == null) { return null; } return o.toString ().toLowerCase (); } public String to_string (Object o) { return this.toString (o); } public String toString (Object o) { return o + ""; } public Number to_number (Object o) { return this.toNumber (o); } public Number toNumber (Object o) { if (o == null) { return null; } if (o instanceof String) { // Try and parse as a double. try { return new Double ((String) o); } catch (Exception e) { // Ignore? Maybe have an option... } } if (o instanceof Date) { return new Double (((Date) o).getTime ()); } if (!(o instanceof Number)) { return null; } return (Number) o; } } josql-2.2/src/org/josql/functions/FileMatch.java000066400000000000000000000030511157743651500217370ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import java.io.File; /** * This class represents the match of a String in a file. */ public class FileMatch { private File f = null; private int line = 0; private int col = 0; private String str = null; private String oLine = null; public FileMatch (File f, int line, int col, String str, String oLine) { this.f = f; this.line = line; this.col = col; this.str = str; this.oLine = oLine; } public String toString () { return this.f.getPath () + "[" + this.line + "," + this.col + "] \"" + this.str + "\" " + this.oLine; } public String getOriginalLine () { return this.oLine; } public String getString () { return this.str; } public int getColumn () { return this.col; } public int getLine () { return this.line; } public File getFile () { return this.f; } } josql-2.2/src/org/josql/functions/FormattingFunctions.java000066400000000000000000000147171157743651500241210ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import java.util.Date; import java.text.SimpleDateFormat; import java.text.DecimalFormat; import com.gentlyweb.utils.TimeDuration; import com.gentlyweb.utils.Timing; import com.gentlyweb.utils.Getter; import org.josql.Query; import org.josql.QueryExecutionException; public class FormattingFunctions extends AbstractFunctionHandler { public static final String HANDLER_ID = "_internal_formatting"; public static String DEFAULT_DATE_FORMAT_SPEC = "dd/MMM/yyyy"; public static String DEFAULT_DATE_TIME_FORMAT_SPEC = FormattingFunctions.DEFAULT_DATE_FORMAT_SPEC + ", hh:mm:ss"; public static String DEFAULT_DECIMAL_FORMAT_SPEC = "###,###,###.##"; private SimpleDateFormat defSDF = new SimpleDateFormat (FormattingFunctions.DEFAULT_DATE_FORMAT_SPEC); private SimpleDateFormat defSDTF = new SimpleDateFormat (FormattingFunctions.DEFAULT_DATE_TIME_FORMAT_SPEC); public String formatTimeDuration (Object o) throws QueryExecutionException { if (o instanceof Number) { return TimeDuration.getInstance (((Number) o).longValue ()).format (); } if (o instanceof Date) { return TimeDuration.getInstance ((Date) o).format (); } if (o instanceof TimeDuration) { return TimeDuration.getInstance ((TimeDuration) o).format (); } if (o instanceof Timing) { return TimeDuration.getInstance ((Timing) o).format (); } throw new QueryExecutionException ("Type: " + o.getClass ().getName () + " not supported."); } public void setDefaultDateFormatSpec (String spec) { this.defSDF = new SimpleDateFormat (spec); } public String formatDate (Object o) throws QueryExecutionException { if (o == null) { throw new QueryExecutionException ("Cannot format a null date."); } Date d = null; if (o instanceof Date) { d = (Date) o; } if (o instanceof Number) { d = new Date (((Number) o).longValue ()); } // If this is a string try and parse the string first, basically convert // from one format to another. if (o instanceof String) { d = ((ConversionFunctions) this.q.getFunctionHandler (ConversionFunctions.HANDLER_ID)).toDate ((String) o); } if (d == null) { throw new QueryExecutionException ("Type: " + o.getClass ().getName () + " not supported."); } return this.defSDF.format (d); } public String formatDateTime (Object o) throws QueryExecutionException { if (o == null) { throw new QueryExecutionException ("Cannot format a null date."); } Date d = null; if (o instanceof Date) { d = (Date) o; } if (o instanceof Number) { d = new Date (((Number) o).longValue ()); } // If this is a string try and parse the string first, basically convert // from one format to another. if (o instanceof String) { d = ((ConversionFunctions) this.q.getFunctionHandler (ConversionFunctions.HANDLER_ID)).toDate ((String) o); } if (d == null) { throw new QueryExecutionException ("Type: " + o.getClass ().getName () + " not supported."); } return this.defSDTF.format (d); } public String formatDate (Query q, Object o, Getter g, String spec, String saveValueName) throws QueryExecutionException { if (g != null) { try { o = g.getValue (o); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value from accessor: " + g, e); } } if (o == null) { return null + ""; } Date d = null; if (o instanceof Date) { d = (Date) o; } if (o instanceof Long) { d = new Date (((Long) o).longValue ()); } Object so = null; if (saveValueName != null) { so = q.getSaveValue (saveValueName); } SimpleDateFormat df = null; if (so != null) { df = (SimpleDateFormat) so; } else { if (spec == null) { spec = FormattingFunctions.DEFAULT_DATE_FORMAT_SPEC; } df = new SimpleDateFormat (spec); } return df.format (d); } public String formatNumber (Object n) throws QueryExecutionException { return this.formatNumber (this.q, n, null, null); } public String formatNumber (Query q, Object o, String spec, String saveValueName) throws QueryExecutionException { if (!(o instanceof Number)) { if (o == null) { return "NaN (null)"; } return "NaN (" + o.getClass ().getName () + ")"; } if (o == null) { return "0"; } Object so = null; if (saveValueName != null) { so = q.getSaveValue (saveValueName); } Number n = (Number) o; DecimalFormat df = null; if (so != null) { if (!(so instanceof DecimalFormat)) { throw new QueryExecutionException ("Expected save value: \"" + saveValueName + "\" object to be of type: " + DecimalFormat.class.getName () + ", is: " + so.getClass ().getName ()); } df = (DecimalFormat) so; } else { if (spec == null) { spec = FormattingFunctions.DEFAULT_DECIMAL_FORMAT_SPEC; } df = new DecimalFormat (spec); } return df.format (n.doubleValue ()); } public String formatNumber (Query q, Object o, Getter g, String spec, String saveValueName) throws QueryExecutionException { try { o = g.getValue (o); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value from accessor: " + g, e); } return this.formatNumber (q, o, spec, saveValueName); } } josql-2.2/src/org/josql/functions/FunctionHandler.java000066400000000000000000000023361157743651500231730ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import org.josql.Query; /** * Defines an interface that custom objects can use to indicate that they can * store a reference to the Query object. * A function handler object does NOT have to implement this class, this is here purely * as a convenience for developers so that they can easily get a reference to the Query * object, since the Query object will call the {@link #setQuery(Query)} method. */ public interface FunctionHandler { /** * Set the Query object that the function handler should use. * * @param q The Query object. */ public void setQuery (Query q); } josql-2.2/src/org/josql/functions/GroupingFunctions.java000066400000000000000000000612771157743651500236040ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.Iterator; import java.util.Comparator; import com.gentlyweb.utils.Getter; import org.josql.QueryExecutionException; import org.josql.internal.Utilities; import org.josql.expressions.Expression; import org.josql.Query; public class GroupingFunctions extends AbstractFunctionHandler { public static final String VALUE = "value"; public static final String HANDLER_ID = "_internal_grouping"; public Object least (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { if (saveValueName != null) { Object o = this.q.getSaveValue (saveValueName); if (o != null) { return o; } } if (allobjs.size () == 0) { return null; } Object currObj = this.q.getCurrentObject (); Comparator uc = this.q.getObjectComparator (); Object g = null; int s = allobjs.size (); for (int i = 0; i < s; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); Object v = null; try { v = exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (currObj); throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for maximum value" + e); } if (g == null) { g = v; } else { int c = 0; if (uc != null) { c = uc.compare (v, g); } else { c = Utilities.compare (v, g); } if (c < 0) { g = v; } } } if ((saveValueName != null) && (q != null) ) { q.setSaveValue (saveValueName, g); } this.q.setCurrentObject (currObj); return g; } public Object minObject (Expression exp) throws QueryExecutionException { return this.minObject ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public Object minObject (List allobjs, Expression exp) throws QueryExecutionException { return this.leastObject (allobjs, exp); } public Object leastObject (List allobjs, Expression exp) throws QueryExecutionException { if (allobjs.size () == 0) { return null; } Object currObj = this.q.getCurrentObject (); Object l = null; Object lo = null; int s = allobjs.size (); for (int i = 0; i < s; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); Object v = null; try { v = exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (currObj); throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for maximum value" + e); } if (l == null) { l = v; lo = o; } else { int c = 0; Comparator uc = this.q.getObjectComparator (); if (uc != null) { c = uc.compare (v, l); } else { c = Utilities.compare (v, l); } if (c < 0) { l = v; lo = o; } } } this.q.setCurrentObject (currObj); return lo; } public Object maxObject (List allobjs, Expression exp) throws QueryExecutionException { return this.greatestObject (allobjs, exp); } public Object maxObject (Expression exp) throws QueryExecutionException { return this.maxObject ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public Object greatestObject (List allobjs, Expression exp) throws QueryExecutionException { if (allobjs.size () == 0) { return null; } Object currObj = this.q.getCurrentObject (); Object g = null; Object go = null; int s = allobjs.size (); for (int i = 0; i < s; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); Object v = null; try { v = exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (currObj); throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for maximum value" + e); } if (g == null) { g = v; go = o; } else { int c = 0; Comparator uc = this.q.getObjectComparator (); if (uc != null) { c = uc.compare (v, g); } else { c = Utilities.compare (v, g); } if (c > 0) { g = v; go = o; } } } this.q.setCurrentObject (currObj); return go; } public Object least (List allobjs, Expression exp) throws QueryExecutionException { return this.least (allobjs, exp, null); } public Object min (Expression exp) throws QueryExecutionException { return this.min ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public Object min (List allobjs, Expression exp) throws QueryExecutionException { return this.least (allobjs, exp, null); } public Object min (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { return this.least (allobjs, exp, saveValueName); } public Map.Entry maxEntry (Map m, String type) { int t = 0; if (type.equals (GroupingFunctions.VALUE)) { t = 1; } Map.Entry r = null; Map.Entry le = null; Iterator iter = m.entrySet ().iterator (); while (iter.hasNext ()) { r = (Map.Entry) iter.next (); if (le != null) { if (t == 0) { if (Utilities.isGTEquals (r.getKey (), le.getKey ())) { le = r; } } else { if (Utilities.isGTEquals (r.getValue (), le.getValue ())) { le = r; } } } else { le = r; } } return le; } public Map.Entry minEntry (Object m, String type) throws QueryExecutionException { if (!(m instanceof Map)) { throw new QueryExecutionException ("Only instances of: " + Map.class.getName () + " are supported, passed: " + m.getClass ().getName ()); } return this.minEntry ((Map) m, type); } public Map.Entry minEntry (Map m, String type) { int t = 0; if (type.equals (GroupingFunctions.VALUE)) { t = 1; } Map.Entry r = null; Map.Entry le = null; Iterator iter = m.entrySet ().iterator (); while (iter.hasNext ()) { r = (Map.Entry) iter.next (); if (le != null) { if (t == 0) { if (Utilities.isLTEquals (r.getKey (), le.getKey ())) { le = r; } } else { if (Utilities.isLTEquals (r.getValue (), le.getValue ())) { le = r; } } } else { le = r; } } return le; } public Object max (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { return this.greatest (allobjs, exp, saveValueName); } public Object greatest (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { if (saveValueName != null) { Object o = this.q.getSaveValue (saveValueName); if (o != null) { return (Double) o; } } if (allobjs.size () == 0) { return null; } Object currObj = this.q.getCurrentObject (); Object g = null; int s = allobjs.size (); for (int i = 0; i < s; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); Object v = null; try { v = exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (currObj); throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for maximum value" + e); } if (g == null) { g = v; } else { int c = 0; Comparator uc = this.q.getObjectComparator (); if (uc != null) { c = uc.compare (v, g); } else { c = Utilities.compare (v, g); } if (c > 0) { g = v; } } } if (saveValueName != null) { this.q.setSaveValue (saveValueName, g); } this.q.setCurrentObject (currObj); return g; } public Object greatest (List allobjs, Expression exp) throws QueryExecutionException { return this.greatest (allobjs, exp, null); } public Object max (Expression exp) throws QueryExecutionException { return this.max ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public Object max (List allobjs, Expression exp) throws QueryExecutionException { return this.greatest (allobjs, exp, null); } private double getTotal (List allobjs, Expression exp) throws QueryExecutionException { Object currObj = this.q.getCurrentObject (); double total = 0; int size = allobjs.size (); for (int i = 0; i < size; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); Number n = null; try { n = (Number) exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (currObj); throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for item: " + i + " from the list of objects.", e); } total += n.doubleValue (); } this.q.setCurrentObject (currObj); return total; } public void checkType (Object o, Class expected, Expression exp) throws QueryExecutionException { if (!expected.isInstance (o)) { throw new QueryExecutionException ("Expression: " + exp + " returns type: " + o.getClass ().getName () + " however must return instance of: " + expected.getName ()); } } public Double sum (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { if (saveValueName != null) { Object o = this.q.getSaveValue (saveValueName); if (o != null) { return (Double) o; } } if ((allobjs == null) || (allobjs.size () == 0) ) { return new Double (0); } double total = this.getTotal (allobjs, exp); Double d = new Double (total); if ((saveValueName != null) && (q != null) ) { this.q.setSaveValue (saveValueName, d); } return d; } public Double sum (Expression exp) throws QueryExecutionException { return this.sum ((List) this.q.getAllObjects (), exp); } public Double sum (List objs, Expression exp) throws QueryExecutionException { Class c = null; try { c = exp.getExpectedReturnType (this.q); } catch (Exception e) { throw new QueryExecutionException ("Unable to determine expected return type for expression: " + exp, e); } boolean dyn = false; if (!c.getName ().equals (Object.class.getName ())) { // Should return a number... if (!Utilities.isNumber (c)) { throw new QueryExecutionException ("This function expects the expression: " + exp + " to return a number (sub-class of: " + Number.class.getName () + ") but evaluation of the expression will return an instance of: " + c.getName ()); } } else { dyn = true; } Object co = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); this.q.setAllObjects (objs); int s = objs.size () - 1; double d = 0; for (int i = s; i > -1; i--) { Object o = objs.get (i); this.q.setCurrentObject (o); Object v = null; try { v = exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (co); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to evaluate expression: " + exp + " on item: " + i, e); } if (v == null) { // Skip... i.e. assume it's zero. continue; } if (dyn) { if (!(Utilities.isNumber (v))) { this.q.setCurrentObject (co); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Expected expression: " + exp + " to return a number (sub-class of: " + Number.class.getName () + ") but returns instance of: " + o.getClass ().getName () + " for item: " + i + " (class: " + v.getClass ().getName () + ")"); } } d += ((Number) v).doubleValue (); } this.q.setCurrentObject (co); this.q.setAllObjects (allobjs); return new Double (d); } /** * This function allows you to specify your own accessor as a string that will * be used to access the relevant value for each of the objects in the objs * List. * * @param objs The List of objects you wish to sum over. * @param acc The accessor to create for accessing the value in each of the objects in objs. * @return The summed value. * @throws QueryExecutionException If the accessor is not valid for the objects in the list or * if the accessor throws an exception. */ public Double sum (List objs, String acc) throws QueryExecutionException { if ((objs == null) || (objs.size () == 0) ) { return new Double (0); } // Get the first object. Object o = objs.get (0); Getter get = null; try { get = new Getter (acc, o.getClass ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to create accessor for: " + acc + " with class: " + o.getClass ().getName (), e); } if (!get.getType ().getName ().equals (Object.class.getName ())) { // Should return a number... if (!Utilities.isNumber (get.getType ())) { throw new QueryExecutionException ("This function expects the accessor (second parm): " + acc + " to return a number (sub-class of: " + Number.class.getName () + ") but evaluation of the accessor will return an instance of: " + get.getType ().getName ()); } } int s = objs.size () - 1; Object currobj = this.q.getCurrentObject (); List allobjs = this.q.getAllObjects (); this.q.setAllObjects (objs); double d = 0; for (int i = s; i > -1; i--) { o = objs.get (i); this.q.setCurrentObject (o); Object v = null; try { v = get.getValue (o); } catch (Exception e) { this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); throw new QueryExecutionException ("Unable to evaluate accessor: " + acc + " on item: " + i, e); } if (v == null) { // Skip... i.e. assume it's zero. continue; } d += ((Number) v).doubleValue (); } this.q.setCurrentObject (currobj); this.q.setAllObjects (allobjs); return new Double (d); } public String concat (List allobjs, Expression exp, String sep, String saveValueName) throws QueryExecutionException { if (saveValueName != null) { Object o = this.q.getSaveValue (saveValueName); if (o != null) { return (String) o; } } StringBuffer buf = new StringBuffer (); int size = allobjs.size (); int size1 = size - 1; Object currObj = this.q.getCurrentObject (); List currall = this.q.getAllObjects (); this.q.setAllObjects (allobjs); for (int i = 0; i < size; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); Object v = null; try { v = exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (currObj); this.q.setAllObjects (currall); throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for item: " + i + " from the list of objects.", e); } buf.append (v); if ((sep != null) && (i < size1) ) { buf.append (sep); } } String r = buf.toString (); if ((saveValueName != null) && (q != null) ) { q.setSaveValue (saveValueName, r); } this.q.setCurrentObject (currObj); this.q.setAllObjects (currall); return r; } public String concat (List allobjs, Expression exp, String sep) throws QueryExecutionException { return this.concat (allobjs, exp, sep, null); } public String concat (Expression exp) throws QueryExecutionException { return this.concat ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public String concat (List allobjs, Expression exp) throws QueryExecutionException { return this.concat (allobjs, exp, null, null); } public Double avg (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { if (saveValueName != null) { Object o = this.q.getSaveValue (saveValueName); if (o != null) { return (Double) o; } } if ((allobjs == null) || (allobjs.size () == 0) ) { return new Double (0); } double total = this.getTotal (allobjs, exp); double avg = total / allobjs.size (); Double d = new Double (avg); if (saveValueName != null) { q.setSaveValue (saveValueName, d); } return d; } public Double avg (Expression exp) throws QueryExecutionException { return this.avg ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public Double avg (List allobjs, Expression exp) throws QueryExecutionException { return this.avg (allobjs, exp, null); } /** * A function that will take each item from the passed in List and * determine a "count" for each item, i.e. how many times each item appears. * * @param objs The List of objects to operate on. * @return A Map of object to a count of the number of times the object appears in the list. * @throws QueryExecutionException Won't happen in this method. */ public Map occurrence (List objs) throws QueryExecutionException { return this.occurrence (objs, null); } /* public Map occurrence (Expression exp) throws QueryExecutionException { return this.occurrence ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } */ /** * A function that will take each item from the passed in List and * determine a "count" for each item, i.e. how many times each item appears. * * @param objs The List of objects to operate on. * @param exp An optional expression that should be performed on each object * and the value returned used instead. * @return A Map of object to a count of the number of times the object appears in the list. * @throws QueryExecutionException If the expression cannot be evaluated. */ public Map occurrence (List objs, Expression exp) throws QueryExecutionException { Map occs = new HashMap (); if (objs == null) { return occs; } Object currObj = this.q.getCurrentObject (); List currAll = this.q.getAllObjects (); this.q.setAllObjects (objs); int s = objs.size (); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); if (exp != null) { try { o = exp.getValue (o, this.q); } catch (Exception e) { this.q.setCurrentObject (currObj); this.q.setAllObjects (currAll); throw new QueryExecutionException ("Unable to get value for expression: " + exp + " for object: " + i + " from the list of objects.", e); } } Integer c = (Integer) occs.get (o); int co = 1; if (c != null) { co = c.intValue (); co++; } occs.put (o, Integer.valueOf (co)); } this.q.setCurrentObject (currObj); this.q.setAllObjects (currAll); return occs; } /** * This is the same as {@link #occurrence(List,Expression)} except that the * second expression should evaluate to a number that will be used to limit the * results, the occurrence count must be greater than or equal to the value from * the expression. * * @param objs The List of objects to operate on. * @param exp An optional expression that should be performed on each object * and the value returned used instead. * @param limitExp An expression that when evaluated should return a number, this * will then be used to limit the results returned to those that have an * occurrence count >= that number. * @return A Map of object to a count of the number of times the object appears in the list. * @throws QueryExecutionException If the expression cannot be evaluated or the limitExp * arg does not evaulate to a number. */ public Map occurrence (List objs, Expression exp, Expression limitExp) throws QueryExecutionException { Map rs = this.occurrence (objs, exp); // Evaluate the limit expression. Object o = limitExp.getValue (this.q.getCurrentObject (), this.q); if (!(o instanceof Number)) { throw new QueryExecutionException ("Limit expression: " + limitExp + " does not evaluate to a number"); } int i = ((Number) o).intValue (); Map ret = new HashMap (); Iterator iter = rs.entrySet ().iterator (); while (iter.hasNext ()) { Map.Entry item = (Map.Entry) iter.next (); Object k = item.getKey (); Integer c = (Integer) item.getValue (); if (c.intValue () >= i) { ret.put (k, c); } } return ret; } } josql-2.2/src/org/josql/functions/MiscellaneousFunctions.java000066400000000000000000000231451157743651500246050ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import java.io.*; import java.util.*; import java.lang.reflect.*; import com.gentlyweb.utils.Getter; import org.josql.QueryExecutionException; import org.josql.expressions.Expression; public class MiscellaneousFunctions extends AbstractFunctionHandler implements NotFixedResults { public static final String HANDLER_ID = "_internal_misc"; private Map accessorCache = new HashMap (); private Map getMethodCache = new HashMap (); private Random rand = new Random (); /** * Return the current date. * * @param zeroTime If set to true then the date returned will have it's time fields * set to zero. * @return A date object. */ public Date now (boolean zeroTime) { Date d = null; if (zeroTime) { Calendar c = Calendar.getInstance (); c.set (Calendar.HOUR_OF_DAY, 0); c.set (Calendar.MINUTE, 0); c.set (Calendar.SECOND, 0); c.set (Calendar.MILLISECOND, 0); d = c.getTime (); } else { d = new Date (); } return d; } public void cache (List allobjs, Getter get) throws QueryExecutionException { int s = allobjs.size (); for (int i = 0; i < s; i++) { Object o = allobjs.get (i); try { this.q.setSaveValue (o, get.getValue (o)); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value from accessor: " + get + " from object: " + i, e); } } } public void cache (List allobjs, Expression exp) throws QueryExecutionException { Object co = this.q.getCurrentObject (); int s = allobjs.size (); for (int i = 0; i < s; i++) { Object o = allobjs.get (i); this.q.setCurrentObject (o); try { this.q.setSaveValue (o, exp.getValue (o, q)); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value from expression: " + exp + " from object: " + i, e); } } this.q.setCurrentObject (co); } public double abs (Number d) { return Math.abs (d.doubleValue ()); } public int random () { return this.rand.nextInt (); } public int random (Number n) { return this.rand.nextInt (n.intValue ()); } public double randomDouble () { return this.rand.nextDouble (); } public Object saveValue (Object saveValueName) { return this.q.getSaveValue (saveValueName); } public Object savevalue (Object saveValueName) { return this.q.getSaveValue (saveValueName); } public Object save_value (Object saveValueName) { return this.q.getSaveValue (saveValueName); } public String fileExtension (Object f) { if (f == null) { return null; } String n = null; if (f instanceof String) { n = (String) f; } if (f instanceof File) { File fi = (File) f; if (fi.isDirectory ()) { return null; } n = ((File) f).getName (); } return n.substring (n.lastIndexOf ('.') + 1); } /** * Call the specified accessor on the object. * * @param oExp The expression to use to evaluate to get the object. * @param accExp The expression that is evaluated to get the accessor. * @return The value returned from the accessor. * @throws Exception If there is something wrong. */ public Object accessor (Expression oExp, Expression accExp) throws Exception { // Get the value for the object. Object o = null; try { o = oExp.getValue (this.q.getCurrentObject (), this.q); } catch (Exception e) { throw new QueryExecutionException ("Unable to evaluate expression: " + oExp + " to get object."); } Object a = null; try { a = accExp.getValue (this.q.getCurrentObject (), this.q); } catch (Exception e) { throw new QueryExecutionException ("Unable to evaluate expression: " + accExp + " to get accessor."); } if (a == null) { throw new QueryExecutionException ("Accessor expression: " + accExp + " evaluates to null for object: " + o + " returned from expression: " + oExp); } // Co-erce to a string. return this.accessor (o, a.toString ()); } /** * Get a property from the current object using the "get" method, if one exists, the name value * will be used as the property name. * * @param o The object to call the "get(String)" method on. * @param name The name of the property to retrieve. * @return The value of the parameter. * @throws Exception If there is something wrong. */ public Object get (String name) throws Exception { return this.get (this.q.getCurrentObject (), name); } /** * Get a property from the object using the "get" method, if one exists, the name value * will be used as the property name. * * @param o The object to call the "get(String)" method on. * @param name The name of the property to retrieve. * @return The value of the parameter. * @throws Exception If there is something wrong. */ public Object get (Object o, String name) throws Exception { if (o == null) { return null; } String cn = o.getClass ().getName (); // See if we already have the getter. Method m = (Method) this.accessorCache.get (cn); if (m == null) { Class[] argTypes = { String.class }; try { m = o.getClass ().getMethod ("get", argTypes); } catch (Exception e) { throw new QueryExecutionException ("No get method taking a single string parameter found in: " + cn); } this.getMethodCache.put (cn, m); } Object parms[] = { name }; return m.invoke (o, parms); } /** * Call the specified accessor on the object. * * @param o The object to call the accessor on. * @param acc The accessor. * @return The value returned from the accessor. * @throws Exception If there is something wrong. */ public Object accessor (Object o, String acc) throws Exception { if (o == null) { return null; } // See if we already have the getter. Getter g = (Getter) this.accessorCache.get (o.getClass ().getName () + acc); if (g == null) { // Create a new Getter for the class of the object. g = new Getter (acc, o.getClass ()); this.accessorCache.put (o.getClass ().getName () + acc, g); } return g.getValue (o); } public Object ifThen (Expression ifcond, Expression thenVal) throws QueryExecutionException { if (ifcond.isTrue (this.q.getCurrentObject (), this.q)) { return thenVal.getValue (this.q.getCurrentObject (), this.q); } return null; } public Object ifThenElse (Expression ifcond, Expression thenVal, Expression elseVal) throws QueryExecutionException { Object i = this.ifThen (ifcond, thenVal); if (i == null) { return elseVal.getValue (this.q.getCurrentObject (), this.q); } return i; } public Object eval (Expression exp) throws QueryExecutionException { return exp.getValue (this.q.getCurrentObject (), this.q); } /** * Evaluates the type expression to produce a object whose type * should be compared against the class gained from evaluation of the * clazz expression. * In effect the following is performed: *
     *   obj.getValue (q.getCurrentObject (), q)
     *     instanceof clazz.getValue (q.getCurrentObject (), q).getClass ()
     * 
*

* This is really just a thin wrapper around {@link Class#isInstance(Object)}. * * @param obj The expression that represents the object to * against. * @param clazz The expression that represents the class of the type * to compare against. * @throws QueryExecutionException If either of the expressions can't * be evaluated. */ public Boolean instanceOf (Expression obj, Expression clazz) throws QueryExecutionException { return Boolean.valueOf (clazz.getValue (this.q.getCurrentObject (), q).getClass ().isInstance (obj.getValue (this.q.getCurrentObject (), q))); } } josql-2.2/src/org/josql/functions/NotFixedResults.java000066400000000000000000000016011157743651500232040ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; /** * A marker interface that tells JoSQL that any functions within a class implementing * this interface will NOT return fixed results for fixed inputs. * * See: http://josql.sourceforge.net/manual/functions.html */ public interface NotFixedResults { } josql-2.2/src/org/josql/functions/StringFunctions.java000066400000000000000000000317231157743651500232510ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions; import java.io.File; import java.io.FileReader; import java.io.BufferedReader; import java.util.List; import java.util.ArrayList; import org.josql.functions.regexp.RegExpFactory; import org.josql.functions.regexp.RegExp; import org.josql.QueryExecutionException; /** * This class holds functions that operate on strings in some way. */ public class StringFunctions extends AbstractFunctionHandler { public static final String HANDLER_ID = "_internal_string"; private RegExpFactory regExpF = null; private void initRegExpFactory () { this.regExpF = new RegExpFactory (this.q); } /** * Match a regular expression against the object passed in. * * @param o The object to match against, toString is called on the object. * @param re The regular expression to match. * @return true if the expression matches. * @throws QueryExecutionException If the match cannot be performed, or if there is no suitable * regular expression library available to the {@link RegExpFactory}. */ public boolean regexp (Object o, String re) throws QueryExecutionException { if (this.regExpF == null) { this.initRegExpFactory (); } RegExp regexp = this.regExpF.getDefaultInstance (this.q); if (regexp == null) { throw new QueryExecutionException ("No default regular expression library available for: " + this.regExpF.getDefaultInstanceName ()); } if (o == null) { return false; } String v = o.toString (); return regexp.match (re, v); } /** * Match a regular expression against the object passed in using the specified regular expression * library, pre-defined library names can be found in: {@link RegExpFactory}. * * @param o The object to match against, toString is called on the object. * @param re The regular expression to match. * @param instName The name of the regular expression library to use. * @return true if the expression matches. * @throws QueryExecutionException If the match cannot be performed, or if the instName * regular expression library is not available to the {@link RegExpFactory}. */ public boolean regexp (Object o, String re, String instName) throws QueryExecutionException { if (this.regExpF == null) { this.initRegExpFactory (); } RegExp regexp = this.regExpF.getInstance (instName, this.q); if (regexp == null) { throw new QueryExecutionException ("No regular expression library available for: " + instName); } if (o == null) { return false; } String v = o.toString (); return regexp.match (re, v); } /** * grep * through a file, line by line, and determine what matches there are to the nominated * String. Return a List of {@link FileMatch} objects. * * @param f The File to match against. * @param s The string to match. * @param ignoreCase If set to true then the case of the line and string to * match are ignored. * @return The List of {@link FileMatch} objects. */ public List grep (File f, String s, boolean ignoreCase) throws QueryExecutionException { if ((f == null) || (!f.exists ()) || (f.isDirectory ()) || (!f.canRead ()) ) { return null; } List retData = new ArrayList (); try { BufferedReader br = new BufferedReader (new FileReader (f)); String l = br.readLine (); int lc = 1; String ss = s; if (ignoreCase) { ss = s.toLowerCase (); } while (l != null) { int ind = -1; if (ignoreCase) { ind = l.toLowerCase ().indexOf (ss); } else { ind = l.indexOf (ss); } if (ind != -1) { retData.add (new FileMatch (f, lc, ind, s, l)); } l = br.readLine (); lc++; } br.close (); } catch (Exception e) { throw new QueryExecutionException ("Unable to read from file: " + f, e); } return retData; } /** * grep * through a file, line by line, and determine what matches there are to the nominated * regular expression using the specified regular expression implementation. * Return a List of {@link FileMatch} objects. * * @param f The File to match against. * @param regexp The regular expression to match against each line. This will use the * default regular expression library. In this case the location of the match * (i.e. {@link FileMatch#getColumn()}) will be -1 since the regular expression * handling does not support location matching. Also, {@link FileMatch#getString()} * will contain the regular expression used. * @param instName The instance name to use. * @return The List of {@link FileMatch} objects. * @throws QueryExecutionException If the default regular expression implementation is not * available or if the file cannot be read. */ public List rgrep (File f, String regexp, String instName) throws QueryExecutionException { if (this.regExpF == null) { this.initRegExpFactory (); } RegExp reImpl = this.regExpF.getInstance (instName, this.q); if (reImpl == null) { throw new QueryExecutionException ("No default regular expression library available for: " + instName); } return this.rgrep (f, regexp, reImpl); } /** * grep * through a file, line by line, and determine what matches there are to the nominated * regular expression. Return a List of {@link FileMatch} objects. * * @param f The File to match against. * @param regexp The regular expression to match against each line. This will use the * default regular expression library. In this case the location of the match * (i.e. {@link FileMatch#getColumn()}) will be -1 since the regular expression * handling does not support location matching. Also, {@link FileMatch#getString()} * will contain the regular expression used. * @return The List of {@link FileMatch} objects. * @throws QueryExecutionException If the default regular expression implementation is not * available or if the file cannot be read. */ public List rgrep (File f, String regexp) throws QueryExecutionException { if (this.regExpF == null) { this.initRegExpFactory (); } RegExp reImpl = this.regExpF.getDefaultInstance (this.q); if (reImpl == null) { throw new QueryExecutionException ("No default regular expression library available for: " + this.regExpF.getDefaultInstanceName ()); } return this.rgrep (f, regexp, reImpl); } private List rgrep (File f, String regexp, RegExp reImpl) throws QueryExecutionException { if ((f == null) || (!f.exists ()) || (f.isDirectory ()) || (!f.canRead ()) ) { return null; } List retData = new ArrayList (); try { BufferedReader br = new BufferedReader (new FileReader (f)); String l = br.readLine (); int lc = 1; while (l != null) { if (reImpl.match (regexp, l)) { retData.add (new FileMatch (f, lc, -1, regexp, l)); } l = br.readLine (); lc++; } br.close (); } catch (Exception e) { throw new QueryExecutionException ("Unable to read from file: " + f, e); } return retData; } /** * grep * through a file, line by line, and determine what matches there are to the nominated * String. Return a List of {@link FileMatch} objects. * * @param f The File to match against. * @param s The string to match. * @return The List of {@link FileMatch} objects. */ public List grep (File f, String s) throws QueryExecutionException { return this.grep (f, s, false); } /** * Given a string trim the passed in string from the front and end, set v to null * to have just whitespace trimmed. Both are converted to strings first. * * @param o The string to trim. * @param v The string to trim from the front and end. Set to null to just trim * whitespace. * @return The trimmed string. */ public String trim (Object o, Object v) { if (o == null) { return null; } String os = o.toString (); if (v == null) { return os.trim (); } String vs = v.toString (); if (os.endsWith (vs)) { os = os.substring (0, vs.length ()); } if (os.startsWith (vs)) { os = os.substring (vs.length ()); } return os; } /** * A thinly veiled wrapper around the {@link String#lastIndexOf(String)} method. * Both o and i are converted to Strings and then the "lastIndexoOf" method * is called on o with i as the argument. * * @param o The string to search. * @param i The string to match. * @return The last index of i within o. If o is null then * -1 is returned. If i is null then -1 is returned. */ public double lastIndexOf (Object o, Object i) { if (o == null) { return -1; } if (i == null) { return -1; } String os = o.toString (); String is = i.toString (); return os.lastIndexOf (is); } /** * Return a substring of the passed in object (in a string form). See {@link #subStr(Object,double,double)} * for the full details since this is just a thin-wrapper around that method with the t * parameter set to -1. * * @param o The object to convert to a string and return the substring. * @param f The start index. If this is set to 0 then the entire string is returned. * @return The substring. */ public String subStr (Object o, double f) { return this.subStr (o, f, -1); } /** * A function to return a substring of a String. If the passed in object isn't * a string then it is converted to a string before processing. * * @param o The object to convert to a string and return the substring. * @param f The start index. If it's < 0 then "" is returned. If the start is out of * range of the string then "" is returned. * @param t The end index. If it's > f then it is reset to -1. If it's -1 then * it's ignored and the substring from the start is used. If the end is greater * than the length of the string then it is ignored. * @return The substring. */ public String subStr (Object o, double f, double t) { if (o == null) { return null; } int fi = (int) f; int ti = (int) t; String s = o.toString (); if ((fi < 0) || (fi > s.length ()) ) { return ""; } if ((ti < fi) || (ti > s.length ()) ) { ti = -1; } if (ti == -1) { return s.substring (fi); } return s.substring (fi, ti); } public double length (Object o) { if (o == null) { return 0; } if (o instanceof String) { return ((String) o).length (); } return o.toString ().length (); } } josql-2.2/src/org/josql/functions/regexp/000077500000000000000000000000001157743651500205335ustar00rootroot00000000000000josql-2.2/src/org/josql/functions/regexp/AbstractRegExpWrapper.java000066400000000000000000000003241157743651500256140ustar00rootroot00000000000000package org.josql.functions.regexp; import org.josql.*; public abstract class AbstractRegExpWrapper { public abstract boolean isAvailable (Query q); public abstract String getSupportedVersion (); } josql-2.2/src/org/josql/functions/regexp/ApacheRegExpWrapper.java000066400000000000000000000061141157743651500252350ustar00rootroot00000000000000package org.josql.functions.regexp; import java.util.Map; import java.util.HashMap; import org.josql.*; import java.lang.reflect.Method; public class ApacheRegExpWrapper extends AbstractRegExpWrapper implements RegExp { public static final String SUPPORTED_VERSION = "1.3"; private final String compilerClassName = "org.apache.regexp.RECompiler"; private final String matcherClassName = "org.apache.regexp.RE"; private final String programClassName = "org.apache.regexp.REProgram"; private final String compileMethName = "compile"; private final String setProgramMethName = "setProgram"; private final String matchMethName = "match"; private Method compileMeth = null; private Method setProgramMeth = null; private Method matchMeth = null; private Class compilerClass = null; private Class matcherClass = null; private Map patterns = new HashMap (); public ApacheRegExpWrapper () { } public String getSupportedVersion () { return ApacheRegExpWrapper.SUPPORTED_VERSION; } public boolean isAvailable (Query q) { try { q.loadClass (this.compilerClassName); return true; } catch (Exception e) { return false; } } public void init (Query q) throws QueryExecutionException { try { this.compilerClass = q.loadClass (this.compilerClassName); Class argTypes[] = {String.class}; this.compileMeth = this.compilerClass.getMethod (this.compileMethName, argTypes); this.matcherClass = q.loadClass (this.matcherClassName); Class pc = q.loadClass (this.programClassName); Class argTypes2[] = {pc}; this.setProgramMeth = this.matcherClass.getMethod (this.setProgramMethName, argTypes2); this.matchMeth = this.matcherClass.getMethod (this.matchMethName, argTypes); } catch (Exception e) { throw new QueryExecutionException ("Unable to init", e); } } public boolean match (String pattern, String val) throws QueryExecutionException { try { // See if we already have the pattern. Object o = this.patterns.get (pattern); if (o == null) { // Create a new compiler. Object c = this.compilerClass.newInstance (); Object args[] = {pattern}; // Compile the pattern. Object program = this.compileMeth.invoke (c, args); // Create a new RE. Object re = this.matcherClass.newInstance (); Object args2[] = {program}; // Apply the program. this.setProgramMeth.invoke (re, args2); this.patterns.put (pattern, re); o = re; } Object args[] = {val}; // Now try and match the value. return ((Boolean) this.matchMeth.invoke (o, args)).booleanValue (); } catch (Exception e) { throw new QueryExecutionException ("Unable to match value: " + val + " against pattern: " + pattern, e); } } } josql-2.2/src/org/josql/functions/regexp/GNURegExpWrapper.java000066400000000000000000000054601157743651500245100ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions.regexp; import java.util.Map; import java.util.HashMap; import org.josql.*; import java.lang.reflect.Method; import java.lang.reflect.Constructor; /** * The wrapper implementation for the GNU implementation of regular expression matching. * See: http://www.cacas.org/java/gnu/regexp/ for details. */ public class GNURegExpWrapper extends AbstractRegExpWrapper implements RegExp { public static final String SUPPORTED_VERSION = "1.1.4"; private final String reClassName = "gnu.regexp.RE"; private final String isMatchMethName = "isMatch"; private Map patterns = new HashMap (); private Constructor cons = null; private Method isMatchMeth = null; public GNURegExpWrapper () { } public String getSupportedVersion () { return GNURegExpWrapper.SUPPORTED_VERSION; } public boolean isAvailable (Query q) { try { q.loadClass (this.reClassName); return true; } catch (Exception e) { return false; } } public boolean match (String pattern, String val) throws QueryExecutionException { try { Object o = this.patterns.get (pattern); if (o == null) { Object args[] = {pattern}; o = this.cons.newInstance (args); this.patterns.put (pattern, o); } Object args[] = {val}; return ((Boolean) this.isMatchMeth.invoke (o, args)).booleanValue (); } catch (Exception e) { throw new QueryExecutionException ("Unable to match value: " + val + " against pattern: " + pattern, e); } } public void init (Query q) throws QueryExecutionException { try { // Bit easier this one! Class reClass = q.loadClass (reClassName); Class argTypes[] = {Object.class}; this.cons = reClass.getConstructor (argTypes); this.isMatchMeth = reClass.getMethod (this.isMatchMethName, argTypes); } catch (Exception e) { throw new QueryExecutionException ("Unable to init", e); } } } josql-2.2/src/org/josql/functions/regexp/OroApacheRegExpWrapper.java000066400000000000000000000073231157743651500257200ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions.regexp; import java.util.Map; import java.util.HashMap; import org.josql.*; import java.lang.reflect.Method; /** * The wrapper implementation for the Apache ORO implementation of regular expression matching. * See: http://jakarta.apache.org/oro/ for details. */ public class OroApacheRegExpWrapper extends AbstractRegExpWrapper implements RegExp { public static final String SUPPORTED_VERSION = "2.0.8"; private final String compilerClassName = "org.apache.oro.text.regex.Perl5Compiler"; private final String matcherClassName = "org.apache.oro.text.regex.Perl5Matcher"; private final String patternClassName = "org.apache.oro.text.regex.Pattern"; private final String matchesMethName = "matches"; private final String compileMethName = "compile"; private Method compileMeth = null; private Method matchesMeth = null; private Object compiler = null; private Object matcher = null; private Map patterns = new HashMap (); public OroApacheRegExpWrapper () { } public String getSupportedVersion () { return OroApacheRegExpWrapper.SUPPORTED_VERSION; } public boolean isAvailable (Query q) { try { q.loadClass (this.patternClassName); return true; } catch (Exception e) { return false; } } public boolean match (String pattern, String val) throws QueryExecutionException { try { // See if we already have the pattern. Object o = this.patterns.get (pattern); if (o == null) { Object args[] = {pattern}; // Create a new Pattern. o = this.compileMeth.invoke (this.compiler, args); this.patterns.put (pattern, o); } Object args[] = {val, o}; // Match them! return ((Boolean) this.matchesMeth.invoke (this.matcher, args)).booleanValue (); } catch (Exception e) { throw new QueryExecutionException ("Unable to match value: " + val + " against pattern: " + pattern, e); } } public void init (Query q) throws QueryExecutionException { try { Class compClass = q.loadClass (this.compilerClassName); // Create a new Compiler instance. this.compiler = compClass.newInstance (); // Get the compile(String) method. Class argTypes[] = {String.class}; this.compileMeth = compClass.getMethod (this.compileMethName, argTypes); Class matchClass = q.loadClass (this.matcherClassName); // Create a new matcher. this.matcher = matchClass.newInstance (); Class patternClass = q.loadClass (this.patternClassName); Class argTypes2[] = {String.class, patternClass}; // Get the matches(String,Pattern) method... this.matchesMeth = matchClass.getMethod (this.matchesMethName, argTypes2); } catch (Exception e) { throw new QueryExecutionException ("Unable to init", e); } } } josql-2.2/src/org/josql/functions/regexp/RegExp.java000066400000000000000000000020471157743651500225730ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions.regexp; import org.josql.*; /** * Defines a regular expression, use the {@link RegExpFactory#getDefaultInstance()} to * get the "default" instance, and then just call: {@link #match(String,String)}. */ public interface RegExp { public boolean match (String pattern, String val) throws QueryExecutionException; public void init (Query q) throws QueryExecutionException; } josql-2.2/src/org/josql/functions/regexp/RegExpFactory.java000066400000000000000000000067761157743651500241400ustar00rootroot00000000000000package org.josql.functions.regexp; import java.util.Map; import java.util.HashMap; import org.josql.*; public class RegExpFactory { /** * The instance name to use for the Java 1.4 (java.util.regex) regular expression library. * Whilst this is the default it will not be available on version of Java < 1.4. */ public static final String JAVA_INST = "java"; /** * The instance name to use for the ORO Apache regular expression library. */ public static final String ORO_INST = "oro"; /** * The instance name to use for the GNU regular expression library. */ public static final String GNU_INST = "gnu"; /** * The instance name to use for the Apache RegExp regular expression library. */ public static final String APACHE_REGEXP_INST = "apache.regexp"; private String defInst = RegExpFactory.JAVA_INST; private Map mappings = new HashMap (); private Map versions = new HashMap (); public RegExpFactory (Query q) { StandardJavaRegExpWrapper j = new StandardJavaRegExpWrapper (); if (j.isAvailable (q)) { this.mappings.put (RegExpFactory.JAVA_INST, StandardJavaRegExpWrapper.class); this.versions.put (RegExpFactory.JAVA_INST, j.getSupportedVersion ()); } OroApacheRegExpWrapper o = new OroApacheRegExpWrapper (); if (o.isAvailable (q)) { this.mappings.put (RegExpFactory.ORO_INST, OroApacheRegExpWrapper.class); this.versions.put (RegExpFactory.ORO_INST, o.getSupportedVersion ()); } GNURegExpWrapper g = new GNURegExpWrapper (); if (g.isAvailable (q)) { this.mappings.put (RegExpFactory.GNU_INST, GNURegExpWrapper.class); this.versions.put (RegExpFactory.GNU_INST, g.getSupportedVersion ()); } ApacheRegExpWrapper a = new ApacheRegExpWrapper (); if (a.isAvailable (q)) { this.mappings.put (RegExpFactory.APACHE_REGEXP_INST, ApacheRegExpWrapper.class); this.versions.put (RegExpFactory.APACHE_REGEXP_INST, a.getSupportedVersion ()); } } public String getSupportedVersion (String instName) { return (String) this.versions.get (instName); } public String getDefaultInstanceName () { return this.defInst; } public void addInstance (String name, RegExp re, boolean def) { this.mappings.put (name, re); if (def) { this.defInst = name; } } public void setDefaultInstanceName (String n) { if (!this.mappings.containsKey (n)) { throw new IllegalArgumentException ("No appropriate wrapper class found for instance name: " + n); } this.defInst = n; } public RegExp getDefaultInstance (Query q) throws QueryExecutionException { return this.getInstance (this.defInst, q); } public RegExp getInstance (String type, Query q) throws QueryExecutionException { Object o = this.mappings.get (type); if (o == null) { return null; } if (o instanceof RegExp) { // Already inited... return (RegExp) o; } Class c = (Class) o; try { RegExp re = (RegExp) c.newInstance (); re.init (q); this.mappings.put (type, re); return re; } catch (Exception e) { throw new QueryExecutionException ("Unable to init RegExp instance: " + c.getName (), e); } } } josql-2.2/src/org/josql/functions/regexp/StandardJavaRegExpWrapper.java000066400000000000000000000067771157743651500264350ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.functions.regexp; import java.util.Map; import java.util.HashMap; import org.josql.*; import java.lang.reflect.Method; /** * The wrapper implementation for the Java 1.4 regular expression matching (java.util.regex). * See: {@link java.util.regex}. */ public class StandardJavaRegExpWrapper extends AbstractRegExpWrapper implements RegExp { public static final String SUPPORTED_VERSION = "1.4"; private final String compileMethName = "compile"; private final String matcherMethName = "matcher"; private final String matchesMethName = "matches"; private final String matcherClassName = "java.util.regex.Matcher"; private final String patternClassName = "java.util.regex.Pattern"; private Method compileMeth = null; private Method matcherMeth = null; private Method matchesMeth = null; private Map patterns = new HashMap (); public StandardJavaRegExpWrapper () { } public String getSupportedVersion () { return StandardJavaRegExpWrapper.SUPPORTED_VERSION; } public boolean isAvailable (Query q) { try { q.loadClass (this.patternClassName); return true; } catch (Exception e) { return false; } } public boolean match (String pattern, String val) throws QueryExecutionException { try { // See if we already have a Pattern for this pattern. Object o = this.patterns.get (pattern); if (o == null) { Object args[] = {pattern}; // Create a new one. Static method. o = this.compileMeth.invoke (null, args); this.patterns.put (pattern, o); } Object args[] = {val}; // Now create the matcher. Object matcher = this.matcherMeth.invoke (o, args); // Now invoke the "matches" method. return ((Boolean) this.matchesMeth.invoke (matcher, null)).booleanValue (); } catch (Exception e) { throw new QueryExecutionException ("Unable to match value: " + val + " against pattern: " + pattern, e); } } public void init (Query q) throws QueryExecutionException { try { Class pc = q.loadClass (this.patternClassName); Class argTypes[] = {String.class}; // Get the "compile" method. this.compileMeth = pc.getMethod (this.compileMethName, argTypes); Class argTypes2[] = {CharSequence.class}; // Get the "matcher" method. this.matcherMeth = pc.getMethod (this.matcherMethName, argTypes2); Class mc = q.loadClass (this.matcherClassName); // Get the matches method. this.matchesMeth = mc.getMethod (this.matchesMethName, null); } catch (Exception e) { throw new QueryExecutionException ("Unable to init", e); } } } josql-2.2/src/org/josql/incubator/000077500000000000000000000000001157743651500172175ustar00rootroot00000000000000josql-2.2/src/org/josql/incubator/FilteredArrayList.java000066400000000000000000000143061157743651500234570ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.incubator; import java.util.List; import java.util.Collection; import java.util.Collections; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.QueryParseException; import org.josql.expressions.Expression; public class FilteredArrayList extends ArrayList { private Expression where = null; private Comparator orderByComp = null; private Query q = null; private Exception ex = null; private boolean noThrow = false; public FilteredArrayList (String q) throws QueryParseException { this (q, 10); } public FilteredArrayList (String q, int cap) throws QueryParseException { super (cap); this.q = new Query (); this.q.parse (q); this.where = this.q.getWhereClause (); } public FilteredArrayList (String q, Collection c) throws QueryParseException { this (q); this.addAll (c); } public FilteredArrayList (Query q) { this.q = q; } public FilteredArrayList (Query q, Collection c) { this (q); this.addAll (c); } public boolean isNoThrowOnWhereFalse () { return this.noThrow; } public void setNoThrowOnWhereFalse (boolean v) { this.noThrow = v; } public Exception getException () { return this.ex; } public Query getQuery () { return this.q; } public void resort () { if (this.orderByComp == null) { this.orderByComp = this.q.getOrderByComparator (); } if (this.orderByComp != null) { Collections.sort (this, this.orderByComp); return; } Collections.sort (this); } private boolean check (Object o) throws IllegalArgumentException { this.ex = null; if (this.where == null) { return true; } try { if (!this.where.isTrue (o, this.q)) { if (!this.noThrow) { throw new IllegalArgumentException ("Where clause: " + this.where + " evaluates to false for object cannot be added"); } return false; } return true; } catch (QueryExecutionException e) { this.ex = e; throw new IllegalArgumentException ("Where clause: " + this.where + " throws exception during execution, use: getException for details."); } } public boolean addAll (Collection c) throws IllegalArgumentException { int s = this.size () - 1; if (s < 0) { s = 0; } return this.addAll (s, c); } public boolean addAll (int index, Collection c) throws IllegalArgumentException { this.ex = null; if (c == null) { throw new NullPointerException ("Expected collection to be non-null."); } boolean change = false; int st = index; if (c instanceof List) { List l = (List) c; int s = l.size (); for (int i = 0; i < s; i++) { Object o = l.get (i); try { if (this.where.isTrue (o, this.q)) { super.add (st, o); st++; change = true; } else { if (!this.noThrow) { throw new IllegalArgumentException ("Where clause: " + this.where + " evaluates to false for object cannot be added"); } } } catch (QueryExecutionException e) { this.ex = e; throw new IllegalArgumentException ("Where clause: " + this.where + " throws exception during execution, use: getException for details."); } } } else { Iterator iter = c.iterator (); while (iter.hasNext ()) { Object o = iter.next (); try { if (this.where.isTrue (o, this.q)) { super.add (st, o); st++; change = true; } else { if (!this.noThrow) { throw new IllegalArgumentException ("Where clause: " + this.where + " evaluates to false for object cannot be added"); } } } catch (QueryExecutionException e) { this.ex = e; throw new IllegalArgumentException ("Where clause: " + this.where + " throws exception during execution, use: getException for details."); } } } return change; } public void add (int index, Object o) throws IllegalArgumentException { if (!this.check (o)) { return; } super.add (index, o); } public Object set (int index, Object o) throws IllegalArgumentException { Object oo = this.get (index); if (!this.check (o)) { return oo; } super.set (index, o); return oo; } public boolean add (Object o) throws IllegalArgumentException { if (!this.check (o)) { return false; } return super.add (o); } public boolean canAdd (Object o) throws QueryExecutionException { return this.where.isTrue (o, this.q); } public Object clone () { FilteredArrayList l = new FilteredArrayList (this.q, this); return l; } public List cloneList (Query q) { return new FilteredArrayList (q, this); } public List cloneList () { return new FilteredArrayList (this.q, this); } public FilteredArrayList cloneSelf () { return (FilteredArrayList) this.cloneList (); } public FilteredArrayList cloneSelf (Query q) { return (FilteredArrayList) this.cloneList (q); } } josql-2.2/src/org/josql/incubator/ObjectIndex.java000066400000000000000000000125771157743651500222740ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.incubator; import java.util.List; import java.util.ArrayList; import java.util.Comparator; import java.util.Collections; import com.gentlyweb.utils.Getter; /** * This is an experimental class aimed at producing an index across a * collection of homogeneous objects. It should be noted here that it is the "sorting" * of the elements in the List of objects that takes nearly all the time here. * Use the {@link #sort()} method yourself to only perform sort once. Everytime you * add an object however the sort status of the List of objects will be invalidated and * have to be re-sorted before you have retrieve the objects again. */ public class ObjectIndex implements Comparator { private List objs = new ArrayList (); private List indices = new ArrayList (); private Class c = null; private int size = -1; private boolean dirty = false; private boolean syncOnAdd = false; public ObjectIndex (Class c) { this.c = c; } public boolean isSyncOnAdd () { return this.syncOnAdd; } public void setSyncOnAdd (boolean v) { this.syncOnAdd = v; } public List getObjects (List keys) { if (this.dirty) { Collections.sort (this.objs, this); this.dirty = false; } List res = new ArrayList (); int low = 0; int os1 = this.objs.size () - 1; int high = os1; while (low <= high) { int mid = (low + high) / 2; Object o = this.objs.get (mid); int r = this.compare (o, keys); if (r != 0) { // They are not equal, so now determine whether we go "up" or "down". if (r < 0) { low = mid + 1; } else { high = mid - 1; } } else { // Add it to the list... res.add (o); int oi = mid; // Now we need to check either side for others that may // match. while (mid < os1) { mid++; o = this.objs.get (mid); r = this.compare (o, keys); if (r == 0) { res.add (o); } else { // Not equal... break; } } mid = oi; while (mid > -1) { mid--; o = this.objs.get (mid); r = this.compare (o, keys); if (r == 0) { res.add (o); } else { // Not equal... break; } } // If we are here then we've got 'em all. break; } } return res; } public int size () { return this.size; } public void sort () { Collections.sort (this.objs, this); this.dirty = false; } public void add (String name) { if (this.syncOnAdd) { Collections.sort (this.objs, this); this.dirty = false; } else { this.dirty = true; } this.indices.add (new Getter (name, this.c)); } public void removeObject (Object o) { this.objs.remove (o); } public void addObject (Object o) { if (this.objs.contains (o)) { return; } if (this.syncOnAdd) { Collections.sort (this.objs, this); this.dirty = false; } else { this.dirty = true; } this.objs.add (o); this.size = this.objs.size (); } public int compare (Object o, List keys) { try { int ks = keys.size (); for (int i = 0; i < ks; i++) { Getter g = (Getter) this.indices.get (i); Object eo1 = g.getValue (o); Object kso = keys.get (i); // Can't compare what's not there, return 0. if ((eo1 == null) || (kso == null) ) { return 0; } int v = 0; if (eo1 instanceof Comparable) { // We can use a simple compareTo. Comparable comp = (Comparable) eo1; v = comp.compareTo (kso); } else { v = eo1.toString ().compareTo (kso.toString ()); } if (v != 0) { return v; } // They are equal, so need to go to the next field... continue; } } catch (Exception e) { } // All equal. return 0; } public int compare (Object o1, Object o2) { try { for (int i = 0; i < this.size; i++) { Getter g = (Getter) this.indices.get (i); Object eo1 = g.getValue (o1); Object eo2 = g.getValue (o2); // Can't compare what's not there, return 0. if ((eo1 == null) || (eo2 == null) ) { return 0; } int v = 0; if (eo1 instanceof Comparable) { // We can use a simple compareTo. Comparable comp = (Comparable) eo1; v = comp.compareTo (eo2); } else { v = eo1.toString ().compareTo (eo2.toString ()); } if (v != 0) { return v; } // They are equal, so need to go to the next field... continue; } } catch (Exception e) { } // All equal. return 0; } } josql-2.2/src/org/josql/internal/000077500000000000000000000000001157743651500170455ustar00rootroot00000000000000josql-2.2/src/org/josql/internal/ColumnReference.java000066400000000000000000000017371157743651500227740ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; public class ColumnReference { private int index = -1; private String name = null; public void setName (String n) { this.name = n; } public String getName () { return this.name; } public int getIndex () { return this.index; } public void setIndex (int ind) { this.index = ind; } } josql-2.2/src/org/josql/internal/GroupByExpressionComparator.java000066400000000000000000000146201157743651500254120ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; import java.util.List; import java.util.ArrayList; import java.util.Comparator; import java.util.Map; import java.util.HashMap; import org.josql.expressions.Expression; import org.josql.Query; import org.josql.QueryResults; public class GroupByExpressionComparator implements Comparator { private List items = new ArrayList (); private Query q = null; private int size = 0; private int count = 0; private Exception exp = null; private Object nullObj = new Object (); private Map cache = new HashMap (); private boolean caching = false; private Comparator uc = null; public GroupByExpressionComparator (Query q, Comparator userComparator, boolean caching) { this.q = q; this.caching = caching; this.uc = userComparator; } public int getCount () { return this.count; } public boolean equals (Object o) { throw new UnsupportedOperationException ("Not supported for instances of: " + this.getClass ().getName ()); } public boolean isCaching () { return this.caching; } public void setCaching (boolean b) { this.caching = b; } public void clearCache () { this.cache.clear (); } public int ci (Object o1, Object o2) throws Exception { List lo1 = (List) o1; List lo2 = (List) o2; QueryResults qr = this.q.getQueryResults (); for (int i = 0; i < this.size; i++) { Item it = (Item) this.items.get (i); // The "current object" here will be a list, it is also the "key" // to the group by results. this.q.setAllObjects ((List) qr.getGroupByResults ().get (lo1)); this.q.setCurrentGroupByObjects (this.q.getAllObjects ()); // Also, setup the save values. this.q.setSaveValues ((Map) qr.getGroupBySaveValues (lo1)); this.q.setCurrentObject (o1); Object eo1 = null; if (it.exp != null) { eo1 = it.exp.getValue (o1, this.q); } else { eo1 = lo1.get (it.ind); } this.q.setAllObjects ((List) qr.getGroupByResults ().get (lo2)); // Also, setup the save values. this.q.setSaveValues ((Map) qr.getGroupBySaveValues (lo2)); this.q.setCurrentObject (o2); Object eo2 = null; if (it.exp != null) { eo2 = it.exp.getValue (o2, this.q); } else { eo2 = lo2.get (it.ind); } // Compare them... int c = 0; if (this.uc != null) { c = this.uc.compare (eo1, eo2); } else { c = Utilities.compare (eo1, eo2); } if (c == 0) { // Go to the next... continue; } // For speed reasons, 1 is used here rather than the constant. if (it.dir == 1) { c = -1 * c; } return c; } return 0; } public int cic (Object o1, Object o2) throws Exception { this.count++; Map co = null; boolean get = true; Item it = null; Object eo1 = null; Object eo2 = null; QueryResults qr = this.q.getQueryResults (); List lo1 = (List) o1; List lo2 = (List) o2; for (int i = 0; i < this.size; i++) { it = (Item) this.items.get (i); eo1 = null; get = true; co = (Map) cache.get (o1); if (co == null) { co = new HashMap (this.size); cache.put (o1, co); get = false; } if (get) { eo1 = co.get (it); if (eo1 == this.nullObj) { eo1 = null; } } if (eo1 == null) { this.q.setAllObjects ((List) qr.getGroupByResults ().get (lo1)); // Also, setup the save values. this.q.setSaveValues ((Map) qr.getGroupBySaveValues (lo1)); this.q.setCurrentObject (o1); if (it.exp != null) { eo1 = it.exp.getValue (o1, this.q); } else { eo1 = lo1.get (it.ind - 1); } co.put (it, eo1); } get = true; eo2 = null; co = (Map) cache.get (o2); if (co == null) { co = new HashMap (this.size); cache.put (o2, co); get = false; } if (get) { eo2 = co.get (it); } if (eo2 == null) { this.q.setAllObjects ((List) qr.getGroupByResults ().get (lo2)); // Also, setup the save values. this.q.setSaveValues ((Map) qr.getGroupBySaveValues (lo2)); this.q.setCurrentObject (o2); if (it.exp != null) { eo2 = it.exp.getValue (o2, this.q); } else { eo2 = lo2.get (it.ind - 1); } co.put (it, eo2); } // Compare them... int c = 0; if (this.uc != null) { c = this.uc.compare (eo1, eo2); } else { c = Utilities.compare (eo1, eo2); } if (c == 0) { // Go to the next... continue; } // For speed reasons, 1 is used here rather than the constant. if (it.dir == 1) { c = -1 * c; } return c; } return 0; } public int compare (Object o1, Object o2) { try { if (this.caching) { return this.cic (o1, o2); } else { return this.ci (o1, o2); } } catch (Exception e) { this.exp = e; return 0; } } public Exception getException () { return this.exp; } public void addSortItem (Expression exp, int ind, int dir) { Item it = new Item (); it.dir = dir; it.ind = ind; it.exp = exp; this.items.add (it); this.size = this.items.size (); } private class Item { public int dir = 0; public int ind = 0; public Expression exp = null; } } josql-2.2/src/org/josql/internal/Grouper.java000066400000000000000000000037371157743651500213450ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import org.josql.Query; import org.josql.QueryExecutionException; import org.josql.expressions.Expression; public class Grouper { private List cols = new ArrayList (); private Query q = null; private int cs = -1; public Grouper (Query q) { this.q = q; } public List getExpressions () { return this.cols; } public void addExpression (Expression e) { this.cols.add (e); this.cs = cols.size (); } public Map group (List objs) throws QueryExecutionException { Map retVals = new HashMap (); int s = objs.size (); List l = null; for (int j = 0; j < s; j++) { Object o = objs.get (j); this.q.setCurrentObject (o); l = new ArrayList (); // Get the values... for (int i = 0; i < this.cs; i++) { Expression exp = (Expression) this.cols.get (i); try { l.add (exp.getValue (o, this.q)); } catch (Exception e) { throw new QueryExecutionException ("Unable to get group by value for expression: " + exp, e); } } List v = (List) retVals.get (l); if (v == null) { v = new ArrayList (); retVals.put (l, v); } v.add (o); } return retVals; } } josql-2.2/src/org/josql/internal/LikePatternSymbol.java000066400000000000000000000033061157743651500233220ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; public class LikePatternSymbol { public static final int SYMBOL_F = 0; public static final int SYMBOL_E = 1; public static final int SYMBOL_A = 2; public static final int SYMBOL_N = 3; public String part = null; public int code = -1; public static LikePatternSymbol getSymbol (int code) { return new LikePatternSymbol (code); } public static LikePatternSymbol getSymbol (String part) { return new LikePatternSymbol (part); } public String toString () { return "Part: " + this.part + ", code: " + this.code; } public LikePatternSymbol (int code) { this.code = code; } public LikePatternSymbol (String part) { this.part = part; } public boolean hashCode (Object o) { return ((LikePatternSymbol) o).code == this.code; } } josql-2.2/src/org/josql/internal/Limit.java000066400000000000000000000106541157743651500207740ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; import java.util.List; import java.util.ArrayList; import org.josql.expressions.ValueExpression; import org.josql.Query; import org.josql.QueryParseException; import org.josql.QueryExecutionException; public class Limit { private ValueExpression start = null; private ValueExpression rowsCount = null; public Limit () { } public void init (Query q) throws QueryParseException { // Init the value expressions... if (this.start != null) { this.start.init (q); // Should probably check to ensure that accessors aren't used... since // we don't have a "current object" to work on!. Class c = this.start.getExpectedReturnType (q); if (!Utilities.isNumber (c)) { throw new QueryParseException ("The expected return type of the start expression: \"" + this.start + "\" of the LIMIT clause is: " + c.getName () + " however the expression when evaluated must return a numeric result."); } } this.rowsCount.init (q); // Should probably check to ensure that accessors aren't used... since // we don't have a "current object" to work on!. // Try and determine what the expected type is that we will return. Class c = this.rowsCount.getExpectedReturnType (q); if (!Utilities.isNumber (c)) { throw new QueryParseException ("The expected return type of the rows count expression: \"" + this.rowsCount + "\" of the LIMIT clause is: " + c.getName () + " however the expression when evaluated must return a numeric result."); } } public List getSubList (List objs, Query q) throws QueryExecutionException { // Get the row count. Object o = this.rowsCount.evaluate (null, q); int rows = -1; // Ensure that it is a number. if ((o != null) && (!(o instanceof Number)) ) { throw new QueryExecutionException ("Return value of rows count expression: \"" + this.rowsCount + "\" for the LIMIT clause is of type: " + o.getClass ().getName () + " expected it to return a numeric value."); } if (o != null) { // There are rounding issues here, but if the user provides a float/double value... rows = ((Number) o).intValue (); } int start = 0; // Now get the start value... if (this.start != null) { Object s = this.start.evaluate (null, q); // Ensure that it is a number. if ((s != null) && (!(s instanceof Number)) ) { throw new QueryExecutionException ("Return value of the start expression: \"" + this.start + "\" for the LIMIT clause is of type: " + s.getClass ().getName () + " expected it to return a numeric value."); } if (s != null) { // There are rounding issues here, but if the user provides a float/double value... start = ((Number) s).intValue (); // Whilst for the user rows start at 1, for us they start at 0... start--; } } int ls = objs.size (); // Now get our sub-list. if (start > (ls - 1)) { // Return nothing, outside of the range. return new ArrayList (); } if (rows > 0) { if ((start + rows) > (ls - 1)) { // Just return the rows starting at start... // We return a new list to prevent issues with modifications... return new ArrayList (objs.subList (start, ls)); } // Here we return start + rows. return new ArrayList (objs.subList (start, start + rows)); } else { // Just ignore the rows... return new ArrayList (objs.subList (start, ls)); } } public void setStart (ValueExpression v) { this.start = v; } public void setRowsCount (ValueExpression v) { this.rowsCount = v; } } josql-2.2/src/org/josql/internal/ListExpressionComparator.java000066400000000000000000000120141157743651500247310ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; import java.util.List; import java.util.ArrayList; import java.util.Comparator; import java.util.Map; import java.util.HashMap; import org.josql.expressions.Expression; import org.josql.Query; public class ListExpressionComparator implements Comparator { private List items = new ArrayList (); private Query q = null; private int size = 0; private int count = 0; private Exception exp = null; private Object nullObj = new Object (); private Map cache = new HashMap (); private boolean caching = false; private Comparator uc = null; public ListExpressionComparator (Query q, Comparator userComparator, boolean caching) { this.q = q; this.caching = caching; this.uc = userComparator; } public int getCount () { return this.count; } public boolean equals (Object o) { throw new UnsupportedOperationException ("Not supported for instances of: " + this.getClass ().getName ()); } public boolean isCaching () { return this.caching; } public void setCaching (boolean b) { this.caching = b; } public void clearCache () { this.cache.clear (); } public int ci (Object o1, Object o2) throws Exception { for (int i = 0; i < this.size; i++) { Item it = (Item) this.items.get (i); this.q.setCurrentObject (o1); Object eo1 = it.exp.getValue (o1, this.q); this.q.setCurrentObject (o2); Object eo2 = it.exp.getValue (o2, this.q); int c = 0; // Compare them... if (this.uc != null) { c = this.uc.compare (eo1, eo2); } else { c = Utilities.compare (eo1, eo2); } if (c == 0) { // Go to the next... continue; } // For speed reasons, 1 is used here rather than the constant. if (it.dir == 1) { c = -1 * c; } return c; } return 0; } public int cic (Object o1, Object o2) throws Exception { this.count++; Map co = null; boolean get = true; Item it = null; Object eo1 = null; Object eo2 = null; for (int i = 0; i < this.size; i++) { it = (Item) this.items.get (i); eo1 = null; get = true; co = (Map) cache.get (o1); if (co == null) { co = new HashMap (this.size); cache.put (o1, co); get = false; } if (get) { eo1 = co.get (it); if (eo1 == this.nullObj) { eo1 = null; } } if (eo1 == null) { this.q.setCurrentObject (o1); eo1 = it.exp.getValue (o1, this.q); co.put (it, eo1); } get = true; eo2 = null; co = (Map) cache.get (o2); if (co == null) { co = new HashMap (this.size); cache.put (o2, co); get = false; } if (get) { eo2 = co.get (it); } if (eo2 == null) { this.q.setCurrentObject (o2); eo2 = it.exp.getValue (o2, this.q); co.put (it, eo2); } // Compare them... int c = 0; if (this.uc != null) { c = this.uc.compare (eo1, eo2); } else { c = Utilities.compare (eo1, eo2); } if (c == 0) { // Go to the next... continue; } // For speed reasons, 1 is used here rather than the constant. if (it.dir == 1) { c = -1 * c; } return c; } return 0; } public int compare (Object o1, Object o2) { try { if (this.caching) { return this.cic (o1, o2); } else { return this.ci (o1, o2); } } catch (Exception e) { this.exp = e; return 0; } } public Exception getException () { return this.exp; } public List getSortItems () { return this.items; } public void addSortItem (Expression exp, int dir) { Item it = new Item (); it.dir = dir; it.exp = exp; this.items.add (it); this.size = this.items.size (); } private class Item { public int dir = 0; public Expression exp = null; } } josql-2.2/src/org/josql/internal/MethodFilter.java000066400000000000000000000065621157743651500223070ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; import java.util.List; import java.util.ArrayList; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import com.gentlyweb.utils.GeneralFilter; import com.gentlyweb.utils.FilterException; public class MethodFilter { private Class c = null; private List ps = null; private String name = null; private int type = -1; private List modifiers = null; public MethodFilter () { } public MethodFilter (Class c) { this.c = c; } public void setClass (Class c) { this.c = c; } public void addModifier (int m) { if (this.modifiers == null) { this.modifiers = new ArrayList (); } this.modifiers.add (Integer.valueOf (m)); } public List filter () throws IllegalAccessException, InvocationTargetException, FilterException { Method[] ms = this.c.getMethods (); List res = new ArrayList (); if (ms.length == 0) { return res; } GeneralFilter gf = null; if (this.name != null) { gf = new GeneralFilter (Method.class); gf.addField ("name", name, this.type); } for (int i = 0; i < ms.length; i++) { Method m = ms[i]; if (gf != null) { if (!gf.accept (m)) { continue; } } // Now check that it has the correct modifiers... if (!this.hasModifiers (m)) { continue; } // Now check the parm types. if (!this.hasParameters (m)) { continue; } res.add (m); } return res; } private boolean hasParameters (Method m) { if (this.ps == null) { return true; } // Allowing for widening of types here. Class[] mpt = m.getParameterTypes (); if (mpt.length != this.ps.size ()) { return false; } for (int i = 0; i < mpt.length; i++) { Class c = mpt[i]; Class pc = (Class) this.ps.get (i); if (pc == null) { // Skip this one because we can't compare... continue; } if (!c.isAssignableFrom (pc)) { return false; } } return true; } private boolean hasModifiers (Method m) { if (this.modifiers != null) { int mmods = m.getModifiers (); for (int i = 0; i < this.modifiers.size (); i++) { int in = ((Integer) this.modifiers.get (i)).intValue (); if ((mmods & in) == 0) { return false; } } } return true; } public void setParameterTypes (List pt) { this.ps = pt; } public void setName (String n, int type) { this.name = n; this.type = type; } } josql-2.2/src/org/josql/internal/OrderBy.java000066400000000000000000000030731157743651500212610ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; import org.josql.expressions.Expression; public class OrderBy { public static final int ASC = 0; public static final int DESC = 1; private int type = -1; private int ci = -1; private Expression exp = null; public void setExpression (Expression exp) { this.exp = exp; } public int getIndex () { return this.ci; } public Expression getExpression () { return this.exp; } public void setIndex (int ci) { this.ci = ci; } public int getType () { return this.type; } public void setType (int t) { this.type = t; } public String toString () { StringBuffer b = new StringBuffer (); if (this.ci > -1) { b.append (this.ci); } else { b.append (this.exp); } if (this.type == OrderBy.ASC) { b.append (" ASC"); } if (this.type == OrderBy.DESC) { b.append (" DESC"); } return b.toString (); } } josql-2.2/src/org/josql/internal/Setter.java000066400000000000000000000204271157743651500211630ustar00rootroot00000000000000package org.josql.internal; import java.util.*; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.StringTokenizer; import com.gentlyweb.utils.Getter; /** * This class is used to perform access into a Java object using a * String value with a specific notation. *

* The Accessor uses a dot notation such as field1.method1.method2 to * perform the access on an object. Each value in the notation refers to * a field or method (a no argument method) of the type of the previous * value. * For instance if you have the following class structure: *

*
 * public class A 
 * {
 *    public B = new B ();
 * }
 * 
 * public class B
 * {
 *    public C = new C ();
 * }
 * 
 * public class C
 * {
 *    String d = "";
 * }
 * 
*

* You would then use the notation: B.C.d to get access to * field d in Class C. *

* The Accessor also supports a [ ] notation for accessing * into Lists/Maps and Arrays. If the value between the [ ] * is an integer then we look for the associated type to be either * an array or a List, we then index into it with the integer. If * the value is NOT an integer then we use assume the * type is a Map and use it as a key into the Map. *

* For instance changing the example above: *

*
 * public class A 
 * {
 *    public List vals = new ArrayList ();
 * }
 * 
*

Method[] methods = c.getMethods (); for (int i = 0; i < methods.length; i++) { if ((methods[i].getName ().equals (getMethod.toString ())) && (methods[i].getParameterTypes ().length == 0) ) { // This is the one... return methods[i]; } } return null; * Now we could use: vals[X] where X is a positive integer. * Or changing again: *

*
 * public class A 
 * {
 *    public Map vals = new HashMap ();
 * }
 * 
*

* We could use: vals[VALUE] where VALUE would then be * used as a Key into the vals HashMap. *

* Note: The Accessor is NOT designed to be an all purpose * method of gaining access to a class. It has specific uses and for * most will be of no use at all. It should be used for general purpose * applications where you want to access specific fields of an object * without having to know the exact type. One such application is in * the GeneralComparator, in that case arbitrary Objects can * be sorted without having to write complex Comparators or implementing * the Comparable interface AND it gives the flexibility that sorting * can be changed ad-hoc. *

* The Accessor looks for in the following order: *

*

* Note: we have had to add the 3rd type to allow for methods that don't follow * JavaBeans conventions (there are loads in the standard Java APIs which makes * accessing impossible otherwise). */ public class Setter { private Getter getter = null; private Object setter = null; private Class clazz = null; /** * @param ref The reference for the setter. * @param clazz The Class to get the field from. */ public Setter (String ref, Class clazz, Class[] parmTypes) throws IllegalArgumentException, NoSuchMethodException { this.clazz = clazz; StringTokenizer t = new StringTokenizer (ref, "."); StringBuffer getRef = new StringBuffer (); if (t.countTokens () > 1) { // Get everything up to the last part. while (t.hasMoreTokens ()) { getRef.append (t.nextToken ()); if (t.countTokens () > 1) { getRef.append ('.'); } if (t.countTokens () == 1) { // Now get the Getter. this.getter = new Getter (getRef.toString (), clazz); // Get the return type from the getter. clazz = this.getter.getType (); break; } } } // Now for the final part this is the setter. String set = t.nextToken (); // Get the Fields. Field[] fields = clazz.getFields (); Field f = null; // See if the token matches... for (int i = 0; i < fields.length; i++) { if (fields[i].getName ().equals (set)) { // Found it... f = fields[i]; this.setter = f; return; } } // If we are here then it's not a public field. // Now convert it to a method name and use the // JavaBeans convention... // Now get the method... StringBuffer name = new StringBuffer (set); name.setCharAt (0, Character.toUpperCase (name.charAt (0))); name.insert (0, "set"); String nName = name.toString (); List meths = new ArrayList (); Utilities.getMethods (clazz, nName, Modifier.PUBLIC, meths); TreeMap sm = new TreeMap (); // Now compare the parm types. for (int i = 0; i < meths.size (); i++) { Method m = (Method) meths.get (i); Class[] mpts = m.getParameterTypes (); int score = Utilities.matchMethodArgs (mpts, parmTypes); if (score > 0) { sm.put (Integer.valueOf (score), m); } } // Get the last key if (sm.size () > 0) { this.setter = (Method) sm.get (sm.lastKey ()); } if (this.setter == null) { meths = new ArrayList (); Utilities.getMethods (clazz, set, Modifier.PUBLIC, meths); sm = new TreeMap (); // Now compare the parm types. for (int i = 0; i < meths.size (); i++) { Method m = (Method) meths.get (i); Class[] mpts = m.getParameterTypes (); int score = Utilities.matchMethodArgs (mpts, parmTypes); if (score > 0) { sm.put (Integer.valueOf (score), m); } } // Get the last key if (sm.size () > 0) { this.setter = (Method) sm.get (sm.lastKey ()); } } if (this.setter == null) { throw new IllegalArgumentException ("Unable to find required method: " + nName + " or: " + set + " in class: " + clazz.getName () + " taking parms: " + Arrays.toString (parmTypes)); } } public Class getBaseClass () { return this.clazz; } public void setValue (Object target, Object value) throws IllegalAccessException, InvocationTargetException, IllegalArgumentException { Object[] vals = {value}; this.setValue (target, vals); } public void setValue (Object target, Object[] values) throws IllegalAccessException, InvocationTargetException, IllegalArgumentException { // Get the object to set on from the getter. if (this.getter != null) { target = this.getter.getValue (target); } // Now call our accessor on the obj and set the value. if (this.setter instanceof Field) { Field f = (Field) this.setter; f.set (target, values[0]); return; } if (this.setter instanceof Method) { Method m = (Method) this.setter; m.invoke (target, Utilities.convertArgs (values, m.getParameterTypes ())); } } /** * Get the class of the type of object we expect in the {@link #setValue(Object,Object)} * method. * * @return The class. */ public Class getType () { // See what type the accessor is... if (this.setter instanceof Method) { Method m = (Method) this.setter; Class[] parms = m.getParameterTypes (); return parms[0]; } if (this.setter instanceof Field) { // It's a field...so... Field f = (Field) this.setter; return f.getType (); } return null; } } josql-2.2/src/org/josql/internal/Utilities.java000066400000000000000000000666061157743651500217010ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.internal; import java.util.*; import java.lang.reflect.Method; import com.gentlyweb.utils.StringUtils; public class Utilities { public static LikePatternSymbol F = LikePatternSymbol.getSymbol (LikePatternSymbol.SYMBOL_F); public static LikePatternSymbol A = LikePatternSymbol.getSymbol (LikePatternSymbol.SYMBOL_A); public static LikePatternSymbol E = LikePatternSymbol.getSymbol (LikePatternSymbol.SYMBOL_E); public static LikePatternSymbol N = LikePatternSymbol.getSymbol (LikePatternSymbol.SYMBOL_N); public static final int GT = 0; public static final int GTE = 1; public static final int LT = 2; public static final int LTE = 3; public static final int EQ = 4; private static Map pCNames = new HashMap (); private static Map primNames = new HashMap (); private static Map primCls = new HashMap (); private static Comparator objComp = null; static { Utilities.pCNames.put ("double", ""); Utilities.pCNames.put (Double.class.getName (), ""); Utilities.pCNames.put ("int", ""); Utilities.pCNames.put (Integer.class.getName (), ""); Utilities.pCNames.put ("float", ""); Utilities.pCNames.put (Float.class.getName (), ""); Utilities.pCNames.put ("long", ""); Utilities.pCNames.put (Long.class.getName (), ""); Utilities.pCNames.put ("short", ""); Utilities.pCNames.put (Short.class.getName (), ""); Utilities.pCNames.put ("byte", ""); Utilities.pCNames.put (Byte.class.getName (), ""); Utilities.pCNames.put (Number.class.getName (), ""); Utilities.primNames.put (Double.TYPE.getName (), Double.class.getName ()); Utilities.primNames.put (Double.class.getName (), Double.TYPE.getName ()); Utilities.primNames.put (Integer.TYPE.getName (), Integer.class.getName ()); Utilities.primNames.put (Integer.class.getName (), Integer.TYPE.getName ()); Utilities.primNames.put (Float.TYPE.getName (), Float.class.getName ()); Utilities.primNames.put (Float.class.getName (), Float.TYPE.getName ()); Utilities.primNames.put (Long.TYPE.getName (), Long.class.getName ()); Utilities.primNames.put (Long.class.getName (), Long.TYPE.getName ()); Utilities.primNames.put (Short.TYPE.getName (), Short.class.getName ()); Utilities.primNames.put (Short.class.getName (), Short.TYPE.getName ()); Utilities.primNames.put (Byte.TYPE.getName (), Byte.class.getName ()); Utilities.primNames.put (Byte.class.getName (), Byte.TYPE.getName ()); Utilities.primNames.put (Character.TYPE.getName (), Character.class.getName ()); Utilities.primNames.put (Character.class.getName (), Character.TYPE.getName ()); Utilities.primNames.put (Boolean.TYPE.getName (), Boolean.class.getName ()); Utilities.primNames.put (Boolean.class.getName (), Boolean.TYPE.getName ()); Utilities.primCls.put (Double.TYPE.getName (), Double.TYPE); Utilities.primCls.put (Double.class.getName (), Double.TYPE); Utilities.primCls.put (Integer.TYPE.getName (), Integer.TYPE); Utilities.primCls.put (Integer.class.getName (), Integer.TYPE); Utilities.primCls.put (Float.TYPE.getName (), Float.TYPE); Utilities.primCls.put (Float.class.getName (), Float.TYPE); Utilities.primCls.put (Long.TYPE.getName (), Long.TYPE); Utilities.primCls.put (Long.class.getName (), Long.TYPE); Utilities.primCls.put (Short.TYPE.getName (), Short.TYPE); Utilities.primCls.put (Short.class.getName (), Short.TYPE); Utilities.primCls.put (Byte.TYPE.getName (), Byte.TYPE); Utilities.primCls.put (Byte.class.getName (), Byte.TYPE); Utilities.primCls.put (Character.TYPE.getName (), Character.TYPE); Utilities.primCls.put (Character.class.getName (), Character.TYPE); Utilities.primCls.put (Boolean.TYPE.getName (), Boolean.TYPE); Utilities.primCls.put (Boolean.class.getName (), Boolean.TYPE); } public static void setObjectComparator (Comparator c) { Utilities.objComp = c; } public static Class getObjectClass (Class c) { if (c.isPrimitive ()) { String n = c.getName (); if (n.equals (Boolean.TYPE.getName ())) { return Boolean.class; } if (n.equals (Long.TYPE.getName ())) { return Long.class; } if (n.equals (Short.TYPE.getName ())) { return Short.class; } if (n.equals (Integer.TYPE.getName ())) { return Integer.class; } if (n.equals (Double.TYPE.getName ())) { return Double.class; } if (n.equals (Character.TYPE.getName ())) { return Character.class; } if (n.equals (Float.TYPE.getName ())) { return Float.class; } if (n.equals (Byte.TYPE.getName ())) { return Byte.class; } } return c; } public static Class getPrimitiveClass (Class c) { return (Class) Utilities.primCls.get (c.getName ()); } public static boolean isPrimitiveClass (Class c) { return Utilities.primNames.containsKey (c.getName ()); } public static boolean getResult (boolean v, boolean n) { if (v) { if (n) { return false; } return true; } if (n) { return true; } return false; } /** * This method encapsulates our "matching" mechanism. It handles collections correctly * and will match according to the combination of igoreCase, type and * not. * * Note: this method deliberately throws no exceptions, and it tries hard to ensure that * ClassCastExceptions and NullPointerExceptions are also NOT thrown, in other words in * theory it should be possible to compare ANY object against ANY other in safety. However * if the objects DO NOT implement comparable (and are type compatible, i.e. can r * be assigned to l) then a string comparison is performed so you may be at the mercy * of the {@link String#toString()} method of each object. In general this is not a problem * but beware of potential gotchas such as: * * SELECT * * FROM MyObject * WHERE 20 >= (SELECT value * FROM myList) * *

     * It's tempting to think here that the query will return the correct result, however this is
     * NOT true because the sub-query will return a List of Lists (with "value" as the single
     * item in each list of the sub-query results).  To make the query above work as expected you
     * should use:
     * 
     *   SELECT *
     *   FROM   MyObject
     *   // The value will be returned instead of an enclosing list.
     *   WHERE  20 >= (SELECT [*] value 
     *                 FROM   myList)
     * 
     *
     * @param l The LHS object.
     * @param r The RHS object.
     * @param ignoreCase Whether to ignore the case or not, note: setting this to true
     *                   will force a string comparison (the object to compare against will be
     *                   converted to a string via: {@link String#toString()} and then "lowered".
     * @param type The type of comparison to make, should be one of:
     *             {@link Utilities#GT}, {@link Utilities#GTE}, {@link Utilities#LT}
     *             {@link Utilities#LTE}, {@link Utilities#EQ}.
     * @param not Whether the result should be reversed.
     * @return true if l matches r given the rules defined by the 
     *         other parms, false otherwise.
     */
    public static boolean matches (Object  l,
				   Object  r,
				   boolean ignoreCase,
				   int     type,
				   boolean not)
    {

	if (l instanceof Collection)
	{

	    if (r instanceof Collection)
	    {

		Collection cl = (Collection) l;
		Collection cr = (Collection) r;

		boolean lisra = (cl instanceof List);
		boolean risra = (cr instanceof List);

		List rl = null;

		if (risra)
		{

		    rl = (List) cr;

		}

		int rs = cr.size () - 1;

		// Need to now ensure that each item in the left is >, <, >=, <=
		// than every item in the right... sigh... ;)
		if (lisra)
		{

		    List ll = (List) cl;

		    // Can go backwards for slightly faster access.
		    int s = ll.size () - 1;

		    for (int i = s; i > -1; i--)
		    {

		        l = Utilities.lowerValue (ll.get (i),
						  ignoreCase);

			if (risra)
			{

			    for (int j = rs; j > -1; j--)
			    {

				r = Utilities.lowerValue (rl.get (j),
							  ignoreCase);

				if (!Utilities.compare2 (l,
							 r,
							 type,
							 not))
				{

				    return false;

				}				

			    }

			} else {

			    Iterator it = cr.iterator ();

			    while (it.hasNext ())
			    {

				r = Utilities.lowerValue (it.next (),
							  ignoreCase);

				if (!Utilities.compare2 (l,
							 r,
							 type,
							 not))
				{

				    return false;

				}

			    }		    

			}

		    }

		} else {

		    Iterator it = cl.iterator ();

		    while (it.hasNext ())
		    {

			l = Utilities.lowerValue (it.next (),
						  ignoreCase);

			if (risra)
			{

			    for (int j = rs; j > -1; j--)
			    {

				r = Utilities.lowerValue (rl.get (j),
							  ignoreCase);

				if (!Utilities.compare2 (l,
							 r,
							 type,
							 not))
				{

				    return false;

				}

			    }

			} else {

			    Iterator itr = cr.iterator ();

			    while (itr.hasNext ())
			    {

				r = Utilities.lowerValue (itr.next (),
							  ignoreCase);

				if (!Utilities.compare2 (l,
							 r,
							 type,
							 not))
				{

				    return false;

				}		

			    }

			}    

		    }

		}

		// If we are here then it means that ALL values in the RHS
		// collection match the condition with the LHS values
		// so we return true.
		return true;

	    } else {

		// Here we need to check to ensure that ALL values in the LHS
		// collection match the condition for the single RHS value.
		Collection cl = (Collection) l;

		r = Utilities.lowerValue (r,
					  ignoreCase);

		if (cl instanceof List)
		{

		    List ll = (List) cl;

		    int ls = cl.size () - 1;

		    for (int i = ls; i > -1; i--)
		    {

			l = Utilities.lowerValue (ll.get (i),
						  ignoreCase);

			if (!Utilities.compare2 (l,
						 r,
						 type,
						 not))
			{

			    return false;

			}		

		    }

		} else {

		    Iterator cli = cl.iterator ();

		    while (cli.hasNext ())
		    {

			l = Utilities.lowerValue (cli.next (),
						  ignoreCase);

			if (!Utilities.compare2 (l,
						 r,
						 type,
						 not))
			{

			    return false;

			}		

		    }    

		}

		// All values in the LHS match the condition for the RHS
		// value.
		return true;

	    }

	} else {

	    // See if the RHS is a collection.
	    if (r instanceof Collection)
	    {

		l = Utilities.lowerValue (l,
					  ignoreCase);

		Collection cr = (Collection) r;

		if (cr instanceof List)
		{

		    List rl = (List) cr;

		    int rs = rl.size () - 1;

		    for (int i = rs; i > -1; i--)
		    {

			r = Utilities.lowerValue (rl.get (i),
						  ignoreCase);

			if (!Utilities.compare2 (l,
						 r,
						 type,
						 not))
			{

			    return false;

			}		    

		    }

		} else {

		    Iterator cri = cr.iterator ();

		    while (cri.hasNext ())
		    {

			r = Utilities.lowerValue (cri.next (),
						  ignoreCase);

			if (!Utilities.compare2 (l,
						 r,
						 type,
						 not))
			{

			    return false;

			}		

		    }    

		}

		// All values in the RHS match the condition for the LHS
		// value.
		return true;		

	    }

	}

	// Just vanilla objects, so compare.
	// Note: we perform the "lower" at this point because (from above)
	// we want to ensure that the lower is only ever performed once and
	// it's not until now that we can be sure that the objects are not collections.
	return Utilities.compare2 (Utilities.lowerValue (l,
							 ignoreCase),
				   Utilities.lowerValue (r,
							 ignoreCase),
				   type,
				   not);

    }

    private static Object lowerValue (Object  o,
				      boolean ignoreCase)
    {

	if (ignoreCase)
	{

	    o = o.toString ();
	    
	    if (o != null)
	    {

		o = ((String) o).toLowerCase ();
		
	    }

	}

	return o;

    }

    private static boolean compare2 (Object  l,
				     Object  r,
				     int     type,
				     boolean not)
    {

	int c = Utilities.compare (l,
				   r);
	
	// Use the direct values here for speed.
	
	// Check for >
	if ((type == 0)
	    &&
	    (c < 1)
	   )
	{

	    // The LHS value is equal to or less than
	    // the RHS value, but we expect >, so can safely 
	    // return false.
	    if (not)
	    {

		return true;

	    }

	    return false;
	    
	}
	
	// Check for >= or =
	if (((type == 1)
	     ||
	     (type == 4)
	    )
	    &&
	    (c < 0)
	   )
	{

	    // The RHS value is less than the LHS value
	    // but we expect >=, so can safely return false.
	    if (not)
	    {

		return true;

	    }

	    return false;
	    
	}

	// Check for <
	if ((type == 2)
	    &&
	    (c > -1)
	   )
	{

	    // The RHS value is greater than or equal to
	    // the LHS value but we expect <, so can safely return
	    // false.
	    if (not)
	    {

		return true;

	    }

	    return false;

	}

	// Check for <=
	if (((type == 3)
	     ||
	     (type == 4)
	    )
	    &&
	    (c > 0)
	   )
	{

	    // The RHS value is greater than the LHS value
	    // but we expect <=, so can safely return false.
	    if (not)
	    {

		return true;

	    }

	    return false;
	    
	}	

	if (not)
	{

	    return false;

	}

	return true;

    }

    public static int compare (Object o1,
			       Object o2)
    {

        if (Utilities.objComp != null)
        {
            
            return Utilities.objComp.compare (o1,
                                              o2);
            
        }

	if ((o1 == null)
	    &&
	    (o2 == null)
	   )
	{

	    return 0;

	}

        if ((o1 == null)
            &&
            (o2 != null)
           )
        {
            
            return 1;
            
        }

        if ((o1 != null)
            &&
            (o2 == null)
           )
        {
            
            return -1;
            
        }

	if ((o1 instanceof Number)
	    &&
	    (o2 instanceof Number)
	   )
	{

	    return Utilities.getDoubleObject (o1).compareTo (Utilities.getDoubleObject (o2));

	}

	if ((o1 instanceof Comparable)
	    &&
	    (o2 instanceof Comparable)
	    &&
	    (o1.getClass ().isAssignableFrom (o2.getClass ()))
	   )
	{

	    return ((Comparable) o1).compareTo ((Comparable) o2);

	}

	// Force a string comparison.
	String s1 = o1.toString ();
	String s2 = o2.toString ();

	return s1.compareTo (s2);

    }

    public static boolean isGTEquals (Object o1,
				      Object o2)
    {

	return Utilities.matches (o1,
				  o2,
				  false,
				  Utilities.GTE,
				  false);

    }

    public static boolean isLTEquals (Object o1,
				      Object o2)
    {

	return Utilities.matches (o1,
				  o2,
				  false,
				  Utilities.LTE,
				  false);

    }

    public static boolean isEquals (Object o1,
				    Object o2)
    {

	return Utilities.compare (o1,
				  o2) == 0;

    }

    public static Double getDoubleObject (Object o)
    {

	return new Double (Utilities.getDouble (o));

    }

    public static double getDouble (Object o)
    {

	return ((Number) o).doubleValue ();

    }

    public static boolean isNumber (Object o)
    {

	if (o == null)
	{

	    return false;

	}

	return Utilities.pCNames.containsKey (o.getClass ().getName ());

    }

    public static boolean isNumber (Class c)
    {

	return Utilities.pCNames.containsKey (c.getName ());

    }

    public static String formatSignature (String  name,
					  Class[] ps)
    {

	StringBuffer buf = new StringBuffer (name);
	buf.append ("(");
	
	if (ps != null)
	{

	    for (int i = 0; i < ps.length; i++)
	    {
		    
		buf.append (ps[i].getName ());
		
		if (i < (ps.length - 1))
		{

		    buf.append (",");
		    
		}
		
	    }
	    
	}
	
	buf.append (")");
	
	return buf.toString ();

    }

    public static boolean matchLikePattern (List    p,
					    Object  lhs,
					    boolean not,
					    boolean ignoreCase)
    {

	if (lhs instanceof Collection)
	{

	    return Utilities.matchLikePattern (p,
					       (Collection) lhs,
					       not,
					       ignoreCase);

	}

	boolean v = Utilities.matchLikePattern (p,
						lhs,
						ignoreCase);

	if ((!v)
	    &&
	    (not)
	   )
	{

	    return true;

	}

	if ((v)
	    &&
	    (not)
	   )
	{

	    return false;

	}

	return v;

    }

    public static boolean matchLikePattern (List       p,
					    Collection lhs,
					    boolean    not,
					    boolean    ignoreCase)
    {

	if (lhs instanceof List)
	{

	    int s = lhs.size () - 1;

	    List l = (List) lhs;

	    for (int i = s; i > -1; i--)
	    {

		Object o = l.get (i);

		if (!Utilities.matchLikePattern (p,
						 o,
						 ignoreCase))
		{

		    if (not)
		    {

			return true;

		    }

		    return false;

		}

	    }

	    if (not)
	    {

		return false;

	    }

	    return true;

	}

	Iterator iter = lhs.iterator ();

	while (iter.hasNext ())
	{

	    Object o = iter.next ();

	    if (!Utilities.matchLikePattern (p,
					     o,
					     ignoreCase))
	    {

		if (not)
		{

		    return true;

		}

		return false;

	    }

	}
	
	if (not)
	{

	    return false;

	}

	return true;

    }

    public static boolean matchLikePattern (List    p,
					    Object  o,
					    boolean ignoreCase)
    {

	if (o == null)
	{

	    return false;

	}

	String st = o.toString ();
	
	if (ignoreCase)
	{

	    st = st.toLowerCase ();

	}

	return Utilities.matchLikePattern (p,
					   st);

    }

    public static int getLastMatch (String value,
                                     String search,
                                     int    start)
    {

        int last = -1;

        while ((start = value.indexOf (search, start)) != -1)
        {

            last = start;
            start += search.length ();

        };

        return last;
        
    }

    public static boolean matchLikePattern (List    p,
					    String  value)
    {

	if (value == null)
	{

	    return false;

	}

        boolean accept = true;

        LikePatternSymbol c = null;
        LikePatternSymbol pm = null;        

        int currPos = 0;
        int cmdPos = 0;

	int s = p.size ();

        while (cmdPos < s)
        {

            c = (LikePatternSymbol) p.get (cmdPos);
            pm = (LikePatternSymbol) p.get (cmdPos + 1);

            if (c.equals (Utilities.F))
            {

                // if we are to find 'anything'
                // then we are done
                if (pm.equals (Utilities.A))
                {

                    break;

                }

                // otherwise search for the param
                // from the curr pos
                
                int nextPos = Utilities.getLastMatch (value,
                                                      pm.part,
                                                      currPos);
                                                   
/*
                int nextPos = value.indexOf (pm.part,
					     currPos);
*/        
                if (nextPos >= 0)
                {

                    // found it
                    currPos = nextPos + pm.part.length ();

                } else {

                    accept = false;
		    break;

                }

            } else {

                if (c.equals (Utilities.E))
                {

                    // if we are to expect 'nothing'
                    // then we MUST be at the end of the string
                    if (pm.equals (Utilities.N))
                    {

                        if (currPos != value.length ())
                        {

                            accept = false;

                        }

                        // since we expect nothing else,
                        // we must finish here
                        break;

                    } else { 

                        // otherwise, check if the expected string
                        // is at our current position
                        
                        int nextPos = Utilities.getLastMatch (value,
                                                              pm.part,
                                                              currPos);
                        
/*
                        int nextPos = value.lastIndexOf (pm.part,
						     currPos);
*/
                        if (nextPos != currPos)
                        {

                            accept = false;
                            break;

                        }

                        // if we've made it this far, then we've
                        // found what we're looking for
                        currPos += pm.part.length ();

                    }

                }

            }

            cmdPos += 2;
        }

	return accept;

    }

    public static boolean matchLikePattern (List    p,
					    String  value,
					    boolean not)
    {

	boolean accept = Utilities.matchLikePattern (p,
						     value);

	if (not)
	{

	    return !accept;

	}

	return accept;

    }

    public static List getLikePattern (String value,
				       String wildcard)
    {

	List p = new ArrayList ();

        StringTokenizer t = new StringTokenizer (value, 
						 wildcard, 
						 true);

        String tok = null;

        while (t.hasMoreTokens ())
        {

            tok = t.nextToken ();

            if (tok.equals (wildcard))
            {

                p.add (Utilities.F);
    
                if (t.hasMoreTokens ())
                {

                    tok = t.nextToken ();
                                        
                    p.add (LikePatternSymbol.getSymbol (tok));

                } else {

                    p.add (Utilities.A);

                }

            } else {

                p.add (Utilities.E);
                p.add (LikePatternSymbol.getSymbol (tok));

            }

        }

        if ((tok == null)
	    ||
	    (!tok.equals (wildcard))
	   )	    
        {

            p.add (Utilities.E);
            p.add (Utilities.N);

        }

	return p;

    }

    public static String stripQuotes (String s)
    {

	if (s == null)
	{

	    return s;

	}

	if (((s.charAt (0) == '\'')
	     &&
	     (s.charAt (s.length () - 1) == '\'')
	    )
	    ||
	    ((s.charAt (0) == '"')
	     &&
	     (s.charAt (s.length () - 1) == '"')
	    )
	   )
	{ 

	    return s.substring (1,
				s.length () - 1);

	}

	return s;

    }

    public static void getMethods (Class  c,
				   String name,
				   int    mods,
				   List   ms)
    {

	if (c == null)
	{

	    return;

	}

	Method[] meths = c.getDeclaredMethods ();

	for (int i = 0; i < meths.length; i++)
	{

	    Method m = meths[i];

	    if ((m.getName ().equals (name))
		&&
		((m.getModifiers () & mods) == mods)
	       )
	    {

		if (!ms.contains (m))
		{

		    // This is one.
		    ms.add (m);

		}

	    }

	}	

	// Now get all the super-classes.
	Class sup = c.getSuperclass ();

	if (sup != null)
	{

	    Utilities.getMethods (sup,
				  name,
				  mods,
				  ms);

	}

	// Now work up through the super-classes/interfaces.
	Class[] ints = c.getInterfaces ();

	for (int i = 0; i < ints.length; i++)
	{

	    Class in = ints[i];

	    Utilities.getMethods (in,
				  name,
				  mods,
				  ms);

	}

    }

    public static int matchMethodArgs (Class[] args,
				       Class[] compArgs)
    {

	if ((compArgs == null)
	    &&
	    (args == null)
	   )
	{

	    return 2;

	}

	if ((compArgs == null)
	    &&
	    (args.length == 0)
	   )
	{

	    return 2;

	}

	if ((compArgs == null)
	    &&
	    (args.length > 0)
	   )
	{

	    return 0;

	}

	if (args.length != compArgs.length)
	{

	    return 0;

	}

	// The score here helps in argument resolution, a more specific argument
	// match (that is NOT expression in the method args) will score higher and
	// thus is a better match.
	int score = 0;

	for (int i = 0; i < args.length; i++)
	{

	    Class c = args[i];

	    // See if the arg is object, which means "I can accept any type".
	    if (c.getClass ().getName ().equals (Object.class.getName ()))
	    {

		score += 1;

		continue;

	    }

	    Class cc = compArgs[i];

	    if (cc == null)
	    {

		// Can't match this arg.
		continue;

	    } else {

		if (c.isAssignableFrom (cc))
		{

		    score += 2;

		    continue;

		}

	    }

	    if ((Utilities.isNumber (cc))
		&&
		(Utilities.isNumber (c))
	       )
	    {

		score += 1;

		// This matches...
		continue;

	    }

	    if ((Utilities.isPrimitiveClass (c))
		&&
		(Utilities.isPrimitiveClass (cc))
	       )
	    {

		// It is a primitive class as well, so now see if they are compatible.
		if (Utilities.getPrimitiveClass (c).isAssignableFrom (Utilities.getPrimitiveClass (cc)))
		{

		    score += 1;

		    // They are assignable...
		    continue;

		}

	    }

	    // See if the type is an object... this "may" mean
	    // that we can match and it may not, it will be determined at runtime.
	    if (cc.getName ().equals (Object.class.getName ()))
	    {

		score += 1;

		continue;

	    }

	    // If we are here then we can't match this arg type...
	    // No point checking any further...
	    return 0;

	}

	// All args can be matched.
	return score;

    } 

    public static Object[] convertArgs (Object[] args,
					Class[]  argTypes)
    {

	if (args == null)
	{

	    return args;

	}

	Object[] nargs = new Object [args.length];

	for (int i = 0; i < argTypes.length; i++)
	{

	    if (Utilities.isNumber (argTypes[i]))
	    {

		Class c = Utilities.getObjectClass (argTypes[i]);

		// This arg is a number, need to now convert to the type in the args.
		Number arg = (Number) args[i];

		if (Double.class.isAssignableFrom (c))
		{

		    nargs[i] = arg;

		    continue;

		}

		if (Short.class.isAssignableFrom (c))
		{

		    nargs[i] = new Short (arg.shortValue ());

		    continue;

		}

		if (Integer.class.isAssignableFrom (c))
		{

		    nargs[i] = Integer.valueOf (arg.intValue ());

		    continue;

		}

		if (Long.class.isAssignableFrom (c))
		{

		    nargs[i] = new Long (arg.longValue ());

		    continue;

		}

		if (Float.class.isAssignableFrom (c))
		{

		    nargs[i] = new Float (arg.floatValue ());

		    continue;

		}

		if (Byte.class.isAssignableFrom (c))
		{

		    nargs[i] = new Byte (arg.byteValue ());

		    continue;

		}

	    } else {

		nargs[i] = args[i];

	    }

	}

	return nargs;

    }

    public static String unescapeString (String v)
    {
        
        v = StringUtils.replaceString (v,
                                 "\\\\",
                                 "\\");
        v = StringUtils.replaceString (v,
                                 "\\\"",
                                 "\"");
        v = StringUtils.replaceString (v,
                                 "\\'",
                                 "'");
                                 
        return v;
        
    }

}
josql-2.2/src/org/josql/parser/000077500000000000000000000000001157743651500165255ustar00rootroot00000000000000josql-2.2/src/org/josql/parser/JavaCharStream.java000066400000000000000000000350611157743651500222300ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 4.0 */
package org.josql.parser;

/**
 * An implementation of interface CharStream, where the stream is assumed to
 * contain only ASCII characters (with java-like unicode escape processing).
 */

public class JavaCharStream
{
  public static final boolean staticFlag = false;
  static final int hexval(char c) throws java.io.IOException {
    switch(c)
    {
       case '0' :
          return 0;
       case '1' :
          return 1;
       case '2' :
          return 2;
       case '3' :
          return 3;
       case '4' :
          return 4;
       case '5' :
          return 5;
       case '6' :
          return 6;
       case '7' :
          return 7;
       case '8' :
          return 8;
       case '9' :
          return 9;

       case 'a' :
       case 'A' :
          return 10;
       case 'b' :
       case 'B' :
          return 11;
       case 'c' :
       case 'C' :
          return 12;
       case 'd' :
       case 'D' :
          return 13;
       case 'e' :
       case 'E' :
          return 14;
       case 'f' :
       case 'F' :
          return 15;
    }

    throw new java.io.IOException(); // Should never come here
  }

  public int bufpos = -1;
  int bufsize;
  int available;
  int tokenBegin;
  protected int bufline[];
  protected int bufcolumn[];

  protected int column = 0;
  protected int line = 1;

  protected boolean prevCharIsCR = false;
  protected boolean prevCharIsLF = false;

  protected java.io.Reader inputStream;

  protected char[] nextCharBuf;
  protected char[] buffer;
  protected int maxNextCharInd = 0;
  protected int nextCharInd = -1;
  protected int inBuf = 0;
  protected int tabSize = 8;

  protected void setTabSize(int i) { tabSize = i; }
  protected int getTabSize(int i) { return tabSize; }

  protected void ExpandBuff(boolean wrapAround)
  {
     char[] newbuffer = new char[bufsize + 2048];
     int newbufline[] = new int[bufsize + 2048];
     int newbufcolumn[] = new int[bufsize + 2048];

     try
     {
        if (wrapAround)
        {
           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
           System.arraycopy(buffer, 0, newbuffer,
                                             bufsize - tokenBegin, bufpos);
           buffer = newbuffer;

           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
           bufline = newbufline;

           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
           bufcolumn = newbufcolumn;

           bufpos += (bufsize - tokenBegin);
        }
        else
        {
           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
           buffer = newbuffer;

           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
           bufline = newbufline;

           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
           bufcolumn = newbufcolumn;

           bufpos -= tokenBegin;
        }
     }
     catch (Throwable t)
     {
        throw new Error(t.getMessage());
     }

     available = (bufsize += 2048);
     tokenBegin = 0;
  }

  protected void FillBuff() throws java.io.IOException
  {
     int i;
     if (maxNextCharInd == 4096)
        maxNextCharInd = nextCharInd = 0;

     try {
        if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
                                            4096 - maxNextCharInd)) == -1)
        {
           inputStream.close();
           throw new java.io.IOException();
        }
        else
           maxNextCharInd += i;
        return;
     }
     catch(java.io.IOException e) {
        if (bufpos != 0)
        {
           --bufpos;
           backup(0);
        }
        else
        {
           bufline[bufpos] = line;
           bufcolumn[bufpos] = column;
        }
        throw e;
     }
  }

  protected char ReadByte() throws java.io.IOException
  {
     if (++nextCharInd >= maxNextCharInd)
        FillBuff();

     return nextCharBuf[nextCharInd];
  }

  public char BeginToken() throws java.io.IOException
  {     
     if (inBuf > 0)
     {
        --inBuf;

        if (++bufpos == bufsize)
           bufpos = 0;

        tokenBegin = bufpos;
        return buffer[bufpos];
     }

     tokenBegin = 0;
     bufpos = -1;

     return readChar();
  }     

  protected void AdjustBuffSize()
  {
     if (available == bufsize)
     {
        if (tokenBegin > 2048)
        {
           bufpos = 0;
           available = tokenBegin;
        }
        else
           ExpandBuff(false);
     }
     else if (available > tokenBegin)
        available = bufsize;
     else if ((tokenBegin - available) < 2048)
        ExpandBuff(true);
     else
        available = tokenBegin;
  }

  protected void UpdateLineColumn(char c)
  {
     column++;

     if (prevCharIsLF)
     {
        prevCharIsLF = false;
        line += (column = 1);
     }
     else if (prevCharIsCR)
     {
        prevCharIsCR = false;
        if (c == '\n')
        {
           prevCharIsLF = true;
        }
        else
           line += (column = 1);
     }

     switch (c)
     {
        case '\r' :
           prevCharIsCR = true;
           break;
        case '\n' :
           prevCharIsLF = true;
           break;
        case '\t' :
           column--;
           column += (tabSize - (column % tabSize));
           break;
        default :
           break;
     }

     bufline[bufpos] = line;
     bufcolumn[bufpos] = column;
  }

  public char readChar() throws java.io.IOException
  {
     if (inBuf > 0)
     {
        --inBuf;

        if (++bufpos == bufsize)
           bufpos = 0;

        return buffer[bufpos];
     }

     char c;

     if (++bufpos == available)
        AdjustBuffSize();

     if ((buffer[bufpos] = c = ReadByte()) == '\\')
     {
        UpdateLineColumn(c);

        int backSlashCnt = 1;

        for (;;) // Read all the backslashes
        {
           if (++bufpos == available)
              AdjustBuffSize();

           try
           {
              if ((buffer[bufpos] = c = ReadByte()) != '\\')
              {
                 UpdateLineColumn(c);
                 // found a non-backslash char.
                 if ((c == 'u') && ((backSlashCnt & 1) == 1))
                 {
                    if (--bufpos < 0)
                       bufpos = bufsize - 1;

                    break;
                 }

                 backup(backSlashCnt);
                 return '\\';
              }
           }
           catch(java.io.IOException e)
           {
              if (backSlashCnt > 1)
                 backup(backSlashCnt);

              return '\\';
           }

           UpdateLineColumn(c);
           backSlashCnt++;
        }

        // Here, we have seen an odd number of backslash's followed by a 'u'
        try
        {
           while ((c = ReadByte()) == 'u')
              ++column;

           buffer[bufpos] = c = (char)(hexval(c) << 12 |
                                       hexval(ReadByte()) << 8 |
                                       hexval(ReadByte()) << 4 |
                                       hexval(ReadByte()));

           column += 4;
        }
        catch(java.io.IOException e)
        {
           throw new Error("Invalid escape character at line " + line +
                                         " column " + column + ".");
        }

        if (backSlashCnt == 1)
           return c;
        else
        {
           backup(backSlashCnt - 1);
           return '\\';
        }
     }
     else
     {
        UpdateLineColumn(c);
        return (c);
     }
  }

  /**
   * @deprecated 
   * @see #getEndColumn
   */

  public int getColumn() {
     return bufcolumn[bufpos];
  }

  /**
   * @deprecated 
   * @see #getEndLine
   */

  public int getLine() {
     return bufline[bufpos];
  }

  public int getEndColumn() {
     return bufcolumn[bufpos];
  }

  public int getEndLine() {
     return bufline[bufpos];
  }

  public int getBeginColumn() {
     return bufcolumn[tokenBegin];
  }

  public int getBeginLine() {
     return bufline[tokenBegin];
  }

  public void backup(int amount) {

    inBuf += amount;
    if ((bufpos -= amount) < 0)
       bufpos += bufsize;
  }

  public JavaCharStream(java.io.Reader dstream,
                 int startline, int startcolumn, int buffersize)
  {
    inputStream = dstream;
    line = startline;
    column = startcolumn - 1;

    available = bufsize = buffersize;
    buffer = new char[buffersize];
    bufline = new int[buffersize];
    bufcolumn = new int[buffersize];
    nextCharBuf = new char[4096];
  }

  public JavaCharStream(java.io.Reader dstream,
                                        int startline, int startcolumn)
  {
     this(dstream, startline, startcolumn, 4096);
  }

  public JavaCharStream(java.io.Reader dstream)
  {
     this(dstream, 1, 1, 4096);
  }
  public void ReInit(java.io.Reader dstream,
                 int startline, int startcolumn, int buffersize)
  {
    inputStream = dstream;
    line = startline;
    column = startcolumn - 1;

    if (buffer == null || buffersize != buffer.length)
    {
      available = bufsize = buffersize;
      buffer = new char[buffersize];
      bufline = new int[buffersize];
      bufcolumn = new int[buffersize];
      nextCharBuf = new char[4096];
    }
    prevCharIsLF = prevCharIsCR = false;
    tokenBegin = inBuf = maxNextCharInd = 0;
    nextCharInd = bufpos = -1;
  }

  public void ReInit(java.io.Reader dstream,
                                        int startline, int startcolumn)
  {
     ReInit(dstream, startline, startcolumn, 4096);
  }

  public void ReInit(java.io.Reader dstream)
  {
     ReInit(dstream, 1, 1, 4096);
  }
  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
  {
     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
  }

  public JavaCharStream(java.io.InputStream dstream, int startline,
  int startcolumn, int buffersize)
  {
     this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
  }

  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
                        int startcolumn) throws java.io.UnsupportedEncodingException
  {
     this(dstream, encoding, startline, startcolumn, 4096);
  }

  public JavaCharStream(java.io.InputStream dstream, int startline,
                        int startcolumn)
  {
     this(dstream, startline, startcolumn, 4096);
  }

  public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
  {
     this(dstream, encoding, 1, 1, 4096);
  }

  public JavaCharStream(java.io.InputStream dstream)
  {
     this(dstream, 1, 1, 4096);
  }

  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
  {
     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
  }

  public void ReInit(java.io.InputStream dstream, int startline,
  int startcolumn, int buffersize)
  {
     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
  }
  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
                     int startcolumn) throws java.io.UnsupportedEncodingException
  {
     ReInit(dstream, encoding, startline, startcolumn, 4096);
  }
  public void ReInit(java.io.InputStream dstream, int startline,
                     int startcolumn)
  {
     ReInit(dstream, startline, startcolumn, 4096);
  }
  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
  {
     ReInit(dstream, encoding, 1, 1, 4096);
  }

  public void ReInit(java.io.InputStream dstream)
  {
     ReInit(dstream, 1, 1, 4096);
  }

  public String GetImage()
  {
     if (bufpos >= tokenBegin)
        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
     else
        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
                              new String(buffer, 0, bufpos + 1);
  }

  public char[] GetSuffix(int len)
  {
     char[] ret = new char[len];

     if ((bufpos + 1) >= len)
        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
     else
     {
        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
                                                          len - bufpos - 1);
        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
     }

     return ret;
  }

  public void Done()
  {
     nextCharBuf = null;
     buffer = null;
     bufline = null;
     bufcolumn = null;
  }

  /**
   * Method to adjust line and column numbers for the start of a token.
   */
  public void adjustBeginLineColumn(int newLine, int newCol)
  {
     int start = tokenBegin;
     int len;

     if (bufpos >= tokenBegin)
     {
        len = bufpos - tokenBegin + inBuf + 1;
     }
     else
     {
        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
     }

     int i = 0, j = 0, k = 0;
     int nextColDiff = 0, columnDiff = 0;

     while (i < len &&
            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
     {
        bufline[j] = newLine;
        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
        bufcolumn[j] = newCol + columnDiff;
        columnDiff = nextColDiff;
        i++;
     } 

     if (i < len)
     {
        bufline[j] = newLine++;
        bufcolumn[j] = newCol + columnDiff;

        while (i++ < len)
        {
           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
              bufline[j] = newLine++;
           else
              bufline[j] = newLine;
        }
     }

     line = bufline[j];
     column = bufcolumn[j];
  }

}
josql-2.2/src/org/josql/parser/JoSQLParser.java000066400000000000000000003270641157743651500215110ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. JoSQLParser.java */
package org.josql.parser;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import org.josql.Query;

import org.josql.internal.OrderBy;
import org.josql.internal.Limit;
import org.josql.internal.Utilities;
import org.josql.internal.ColumnReference;

import org.josql.expressions.*;

/**
 * The parser generated by JavaCC
 */
public class JoSQLParser implements JoSQLParserConstants {

  final public BindVariable BindVariable() throws ParseException {
  Token t = null;
  BindVariable result = new BindVariable ();
  String prefix = "";
  String acc = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 48:
      jj_consume_token(48);
      t = KeywordName();
                            result.setName (t.image);
      break;
    case 49:
      jj_consume_token(49);
      t = jj_consume_token(S_IDENTIFIER);
                              prefix = "_";  result.setName (prefix + t.image);
      break;
    case 50:
      jj_consume_token(50);
          result.setAnonymous (true);
      break;
    default:
      jj_la1[0] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 51:
      jj_consume_token(51);
      acc = Name();
                        result.setAccessor (acc);
      break;
    default:
      jj_la1[1] = jj_gen;
      ;
    }
      {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public SaveValue SaveValue() throws ParseException {
  Token t = null;
  SaveValue result = new SaveValue ();
  String v = null;
  String acc = null;
    jj_consume_token(52);
    t = KeywordName();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 51:
      jj_consume_token(51);
      acc = Name();
                                              result.setAccessor (acc);
      break;
    default:
      jj_la1[2] = jj_gen;
      ;
    }
      result.setName (t.image);

      {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public void parseQuery(Query q) throws ParseException {
    Query(q);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 53:
      jj_consume_token(53);
      break;
    default:
      jj_la1[3] = jj_gen;
      ;
    }
    jj_consume_token(0);
  }

  final public String Name() throws ParseException {
  StringBuffer v = new StringBuffer ();
  Token val = null;
    // Is in form... name.name.name
       val = KeywordName();
                          v.append (val.image);
    label_1:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 51:
        ;
        break;
      default:
        jj_la1[4] = jj_gen;
        break label_1;
      }
      jj_consume_token(51);
          v.append (".");
      val = KeywordName();
                          v.append (val.image);
    }
     {if (true) return v.toString ();}
    throw new Error("Missing return statement in function");
  }

  final public Token KeywordName() throws ParseException {
  Token t = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
      t = jj_consume_token(K_AS);
      break;
    case K_BY:
      t = jj_consume_token(K_BY);
      break;
    case K_IS:
      t = jj_consume_token(K_IS);
      break;
    case K_IN:
      t = jj_consume_token(K_IN);
      break;
    case K_OR:
      t = jj_consume_token(K_OR);
      break;
    case K_ON:
      t = jj_consume_token(K_ON);
      break;
    case K_ALL:
      t = jj_consume_token(K_ALL);
      break;
    case K_AND:
      t = jj_consume_token(K_AND);
      break;
    case K_NOT:
      t = jj_consume_token(K_NOT);
      break;
    case K_ASC:
      t = jj_consume_token(K_ASC);
      break;
    case K_DESC:
      t = jj_consume_token(K_DESC);
      break;
    case K_LIKE:
      t = jj_consume_token(K_LIKE);
      break;
    case K_INLIKE:
      t = jj_consume_token(K_INLIKE);
      break;
    case K_WHERE:
      t = jj_consume_token(K_WHERE);
      break;
    case K_GROUP:
      t = jj_consume_token(K_GROUP);
      break;
    case K_LIMIT:
      t = jj_consume_token(K_LIMIT);
      break;
    case K_ORDER:
      t = jj_consume_token(K_ORDER);
      break;
    case K_SELECT:
      t = jj_consume_token(K_SELECT);
      break;
    case K_DISTINCT:
      t = jj_consume_token(K_DISTINCT);
      break;
    case K_NEW:
      t = jj_consume_token(K_NEW);
      break;
    case K_TRUE:
      t = jj_consume_token(K_TRUE);
      break;
    case K_FALSE:
      t = jj_consume_token(K_FALSE);
      break;
    case K_HAVING:
      t = jj_consume_token(K_HAVING);
      break;
    case K_BETWEEN:
      t = jj_consume_token(K_BETWEEN);
      break;
    case K_USE:
      t = jj_consume_token(K_USE);
      break;
    case K_EXECUTE:
      t = jj_consume_token(K_EXECUTE);
      break;
    case K_RESULTS:
      t = jj_consume_token(K_RESULTS);
      break;
    case K_WHERE_RESULTS:
      t = jj_consume_token(K_WHERE_RESULTS);
      break;
    case K_HAVING_RESULTS:
      t = jj_consume_token(K_HAVING_RESULTS);
      break;
    case K_GROUP_BY_RESULTS:
      t = jj_consume_token(K_GROUP_BY_RESULTS);
      break;
    case S_IDENTIFIER:
      t = jj_consume_token(S_IDENTIFIER);
      break;
    default:
      jj_la1[5] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  {if (true) return t;}
    throw new Error("Missing return statement in function");
  }

/*
String MultiName():
{

  StringBuffer v = new StringBuffer ();
  Token val = null;
  
}
{

  // Is in form... name[name.name]
  val = Name()
  [ "[" [  |  ] val = PrimaryExpression() "]" { v.append (val.image); } ]
  {

     return v.toString ();

  }

} 
*/
  final public String RelObjectName() throws ParseException {
        Token tk = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
    case K_BY:
    case K_IS:
    case K_IN:
    case K_OR:
    case K_ON:
    case K_ALL:
    case K_AND:
    case K_NOT:
    case K_ASC:
    case K_DESC:
    case K_LIKE:
    case K_INLIKE:
    case K_WHERE:
    case K_GROUP:
    case K_LIMIT:
    case K_ORDER:
    case K_SELECT:
    case K_HAVING:
    case K_BETWEEN:
    case K_DISTINCT:
    case K_USE:
    case K_TRUE:
    case K_FALSE:
    case K_EXECUTE:
    case K_RESULTS:
    case K_WHERE_RESULTS:
    case K_HAVING_RESULTS:
    case K_GROUP_BY_RESULTS:
    case K_NEW:
    case S_IDENTIFIER:
      tk = KeywordName();
      break;
    case S_CHAR_LITERAL:
      tk = jj_consume_token(S_CHAR_LITERAL);
      break;
    case S_CHAR_LITERAL2:
      tk = jj_consume_token(S_CHAR_LITERAL2);
      break;
    default:
      jj_la1[6] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
      {if (true) return tk.image;}
    throw new Error("Missing return statement in function");
  }

  final public void Query(Query q) throws ParseException {
        List cols = null;
        List fromItems = null;
        List joins = null;
        Expression where = null;
        List orderBys = null;
        List groupOrderBys = null;
        List groupBys = null;
        Expression having = null;
        Limit limit = null;
        Limit grpLimit = null;
        Expression from = null;
        Map execute = null;
        boolean distinct = false;
    jj_consume_token(K_SELECT);
    if (jj_2_1(2)) {
      jj_consume_token(K_DISTINCT);
                                              q.setWantDistinctResults (true);
    } else {
      ;
    }
    cols = SelectItemsList(q);
    from = From();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_WHERE:
      where = WhereClause();
      break;
    default:
      jj_la1[7] = jj_gen;
      ;
    }
    if (jj_2_2(2)) {
      groupBys = GroupBys();
    } else {
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_HAVING:
      having = Having();
      break;
    default:
      jj_la1[8] = jj_gen;
      ;
    }
    if (jj_2_3(2147483647)) {
      groupOrderBys = GroupOrderBys();
    } else {
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_ORDER:
      orderBys = OrderBys();
      break;
    default:
      jj_la1[9] = jj_gen;
      ;
    }
    if (jj_2_4(2147483647)) {
      grpLimit = GroupLimit();
    } else {
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_LIMIT:
      limit = Limit();
      break;
    default:
      jj_la1[10] = jj_gen;
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_EXECUTE:
      execute = ExecuteOn();
      break;
    default:
      jj_la1[11] = jj_gen;
      ;
    }
      // We set all the values since they are all dependent on the class 
      // being available.
      q.setFrom (from);
      q.setColumns (cols);
      q.setWhere (where);
      q.setHaving (having);
      q.setGroupByOrderColumns (groupOrderBys);
      q.setOrderByColumns (orderBys);
      q.setGroupByColumns (groupBys);
      q.setGroupByLimit (grpLimit);
      q.setLimit (limit);
      q.setExecuteOnFunctions (execute);
  }

  final public Map ExecuteOn() throws ParseException {
   Map et = new HashMap ();
    label_2:
    while (true) {
      jj_consume_token(K_EXECUTE);
      jj_consume_token(K_ON);
      et = ExecuteOnType(et);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case K_EXECUTE:
        ;
        break;
      default:
        jj_la1[12] = jj_gen;
        break label_2;
      }
    }
      {if (true) return et;}
    throw new Error("Missing return statement in function");
  }

  final public Map ExecuteOnType(Map execOn) throws ParseException {
   List el = null;
   String type = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_ALL:
      jj_consume_token(K_ALL);
              type = Query.ALL;
      break;
    case K_RESULTS:
      jj_consume_token(K_RESULTS);
                  type = Query.RESULTS;
      break;
    case K_WHERE_RESULTS:
      jj_consume_token(K_WHERE_RESULTS);
                        type = Query.RESULTS;
      break;
    case K_HAVING_RESULTS:
      jj_consume_token(K_HAVING_RESULTS);
                         type = Query.HAVING_RESULTS;
      break;
    case K_GROUP_BY_RESULTS:
      jj_consume_token(K_GROUP_BY_RESULTS);
                           type = Query.GROUP_BY_RESULTS;
      break;
    default:
      jj_la1[13] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    el = AliasedSQLExpressionList();
      List fs = (List) execOn.get (type);

      if (fs != null)
      {

         fs.addAll (el);

      } else {

         execOn.put (type,
                     el);

      }
      {if (true) return execOn;}
    throw new Error("Missing return statement in function");
  }

  final public List SelectItemsList(Query q) throws ParseException {
        List selectItemsList = new ArrayList();
        SelectItemExpression si = null;
    si = SelectItem(q);
                         if (si != null) { selectItemsList.add (si); }
    label_3:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 54:
        ;
        break;
      default:
        jj_la1[14] = jj_gen;
        break label_3;
      }
      jj_consume_token(54);
      si = SelectItem(q);
                                                                                                   if (si != null) { selectItemsList.add (si); }
    }
      {if (true) return selectItemsList;}
    throw new Error("Missing return statement in function");
  }

  final public List FunctionList() throws ParseException {
        List fList = new ArrayList();
        AliasedFunction f = null;
        String alias = null;
    f = AliasedFunction();
                            fList.add (f);
    label_4:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 54:
        ;
        break;
      default:
        jj_la1[15] = jj_gen;
        break label_4;
      }
      jj_consume_token(54);
      f = AliasedFunction();
                                                                          fList.add (f);
    }
      {if (true) return fList;}
    throw new Error("Missing return statement in function");
  }

  final public AliasedFunction AliasedFunction() throws ParseException {
   AliasedFunction af = new AliasedFunction ();
   String alias = null;
   Function f = null;
    f = Function();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
    case K_BY:
    case K_IS:
    case K_IN:
    case K_OR:
    case K_ON:
    case K_ALL:
    case K_AND:
    case K_NOT:
    case K_ASC:
    case K_DESC:
    case K_LIKE:
    case K_INLIKE:
    case K_WHERE:
    case K_GROUP:
    case K_LIMIT:
    case K_ORDER:
    case K_SELECT:
    case K_HAVING:
    case K_BETWEEN:
    case K_DISTINCT:
    case K_USE:
    case K_TRUE:
    case K_FALSE:
    case K_EXECUTE:
    case K_RESULTS:
    case K_WHERE_RESULTS:
    case K_HAVING_RESULTS:
    case K_GROUP_BY_RESULTS:
    case K_NEW:
    case S_IDENTIFIER:
    case S_CHAR_LITERAL:
    case S_CHAR_LITERAL2:
      alias = Alias();
      break;
    default:
      jj_la1[16] = jj_gen;
      ;
    }
      af.setAlias (alias);
      af.setExpression (f);

      {if (true) return af;}
    throw new Error("Missing return statement in function");
  }

  final public SelectItemExpression SelectItem(Query q) throws ParseException {
        String alias = null;
        SelectItemExpression csei = null;
        Expression expression = null;
        boolean addItemsFromColl = false;
        Token addItemType = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 55:
      jj_consume_token(55);
            q.setWantObjects (true); {if (true) return null;}
      break;
    case K_AS:
    case K_BY:
    case K_IS:
    case K_IN:
    case K_OR:
    case K_ON:
    case K_ALL:
    case K_AND:
    case K_NOT:
    case K_ASC:
    case K_DESC:
    case K_NULL:
    case K_LIKE:
    case K_INLIKE:
    case K_WHERE:
    case K_GROUP:
    case K_LIMIT:
    case K_ORDER:
    case K_SELECT:
    case K_HAVING:
    case K_BETWEEN:
    case K_DISTINCT:
    case K_USE:
    case K_TRUE:
    case K_FALSE:
    case K_EXECUTE:
    case K_RESULTS:
    case K_WHERE_RESULTS:
    case K_HAVING_RESULTS:
    case K_GROUP_BY_RESULTS:
    case K_NEW:
    case S_IDENTIFIER:
    case S_CHAR_LITERAL:
    case S_CHAR_LITERAL2:
    case S_DOUBLE:
    case S_INTEGER:
    case 48:
    case 49:
    case 50:
    case 52:
    case 56:
    case 58:
    case 70:
    case 71:
      if (jj_2_5(2)) {
        jj_consume_token(56);
        jj_consume_token(55);
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case 54:
          jj_consume_token(54);
          addItemType = KeywordName();
          break;
        default:
          jj_la1[17] = jj_gen;
          ;
        }
        jj_consume_token(57);
                                                                     addItemsFromColl = true;
      } else {
        ;
      }
      expression = ExpressionList();
                                                                                                                                  csei = new SelectItemExpression (); csei.setExpression (expression);
      if (jj_2_6(2)) {
        alias = Alias();
                                        csei.setAlias (alias);
      } else {
        ;
      }
      break;
    default:
      jj_la1[18] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
            if (addItemsFromColl)
            {

               csei.setAddItemsType (java.util.Collection.class);

               if (addItemType != null)
               {

                  csei.setAddMapType (addItemType.image);
                  csei.setAddItemsType (java.util.Map.class);

               }

            }

            {if (true) return csei;}
    throw new Error("Missing return statement in function");
  }

  final public NewObjectExpression NewObjectExpression() throws ParseException {
   String setterName = null;
   String className = null;
   List conArgs = null;
   Expression expression = null;

   NewObjectExpression noe = new NewObjectExpression ();
    jj_consume_token(K_NEW);
            noe = new NewObjectExpression ();
    className = Name();
                                                                     noe.setClassName (className);
    jj_consume_token(58);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
    case K_BY:
    case K_IS:
    case K_IN:
    case K_OR:
    case K_ON:
    case K_ALL:
    case K_AND:
    case K_NOT:
    case K_ASC:
    case K_DESC:
    case K_NULL:
    case K_LIKE:
    case K_INLIKE:
    case K_WHERE:
    case K_GROUP:
    case K_LIMIT:
    case K_ORDER:
    case K_SELECT:
    case K_HAVING:
    case K_BETWEEN:
    case K_DISTINCT:
    case K_USE:
    case K_TRUE:
    case K_FALSE:
    case K_EXECUTE:
    case K_RESULTS:
    case K_WHERE_RESULTS:
    case K_HAVING_RESULTS:
    case K_GROUP_BY_RESULTS:
    case K_NEW:
    case S_IDENTIFIER:
    case S_CHAR_LITERAL:
    case S_CHAR_LITERAL2:
    case S_DOUBLE:
    case S_INTEGER:
    case 48:
    case 49:
    case 50:
    case 52:
    case 56:
    case 58:
    case 70:
    case 71:
      conArgs = SQLExpressionList();
                                                                                                                                           noe.setConstructorArgs (conArgs);
      break;
    default:
      jj_la1[19] = jj_gen;
      ;
    }
    jj_consume_token(59);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 60:
      jj_consume_token(60);
      expression = ExpressionList();
      jj_consume_token(K_INTO);
      setterName = Name();
                                                                     noe.addIntoExpression (expression, setterName);
      label_5:
      while (true) {
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case 54:
          ;
          break;
        default:
          jj_la1[20] = jj_gen;
          break label_5;
        }
        jj_consume_token(54);
        expression = ExpressionList();
        jj_consume_token(K_INTO);
        setterName = Name();
                                                                         noe.addIntoExpression (expression, setterName);
      }
      jj_consume_token(61);
      break;
    default:
      jj_la1[21] = jj_gen;
      ;
    }
      {if (true) return noe;}
    throw new Error("Missing return statement in function");
  }

  final public String Alias() throws ParseException {
  String retval = null;
    if (jj_2_7(2)) {
      jj_consume_token(K_AS);
    } else {
      ;
    }
    retval = RelObjectName();
     {if (true) return retval;}
    throw new Error("Missing return statement in function");
  }

  final public Expression From() throws ParseException {
   String cn = null;
   Expression from = null;
    jj_consume_token(K_FROM);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 48:
    case 49:
    case 50:
      from = BindVariable();
      break;
    case 52:
      from = SaveValue();
      break;
    default:
      jj_la1[23] = jj_gen;
      if (jj_2_8(3)) {
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case K_NULL:
          jj_consume_token(K_NULL);
                  cn = "null";
          break;
        case K_AS:
        case K_BY:
        case K_IS:
        case K_IN:
        case K_OR:
        case K_ON:
        case K_ALL:
        case K_AND:
        case K_NOT:
        case K_ASC:
        case K_DESC:
        case K_LIKE:
        case K_INLIKE:
        case K_WHERE:
        case K_GROUP:
        case K_LIMIT:
        case K_ORDER:
        case K_SELECT:
        case K_HAVING:
        case K_BETWEEN:
        case K_DISTINCT:
        case K_USE:
        case K_TRUE:
        case K_FALSE:
        case K_EXECUTE:
        case K_RESULTS:
        case K_WHERE_RESULTS:
        case K_HAVING_RESULTS:
        case K_GROUP_BY_RESULTS:
        case K_NEW:
        case S_IDENTIFIER:
          cn = Name();
          break;
        default:
          jj_la1[22] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
       ConstantExpression ce = new ConstantExpression (); from = ce; ce.setValue (cn);
      } else if (jj_2_9(3)) {
        from = Function();
      } else {
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
      {if (true) return from;}
    throw new Error("Missing return statement in function");
  }

  final public Expression WhereClause() throws ParseException {
        Expression retval = null;
    jj_consume_token(K_WHERE);
    retval = ExpressionList();
      {if (true) return retval;}
    throw new Error("Missing return statement in function");
  }

  final public List GroupBys() throws ParseException {
        List groupBys = new ArrayList();
        OrderBy ob = null;
    jj_consume_token(K_GROUP);
    jj_consume_token(K_BY);
    ob = OrderBy();
                                      groupBys.add (ob);
    label_6:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 54:
        ;
        break;
      default:
        jj_la1[24] = jj_gen;
        break label_6;
      }
      jj_consume_token(54);
      ob = OrderBy();
                              groupBys.add (ob);
    }
        {if (true) return groupBys;}
    throw new Error("Missing return statement in function");
  }

  final public Expression Having() throws ParseException {
        Expression having = null;
    jj_consume_token(K_HAVING);
    having = ExpressionList();
                {if (true) return having;}
    throw new Error("Missing return statement in function");
  }

  final public List OrderBys() throws ParseException {
   List orderBys = new ArrayList ();
   OrderBy ob = null;
    jj_consume_token(K_ORDER);
    jj_consume_token(K_BY);
    ob = OrderBy();
                                      orderBys.add (ob);
    label_7:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 54:
        ;
        break;
      default:
        jj_la1[25] = jj_gen;
        break label_7;
      }
      jj_consume_token(54);
      ob = OrderBy();
                              orderBys.add (ob);
    }
        {if (true) return orderBys;}
    throw new Error("Missing return statement in function");
  }

  final public List GroupOrderBys() throws ParseException {
   List orderBys = new ArrayList ();
   OrderBy ob = null;
    jj_consume_token(K_GROUP);
    jj_consume_token(K_BY);
    jj_consume_token(K_ORDER);
    ob = OrderBy();
                                                orderBys.add (ob);
    label_8:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 54:
        ;
        break;
      default:
        jj_la1[26] = jj_gen;
        break label_8;
      }
      jj_consume_token(54);
      ob = OrderBy();
                              orderBys.add (ob);
    }
        {if (true) return orderBys;}
    throw new Error("Missing return statement in function");
  }

  final public OrderBy OrderBy() throws ParseException {
   OrderBy oe = new OrderBy ();
   String acc = null;
   Token ci = null;
   int cInt = -1;
   Expression exp = null;
    if (jj_2_10(2)) {
      ci = jj_consume_token(S_INTEGER);
                                     cInt = Integer.parseInt (ci.image); oe.setIndex (cInt);
    } else {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case K_AS:
      case K_BY:
      case K_IS:
      case K_IN:
      case K_OR:
      case K_ON:
      case K_ALL:
      case K_AND:
      case K_NOT:
      case K_ASC:
      case K_DESC:
      case K_NULL:
      case K_LIKE:
      case K_INLIKE:
      case K_WHERE:
      case K_GROUP:
      case K_LIMIT:
      case K_ORDER:
      case K_SELECT:
      case K_HAVING:
      case K_BETWEEN:
      case K_DISTINCT:
      case K_USE:
      case K_TRUE:
      case K_FALSE:
      case K_EXECUTE:
      case K_RESULTS:
      case K_WHERE_RESULTS:
      case K_HAVING_RESULTS:
      case K_GROUP_BY_RESULTS:
      case K_NEW:
      case S_IDENTIFIER:
      case S_CHAR_LITERAL:
      case S_CHAR_LITERAL2:
      case S_DOUBLE:
      case S_INTEGER:
      case 48:
      case 49:
      case 50:
      case 52:
      case 56:
      case 58:
      case 70:
      case 71:
        exp = ExpressionList();
                             oe.setExpression (exp);
        break;
      default:
        jj_la1[27] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_ASC:
    case K_DESC:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case K_ASC:
        jj_consume_token(K_ASC);
               oe.setType (OrderBy.ASC);
        break;
      case K_DESC:
        jj_consume_token(K_DESC);
                                                        oe.setType (OrderBy.DESC);
        break;
      default:
        jj_la1[28] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      break;
    default:
      jj_la1[29] = jj_gen;
      ;
    }
      {if (true) return oe;}
    throw new Error("Missing return statement in function");
  }

  final public Limit Limit() throws ParseException {
        Limit limit = new Limit ();
        Token token = null;
        Expression start = null;
        Expression rows = null;
    jj_consume_token(K_LIMIT);
    if (jj_2_11(2)) {
      start = SimpleExpression();
      jj_consume_token(54);
    } else {
      ;
    }
    rows = SimpleExpression();
      if ((start != null)
          &&
          (!(start instanceof ValueExpression))
         )
      {

         {if (true) throw new ParseException ("Only expressions that return a numeric value are supported as the start value for the LIMIT part of the query.");}

      }

      if (!(rows instanceof ValueExpression))
      {

         {if (true) throw new ParseException ("Only expressions that return a numeric value are supported as the rows value for the LIMIT part of the query.");}

      }

      limit.setStart ((ValueExpression) start);
      limit.setRowsCount ((ValueExpression) rows);

      {if (true) return limit;}
    throw new Error("Missing return statement in function");
  }

  final public Limit GroupLimit() throws ParseException {
        Limit limit = new Limit ();
        Token token = null;
        Expression start = null;
        Expression rows = null;
    jj_consume_token(K_GROUP);
    jj_consume_token(K_BY);
    jj_consume_token(K_LIMIT);
    if (jj_2_12(2)) {
      start = SimpleExpression();
      jj_consume_token(54);
    } else {
      ;
    }
    rows = SimpleExpression();
      if ((start != null)
          &&
          (!(start instanceof ValueExpression))
         )
      {

         {if (true) throw new ParseException ("Only expressions that return a numeric value are supported as the start value for the LIMIT part of the query.");}

      }

      if (!(rows instanceof ValueExpression))
      {

         {if (true) throw new ParseException ("Only expressions that return a numeric value are supported as the rows value for the LIMIT part of the query.");}

      }

      limit.setStart ((ValueExpression) start);
      limit.setRowsCount ((ValueExpression) rows);

      {if (true) return limit;}
    throw new Error("Missing return statement in function");
  }

  final public ColumnReference ColumnReference() throws ParseException {
        ColumnReference retval = new ColumnReference ();
        String name = null;
        int index = -1;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
    case K_BY:
    case K_IS:
    case K_IN:
    case K_OR:
    case K_ON:
    case K_ALL:
    case K_AND:
    case K_NOT:
    case K_ASC:
    case K_DESC:
    case K_LIKE:
    case K_INLIKE:
    case K_WHERE:
    case K_GROUP:
    case K_LIMIT:
    case K_ORDER:
    case K_SELECT:
    case K_HAVING:
    case K_BETWEEN:
    case K_DISTINCT:
    case K_USE:
    case K_TRUE:
    case K_FALSE:
    case K_EXECUTE:
    case K_RESULTS:
    case K_WHERE_RESULTS:
    case K_HAVING_RESULTS:
    case K_GROUP_BY_RESULTS:
    case K_NEW:
    case S_IDENTIFIER:
      name = Name();
                         retval.setName (name);
      break;
    case S_INTEGER:
      index = ColumnIndex();
                                   retval.setIndex (index);
      break;
    default:
      jj_la1[30] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
          {if (true) return retval;}
    throw new Error("Missing return statement in function");
  }

  final public int ColumnIndex() throws ParseException {
   Token index = null;
    index = jj_consume_token(S_INTEGER);
           {if (true) return Integer.parseInt(index.image);}
    throw new Error("Missing return statement in function");
  }

  final public Expression ExpressionList() throws ParseException {
   ExpressionList el = null;
   Expression expr = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
    case K_BY:
    case K_IS:
    case K_IN:
    case K_OR:
    case K_ON:
    case K_ALL:
    case K_AND:
    case K_NOT:
    case K_ASC:
    case K_DESC:
    case K_NULL:
    case K_LIKE:
    case K_INLIKE:
    case K_WHERE:
    case K_GROUP:
    case K_LIMIT:
    case K_ORDER:
    case K_SELECT:
    case K_HAVING:
    case K_BETWEEN:
    case K_DISTINCT:
    case K_USE:
    case K_TRUE:
    case K_FALSE:
    case K_EXECUTE:
    case K_RESULTS:
    case K_WHERE_RESULTS:
    case K_HAVING_RESULTS:
    case K_GROUP_BY_RESULTS:
    case K_NEW:
    case S_IDENTIFIER:
    case S_CHAR_LITERAL:
    case S_CHAR_LITERAL2:
    case S_DOUBLE:
    case S_INTEGER:
    case 48:
    case 49:
    case 50:
    case 52:
    case 58:
    case 70:
    case 71:
      expr = OrExpression();
                            {if (true) return expr;}
      break;
    case 56:
      jj_consume_token(56);
      expr = ExpressionList();
                                  el = new ExpressionList (); el.addExpression (expr);
      label_9:
      while (true) {
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case 54:
          ;
          break;
        default:
          jj_la1[31] = jj_gen;
          break label_9;
        }
        jj_consume_token(54);
        expr = ExpressionList();
                                    el.addExpression (expr);
      }
      jj_consume_token(57);
        {if (true) return el;}
      break;
    default:
      jj_la1[32] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
  }

  final public Expression OrExpression() throws ParseException {
        Expression left;
        Expression right;
        Expression result;
    left = AndExpression();
                                  result = left;
    label_10:
    while (true) {
      if (jj_2_13(2147483647)) {
        ;
      } else {
        break label_10;
      }
      jj_consume_token(K_OR);
      right = ExpressionList();
                                result = new AndOrExpression ();
                                BinaryExpression be = (BinaryExpression) result;
                                be.setLeft (left);
                                be.setRight (right);
    }
                {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public Expression AndExpression() throws ParseException {
        Expression left;
        Expression right;
        Expression result;
    left = Condition();
                             result = left;
    label_11:
    while (true) {
      if (jj_2_14(2147483647)) {
        ;
      } else {
        break label_11;
      }
      jj_consume_token(K_AND);
      right = ExpressionList();
                        result = new AndOrExpression ();

                        AndOrExpression aoe = (AndOrExpression) result;
                        aoe.setLeft (left);
                        aoe.setRight (right);
                        aoe.setAnd (true);
    }
          {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public Expression Condition() throws ParseException {
        Expression result;
    if (jj_2_15(2147483647)) {
      result = SQLCondition();
    } else {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case K_AS:
      case K_BY:
      case K_IS:
      case K_IN:
      case K_OR:
      case K_ON:
      case K_ALL:
      case K_AND:
      case K_NOT:
      case K_ASC:
      case K_DESC:
      case K_NULL:
      case K_LIKE:
      case K_INLIKE:
      case K_WHERE:
      case K_GROUP:
      case K_LIMIT:
      case K_ORDER:
      case K_SELECT:
      case K_HAVING:
      case K_BETWEEN:
      case K_DISTINCT:
      case K_USE:
      case K_TRUE:
      case K_FALSE:
      case K_EXECUTE:
      case K_RESULTS:
      case K_WHERE_RESULTS:
      case K_HAVING_RESULTS:
      case K_GROUP_BY_RESULTS:
      case K_NEW:
      case S_IDENTIFIER:
      case S_CHAR_LITERAL:
      case S_CHAR_LITERAL2:
      case S_DOUBLE:
      case S_INTEGER:
      case 48:
      case 49:
      case 50:
      case 52:
      case 58:
      case 70:
      case 71:
        result = RegularCondition();
        break;
      default:
        jj_la1[33] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
          {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public Expression RegularCondition() throws ParseException {
        Expression result = null;
        Expression left = null;
        Expression right = null;
        boolean ignoreCase = false;
    left = SimpleExpression();
                                    result = left;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 62:
    case 63:
    case 64:
    case 65:
    case 66:
    case 67:
    case 68:
    case 69:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 62:
        jj_consume_token(62);
                 ignoreCase = true;
        break;
      default:
        jj_la1[34] = jj_gen;
        ;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 63:
        jj_consume_token(63);
                 result = new GTLTExpression (); GTLTExpression lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.GT);
        break;
      case 64:
        jj_consume_token(64);
                   result = new GTLTExpression (); lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.LT);
        break;
      case 65:
        jj_consume_token(65);
                   result = new EqualsExpression (); EqualsExpression ee = (EqualsExpression) result; ee.setIgnoreCase (ignoreCase);
        break;
      case 66:
        jj_consume_token(66);
                    result = new GTLTExpression (); lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.GTE);
        break;
      case 67:
        jj_consume_token(67);
                    result = new GTLTExpression (); lt = (GTLTExpression) result; lt.setIgnoreCase (ignoreCase); lt.setType (Utilities.LTE);
        break;
      case 68:
      case 69:
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case 68:
          jj_consume_token(68);
          break;
        case 69:
          jj_consume_token(69);
          break;
        default:
          jj_la1[35] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
                             result = new EqualsExpression (); ee = (EqualsExpression) result; ee.setNot (true); ee.setIgnoreCase (ignoreCase);
        break;
      default:
        jj_la1[36] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      right = SimpleExpression();
          BinaryExpression be = (BinaryExpression) result;
          be.setLeft (left);
          be.setRight (right);
      break;
    default:
      jj_la1[37] = jj_gen;
      ;
    }
       {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public Expression SQLCondition() throws ParseException {
        Expression result;
    if (jj_2_16(2147483647)) {
      result = InExpression();
    } else if (jj_2_17(2147483647)) {
      result = BetweenExpression();
    } else if (jj_2_18(2147483647)) {
      result = IsNullExpression();
    } else {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case K_AS:
      case K_BY:
      case K_IS:
      case K_IN:
      case K_OR:
      case K_ON:
      case K_ALL:
      case K_AND:
      case K_NOT:
      case K_ASC:
      case K_DESC:
      case K_NULL:
      case K_LIKE:
      case K_INLIKE:
      case K_WHERE:
      case K_GROUP:
      case K_LIMIT:
      case K_ORDER:
      case K_SELECT:
      case K_HAVING:
      case K_BETWEEN:
      case K_DISTINCT:
      case K_USE:
      case K_TRUE:
      case K_FALSE:
      case K_EXECUTE:
      case K_RESULTS:
      case K_WHERE_RESULTS:
      case K_HAVING_RESULTS:
      case K_GROUP_BY_RESULTS:
      case K_NEW:
      case S_IDENTIFIER:
      case S_CHAR_LITERAL:
      case S_CHAR_LITERAL2:
      case S_DOUBLE:
      case S_INTEGER:
      case 48:
      case 49:
      case 50:
      case 52:
      case 58:
      case 70:
      case 71:
        result = LikeExpression();
        break;
      default:
        jj_la1[38] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
          {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public InExpression InExpression() throws ParseException {
        InExpression result = new InExpression();
        List items = null;
        Expression left = null;
    left = SimpleExpression();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_NOT:
      jj_consume_token(K_NOT);
               result.setNot(true);
      break;
    default:
      jj_la1[39] = jj_gen;
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 62:
      jj_consume_token(62);
                                                result.setIgnoreCase (true);
      break;
    default:
      jj_la1[40] = jj_gen;
      ;
    }
    jj_consume_token(K_IN);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 62:
      jj_consume_token(62);
                                                                                                result.setIgnoreCase (true);
      break;
    default:
      jj_la1[41] = jj_gen;
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_LIKE:
      jj_consume_token(K_LIKE);
                                                                                                                                              result.setDoLike (true);
      break;
    default:
      jj_la1[42] = jj_gen;
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_ALL:
      jj_consume_token(K_ALL);
                                                                                                                                                                                        result.setAll (true);
      break;
    default:
      jj_la1[43] = jj_gen;
      ;
    }
    jj_consume_token(58);
    items = SQLExpressionList();
    jj_consume_token(59);
           if (!(left instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The left-hand side of an [NOT] IN clause must be a value expression.");}

           }

           result.setLeft ((ValueExpression) left);

           for (int i = 0; i < items.size (); i++)
           {

              if (!(items.get (i) instanceof ValueExpression))
              {

                 {if (true) throw new ParseException ("Item: " + (i + 1) + " from the [NOT] IN clause is NOT a value expression, is: \"" + items.get (i).toString () + "\"");}

              }

           }

           result.setItems (items);
           {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public BetweenExpression BetweenExpression() throws ParseException {
        BetweenExpression result = new BetweenExpression ();
        Expression left = null;
        Expression start = null;
        Expression end = null;
    left = SimpleExpression();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_NOT:
      jj_consume_token(K_NOT);
                       result.setNot(true);
      break;
    default:
      jj_la1[44] = jj_gen;
      ;
    }
    jj_consume_token(K_BETWEEN);
    start = SimpleExpression();
    jj_consume_token(K_AND);
    end = SimpleExpression();
           if (!(left instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The left-hand side of an [NOT] BETWEEN clause must be a value expression, is: \"" + left + "\"");}

           }

           if (!(start instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The START value of an [NOT] BETWEEN clause must be a value expression, is: \"" + start + "\"");}

           }

           if (!(end instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The END value of an [NOT] BETWEEN clause must be a value expression, is: \"" + end + "\"");}

           }

                result.setLeft ((ValueExpression) left);
                result.setStart ((ValueExpression) start);
                result.setEnd ((ValueExpression) end);
                {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public LikeExpression LikeExpression() throws ParseException {
        LikeExpression result = new LikeExpression ();
        Expression left = null;
        Expression right = null;
    left = SimpleExpression();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_NOT:
      jj_consume_token(K_NOT);
               result.setNot (true);
      break;
    default:
      jj_la1[45] = jj_gen;
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 62:
      jj_consume_token(62);
                                                 result.setIgnoreCase (true);
      break;
    default:
      jj_la1[46] = jj_gen;
      ;
    }
    jj_consume_token(K_LIKE);
    right = SimpleExpression();
                result.setLeft (left);
                result.setRight (right);
                {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public IsNullExpression IsNullExpression() throws ParseException {
        IsNullExpression result = new IsNullExpression ();
        Expression left = null;
    left = SimpleExpression();
    jj_consume_token(K_IS);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_NOT:
      jj_consume_token(K_NOT);
                      result.setNot (true);
      break;
    default:
      jj_la1[47] = jj_gen;
      ;
    }
    jj_consume_token(K_NULL);
                result.setLeft (left);
                {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public List SQLExpressionList() throws ParseException {
        List expressions = new ArrayList();
        Expression expr = null;
        ExpressionList eList = null;
        List exprList = null;
    expr = ExpressionList();
                              expressions.add(expr);
    label_12:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 54:
        ;
        break;
      default:
        jj_la1[48] = jj_gen;
        break label_12;
      }
      jj_consume_token(54);
      expr = ExpressionList();
                                                                                      expressions.add(expr);
    }
                {if (true) return expressions;}
    throw new Error("Missing return statement in function");
  }

  final public List AliasedSQLExpressionList() throws ParseException {
        List expressions = new ArrayList();
        AliasedExpression aexp = null;
        Expression expr = null;
        String alias = null;
    expr = ExpressionList();
                              aexp = new AliasedExpression (); aexp.setExpression (expr); expressions.add (aexp);
    if (jj_2_19(2)) {
      alias = Alias();
                                                                                                                                                     aexp.setAlias (alias);
    } else {
      ;
    }
    label_13:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 54:
        ;
        break;
      default:
        jj_la1[49] = jj_gen;
        break label_13;
      }
      jj_consume_token(54);
      expr = ExpressionList();
                                                                                                                                                                                                               aexp = new AliasedExpression (); aexp.setExpression (expr); expressions.add (aexp);
      if (jj_2_20(2)) {
        alias = Alias();
                                                                                                                                                                                                                                                                                                                                      aexp.setAlias (alias);
      } else {
        ;
      }
    }
                {if (true) return expressions;}
    throw new Error("Missing return statement in function");
  }

  final public Expression SimpleExpression() throws ParseException {
        Expression result = null;
    if (jj_2_21(3)) {
      result = AdditiveExpression();
    } else if (jj_2_22(3)) {
      result = MultiplicativeExpression();
    } else if (jj_2_23(3)) {
      result = PrimaryExpression();
    } else {
      jj_consume_token(-1);
      throw new ParseException();
    }
        {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public Expression AdditiveExpression() throws ParseException {
        Expression result = null;
        Expression left = null;
        Expression right = null;
        int type = -1;
    left = MultiplicativeExpression();
                                         result = left;
    label_14:
    while (true) {
      if (jj_2_24(2)) {
        ;
      } else {
        break label_14;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 70:
        jj_consume_token(70);
                            type = ArithmeticExpression.ADDITION;
        break;
      case 71:
        jj_consume_token(71);
                            type = ArithmeticExpression.SUBTRACT;
        break;
      default:
        jj_la1[50] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      right = AdditiveExpression();
           if (!(left instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The left-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression.");}

           }

           if (!(right instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The right-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression.");}

           }

                  ArithmeticExpression ae = new ArithmeticExpression ();
                  ae.setLeft ((ValueExpression) left);
                  ae.setRight ((ValueExpression) right);
                  result = ae;
                  ae.setType (type);
    }
      {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public Expression MultiplicativeExpression() throws ParseException {
        Expression result = null;
        Expression left = null;
        Expression right = null;
        int type = -1;
    left = PrimaryExpression();
                                  result = left;
    label_15:
    while (true) {
      if (jj_2_25(2)) {
        ;
      } else {
        break label_15;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 55:
        jj_consume_token(55);
                            type = ArithmeticExpression.MULTIPLY;
        break;
      case 72:
        jj_consume_token(72);
                             type = ArithmeticExpression.DIVIDE;
        break;
      case 73:
        jj_consume_token(73);
                             type = ArithmeticExpression.MODULUS;
        break;
      default:
        jj_la1[51] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      right = AdditiveExpression();
           if (!(left instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The left-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression.");}

           }

           if (!(right instanceof ValueExpression))
           {

              {if (true) throw new ParseException ("The right-hand side of an arithmetic expresion (+, -, *, / or %) must be a value expression.");}

           }

                  ArithmeticExpression ae = new ArithmeticExpression ();
                  ae.setLeft ((ValueExpression) left);
                  ae.setRight ((ValueExpression) right);
                  result = ae;
                  ae.setType (type);
    }
      {if (true) return result;}
    throw new Error("Missing return statement in function");
  }

  final public Expression PrimaryExpression() throws ParseException {
        Expression retval = null;
        Token token = null;
        boolean isInverse = false;
        String tmp = "";
        String accName = null;
    if (jj_2_26(2)) {
      retval = NewObjectExpression();
    } else if (jj_2_27(2)) {
      retval = SubQueryExpression();
    } else {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case K_NULL:
        jj_consume_token(K_NULL);
                     retval = new ConstantExpression (); ConstantExpression ce = (ConstantExpression) retval; ce.setValue (null);
        break;
      default:
        jj_la1[62] = jj_gen;
        if (jj_2_28(2)) {
          jj_consume_token(K_TRUE);
                                  retval = new BooleanExpression (); BooleanExpression be = (BooleanExpression) retval; be.setValue (Boolean.TRUE);
        } else if (jj_2_29(2)) {
          jj_consume_token(K_FALSE);
                                   retval = new BooleanExpression (); BooleanExpression be = (BooleanExpression) retval; be.setValue (Boolean.FALSE);
        } else {
          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
          case 48:
          case 49:
          case 50:
            retval = BindVariable();
            break;
          case 52:
            retval = SaveValue();
            break;
          default:
            jj_la1[63] = jj_gen;
            if (jj_2_30(2147483647)) {
              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
              case 70:
              case 71:
                switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
                case 70:
                  jj_consume_token(70);
                  break;
                case 71:
                  jj_consume_token(71);
                                                              isInverse = true;
                  break;
                default:
                  jj_la1[52] = jj_gen;
                  jj_consume_token(-1);
                  throw new ParseException();
                }
                break;
              default:
                jj_la1[53] = jj_gen;
                ;
              }
              retval = Function();
            } else if (jj_2_31(2147483647)) {
              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
              case 70:
              case 71:
                switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
                case 70:
                  jj_consume_token(70);
                  break;
                case 71:
                  jj_consume_token(71);
                                                                    tmp = "-";
                  break;
                default:
                  jj_la1[54] = jj_gen;
                  jj_consume_token(-1);
                  throw new ParseException();
                }
                break;
              default:
                jj_la1[55] = jj_gen;
                ;
              }
              token = jj_consume_token(S_DOUBLE);
                                                                                                      retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (new Double (tmp+token.image));
            } else if (jj_2_32(2147483647)) {
              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
              case 70:
              case 71:
                switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
                case 70:
                  jj_consume_token(70);
                  break;
                case 71:
                  jj_consume_token(71);
                                                                            tmp = "-";
                  break;
                default:
                  jj_la1[56] = jj_gen;
                  jj_consume_token(-1);
                  throw new ParseException();
                }
                break;
              default:
                jj_la1[57] = jj_gen;
                ;
              }
              token = jj_consume_token(S_INTEGER);
                                                                                                               retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (new Double (tmp+token.image));
            } else if (jj_2_33(2)) {
              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
              case 70:
              case 71:
                switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
                case 70:
                  jj_consume_token(70);
                  break;
                case 71:
                  jj_consume_token(71);
                                      isInverse = true;
                  break;
                default:
                  jj_la1[58] = jj_gen;
                  jj_consume_token(-1);
                  throw new ParseException();
                }
                break;
              default:
                jj_la1[59] = jj_gen;
                ;
              }
              accName = Name();
                                                                             retval= new Accessor (); Accessor a = (Accessor) retval; a.setAccessor (accName);
            } else if (jj_2_34(2)) {
              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
              case 70:
              case 71:
                switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
                case 70:
                  jj_consume_token(70);
                  break;
                case 71:
                  jj_consume_token(71);
                                     isInverse = true;
                  break;
                default:
                  jj_la1[60] = jj_gen;
                  jj_consume_token(-1);
                  throw new ParseException();
                }
                break;
              default:
                jj_la1[61] = jj_gen;
                ;
              }
              jj_consume_token(58);
              retval = ExpressionList();
              jj_consume_token(59);
                                                                                               retval.setBracketed (true);
            } else {
              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
              case S_CHAR_LITERAL:
                token = jj_consume_token(S_CHAR_LITERAL);
                                   retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (token.image.substring (1,token.image.length () - 1));
                break;
              case S_CHAR_LITERAL2:
                token = jj_consume_token(S_CHAR_LITERAL2);
                                    retval = new ConstantExpression (); ce = (ConstantExpression) retval; ce.setValue (token.image.substring (1,token.image.length () - 1));
                break;
              default:
                jj_la1[64] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
              }
            }
          }
        }
      }
    }
        {if (true) return retval;}
    throw new Error("Missing return statement in function");
  }

  final public Function Function() throws ParseException {
        Function retval = new Function ();
        String funcName = null;
        String tmp = null;
        List params = null;
        String acc = null;
    funcName = Name();
    jj_consume_token(58);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
    case K_BY:
    case K_IS:
    case K_IN:
    case K_OR:
    case K_ON:
    case K_ALL:
    case K_AND:
    case K_NOT:
    case K_ASC:
    case K_DESC:
    case K_NULL:
    case K_LIKE:
    case K_INLIKE:
    case K_WHERE:
    case K_GROUP:
    case K_LIMIT:
    case K_ORDER:
    case K_SELECT:
    case K_HAVING:
    case K_BETWEEN:
    case K_DISTINCT:
    case K_USE:
    case K_TRUE:
    case K_FALSE:
    case K_EXECUTE:
    case K_RESULTS:
    case K_WHERE_RESULTS:
    case K_HAVING_RESULTS:
    case K_GROUP_BY_RESULTS:
    case K_NEW:
    case S_IDENTIFIER:
    case S_CHAR_LITERAL:
    case S_CHAR_LITERAL2:
    case S_DOUBLE:
    case S_INTEGER:
    case 48:
    case 49:
    case 50:
    case 52:
    case 56:
    case 58:
    case 70:
    case 71:
      params = SQLExpressionList();
      break;
    default:
      jj_la1[65] = jj_gen;
      ;
    }
    jj_consume_token(59);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 51:
      jj_consume_token(51);
      acc = Name();
      break;
    default:
      jj_la1[66] = jj_gen;
      ;
    }
            retval.setParameters (params);
            retval.setName (funcName);
            retval.setAccessor (acc);
            {if (true) return retval;}
    throw new Error("Missing return statement in function");
  }

  final public SubQueryExpression SubQueryExpression() throws ParseException {
    Query q = new Query ();
    SubQueryExpression exp = new SubQueryExpression (q);
    String acc = null;
    jj_consume_token(58);
    Query(q);
    jj_consume_token(59);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 51:
      jj_consume_token(51);
      acc = Name();
                                          exp.setAccessor (acc);
      break;
    default:
      jj_la1[67] = jj_gen;
      ;
    }
      {if (true) return exp;}
    throw new Error("Missing return statement in function");
  }

  final private boolean jj_2_1(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_1(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(0, xla); }
  }

  final private boolean jj_2_2(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_2(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(1, xla); }
  }

  final private boolean jj_2_3(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_3(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(2, xla); }
  }

  final private boolean jj_2_4(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_4(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(3, xla); }
  }

  final private boolean jj_2_5(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_5(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(4, xla); }
  }

  final private boolean jj_2_6(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_6(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(5, xla); }
  }

  final private boolean jj_2_7(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_7(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(6, xla); }
  }

  final private boolean jj_2_8(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_8(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(7, xla); }
  }

  final private boolean jj_2_9(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_9(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(8, xla); }
  }

  final private boolean jj_2_10(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_10(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(9, xla); }
  }

  final private boolean jj_2_11(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_11(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(10, xla); }
  }

  final private boolean jj_2_12(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_12(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(11, xla); }
  }

  final private boolean jj_2_13(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_13(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(12, xla); }
  }

  final private boolean jj_2_14(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_14(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(13, xla); }
  }

  final private boolean jj_2_15(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_15(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(14, xla); }
  }

  final private boolean jj_2_16(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_16(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(15, xla); }
  }

  final private boolean jj_2_17(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_17(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(16, xla); }
  }

  final private boolean jj_2_18(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_18(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(17, xla); }
  }

  final private boolean jj_2_19(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_19(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(18, xla); }
  }

  final private boolean jj_2_20(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_20(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(19, xla); }
  }

  final private boolean jj_2_21(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_21(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(20, xla); }
  }

  final private boolean jj_2_22(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_22(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(21, xla); }
  }

  final private boolean jj_2_23(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_23(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(22, xla); }
  }

  final private boolean jj_2_24(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_24(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(23, xla); }
  }

  final private boolean jj_2_25(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_25(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(24, xla); }
  }

  final private boolean jj_2_26(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_26(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(25, xla); }
  }

  final private boolean jj_2_27(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_27(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(26, xla); }
  }

  final private boolean jj_2_28(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_28(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(27, xla); }
  }

  final private boolean jj_2_29(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_29(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(28, xla); }
  }

  final private boolean jj_2_30(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_30(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(29, xla); }
  }

  final private boolean jj_2_31(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_31(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(30, xla); }
  }

  final private boolean jj_2_32(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_32(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(31, xla); }
  }

  final private boolean jj_2_33(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_33(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(32, xla); }
  }

  final private boolean jj_2_34(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_34(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(33, xla); }
  }

  final private boolean jj_3R_65() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_85()) jj_scanpos = xsp;
    if (jj_scan_token(S_DOUBLE)) return true;
    return false;
  }

  final private boolean jj_3R_149() {
    if (jj_scan_token(K_GROUP_BY_RESULTS)) return true;
    return false;
  }

  final private boolean jj_3R_148() {
    if (jj_scan_token(K_HAVING_RESULTS)) return true;
    return false;
  }

  final private boolean jj_3R_63() {
    if (jj_3R_83()) return true;
    return false;
  }

  final private boolean jj_3R_62() {
    if (jj_3R_82()) return true;
    return false;
  }

  final private boolean jj_3R_147() {
    if (jj_scan_token(K_WHERE_RESULTS)) return true;
    return false;
  }

  final private boolean jj_3_29() {
    if (jj_scan_token(K_FALSE)) return true;
    return false;
  }

  final private boolean jj_3_28() {
    if (jj_scan_token(K_TRUE)) return true;
    return false;
  }

  final private boolean jj_3R_146() {
    if (jj_scan_token(K_RESULTS)) return true;
    return false;
  }

  final private boolean jj_3R_61() {
    if (jj_scan_token(K_NULL)) return true;
    return false;
  }

  final private boolean jj_3_27() {
    if (jj_3R_37()) return true;
    return false;
  }

  final private boolean jj_3R_145() {
    if (jj_scan_token(K_ALL)) return true;
    return false;
  }

  final private boolean jj_3R_136() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_145()) {
    jj_scanpos = xsp;
    if (jj_3R_146()) {
    jj_scanpos = xsp;
    if (jj_3R_147()) {
    jj_scanpos = xsp;
    if (jj_3R_148()) {
    jj_scanpos = xsp;
    if (jj_3R_149()) return true;
    }
    }
    }
    }
    if (jj_3R_150()) return true;
    return false;
  }

  final private boolean jj_3_26() {
    if (jj_3R_36()) return true;
    return false;
  }

  final private boolean jj_3R_101() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_44()) return true;
    return false;
  }

  final private boolean jj_3R_76() {
    if (jj_scan_token(56)) return true;
    if (jj_3R_44()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_101()) { jj_scanpos = xsp; break; }
    }
    if (jj_scan_token(57)) return true;
    return false;
  }

  final private boolean jj_3R_44() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_75()) {
    jj_scanpos = xsp;
    if (jj_3R_76()) return true;
    }
    return false;
  }

  final private boolean jj_3R_75() {
    if (jj_3R_87()) return true;
    return false;
  }

  final private boolean jj_3R_30() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_26()) {
    jj_scanpos = xsp;
    if (jj_3_27()) {
    jj_scanpos = xsp;
    if (jj_3R_61()) {
    jj_scanpos = xsp;
    if (jj_3_28()) {
    jj_scanpos = xsp;
    if (jj_3_29()) {
    jj_scanpos = xsp;
    if (jj_3R_62()) {
    jj_scanpos = xsp;
    if (jj_3R_63()) {
    jj_scanpos = xsp;
    if (jj_3R_64()) {
    jj_scanpos = xsp;
    if (jj_3R_65()) {
    jj_scanpos = xsp;
    if (jj_3R_66()) {
    jj_scanpos = xsp;
    if (jj_3_33()) {
    jj_scanpos = xsp;
    if (jj_3_34()) {
    jj_scanpos = xsp;
    if (jj_3R_67()) {
    jj_scanpos = xsp;
    if (jj_3R_68()) return true;
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    return false;
  }

  final private boolean jj_3_19() {
    if (jj_3R_19()) return true;
    return false;
  }

  final private boolean jj_3R_134() {
    if (jj_scan_token(K_EXECUTE)) return true;
    if (jj_scan_token(K_ON)) return true;
    if (jj_3R_136()) return true;
    return false;
  }

  final private boolean jj_3R_131() {
    Token xsp;
    if (jj_3R_134()) return true;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_134()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_35() {
    if (jj_scan_token(73)) return true;
    return false;
  }

  final private boolean jj_3R_34() {
    if (jj_scan_token(72)) return true;
    return false;
  }

  final private boolean jj_3R_33() {
    if (jj_scan_token(55)) return true;
    return false;
  }

  final private boolean jj_3_4() {
    if (jj_3R_18()) return true;
    return false;
  }

  final private boolean jj_3_3() {
    if (jj_3R_17()) return true;
    return false;
  }

  final private boolean jj_3_1() {
    if (jj_scan_token(K_DISTINCT)) return true;
    return false;
  }

  final private boolean jj_3R_123() {
    if (jj_3R_131()) return true;
    return false;
  }

  final private boolean jj_3R_122() {
    if (jj_3R_130()) return true;
    return false;
  }

  final private boolean jj_3_12() {
    if (jj_3R_23()) return true;
    if (jj_scan_token(54)) return true;
    return false;
  }

  final private boolean jj_3R_121() {
    if (jj_3R_18()) return true;
    return false;
  }

  final private boolean jj_3_25() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_33()) {
    jj_scanpos = xsp;
    if (jj_3R_34()) {
    jj_scanpos = xsp;
    if (jj_3R_35()) return true;
    }
    }
    if (jj_3R_28()) return true;
    return false;
  }

  final private boolean jj_3R_120() {
    if (jj_3R_129()) return true;
    return false;
  }

  final private boolean jj_3R_119() {
    if (jj_3R_17()) return true;
    return false;
  }

  final private boolean jj_3R_118() {
    if (jj_3R_128()) return true;
    return false;
  }

  final private boolean jj_3_2() {
    if (jj_3R_16()) return true;
    return false;
  }

  final private boolean jj_3R_117() {
    if (jj_3R_127()) return true;
    return false;
  }

  final private boolean jj_3R_29() {
    if (jj_3R_30()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3_25()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_69() {
    if (jj_scan_token(K_SELECT)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_1()) jj_scanpos = xsp;
    if (jj_3R_102()) return true;
    if (jj_3R_116()) return true;
    xsp = jj_scanpos;
    if (jj_3R_117()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3_2()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_118()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_119()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_120()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_121()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_122()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_123()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_18() {
    if (jj_scan_token(K_GROUP)) return true;
    if (jj_scan_token(K_BY)) return true;
    if (jj_scan_token(K_LIMIT)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_12()) jj_scanpos = xsp;
    if (jj_3R_23()) return true;
    return false;
  }

  final private boolean jj_3R_32() {
    if (jj_scan_token(71)) return true;
    return false;
  }

  final private boolean jj_3R_31() {
    if (jj_scan_token(70)) return true;
    return false;
  }

  final private boolean jj_3R_79() {
    if (jj_3R_72()) return true;
    return false;
  }

  final private boolean jj_3R_47() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_79()) {
    jj_scanpos = xsp;
    if (jj_scan_token(41)) {
    jj_scanpos = xsp;
    if (jj_scan_token(42)) return true;
    }
    }
    return false;
  }

  final private boolean jj_3R_89() {
    if (jj_scan_token(K_DESC)) return true;
    return false;
  }

  final private boolean jj_3R_57() {
    if (jj_scan_token(K_ALL)) return true;
    return false;
  }

  final private boolean jj_3_24() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_31()) {
    jj_scanpos = xsp;
    if (jj_3R_32()) return true;
    }
    if (jj_3R_28()) return true;
    return false;
  }

  final private boolean jj_3R_81() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_44()) return true;
    return false;
  }

  final private boolean jj_3R_28() {
    if (jj_3R_29()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3_24()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3_11() {
    if (jj_3R_23()) return true;
    if (jj_scan_token(54)) return true;
    return false;
  }

  final private boolean jj_3_23() {
    if (jj_3R_30()) return true;
    return false;
  }

  final private boolean jj_3R_130() {
    if (jj_scan_token(K_LIMIT)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_11()) jj_scanpos = xsp;
    if (jj_3R_23()) return true;
    return false;
  }

  final private boolean jj_3_22() {
    if (jj_3R_29()) return true;
    return false;
  }

  final private boolean jj_3_21() {
    if (jj_3R_28()) return true;
    return false;
  }

  final private boolean jj_3R_23() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_21()) {
    jj_scanpos = xsp;
    if (jj_3_22()) {
    jj_scanpos = xsp;
    if (jj_3_23()) return true;
    }
    }
    return false;
  }

  final private boolean jj_3R_78() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_88()) {
    jj_scanpos = xsp;
    if (jj_3R_89()) return true;
    }
    return false;
  }

  final private boolean jj_3R_88() {
    if (jj_scan_token(K_ASC)) return true;
    return false;
  }

  final private boolean jj_3R_150() {
    if (jj_3R_44()) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_19()) jj_scanpos = xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_151()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_77() {
    if (jj_3R_44()) return true;
    return false;
  }

  final private boolean jj_3_10() {
    if (jj_scan_token(S_INTEGER)) return true;
    return false;
  }

  final private boolean jj_3R_45() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_10()) {
    jj_scanpos = xsp;
    if (jj_3R_77()) return true;
    }
    xsp = jj_scanpos;
    if (jj_3R_78()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_56() {
    if (jj_scan_token(K_LIKE)) return true;
    return false;
  }

  final private boolean jj_3R_91() {
    if (jj_scan_token(62)) return true;
    return false;
  }

  final private boolean jj_3R_46() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_45()) return true;
    return false;
  }

  final private boolean jj_3R_58() {
    if (jj_3R_44()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_81()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_108() {
    if (jj_3R_58()) return true;
    return false;
  }

  final private boolean jj_3R_17() {
    if (jj_scan_token(K_GROUP)) return true;
    if (jj_scan_token(K_BY)) return true;
    if (jj_scan_token(K_ORDER)) return true;
    if (jj_3R_45()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_46()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_72() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(5)) {
    jj_scanpos = xsp;
    if (jj_scan_token(6)) {
    jj_scanpos = xsp;
    if (jj_scan_token(7)) {
    jj_scanpos = xsp;
    if (jj_scan_token(8)) {
    jj_scanpos = xsp;
    if (jj_scan_token(9)) {
    jj_scanpos = xsp;
    if (jj_scan_token(10)) {
    jj_scanpos = xsp;
    if (jj_scan_token(11)) {
    jj_scanpos = xsp;
    if (jj_scan_token(12)) {
    jj_scanpos = xsp;
    if (jj_scan_token(13)) {
    jj_scanpos = xsp;
    if (jj_scan_token(14)) {
    jj_scanpos = xsp;
    if (jj_scan_token(15)) {
    jj_scanpos = xsp;
    if (jj_scan_token(17)) {
    jj_scanpos = xsp;
    if (jj_scan_token(18)) {
    jj_scanpos = xsp;
    if (jj_scan_token(20)) {
    jj_scanpos = xsp;
    if (jj_scan_token(21)) {
    jj_scanpos = xsp;
    if (jj_scan_token(22)) {
    jj_scanpos = xsp;
    if (jj_scan_token(23)) {
    jj_scanpos = xsp;
    if (jj_scan_token(24)) {
    jj_scanpos = xsp;
    if (jj_scan_token(27)) {
    jj_scanpos = xsp;
    if (jj_scan_token(36)) {
    jj_scanpos = xsp;
    if (jj_scan_token(29)) {
    jj_scanpos = xsp;
    if (jj_scan_token(30)) {
    jj_scanpos = xsp;
    if (jj_scan_token(25)) {
    jj_scanpos = xsp;
    if (jj_scan_token(26)) {
    jj_scanpos = xsp;
    if (jj_scan_token(28)) {
    jj_scanpos = xsp;
    if (jj_scan_token(31)) {
    jj_scanpos = xsp;
    if (jj_scan_token(32)) {
    jj_scanpos = xsp;
    if (jj_scan_token(33)) {
    jj_scanpos = xsp;
    if (jj_scan_token(34)) {
    jj_scanpos = xsp;
    if (jj_scan_token(35)) {
    jj_scanpos = xsp;
    if (jj_scan_token(38)) return true;
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    return false;
  }

  final private boolean jj_3R_60() {
    if (jj_scan_token(K_NOT)) return true;
    return false;
  }

  final private boolean jj_3R_133() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_45()) return true;
    return false;
  }

  final private boolean jj_3R_27() {
    if (jj_3R_23()) return true;
    if (jj_scan_token(K_IS)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_60()) jj_scanpos = xsp;
    if (jj_scan_token(K_NULL)) return true;
    return false;
  }

  final private boolean jj_3R_129() {
    if (jj_scan_token(K_ORDER)) return true;
    if (jj_scan_token(K_BY)) return true;
    if (jj_3R_45()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_133()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_73() {
    if (jj_scan_token(51)) return true;
    if (jj_3R_72()) return true;
    return false;
  }

  final private boolean jj_3R_42() {
    if (jj_3R_72()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_73()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_55() {
    if (jj_scan_token(62)) return true;
    return false;
  }

  final private boolean jj_3R_128() {
    if (jj_scan_token(K_HAVING)) return true;
    if (jj_3R_44()) return true;
    return false;
  }

  final private boolean jj_3R_96() {
    if (jj_scan_token(51)) return true;
    if (jj_3R_42()) return true;
    return false;
  }

  final private boolean jj_3R_80() {
    if (jj_3R_23()) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_90()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_91()) jj_scanpos = xsp;
    if (jj_scan_token(K_LIKE)) return true;
    if (jj_3R_23()) return true;
    return false;
  }

  final private boolean jj_3R_90() {
    if (jj_scan_token(K_NOT)) return true;
    return false;
  }

  final private boolean jj_3R_132() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_45()) return true;
    return false;
  }

  final private boolean jj_3R_16() {
    if (jj_scan_token(K_GROUP)) return true;
    if (jj_scan_token(K_BY)) return true;
    if (jj_3R_45()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_132()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_127() {
    if (jj_scan_token(K_WHERE)) return true;
    if (jj_3R_44()) return true;
    return false;
  }

  final private boolean jj_3R_83() {
    if (jj_scan_token(52)) return true;
    if (jj_3R_72()) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_96()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3_9() {
    if (jj_3R_22()) return true;
    return false;
  }

  final private boolean jj_3R_59() {
    if (jj_scan_token(K_NOT)) return true;
    return false;
  }

  final private boolean jj_3R_21() {
    if (jj_3R_42()) return true;
    return false;
  }

  final private boolean jj_3R_95() {
    if (jj_scan_token(51)) return true;
    if (jj_3R_42()) return true;
    return false;
  }

  final private boolean jj_3R_20() {
    if (jj_scan_token(K_NULL)) return true;
    return false;
  }

  final private boolean jj_3R_94() {
    if (jj_scan_token(50)) return true;
    return false;
  }

  final private boolean jj_3R_26() {
    if (jj_3R_23()) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_59()) jj_scanpos = xsp;
    if (jj_scan_token(K_BETWEEN)) return true;
    if (jj_3R_23()) return true;
    if (jj_scan_token(K_AND)) return true;
    if (jj_3R_23()) return true;
    return false;
  }

  final private boolean jj_3_8() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_20()) {
    jj_scanpos = xsp;
    if (jj_3R_21()) return true;
    }
    return false;
  }

  final private boolean jj_3R_93() {
    if (jj_scan_token(49)) return true;
    if (jj_scan_token(S_IDENTIFIER)) return true;
    return false;
  }

  final private boolean jj_3R_126() {
    if (jj_3R_83()) return true;
    return false;
  }

  final private boolean jj_3R_92() {
    if (jj_scan_token(48)) return true;
    if (jj_3R_72()) return true;
    return false;
  }

  final private boolean jj_3_20() {
    if (jj_3R_19()) return true;
    return false;
  }

  final private boolean jj_3R_125() {
    if (jj_3R_82()) return true;
    return false;
  }

  final private boolean jj_3R_82() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_92()) {
    jj_scanpos = xsp;
    if (jj_3R_93()) {
    jj_scanpos = xsp;
    if (jj_3R_94()) return true;
    }
    }
    xsp = jj_scanpos;
    if (jj_3R_95()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_54() {
    if (jj_scan_token(62)) return true;
    return false;
  }

  final private boolean jj_3R_116() {
    if (jj_scan_token(K_FROM)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_125()) {
    jj_scanpos = xsp;
    if (jj_3R_126()) {
    jj_scanpos = xsp;
    if (jj_3_8()) {
    jj_scanpos = xsp;
    if (jj_3_9()) return true;
    }
    }
    }
    return false;
  }

  final private boolean jj_3_7() {
    if (jj_scan_token(K_AS)) return true;
    return false;
  }

  final private boolean jj_3R_19() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_7()) jj_scanpos = xsp;
    if (jj_3R_47()) return true;
    return false;
  }

  final private boolean jj_3R_115() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_44()) return true;
    if (jj_scan_token(K_INTO)) return true;
    if (jj_3R_42()) return true;
    return false;
  }

  final private boolean jj_3R_109() {
    if (jj_scan_token(60)) return true;
    if (jj_3R_44()) return true;
    if (jj_scan_token(K_INTO)) return true;
    if (jj_3R_42()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_115()) { jj_scanpos = xsp; break; }
    }
    if (jj_scan_token(61)) return true;
    return false;
  }

  final private boolean jj_3R_36() {
    if (jj_scan_token(K_NEW)) return true;
    if (jj_3R_42()) return true;
    if (jj_scan_token(58)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_108()) jj_scanpos = xsp;
    if (jj_scan_token(59)) return true;
    xsp = jj_scanpos;
    if (jj_3R_109()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_25() {
    if (jj_3R_23()) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_53()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_54()) jj_scanpos = xsp;
    if (jj_scan_token(K_IN)) return true;
    xsp = jj_scanpos;
    if (jj_3R_55()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_56()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_57()) jj_scanpos = xsp;
    if (jj_scan_token(58)) return true;
    if (jj_3R_58()) return true;
    if (jj_scan_token(59)) return true;
    return false;
  }

  final private boolean jj_3_18() {
    if (jj_3R_27()) return true;
    return false;
  }

  final private boolean jj_3_17() {
    if (jj_3R_26()) return true;
    return false;
  }

  final private boolean jj_3R_53() {
    if (jj_scan_token(K_NOT)) return true;
    return false;
  }

  final private boolean jj_3_16() {
    if (jj_3R_25()) return true;
    return false;
  }

  final private boolean jj_3R_144() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_72()) return true;
    return false;
  }

  final private boolean jj_3R_52() {
    if (jj_3R_80()) return true;
    return false;
  }

  final private boolean jj_3R_51() {
    if (jj_3R_27()) return true;
    return false;
  }

  final private boolean jj_3R_50() {
    if (jj_3R_26()) return true;
    return false;
  }

  final private boolean jj_3R_49() {
    if (jj_3R_25()) return true;
    return false;
  }

  final private boolean jj_3R_24() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_49()) {
    jj_scanpos = xsp;
    if (jj_3R_50()) {
    jj_scanpos = xsp;
    if (jj_3R_51()) {
    jj_scanpos = xsp;
    if (jj_3R_52()) return true;
    }
    }
    }
    return false;
  }

  final private boolean jj_3R_124() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_105()) return true;
    return false;
  }

  final private boolean jj_3_6() {
    if (jj_3R_19()) return true;
    return false;
  }

  final private boolean jj_3_5() {
    if (jj_scan_token(56)) return true;
    if (jj_scan_token(55)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_144()) jj_scanpos = xsp;
    if (jj_scan_token(57)) return true;
    return false;
  }

  final private boolean jj_3R_143() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(68)) {
    jj_scanpos = xsp;
    if (jj_scan_token(69)) return true;
    }
    return false;
  }

  final private boolean jj_3R_142() {
    if (jj_scan_token(67)) return true;
    return false;
  }

  final private boolean jj_3R_113() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_5()) jj_scanpos = xsp;
    if (jj_3R_44()) return true;
    xsp = jj_scanpos;
    if (jj_3_6()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_141() {
    if (jj_scan_token(66)) return true;
    return false;
  }

  final private boolean jj_3R_140() {
    if (jj_scan_token(65)) return true;
    return false;
  }

  final private boolean jj_3R_139() {
    if (jj_scan_token(64)) return true;
    return false;
  }

  final private boolean jj_3R_112() {
    if (jj_scan_token(55)) return true;
    return false;
  }

  final private boolean jj_3R_138() {
    if (jj_scan_token(63)) return true;
    return false;
  }

  final private boolean jj_3R_105() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_112()) {
    jj_scanpos = xsp;
    if (jj_3R_113()) return true;
    }
    return false;
  }

  final private boolean jj_3R_137() {
    if (jj_scan_token(62)) return true;
    return false;
  }

  final private boolean jj_3R_135() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_137()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_3R_138()) {
    jj_scanpos = xsp;
    if (jj_3R_139()) {
    jj_scanpos = xsp;
    if (jj_3R_140()) {
    jj_scanpos = xsp;
    if (jj_3R_141()) {
    jj_scanpos = xsp;
    if (jj_3R_142()) {
    jj_scanpos = xsp;
    if (jj_3R_143()) return true;
    }
    }
    }
    }
    }
    if (jj_3R_23()) return true;
    return false;
  }

  final private boolean jj_3R_114() {
    if (jj_3R_23()) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_135()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3_15() {
    if (jj_3R_24()) return true;
    return false;
  }

  final private boolean jj_3R_110() {
    if (jj_scan_token(51)) return true;
    if (jj_3R_42()) return true;
    return false;
  }

  final private boolean jj_3R_107() {
    if (jj_3R_114()) return true;
    return false;
  }

  final private boolean jj_3R_99() {
    if (jj_scan_token(71)) return true;
    return false;
  }

  final private boolean jj_3R_106() {
    if (jj_3R_24()) return true;
    return false;
  }

  final private boolean jj_3R_103() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_106()) {
    jj_scanpos = xsp;
    if (jj_3R_107()) return true;
    }
    return false;
  }

  final private boolean jj_3R_86() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_3R_99()) return true;
    }
    return false;
  }

  final private boolean jj_3_14() {
    if (jj_scan_token(K_AND)) return true;
    return false;
  }

  final private boolean jj_3R_98() {
    if (jj_scan_token(71)) return true;
    return false;
  }

  final private boolean jj_3R_85() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_3R_98()) return true;
    }
    return false;
  }

  final private boolean jj_3R_97() {
    if (jj_scan_token(71)) return true;
    return false;
  }

  final private boolean jj_3R_111() {
    if (jj_scan_token(K_AND)) return true;
    if (jj_3R_44()) return true;
    return false;
  }

  final private boolean jj_3R_37() {
    if (jj_scan_token(58)) return true;
    if (jj_3R_69()) return true;
    if (jj_scan_token(59)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_110()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_151() {
    if (jj_scan_token(54)) return true;
    if (jj_3R_44()) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3_20()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_84() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_3R_97()) return true;
    }
    return false;
  }

  final private boolean jj_3R_102() {
    if (jj_3R_105()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_124()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_100() {
    if (jj_3R_103()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_111()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3R_48() {
    if (jj_3R_58()) return true;
    return false;
  }

  final private boolean jj_3R_74() {
    if (jj_scan_token(71)) return true;
    return false;
  }

  final private boolean jj_3R_70() {
    if (jj_scan_token(51)) return true;
    if (jj_3R_42()) return true;
    return false;
  }

  final private boolean jj_3_13() {
    if (jj_scan_token(K_OR)) return true;
    return false;
  }

  final private boolean jj_3R_71() {
    if (jj_scan_token(71)) return true;
    return false;
  }

  final private boolean jj_3R_43() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_3R_74()) return true;
    }
    return false;
  }

  final private boolean jj_3R_22() {
    if (jj_3R_42()) return true;
    if (jj_scan_token(58)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_48()) jj_scanpos = xsp;
    if (jj_scan_token(59)) return true;
    xsp = jj_scanpos;
    if (jj_3R_70()) jj_scanpos = xsp;
    return false;
  }

  final private boolean jj_3R_41() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_3R_71()) return true;
    }
    return false;
  }

  final private boolean jj_3R_104() {
    if (jj_scan_token(K_OR)) return true;
    if (jj_3R_44()) return true;
    return false;
  }

  final private boolean jj_3R_40() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_scan_token(71)) return true;
    }
    return false;
  }

  final private boolean jj_3R_39() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_scan_token(71)) return true;
    }
    return false;
  }

  final private boolean jj_3R_38() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(70)) {
    jj_scanpos = xsp;
    if (jj_scan_token(71)) return true;
    }
    return false;
  }

  final private boolean jj_3R_68() {
    if (jj_scan_token(S_CHAR_LITERAL2)) return true;
    return false;
  }

  final private boolean jj_3_32() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_40()) jj_scanpos = xsp;
    if (jj_scan_token(S_INTEGER)) return true;
    return false;
  }

  final private boolean jj_3R_67() {
    if (jj_scan_token(S_CHAR_LITERAL)) return true;
    return false;
  }

  final private boolean jj_3_30() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_38()) jj_scanpos = xsp;
    if (jj_3R_22()) return true;
    return false;
  }

  final private boolean jj_3_31() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_39()) jj_scanpos = xsp;
    if (jj_scan_token(S_DOUBLE)) return true;
    return false;
  }

  final private boolean jj_3_34() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_43()) jj_scanpos = xsp;
    if (jj_scan_token(58)) return true;
    if (jj_3R_44()) return true;
    if (jj_scan_token(59)) return true;
    return false;
  }

  final private boolean jj_3R_87() {
    if (jj_3R_100()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_104()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  final private boolean jj_3_33() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_41()) jj_scanpos = xsp;
    if (jj_3R_42()) return true;
    return false;
  }

  final private boolean jj_3R_66() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_86()) jj_scanpos = xsp;
    if (jj_scan_token(S_INTEGER)) return true;
    return false;
  }

  final private boolean jj_3R_64() {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_84()) jj_scanpos = xsp;
    if (jj_3R_22()) return true;
    return false;
  }

  public JoSQLParserTokenManager token_source;
  JavaCharStream jj_input_stream;
  public Token token, jj_nt;
  private int jj_ntk;
  private Token jj_scanpos, jj_lastpos;
  private int jj_la;
  public boolean lookingAhead = false;
  private boolean jj_semLA;
  private int jj_gen;
  final private int[] jj_la1 = new int[68];
  static private int[] jj_la1_0;
  static private int[] jj_la1_1;
  static private int[] jj_la1_2;
  static {
      jj_la1_0();
      jj_la1_1();
      jj_la1_2();
   }
   private static void jj_la1_0() {
      jj_la1_0 = new int[] {0x0,0x0,0x0,0x0,0x0,0xfff6ffe0,0xfff6ffe0,0x100000,0x2000000,0x800000,0x400000,0x80000000,0x80000000,0x800,0x0,0x0,0xfff6ffe0,0x0,0xfff7ffe0,0xfff7ffe0,0x0,0x0,0xfff7ffe0,0x0,0x0,0x0,0x0,0xfff7ffe0,0xc000,0xc000,0xfff6ffe0,0x0,0xfff7ffe0,0xfff7ffe0,0x0,0x0,0x0,0x0,0xfff7ffe0,0x2000,0x0,0x0,0x20000,0x800,0x2000,0x2000,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0xfff7ffe0,0x0,0x0,};
   }
   private static void jj_la1_1() {
      jj_la1_1 = new int[] {0x70000,0x80000,0x80000,0x200000,0x80000,0x5f,0x65f,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x400000,0x400000,0x65f,0x400000,0x5971e5f,0x5171e5f,0x400000,0x10000000,0x5f,0x170000,0x400000,0x400000,0x400000,0x5171e5f,0x0,0x0,0x105f,0x400000,0x5171e5f,0x4171e5f,0x40000000,0x0,0x80000000,0xc0000000,0x4171e5f,0x0,0x40000000,0x40000000,0x0,0x0,0x0,0x0,0x40000000,0x0,0x400000,0x400000,0x0,0x800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x170000,0x600,0x5171e5f,0x80000,0x80000,};
   }
   private static void jj_la1_2() {
      jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0xc0,0xc0,0x0,0x30,0x3f,0x3f,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x300,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x0,0x0,0x0,0xc0,0x0,0x0,};
   }
  final private JJCalls[] jj_2_rtns = new JJCalls[34];
  private boolean jj_rescan = false;
  private int jj_gc = 0;

  public JoSQLParser(java.io.InputStream stream) {
     this(stream, null);
  }
  public JoSQLParser(java.io.InputStream stream, String encoding) {
    try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source = new JoSQLParserTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 68; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public void ReInit(java.io.InputStream stream) {
     ReInit(stream, null);
  }
  public void ReInit(java.io.InputStream stream, String encoding) {
    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source.ReInit(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 68; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public JoSQLParser(java.io.Reader stream) {
    jj_input_stream = new JavaCharStream(stream, 1, 1);
    token_source = new JoSQLParserTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 68; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public void ReInit(java.io.Reader stream) {
    jj_input_stream.ReInit(stream, 1, 1);
    token_source.ReInit(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 68; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public JoSQLParser(JoSQLParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 68; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public void ReInit(JoSQLParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 68; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  final private Token jj_consume_token(int kind) throws ParseException {
    Token oldToken;
    if ((oldToken = token).next != null) token = token.next;
    else token = token.next = token_source.getNextToken();
    jj_ntk = -1;
    if (token.kind == kind) {
      jj_gen++;
      if (++jj_gc > 100) {
        jj_gc = 0;
        for (int i = 0; i < jj_2_rtns.length; i++) {
          JJCalls c = jj_2_rtns[i];
          while (c != null) {
            if (c.gen < jj_gen) c.first = null;
            c = c.next;
          }
        }
      }
      return token;
    }
    token = oldToken;
    jj_kind = kind;
    throw generateParseException();
  }

  static private final class LookaheadSuccess extends java.lang.Error { }
  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
  final private boolean jj_scan_token(int kind) {
    if (jj_scanpos == jj_lastpos) {
      jj_la--;
      if (jj_scanpos.next == null) {
        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
      } else {
        jj_lastpos = jj_scanpos = jj_scanpos.next;
      }
    } else {
      jj_scanpos = jj_scanpos.next;
    }
    if (jj_rescan) {
      int i = 0; Token tok = token;
      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
      if (tok != null) jj_add_error_token(kind, i);
    }
    if (jj_scanpos.kind != kind) return true;
    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
    return false;
  }

  final public Token getNextToken() {
    if (token.next != null) token = token.next;
    else token = token.next = token_source.getNextToken();
    jj_ntk = -1;
    jj_gen++;
    return token;
  }

  final public Token getToken(int index) {
    Token t = lookingAhead ? jj_scanpos : token;
    for (int i = 0; i < index; i++) {
      if (t.next != null) t = t.next;
      else t = t.next = token_source.getNextToken();
    }
    return t;
  }

  final private int jj_ntk() {
    if ((jj_nt=token.next) == null)
      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
    else
      return (jj_ntk = jj_nt.kind);
  }

  private java.util.Vector jj_expentries = new java.util.Vector();
  private int[] jj_expentry;
  private int jj_kind = -1;
  private int[] jj_lasttokens = new int[100];
  private int jj_endpos;

  private void jj_add_error_token(int kind, int pos) {
    if (pos >= 100) return;
    if (pos == jj_endpos + 1) {
      jj_lasttokens[jj_endpos++] = kind;
    } else if (jj_endpos != 0) {
      jj_expentry = new int[jj_endpos];
      for (int i = 0; i < jj_endpos; i++) {
        jj_expentry[i] = jj_lasttokens[i];
      }
      boolean exists = false;
      for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
        int[] oldentry = (int[])(e.nextElement());
        if (oldentry.length == jj_expentry.length) {
          exists = true;
          for (int i = 0; i < jj_expentry.length; i++) {
            if (oldentry[i] != jj_expentry[i]) {
              exists = false;
              break;
            }
          }
          if (exists) break;
        }
      }
      if (!exists) jj_expentries.addElement(jj_expentry);
      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
    }
  }

  public ParseException generateParseException() {
    jj_expentries.removeAllElements();
    boolean[] la1tokens = new boolean[74];
    for (int i = 0; i < 74; i++) {
      la1tokens[i] = false;
    }
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 68; i++) {
      if (jj_la1[i] == jj_gen) {
        for (int j = 0; j < 32; j++) {
          if ((jj_la1_0[i] & (1< jj_gen) {
          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
          switch (i) {
            case 0: jj_3_1(); break;
            case 1: jj_3_2(); break;
            case 2: jj_3_3(); break;
            case 3: jj_3_4(); break;
            case 4: jj_3_5(); break;
            case 5: jj_3_6(); break;
            case 6: jj_3_7(); break;
            case 7: jj_3_8(); break;
            case 8: jj_3_9(); break;
            case 9: jj_3_10(); break;
            case 10: jj_3_11(); break;
            case 11: jj_3_12(); break;
            case 12: jj_3_13(); break;
            case 13: jj_3_14(); break;
            case 14: jj_3_15(); break;
            case 15: jj_3_16(); break;
            case 16: jj_3_17(); break;
            case 17: jj_3_18(); break;
            case 18: jj_3_19(); break;
            case 19: jj_3_20(); break;
            case 20: jj_3_21(); break;
            case 21: jj_3_22(); break;
            case 22: jj_3_23(); break;
            case 23: jj_3_24(); break;
            case 24: jj_3_25(); break;
            case 25: jj_3_26(); break;
            case 26: jj_3_27(); break;
            case 27: jj_3_28(); break;
            case 28: jj_3_29(); break;
            case 29: jj_3_30(); break;
            case 30: jj_3_31(); break;
            case 31: jj_3_32(); break;
            case 32: jj_3_33(); break;
            case 33: jj_3_34(); break;
          }
        }
        p = p.next;
      } while (p != null);
      } catch(LookaheadSuccess ls) { }
    }
    jj_rescan = false;
  }

  final private void jj_save(int index, int xla) {
    JJCalls p = jj_2_rtns[index];
    while (p.gen > jj_gen) {
      if (p.next == null) { p = p.next = new JJCalls(); break; }
      p = p.next;
    }
    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
  }

  static final class JJCalls {
    int gen;
    Token first;
    int arg;
    JJCalls next;
  }

}
josql-2.2/src/org/josql/parser/JoSQLParserConstants.java000066400000000000000000000046021157743651500233740ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. JoSQLParserConstants.java */
package org.josql.parser;

public interface JoSQLParserConstants {

  int EOF = 0;
  int K_AS = 5;
  int K_BY = 6;
  int K_IS = 7;
  int K_IN = 8;
  int K_OR = 9;
  int K_ON = 10;
  int K_ALL = 11;
  int K_AND = 12;
  int K_NOT = 13;
  int K_ASC = 14;
  int K_DESC = 15;
  int K_NULL = 16;
  int K_LIKE = 17;
  int K_INLIKE = 18;
  int K_FROM = 19;
  int K_WHERE = 20;
  int K_GROUP = 21;
  int K_LIMIT = 22;
  int K_ORDER = 23;
  int K_SELECT = 24;
  int K_HAVING = 25;
  int K_BETWEEN = 26;
  int K_DISTINCT = 27;
  int K_USE = 28;
  int K_TRUE = 29;
  int K_FALSE = 30;
  int K_EXECUTE = 31;
  int K_RESULTS = 32;
  int K_WHERE_RESULTS = 33;
  int K_HAVING_RESULTS = 34;
  int K_GROUP_BY_RESULTS = 35;
  int K_NEW = 36;
  int K_INTO = 37;
  int S_IDENTIFIER = 38;
  int LETTER = 39;
  int SPECIAL_CHARS = 40;
  int S_CHAR_LITERAL = 41;
  int S_CHAR_LITERAL2 = 42;
  int S_DOUBLE = 43;
  int S_INTEGER = 44;
  int DIGIT = 45;
  int LINE_COMMENT = 46;
  int MULTI_LINE_COMMENT = 47;

  int DEFAULT = 0;

  String[] tokenImage = {
    "",
    "\" \"",
    "\"\\t\"",
    "\"\\r\"",
    "\"\\n\"",
    "\"AS\"",
    "\"BY\"",
    "\"IS\"",
    "\"IN\"",
    "\"OR\"",
    "\"ON\"",
    "\"ALL\"",
    "\"AND\"",
    "\"NOT\"",
    "\"ASC\"",
    "\"DESC\"",
    "\"NULL\"",
    "\"LIKE\"",
    "\"INLIKE\"",
    "\"FROM\"",
    "\"WHERE\"",
    "\"GROUP\"",
    "\"LIMIT\"",
    "\"ORDER\"",
    "\"SELECT\"",
    "\"HAVING\"",
    "\"BETWEEN\"",
    "\"DISTINCT\"",
    "\"USE\"",
    "\"TRUE\"",
    "\"FALSE\"",
    "\"EXECUTE\"",
    "\"RESULTS\"",
    "\"WHERE_RESULTS\"",
    "\"HAVING_RESULTS\"",
    "\"GROUP_BY_RESULTS\"",
    "\"new\"",
    "\"->\"",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "\":\"",
    "\":_\"",
    "\"?\"",
    "\".\"",
    "\"@\"",
    "\";\"",
    "\",\"",
    "\"*\"",
    "\"[\"",
    "\"]\"",
    "\"(\"",
    "\")\"",
    "\"{\"",
    "\"}\"",
    "\"$\"",
    "\">\"",
    "\"<\"",
    "\"=\"",
    "\">=\"",
    "\"<=\"",
    "\"<>\"",
    "\"!=\"",
    "\"+\"",
    "\"-\"",
    "\"/\"",
    "\"%\"",
  };

}
josql-2.2/src/org/josql/parser/JoSQLParserTokenManager.java000066400000000000000000001211401157743651500237700ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. JoSQLParserTokenManager.java */
package org.josql.parser;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import org.josql.Query;
import org.josql.internal.OrderBy;
import org.josql.internal.Limit;
import org.josql.internal.Utilities;
import org.josql.internal.ColumnReference;
import org.josql.expressions.*;

public class JoSQLParserTokenManager implements JoSQLParserConstants
{
  public  java.io.PrintStream debugStream = System.out;
  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1)
{
   switch (pos)
   {
      case 0:
         if ((active0 & 0x1fffffffe0L) != 0L)
         {
            jjmatchedKind = 38;
            return 27;
         }
         if ((active1 & 0x100L) != 0L)
            return 19;
         if ((active0 & 0x2000000000L) != 0L || (active1 & 0x80L) != 0L)
            return 13;
         if ((active0 & 0x8000000000000L) != 0L)
            return 9;
         return -1;
      case 1:
         if ((active0 & 0x1fff7bb800L) != 0L)
         {
            if (jjmatchedPos != 1)
            {
               jjmatchedKind = 38;
               jjmatchedPos = 1;
            }
            return 27;
         }
         if ((active0 & 0x8447e0L) != 0L)
            return 27;
         return -1;
      case 2:
         if ((active0 & 0x1010007800L) != 0L)
            return 27;
         if ((active0 & 0xfefff8000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 2;
            return 27;
         }
         return -1;
      case 3:
         if ((active0 & 0xfcff40000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 3;
            return 27;
         }
         if ((active0 & 0x200b8000L) != 0L)
            return 27;
         return -1;
      case 4:
         if ((active0 & 0xa40f00000L) != 0L)
            return 27;
         if ((active0 & 0x58f040000L) != 0L)
         {
            if (jjmatchedPos != 4)
            {
               jjmatchedKind = 38;
               jjmatchedPos = 4;
            }
            return 27;
         }
         return -1;
      case 5:
         if ((active0 & 0xa00000000L) != 0L)
         {
            if (jjmatchedPos != 5)
            {
               jjmatchedKind = 38;
               jjmatchedPos = 5;
            }
            return 1;
         }
         if ((active0 & 0x403040000L) != 0L)
            return 27;
         if ((active0 & 0x18c000000L) != 0L)
         {
            if (jjmatchedPos != 5)
            {
               jjmatchedKind = 38;
               jjmatchedPos = 5;
            }
            return 27;
         }
         return -1;
      case 6:
         if ((active0 & 0x8000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 6;
            return 27;
         }
         if ((active0 & 0xe00000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 6;
            return 1;
         }
         if ((active0 & 0x184000000L) != 0L)
            return 27;
         return -1;
      case 7:
         if ((active0 & 0x8000000L) != 0L)
            return 27;
         if ((active0 & 0xe00000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 7;
            return 1;
         }
         return -1;
      case 8:
         if ((active0 & 0xe00000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 8;
            return 1;
         }
         return -1;
      case 9:
         if ((active0 & 0xe00000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 9;
            return 1;
         }
         return -1;
      case 10:
         if ((active0 & 0xe00000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 10;
            return 1;
         }
         return -1;
      case 11:
         if ((active0 & 0xe00000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 11;
            return 1;
         }
         return -1;
      case 12:
         if ((active0 & 0x200000000L) != 0L)
            return 1;
         if ((active0 & 0xc00000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 12;
            return 1;
         }
         return -1;
      case 13:
         if ((active0 & 0x400000000L) != 0L)
            return 1;
         if ((active0 & 0x800000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 13;
            return 1;
         }
         return -1;
      case 14:
         if ((active0 & 0x800000000L) != 0L)
         {
            jjmatchedKind = 38;
            jjmatchedPos = 14;
            return 1;
         }
         return -1;
      default :
         return -1;
   }
}
private final int jjStartNfa_0(int pos, long active0, long active1)
{
   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1);
}
private final int jjStopAtPos(int pos, int kind)
{
   jjmatchedKind = kind;
   jjmatchedPos = pos;
   return pos + 1;
}
private final int jjStartNfaWithStates_0(int pos, int kind, int state)
{
   jjmatchedKind = kind;
   jjmatchedPos = pos;
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) { return pos + 1; }
   return jjMoveNfa_0(state, pos + 1);
}
private final int jjMoveStringLiteralDfa0_0()
{
   switch(curChar)
   {
      case 33:
         return jjMoveStringLiteralDfa1_0(0x0L, 0x20L);
      case 36:
         return jjStopAtPos(0, 62);
      case 37:
         return jjStopAtPos(0, 73);
      case 40:
         return jjStopAtPos(0, 58);
      case 41:
         return jjStopAtPos(0, 59);
      case 42:
         return jjStopAtPos(0, 55);
      case 43:
         return jjStopAtPos(0, 70);
      case 44:
         return jjStopAtPos(0, 54);
      case 45:
         jjmatchedKind = 71;
         return jjMoveStringLiteralDfa1_0(0x2000000000L, 0x0L);
      case 46:
         return jjStartNfaWithStates_0(0, 51, 9);
      case 47:
         return jjStartNfaWithStates_0(0, 72, 19);
      case 58:
         jjmatchedKind = 48;
         return jjMoveStringLiteralDfa1_0(0x2000000000000L, 0x0L);
      case 59:
         return jjStopAtPos(0, 53);
      case 60:
         jjmatchedKind = 64;
         return jjMoveStringLiteralDfa1_0(0x0L, 0x18L);
      case 61:
         return jjStopAtPos(0, 65);
      case 62:
         jjmatchedKind = 63;
         return jjMoveStringLiteralDfa1_0(0x0L, 0x4L);
      case 63:
         return jjStopAtPos(0, 50);
      case 64:
         return jjStopAtPos(0, 52);
      case 91:
         return jjStopAtPos(0, 56);
      case 93:
         return jjStopAtPos(0, 57);
      case 65:
      case 97:
         return jjMoveStringLiteralDfa1_0(0x5820L, 0x0L);
      case 66:
      case 98:
         return jjMoveStringLiteralDfa1_0(0x4000040L, 0x0L);
      case 68:
      case 100:
         return jjMoveStringLiteralDfa1_0(0x8008000L, 0x0L);
      case 69:
      case 101:
         return jjMoveStringLiteralDfa1_0(0x80000000L, 0x0L);
      case 70:
      case 102:
         return jjMoveStringLiteralDfa1_0(0x40080000L, 0x0L);
      case 71:
      case 103:
         return jjMoveStringLiteralDfa1_0(0x800200000L, 0x0L);
      case 72:
      case 104:
         return jjMoveStringLiteralDfa1_0(0x402000000L, 0x0L);
      case 73:
      case 105:
         return jjMoveStringLiteralDfa1_0(0x40180L, 0x0L);
      case 76:
      case 108:
         return jjMoveStringLiteralDfa1_0(0x420000L, 0x0L);
      case 78:
      case 110:
         return jjMoveStringLiteralDfa1_0(0x1000012000L, 0x0L);
      case 79:
      case 111:
         return jjMoveStringLiteralDfa1_0(0x800600L, 0x0L);
      case 82:
      case 114:
         return jjMoveStringLiteralDfa1_0(0x100000000L, 0x0L);
      case 83:
      case 115:
         return jjMoveStringLiteralDfa1_0(0x1000000L, 0x0L);
      case 84:
      case 116:
         return jjMoveStringLiteralDfa1_0(0x20000000L, 0x0L);
      case 85:
      case 117:
         return jjMoveStringLiteralDfa1_0(0x10000000L, 0x0L);
      case 87:
      case 119:
         return jjMoveStringLiteralDfa1_0(0x200100000L, 0x0L);
      case 123:
         return jjStopAtPos(0, 60);
      case 125:
         return jjStopAtPos(0, 61);
      default :
         return jjMoveNfa_0(2, 0);
   }
}
private final int jjMoveStringLiteralDfa1_0(long active0, long active1)
{
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(0, active0, active1);
      return 1;
   }
   switch(curChar)
   {
      case 61:
         if ((active1 & 0x4L) != 0L)
            return jjStopAtPos(1, 66);
         else if ((active1 & 0x8L) != 0L)
            return jjStopAtPos(1, 67);
         else if ((active1 & 0x20L) != 0L)
            return jjStopAtPos(1, 69);
         break;
      case 62:
         if ((active0 & 0x2000000000L) != 0L)
            return jjStopAtPos(1, 37);
         else if ((active1 & 0x10L) != 0L)
            return jjStopAtPos(1, 68);
         break;
      case 95:
         if ((active0 & 0x2000000000000L) != 0L)
            return jjStopAtPos(1, 49);
         break;
      case 65:
      case 97:
         return jjMoveStringLiteralDfa2_0(active0, 0x442000000L, active1, 0L);
      case 69:
      case 101:
         return jjMoveStringLiteralDfa2_0(active0, 0x1105008000L, active1, 0L);
      case 72:
      case 104:
         return jjMoveStringLiteralDfa2_0(active0, 0x200100000L, active1, 0L);
      case 73:
      case 105:
         return jjMoveStringLiteralDfa2_0(active0, 0x8420000L, active1, 0L);
      case 76:
      case 108:
         return jjMoveStringLiteralDfa2_0(active0, 0x800L, active1, 0L);
      case 78:
      case 110:
         if ((active0 & 0x100L) != 0L)
         {
            jjmatchedKind = 8;
            jjmatchedPos = 1;
         }
         else if ((active0 & 0x400L) != 0L)
            return jjStartNfaWithStates_0(1, 10, 27);
         return jjMoveStringLiteralDfa2_0(active0, 0x41000L, active1, 0L);
      case 79:
      case 111:
         return jjMoveStringLiteralDfa2_0(active0, 0x2000L, active1, 0L);
      case 82:
      case 114:
         if ((active0 & 0x200L) != 0L)
         {
            jjmatchedKind = 9;
            jjmatchedPos = 1;
         }
         return jjMoveStringLiteralDfa2_0(active0, 0x820a80000L, active1, 0L);
      case 83:
      case 115:
         if ((active0 & 0x20L) != 0L)
         {
            jjmatchedKind = 5;
            jjmatchedPos = 1;
         }
         else if ((active0 & 0x80L) != 0L)
            return jjStartNfaWithStates_0(1, 7, 27);
         return jjMoveStringLiteralDfa2_0(active0, 0x10004000L, active1, 0L);
      case 85:
      case 117:
         return jjMoveStringLiteralDfa2_0(active0, 0x10000L, active1, 0L);
      case 88:
      case 120:
         return jjMoveStringLiteralDfa2_0(active0, 0x80000000L, active1, 0L);
      case 89:
      case 121:
         if ((active0 & 0x40L) != 0L)
            return jjStartNfaWithStates_0(1, 6, 27);
         break;
      default :
         break;
   }
   return jjStartNfa_0(0, active0, active1);
}
private final int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1)
{
   if (((active0 &= old0) | (active1 &= old1)) == 0L)
      return jjStartNfa_0(0, old0, old1); 
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(1, active0, 0L);
      return 2;
   }
   switch(curChar)
   {
      case 67:
      case 99:
         if ((active0 & 0x4000L) != 0L)
            return jjStartNfaWithStates_0(2, 14, 27);
         break;
      case 68:
      case 100:
         if ((active0 & 0x1000L) != 0L)
            return jjStartNfaWithStates_0(2, 12, 27);
         return jjMoveStringLiteralDfa3_0(active0, 0x800000L);
      case 69:
      case 101:
         if ((active0 & 0x10000000L) != 0L)
            return jjStartNfaWithStates_0(2, 28, 27);
         return jjMoveStringLiteralDfa3_0(active0, 0x280100000L);
      case 75:
      case 107:
         return jjMoveStringLiteralDfa3_0(active0, 0x20000L);
      case 76:
      case 108:
         if ((active0 & 0x800L) != 0L)
            return jjStartNfaWithStates_0(2, 11, 27);
         return jjMoveStringLiteralDfa3_0(active0, 0x41050000L);
      case 77:
      case 109:
         return jjMoveStringLiteralDfa3_0(active0, 0x400000L);
      case 79:
      case 111:
         return jjMoveStringLiteralDfa3_0(active0, 0x800280000L);
      case 83:
      case 115:
         return jjMoveStringLiteralDfa3_0(active0, 0x108008000L);
      case 84:
      case 116:
         if ((active0 & 0x2000L) != 0L)
            return jjStartNfaWithStates_0(2, 13, 27);
         return jjMoveStringLiteralDfa3_0(active0, 0x4000000L);
      case 85:
      case 117:
         return jjMoveStringLiteralDfa3_0(active0, 0x20000000L);
      case 86:
      case 118:
         return jjMoveStringLiteralDfa3_0(active0, 0x402000000L);
      case 87:
      case 119:
         if ((active0 & 0x1000000000L) != 0L)
            return jjStartNfaWithStates_0(2, 36, 27);
         break;
      default :
         break;
   }
   return jjStartNfa_0(1, active0, 0L);
}
private final int jjMoveStringLiteralDfa3_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(1, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(2, active0, 0L);
      return 3;
   }
   switch(curChar)
   {
      case 67:
      case 99:
         if ((active0 & 0x8000L) != 0L)
            return jjStartNfaWithStates_0(3, 15, 27);
         return jjMoveStringLiteralDfa4_0(active0, 0x80000000L);
      case 69:
      case 101:
         if ((active0 & 0x20000L) != 0L)
            return jjStartNfaWithStates_0(3, 17, 27);
         else if ((active0 & 0x20000000L) != 0L)
            return jjStartNfaWithStates_0(3, 29, 27);
         return jjMoveStringLiteralDfa4_0(active0, 0x1800000L);
      case 73:
      case 105:
         return jjMoveStringLiteralDfa4_0(active0, 0x402440000L);
      case 76:
      case 108:
         if ((active0 & 0x10000L) != 0L)
            return jjStartNfaWithStates_0(3, 16, 27);
         break;
      case 77:
      case 109:
         if ((active0 & 0x80000L) != 0L)
            return jjStartNfaWithStates_0(3, 19, 27);
         break;
      case 82:
      case 114:
         return jjMoveStringLiteralDfa4_0(active0, 0x200100000L);
      case 83:
      case 115:
         return jjMoveStringLiteralDfa4_0(active0, 0x40000000L);
      case 84:
      case 116:
         return jjMoveStringLiteralDfa4_0(active0, 0x8000000L);
      case 85:
      case 117:
         return jjMoveStringLiteralDfa4_0(active0, 0x900200000L);
      case 87:
      case 119:
         return jjMoveStringLiteralDfa4_0(active0, 0x4000000L);
      default :
         break;
   }
   return jjStartNfa_0(2, active0, 0L);
}
private final int jjMoveStringLiteralDfa4_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(2, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(3, active0, 0L);
      return 4;
   }
   switch(curChar)
   {
      case 67:
      case 99:
         return jjMoveStringLiteralDfa5_0(active0, 0x1000000L);
      case 69:
      case 101:
         if ((active0 & 0x100000L) != 0L)
         {
            jjmatchedKind = 20;
            jjmatchedPos = 4;
         }
         else if ((active0 & 0x40000000L) != 0L)
            return jjStartNfaWithStates_0(4, 30, 27);
         return jjMoveStringLiteralDfa5_0(active0, 0x204000000L);
      case 73:
      case 105:
         return jjMoveStringLiteralDfa5_0(active0, 0x8000000L);
      case 75:
      case 107:
         return jjMoveStringLiteralDfa5_0(active0, 0x40000L);
      case 76:
      case 108:
         return jjMoveStringLiteralDfa5_0(active0, 0x100000000L);
      case 78:
      case 110:
         return jjMoveStringLiteralDfa5_0(active0, 0x402000000L);
      case 80:
      case 112:
         if ((active0 & 0x200000L) != 0L)
         {
            jjmatchedKind = 21;
            jjmatchedPos = 4;
         }
         return jjMoveStringLiteralDfa5_0(active0, 0x800000000L);
      case 82:
      case 114:
         if ((active0 & 0x800000L) != 0L)
            return jjStartNfaWithStates_0(4, 23, 27);
         break;
      case 84:
      case 116:
         if ((active0 & 0x400000L) != 0L)
            return jjStartNfaWithStates_0(4, 22, 27);
         break;
      case 85:
      case 117:
         return jjMoveStringLiteralDfa5_0(active0, 0x80000000L);
      default :
         break;
   }
   return jjStartNfa_0(3, active0, 0L);
}
private final int jjMoveStringLiteralDfa5_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(3, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(4, active0, 0L);
      return 5;
   }
   switch(curChar)
   {
      case 95:
         return jjMoveStringLiteralDfa6_0(active0, 0xa00000000L);
      case 69:
      case 101:
         if ((active0 & 0x40000L) != 0L)
            return jjStartNfaWithStates_0(5, 18, 27);
         return jjMoveStringLiteralDfa6_0(active0, 0x4000000L);
      case 71:
      case 103:
         if ((active0 & 0x2000000L) != 0L)
         {
            jjmatchedKind = 25;
            jjmatchedPos = 5;
         }
         return jjMoveStringLiteralDfa6_0(active0, 0x400000000L);
      case 78:
      case 110:
         return jjMoveStringLiteralDfa6_0(active0, 0x8000000L);
      case 84:
      case 116:
         if ((active0 & 0x1000000L) != 0L)
            return jjStartNfaWithStates_0(5, 24, 27);
         return jjMoveStringLiteralDfa6_0(active0, 0x180000000L);
      default :
         break;
   }
   return jjStartNfa_0(4, active0, 0L);
}
private final int jjMoveStringLiteralDfa6_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(4, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(5, active0, 0L);
      return 6;
   }
   switch(curChar)
   {
      case 95:
         return jjMoveStringLiteralDfa7_0(active0, 0x400000000L);
      case 66:
      case 98:
         return jjMoveStringLiteralDfa7_0(active0, 0x800000000L);
      case 67:
      case 99:
         return jjMoveStringLiteralDfa7_0(active0, 0x8000000L);
      case 69:
      case 101:
         if ((active0 & 0x80000000L) != 0L)
            return jjStartNfaWithStates_0(6, 31, 27);
         break;
      case 78:
      case 110:
         if ((active0 & 0x4000000L) != 0L)
            return jjStartNfaWithStates_0(6, 26, 27);
         break;
      case 82:
      case 114:
         return jjMoveStringLiteralDfa7_0(active0, 0x200000000L);
      case 83:
      case 115:
         if ((active0 & 0x100000000L) != 0L)
            return jjStartNfaWithStates_0(6, 32, 27);
         break;
      default :
         break;
   }
   return jjStartNfa_0(5, active0, 0L);
}
private final int jjMoveStringLiteralDfa7_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(5, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(6, active0, 0L);
      return 7;
   }
   switch(curChar)
   {
      case 69:
      case 101:
         return jjMoveStringLiteralDfa8_0(active0, 0x200000000L);
      case 82:
      case 114:
         return jjMoveStringLiteralDfa8_0(active0, 0x400000000L);
      case 84:
      case 116:
         if ((active0 & 0x8000000L) != 0L)
            return jjStartNfaWithStates_0(7, 27, 27);
         break;
      case 89:
      case 121:
         return jjMoveStringLiteralDfa8_0(active0, 0x800000000L);
      default :
         break;
   }
   return jjStartNfa_0(6, active0, 0L);
}
private final int jjMoveStringLiteralDfa8_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(6, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(7, active0, 0L);
      return 8;
   }
   switch(curChar)
   {
      case 95:
         return jjMoveStringLiteralDfa9_0(active0, 0x800000000L);
      case 69:
      case 101:
         return jjMoveStringLiteralDfa9_0(active0, 0x400000000L);
      case 83:
      case 115:
         return jjMoveStringLiteralDfa9_0(active0, 0x200000000L);
      default :
         break;
   }
   return jjStartNfa_0(7, active0, 0L);
}
private final int jjMoveStringLiteralDfa9_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(7, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(8, active0, 0L);
      return 9;
   }
   switch(curChar)
   {
      case 82:
      case 114:
         return jjMoveStringLiteralDfa10_0(active0, 0x800000000L);
      case 83:
      case 115:
         return jjMoveStringLiteralDfa10_0(active0, 0x400000000L);
      case 85:
      case 117:
         return jjMoveStringLiteralDfa10_0(active0, 0x200000000L);
      default :
         break;
   }
   return jjStartNfa_0(8, active0, 0L);
}
private final int jjMoveStringLiteralDfa10_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(8, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(9, active0, 0L);
      return 10;
   }
   switch(curChar)
   {
      case 69:
      case 101:
         return jjMoveStringLiteralDfa11_0(active0, 0x800000000L);
      case 76:
      case 108:
         return jjMoveStringLiteralDfa11_0(active0, 0x200000000L);
      case 85:
      case 117:
         return jjMoveStringLiteralDfa11_0(active0, 0x400000000L);
      default :
         break;
   }
   return jjStartNfa_0(9, active0, 0L);
}
private final int jjMoveStringLiteralDfa11_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(9, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(10, active0, 0L);
      return 11;
   }
   switch(curChar)
   {
      case 76:
      case 108:
         return jjMoveStringLiteralDfa12_0(active0, 0x400000000L);
      case 83:
      case 115:
         return jjMoveStringLiteralDfa12_0(active0, 0x800000000L);
      case 84:
      case 116:
         return jjMoveStringLiteralDfa12_0(active0, 0x200000000L);
      default :
         break;
   }
   return jjStartNfa_0(10, active0, 0L);
}
private final int jjMoveStringLiteralDfa12_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(10, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(11, active0, 0L);
      return 12;
   }
   switch(curChar)
   {
      case 83:
      case 115:
         if ((active0 & 0x200000000L) != 0L)
            return jjStartNfaWithStates_0(12, 33, 1);
         break;
      case 84:
      case 116:
         return jjMoveStringLiteralDfa13_0(active0, 0x400000000L);
      case 85:
      case 117:
         return jjMoveStringLiteralDfa13_0(active0, 0x800000000L);
      default :
         break;
   }
   return jjStartNfa_0(11, active0, 0L);
}
private final int jjMoveStringLiteralDfa13_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(11, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(12, active0, 0L);
      return 13;
   }
   switch(curChar)
   {
      case 76:
      case 108:
         return jjMoveStringLiteralDfa14_0(active0, 0x800000000L);
      case 83:
      case 115:
         if ((active0 & 0x400000000L) != 0L)
            return jjStartNfaWithStates_0(13, 34, 1);
         break;
      default :
         break;
   }
   return jjStartNfa_0(12, active0, 0L);
}
private final int jjMoveStringLiteralDfa14_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(12, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(13, active0, 0L);
      return 14;
   }
   switch(curChar)
   {
      case 84:
      case 116:
         return jjMoveStringLiteralDfa15_0(active0, 0x800000000L);
      default :
         break;
   }
   return jjStartNfa_0(13, active0, 0L);
}
private final int jjMoveStringLiteralDfa15_0(long old0, long active0)
{
   if (((active0 &= old0)) == 0L)
      return jjStartNfa_0(13, old0, 0L);
   try { curChar = input_stream.readChar(); }
   catch(java.io.IOException e) {
      jjStopStringLiteralDfa_0(14, active0, 0L);
      return 15;
   }
   switch(curChar)
   {
      case 83:
      case 115:
         if ((active0 & 0x800000000L) != 0L)
            return jjStartNfaWithStates_0(15, 35, 1);
         break;
      default :
         break;
   }
   return jjStartNfa_0(14, active0, 0L);
}
private final void jjCheckNAdd(int state)
{
   if (jjrounds[state] != jjround)
   {
      jjstateSet[jjnewStateCnt++] = state;
      jjrounds[state] = jjround;
   }
}
private final void jjAddStates(int start, int end)
{
   do {
      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
   } while (start++ != end);
}
private final void jjCheckNAddTwoStates(int state1, int state2)
{
   jjCheckNAdd(state1);
   jjCheckNAdd(state2);
}
private final void jjCheckNAddStates(int start, int end)
{
   do {
      jjCheckNAdd(jjnextStates[start]);
   } while (start++ != end);
}
private final void jjCheckNAddStates(int start)
{
   jjCheckNAdd(jjnextStates[start]);
   jjCheckNAdd(jjnextStates[start + 1]);
}
static final long[] jjbitVec0 = {
   0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
};
static final long[] jjbitVec2 = {
   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
};
private final int jjMoveNfa_0(int startState, int curPos)
{
   int[] nextStates;
   int startsAt = 0;
   jjnewStateCnt = 27;
   int i = 1;
   jjstateSet[0] = startState;
   int j, kind = 0x7fffffff;
   for (;;)
   {
      if (++jjround == 0x7fffffff)
         ReInitRounds();
      if (curChar < 64)
      {
         long l = 1L << curChar;
         MatchLoop: do
         {
            switch(jjstateSet[--i])
            {
               case 27:
               case 1:
                  if ((0x3ff001000000000L & l) == 0L)
                     break;
                  if (kind > 38)
                     kind = 38;
                  jjCheckNAdd(1);
                  break;
               case 19:
                  if (curChar == 42)
                     jjCheckNAddTwoStates(22, 23);
                  else if (curChar == 47)
                  {
                     if (kind > 46)
                        kind = 46;
                     jjCheckNAdd(20);
                  }
                  break;
               case 2:
                  if ((0x3ff000000000000L & l) != 0L)
                  {
                     if (kind > 44)
                        kind = 44;
                     jjCheckNAddStates(0, 2);
                  }
                  else if (curChar == 47)
                     jjAddStates(3, 4);
                  else if (curChar == 45)
                     jjstateSet[jjnewStateCnt++] = 13;
                  else if (curChar == 46)
                     jjCheckNAdd(9);
                  else if (curChar == 34)
                     jjCheckNAddTwoStates(6, 7);
                  else if (curChar == 39)
                     jjCheckNAddTwoStates(3, 4);
                  break;
               case 3:
                  if ((0xffffff7fffffffffL & l) != 0L)
                     jjCheckNAddTwoStates(3, 4);
                  break;
               case 4:
                  if (curChar == 39 && kind > 41)
                     kind = 41;
                  break;
               case 5:
                  if (curChar == 34)
                     jjCheckNAddTwoStates(6, 7);
                  break;
               case 6:
                  if ((0xfffffffbffffffffL & l) != 0L)
                     jjCheckNAddTwoStates(6, 7);
                  break;
               case 7:
                  if (curChar == 34 && kind > 42)
                     kind = 42;
                  break;
               case 8:
                  if (curChar == 46)
                     jjCheckNAdd(9);
                  break;
               case 9:
                  if ((0x3ff000000000000L & l) == 0L)
                     break;
                  if (kind > 43)
                     kind = 43;
                  jjCheckNAddTwoStates(9, 10);
                  break;
               case 11:
                  if ((0x280000000000L & l) != 0L)
                     jjCheckNAdd(12);
                  break;
               case 12:
                  if ((0x3ff000000000000L & l) == 0L)
                     break;
                  if (kind > 43)
                     kind = 43;
                  jjCheckNAdd(12);
                  break;
               case 13:
                  if (curChar == 45 && kind > 46)
                     kind = 46;
                  break;
               case 14:
                  if (curChar == 45)
                     jjstateSet[jjnewStateCnt++] = 13;
                  break;
               case 15:
                  if ((0x3ff000000000000L & l) == 0L)
                     break;
                  if (kind > 44)
                     kind = 44;
                  jjCheckNAddStates(0, 2);
                  break;
               case 16:
                  if ((0x3ff000000000000L & l) != 0L)
                     jjCheckNAddTwoStates(16, 8);
                  break;
               case 17:
                  if ((0x3ff000000000000L & l) == 0L)
                     break;
                  if (kind > 44)
                     kind = 44;
                  jjCheckNAdd(17);
                  break;
               case 18:
                  if (curChar == 47)
                     jjAddStates(3, 4);
                  break;
               case 20:
                  if ((0xffffffffffffdbffL & l) == 0L)
                     break;
                  if (kind > 46)
                     kind = 46;
                  jjCheckNAdd(20);
                  break;
               case 21:
                  if (curChar == 42)
                     jjCheckNAddTwoStates(22, 23);
                  break;
               case 22:
                  if ((0xfffffbffffffffffL & l) != 0L)
                     jjCheckNAddTwoStates(22, 23);
                  break;
               case 23:
                  if (curChar == 42)
                     jjCheckNAddStates(5, 7);
                  break;
               case 24:
                  if ((0xffff7bffffffffffL & l) != 0L)
                     jjCheckNAddTwoStates(25, 23);
                  break;
               case 25:
                  if ((0xfffffbffffffffffL & l) != 0L)
                     jjCheckNAddTwoStates(25, 23);
                  break;
               case 26:
                  if (curChar == 47 && kind > 47)
                     kind = 47;
                  break;
               default : break;
            }
         } while(i != startsAt);
      }
      else if (curChar < 128)
      {
         long l = 1L << (curChar & 077);
         MatchLoop: do
         {
            switch(jjstateSet[--i])
            {
               case 27:
                  if ((0x7fffffe87fffffeL & l) != 0L)
                  {
                     if (kind > 38)
                        kind = 38;
                     jjCheckNAdd(1);
                  }
                  if ((0x7fffffe07fffffeL & l) != 0L)
                  {
                     if (kind > 38)
                        kind = 38;
                     jjCheckNAddTwoStates(0, 1);
                  }
                  break;
               case 2:
               case 0:
                  if ((0x7fffffe07fffffeL & l) == 0L)
                     break;
                  if (kind > 38)
                     kind = 38;
                  jjCheckNAddTwoStates(0, 1);
                  break;
               case 1:
                  if ((0x7fffffe87fffffeL & l) == 0L)
                     break;
                  if (kind > 38)
                     kind = 38;
                  jjCheckNAdd(1);
                  break;
               case 3:
                  jjAddStates(8, 9);
                  break;
               case 6:
                  jjAddStates(10, 11);
                  break;
               case 10:
                  if ((0x2000000020L & l) != 0L)
                     jjAddStates(12, 13);
                  break;
               case 20:
                  if (kind > 46)
                     kind = 46;
                  jjstateSet[jjnewStateCnt++] = 20;
                  break;
               case 22:
                  jjCheckNAddTwoStates(22, 23);
                  break;
               case 24:
               case 25:
                  jjCheckNAddTwoStates(25, 23);
                  break;
               default : break;
            }
         } while(i != startsAt);
      }
      else
      {
         int hiByte = (int)(curChar >> 8);
         int i1 = hiByte >> 6;
         long l1 = 1L << (hiByte & 077);
         int i2 = (curChar & 0xff) >> 6;
         long l2 = 1L << (curChar & 077);
         MatchLoop: do
         {
            switch(jjstateSet[--i])
            {
               case 3:
                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
                     jjAddStates(8, 9);
                  break;
               case 6:
                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
                     jjAddStates(10, 11);
                  break;
               case 20:
                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
                     break;
                  if (kind > 46)
                     kind = 46;
                  jjstateSet[jjnewStateCnt++] = 20;
                  break;
               case 22:
                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
                     jjCheckNAddTwoStates(22, 23);
                  break;
               case 24:
               case 25:
                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
                     jjCheckNAddTwoStates(25, 23);
                  break;
               default : break;
            }
         } while(i != startsAt);
      }
      if (kind != 0x7fffffff)
      {
         jjmatchedKind = kind;
         jjmatchedPos = curPos;
         kind = 0x7fffffff;
      }
      ++curPos;
      if ((i = jjnewStateCnt) == (startsAt = 27 - (jjnewStateCnt = startsAt)))
         return curPos;
      try { curChar = input_stream.readChar(); }
      catch(java.io.IOException e) { return curPos; }
   }
}
static final int[] jjnextStates = {
   16, 8, 17, 19, 21, 23, 24, 26, 3, 4, 6, 7, 11, 12, 
};
private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
{
   switch(hiByte)
   {
      case 0:
         return ((jjbitVec2[i2] & l2) != 0L);
      default : 
         if ((jjbitVec0[i1] & l1) != 0L)
            return true;
         return false;
   }
}
public static final String[] jjstrLiteralImages = {
"", null, null, null, null, null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null, "\55\76", null, null, 
null, null, null, null, null, null, null, null, "\72", "\72\137", "\77", "\56", 
"\100", "\73", "\54", "\52", "\133", "\135", "\50", "\51", "\173", "\175", "\44", 
"\76", "\74", "\75", "\76\75", "\74\75", "\74\76", "\41\75", "\53", "\55", "\57", 
"\45", };
public static final String[] lexStateNames = {
   "DEFAULT", 
};
static final long[] jjtoToken = {
   0xffff1e7fffffffe1L, 0x3ffL, 
};
static final long[] jjtoSkip = {
   0xc0000000001eL, 0x0L, 
};
static final long[] jjtoSpecial = {
   0xc00000000000L, 0x0L, 
};
protected JavaCharStream input_stream;
private final int[] jjrounds = new int[27];
private final int[] jjstateSet = new int[54];
protected char curChar;
public JoSQLParserTokenManager(JavaCharStream stream){
   if (JavaCharStream.staticFlag)
      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
   input_stream = stream;
}
public JoSQLParserTokenManager(JavaCharStream stream, int lexState){
   this(stream);
   SwitchTo(lexState);
}
public void ReInit(JavaCharStream stream)
{
   jjmatchedPos = jjnewStateCnt = 0;
   curLexState = defaultLexState;
   input_stream = stream;
   ReInitRounds();
}
private final void ReInitRounds()
{
   int i;
   jjround = 0x80000001;
   for (i = 27; i-- > 0;)
      jjrounds[i] = 0x80000000;
}
public void ReInit(JavaCharStream stream, int lexState)
{
   ReInit(stream);
   SwitchTo(lexState);
}
public void SwitchTo(int lexState)
{
   if (lexState >= 1 || lexState < 0)
      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
   else
      curLexState = lexState;
}

protected Token jjFillToken()
{
   Token t = Token.newToken(jjmatchedKind);
   t.kind = jjmatchedKind;
   String im = jjstrLiteralImages[jjmatchedKind];
   t.image = (im == null) ? input_stream.GetImage() : im;
   t.beginLine = input_stream.getBeginLine();
   t.beginColumn = input_stream.getBeginColumn();
   t.endLine = input_stream.getEndLine();
   t.endColumn = input_stream.getEndColumn();
   return t;
}

int curLexState = 0;
int defaultLexState = 0;
int jjnewStateCnt;
int jjround;
int jjmatchedPos;
int jjmatchedKind;

public Token getNextToken() 
{
  int kind;
  Token specialToken = null;
  Token matchedToken;
  int curPos = 0;

  EOFLoop :
  for (;;)
  {   
   try   
   {     
      curChar = input_stream.BeginToken();
   }     
   catch(java.io.IOException e)
   {        
      jjmatchedKind = 0;
      matchedToken = jjFillToken();
      matchedToken.specialToken = specialToken;
      return matchedToken;
   }

   try { input_stream.backup(0);
      while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L)
         curChar = input_stream.BeginToken();
   }
   catch (java.io.IOException e1) { continue EOFLoop; }
   jjmatchedKind = 0x7fffffff;
   jjmatchedPos = 0;
   curPos = jjMoveStringLiteralDfa0_0();
   if (jjmatchedKind != 0x7fffffff)
   {
      if (jjmatchedPos + 1 < curPos)
         input_stream.backup(curPos - jjmatchedPos - 1);
      if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
      {
         matchedToken = jjFillToken();
         matchedToken.specialToken = specialToken;
         return matchedToken;
      }
      else
      {
         if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
         {
            matchedToken = jjFillToken();
            if (specialToken == null)
               specialToken = matchedToken;
            else
            {
               matchedToken.specialToken = specialToken;
               specialToken = (specialToken.next = matchedToken);
            }
         }
         continue EOFLoop;
      }
   }
   int error_line = input_stream.getEndLine();
   int error_column = input_stream.getEndColumn();
   String error_after = null;
   boolean EOFSeen = false;
   try { input_stream.readChar(); input_stream.backup(1); }
   catch (java.io.IOException e1) {
      EOFSeen = true;
      error_after = curPos <= 1 ? "" : input_stream.GetImage();
      if (curChar == '\n' || curChar == '\r') {
         error_line++;
         error_column = 0;
      }
      else
         error_column++;
   }
   if (!EOFSeen) {
      input_stream.backup(1);
      error_after = curPos <= 1 ? "" : input_stream.GetImage();
   }
   throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
  }
}

}
josql-2.2/src/org/josql/parser/ParseException.java000066400000000000000000000146311157743651500223260ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
package org.josql.parser;

/**
 * This exception is thrown when parse errors are encountered.
 * You can explicitly create objects of this exception type by
 * calling the method generateParseException in the generated
 * parser.
 *
 * You can modify this class to customize your error reporting
 * mechanisms so long as you retain the public fields.
 */
public class ParseException extends Exception {

  /**
   * This constructor is used by the method "generateParseException"
   * in the generated parser.  Calling this constructor generates
   * a new object of this type with the fields "currentToken",
   * "expectedTokenSequences", and "tokenImage" set.  The boolean
   * flag "specialConstructor" is also set to true to indicate that
   * this constructor was used to create this object.
   * This constructor calls its super class with the empty string
   * to force the "toString" method of parent class "Throwable" to
   * print the error message in the form:
   *     ParseException: 
   */
  public ParseException(Token currentTokenVal,
                        int[][] expectedTokenSequencesVal,
                        String[] tokenImageVal
                       )
  {
    super("");
    specialConstructor = true;
    currentToken = currentTokenVal;
    expectedTokenSequences = expectedTokenSequencesVal;
    tokenImage = tokenImageVal;
  }

  /**
   * The following constructors are for use by you for whatever
   * purpose you can think of.  Constructing the exception in this
   * manner makes the exception behave in the normal way - i.e., as
   * documented in the class "Throwable".  The fields "errorToken",
   * "expectedTokenSequences", and "tokenImage" do not contain
   * relevant information.  The JavaCC generated code does not use
   * these constructors.
   */

  public ParseException() {
    super();
    specialConstructor = false;
  }

  public ParseException(String message) {
    super(message);
    specialConstructor = false;
  }

  /**
   * This variable determines which constructor was used to create
   * this object and thereby affects the semantics of the
   * "getMessage" method (see below).
   */
  protected boolean specialConstructor;

  /**
   * This is the last token that has been consumed successfully.  If
   * this object has been created due to a parse error, the token
   * followng this token will (therefore) be the first error token.
   */
  public Token currentToken;

  /**
   * Each entry in this array is an array of integers.  Each array
   * of integers represents a sequence of tokens (by their ordinal
   * values) that is expected at this point of the parse.
   */
  public int[][] expectedTokenSequences;

  /**
   * This is a reference to the "tokenImage" array of the generated
   * parser within which the parse error occurred.  This array is
   * defined in the generated ...Constants interface.
   */
  public String[] tokenImage;

  /**
   * This method has the standard behavior when this object has been
   * created using the standard constructors.  Otherwise, it uses
   * "currentToken" and "expectedTokenSequences" to generate a parse
   * error message and returns it.  If this object has been created
   * due to a parse error, and you do not catch it (it gets thrown
   * from the parser), then this method is called during the printing
   * of the final stack trace, and hence the correct error message
   * gets displayed.
   */
  public String getMessage() {
    if (!specialConstructor) {
      return super.getMessage();
    }
    String expected = "";
    int maxSize = 0;
    for (int i = 0; i < expectedTokenSequences.length; i++) {
      if (maxSize < expectedTokenSequences[i].length) {
        maxSize = expectedTokenSequences[i].length;
      }
      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
        expected += tokenImage[expectedTokenSequences[i][j]] + " ";
      }
      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
        expected += "...";
      }
      expected += eol + "    ";
    }
    String retval = "Encountered \"";
    Token tok = currentToken.next;
    for (int i = 0; i < maxSize; i++) {
      if (i != 0) retval += " ";
      if (tok.kind == 0) {
        retval += tokenImage[0];
        break;
      }
      retval += add_escapes(tok.image);
      tok = tok.next; 
    }
    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
    retval += "." + eol;
    if (expectedTokenSequences.length == 1) {
      retval += "Was expecting:" + eol + "    ";
    } else {
      retval += "Was expecting one of:" + eol + "    ";
    }
    retval += expected;
    return retval;
  }

  /**
   * The end of line string for this machine.
   */
  protected String eol = System.getProperty("line.separator", "\n");
 
  /**
   * Used to convert raw characters to their escaped version
   * when these raw version cannot be used as part of an ASCII
   * string literal.
   */
  protected String add_escapes(String str) {
      StringBuffer retval = new StringBuffer();
      char ch;
      for (int i = 0; i < str.length(); i++) {
        switch (str.charAt(i))
        {
           case 0 :
              continue;
           case '\b':
              retval.append("\\b");
              continue;
           case '\t':
              retval.append("\\t");
              continue;
           case '\n':
              retval.append("\\n");
              continue;
           case '\f':
              retval.append("\\f");
              continue;
           case '\r':
              retval.append("\\r");
              continue;
           case '\"':
              retval.append("\\\"");
              continue;
           case '\'':
              retval.append("\\\'");
              continue;
           case '\\':
              retval.append("\\\\");
              continue;
           default:
              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
                 String s = "0000" + Integer.toString(ch, 16);
                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
              } else {
                 retval.append(ch);
              }
              continue;
        }
      }
      return retval.toString();
   }

}
josql-2.2/src/org/josql/parser/SimpleCharStream.java000066400000000000000000000235071157743651500226020ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 3.0 */
package org.josql.parser;

/**
 * An implementation of interface CharStream, where the stream is assumed to
 * contain only ASCII characters (without unicode processing).
 */

public class SimpleCharStream
{
  public static final boolean staticFlag = false;
  int bufsize;
  int available;
  int tokenBegin;
  public int bufpos = -1;
  protected int bufline[];
  protected int bufcolumn[];

  protected int column = 0;
  protected int line = 1;

  protected boolean prevCharIsCR = false;
  protected boolean prevCharIsLF = false;

  protected java.io.Reader inputStream;

  protected char[] buffer;
  protected int maxNextCharInd = 0;
  protected int inBuf = 0;

  protected void ExpandBuff(boolean wrapAround)
  {
     char[] newbuffer = new char[bufsize + 2048];
     int newbufline[] = new int[bufsize + 2048];
     int newbufcolumn[] = new int[bufsize + 2048];

     try
     {
        if (wrapAround)
        {
           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
           System.arraycopy(buffer, 0, newbuffer,
                                             bufsize - tokenBegin, bufpos);
           buffer = newbuffer;

           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
           bufline = newbufline;

           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
           bufcolumn = newbufcolumn;

           maxNextCharInd = (bufpos += (bufsize - tokenBegin));
        }
        else
        {
           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
           buffer = newbuffer;

           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
           bufline = newbufline;

           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
           bufcolumn = newbufcolumn;

           maxNextCharInd = (bufpos -= tokenBegin);
        }
     }
     catch (Throwable t)
     {
        throw new Error(t.getMessage());
     }


     bufsize += 2048;
     available = bufsize;
     tokenBegin = 0;
  }

  protected void FillBuff() throws java.io.IOException
  {
     if (maxNextCharInd == available)
     {
        if (available == bufsize)
        {
           if (tokenBegin > 2048)
           {
              bufpos = maxNextCharInd = 0;
              available = tokenBegin;
           }
           else if (tokenBegin < 0)
              bufpos = maxNextCharInd = 0;
           else
              ExpandBuff(false);
        }
        else if (available > tokenBegin)
           available = bufsize;
        else if ((tokenBegin - available) < 2048)
           ExpandBuff(true);
        else
           available = tokenBegin;
     }

     int i;
     try {
        if ((i = inputStream.read(buffer, maxNextCharInd,
                                    available - maxNextCharInd)) == -1)
        {
           inputStream.close();
           throw new java.io.IOException();
        }
        else
           maxNextCharInd += i;
        return;
     }
     catch(java.io.IOException e) {
        --bufpos;
        backup(0);
        if (tokenBegin == -1)
           tokenBegin = bufpos;
        throw e;
     }
  }

  public char BeginToken() throws java.io.IOException
  {
     tokenBegin = -1;
     char c = readChar();
     tokenBegin = bufpos;

     return c;
  }

  protected void UpdateLineColumn(char c)
  {
     column++;

     if (prevCharIsLF)
     {
        prevCharIsLF = false;
        line += (column = 1);
     }
     else if (prevCharIsCR)
     {
        prevCharIsCR = false;
        if (c == '\n')
        {
           prevCharIsLF = true;
        }
        else
           line += (column = 1);
     }

     switch (c)
     {
        case '\r' :
           prevCharIsCR = true;
           break;
        case '\n' :
           prevCharIsLF = true;
           break;
        case '\t' :
           column--;
           column += (8 - (column & 07));
           break;
        default :
           break;
     }

     bufline[bufpos] = line;
     bufcolumn[bufpos] = column;
  }

  public char readChar() throws java.io.IOException
  {
     if (inBuf > 0)
     {
        --inBuf;

        if (++bufpos == bufsize)
           bufpos = 0;

        return buffer[bufpos];
     }

     if (++bufpos >= maxNextCharInd)
        FillBuff();

     char c = buffer[bufpos];

     UpdateLineColumn(c);
     return (c);
  }

  /**
   * @deprecated 
   * @see #getEndColumn
   */

  public int getColumn() {
     return bufcolumn[bufpos];
  }

  /**
   * @deprecated 
   * @see #getEndLine
   */

  public int getLine() {
     return bufline[bufpos];
  }

  public int getEndColumn() {
     return bufcolumn[bufpos];
  }

  public int getEndLine() {
     return bufline[bufpos];
  }

  public int getBeginColumn() {
     return bufcolumn[tokenBegin];
  }

  public int getBeginLine() {
     return bufline[tokenBegin];
  }

  public void backup(int amount) {

    inBuf += amount;
    if ((bufpos -= amount) < 0)
       bufpos += bufsize;
  }

  public SimpleCharStream(java.io.Reader dstream, int startline,
  int startcolumn, int buffersize)
  {
    inputStream = dstream;
    line = startline;
    column = startcolumn - 1;

    available = bufsize = buffersize;
    buffer = new char[buffersize];
    bufline = new int[buffersize];
    bufcolumn = new int[buffersize];
  }

  public SimpleCharStream(java.io.Reader dstream, int startline,
                                                           int startcolumn)
  {
     this(dstream, startline, startcolumn, 4096);
  }

  public SimpleCharStream(java.io.Reader dstream)
  {
     this(dstream, 1, 1, 4096);
  }
  public void ReInit(java.io.Reader dstream, int startline,
  int startcolumn, int buffersize)
  {
    inputStream = dstream;
    line = startline;
    column = startcolumn - 1;

    if (buffer == null || buffersize != buffer.length)
    {
      available = bufsize = buffersize;
      buffer = new char[buffersize];
      bufline = new int[buffersize];
      bufcolumn = new int[buffersize];
    }
    prevCharIsLF = prevCharIsCR = false;
    tokenBegin = inBuf = maxNextCharInd = 0;
    bufpos = -1;
  }

  public void ReInit(java.io.Reader dstream, int startline,
                                                           int startcolumn)
  {
     ReInit(dstream, startline, startcolumn, 4096);
  }

  public void ReInit(java.io.Reader dstream)
  {
     ReInit(dstream, 1, 1, 4096);
  }
  public SimpleCharStream(java.io.InputStream dstream, int startline,
  int startcolumn, int buffersize)
  {
     this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
  }

  public SimpleCharStream(java.io.InputStream dstream, int startline,
                                                           int startcolumn)
  {
     this(dstream, startline, startcolumn, 4096);
  }

  public SimpleCharStream(java.io.InputStream dstream)
  {
     this(dstream, 1, 1, 4096);
  }

  public void ReInit(java.io.InputStream dstream, int startline,
                          int startcolumn, int buffersize)
  {
     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
  }

  public void ReInit(java.io.InputStream dstream)
  {
     ReInit(dstream, 1, 1, 4096);
  }
  public void ReInit(java.io.InputStream dstream, int startline,
                                                           int startcolumn)
  {
     ReInit(dstream, startline, startcolumn, 4096);
  }
  public String GetImage()
  {
     if (bufpos >= tokenBegin)
        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
     else
        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
                              new String(buffer, 0, bufpos + 1);
  }

  public char[] GetSuffix(int len)
  {
     char[] ret = new char[len];

     if ((bufpos + 1) >= len)
        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
     else
     {
        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
                                                          len - bufpos - 1);
        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
     }

     return ret;
  }

  public void Done()
  {
     buffer = null;
     bufline = null;
     bufcolumn = null;
  }

  /**
   * Method to adjust line and column numbers for the start of a token.
   */
  public void adjustBeginLineColumn(int newLine, int newCol)
  {
     int start = tokenBegin;
     int len;

     if (bufpos >= tokenBegin)
     {
        len = bufpos - tokenBegin + inBuf + 1;
     }
     else
     {
        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
     }

     int i = 0, j = 0, k = 0;
     int nextColDiff = 0, columnDiff = 0;

     while (i < len &&
            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
     {
        bufline[j] = newLine;
        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
        bufcolumn[j] = newCol + columnDiff;
        columnDiff = nextColDiff;
        i++;
     } 

     if (i < len)
     {
        bufline[j] = newLine++;
        bufcolumn[j] = newCol + columnDiff;

        while (i++ < len)
        {
           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
              bufline[j] = newLine++;
           else
              bufline[j] = newLine;
        }
     }

     line = bufline[j];
     column = bufcolumn[j];
  }

}
josql-2.2/src/org/josql/parser/Token.java000066400000000000000000000052701157743651500204540ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
package org.josql.parser;

/**
 * Describes the input token stream.
 */

public class Token {

  /**
   * An integer that describes the kind of this token.  This numbering
   * system is determined by JavaCCParser, and a table of these numbers is
   * stored in the file ...Constants.java.
   */
  public int kind;

  /**
   * beginLine and beginColumn describe the position of the first character
   * of this token; endLine and endColumn describe the position of the
   * last character of this token.
   */
  public int beginLine, beginColumn, endLine, endColumn;

  /**
   * The string image of the token.
   */
  public String image;

  /**
   * A reference to the next regular (non-special) token from the input
   * stream.  If this is the last token from the input stream, or if the
   * token manager has not read tokens beyond this one, this field is
   * set to null.  This is true only if this token is also a regular
   * token.  Otherwise, see below for a description of the contents of
   * this field.
   */
  public Token next;

  /**
   * This field is used to access special tokens that occur prior to this
   * token, but after the immediately preceding regular (non-special) token.
   * If there are no such special tokens, this field is set to null.
   * When there are more than one such special token, this field refers
   * to the last of these special tokens, which in turn refers to the next
   * previous special token through its specialToken field, and so on
   * until the first special token (whose specialToken field is null).
   * The next fields of special tokens refer to other special tokens that
   * immediately follow it (without an intervening regular token).  If there
   * is no such token, this field is null.
   */
  public Token specialToken;

  /**
   * Returns the image.
   */
  public String toString()
  {
     return image;
  }

  /**
   * Returns a new Token object, by default. However, if you want, you
   * can create and return subclass objects based on the value of ofKind.
   * Simply add the cases to the switch for all those special cases.
   * For example, if you have a subclass of Token called IDToken that
   * you want to create if ofKind is ID, simlpy add something like :
   *
   *    case MyParserConstants.ID : return new IDToken();
   *
   * to the following switch statement. Then you can cast matchedToken
   * variable to the appropriate type and use it in your lexical actions.
   */
  public static final Token newToken(int ofKind)
  {
     switch(ofKind)
     {
       default : return new Token();
     }
  }

}
josql-2.2/src/org/josql/parser/TokenMgrError.java000066400000000000000000000103641157743651500221340ustar00rootroot00000000000000/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
package org.josql.parser;

public class TokenMgrError extends Error
{
   /*
    * Ordinals for various reasons why an Error of this type can be thrown.
    */

   /**
    * Lexical error occured.
    */
   static final int LEXICAL_ERROR = 0;

   /**
    * An attempt wass made to create a second instance of a static token manager.
    */
   static final int STATIC_LEXER_ERROR = 1;

   /**
    * Tried to change to an invalid lexical state.
    */
   static final int INVALID_LEXICAL_STATE = 2;

   /**
    * Detected (and bailed out of) an infinite loop in the token manager.
    */
   static final int LOOP_DETECTED = 3;

   /**
    * Indicates the reason why the exception is thrown. It will have
    * one of the above 4 values.
    */
   int errorCode;

   /**
    * Replaces unprintable characters by their espaced (or unicode escaped)
    * equivalents in the given string
    */
   protected static final String addEscapes(String str) {
      StringBuffer retval = new StringBuffer();
      char ch;
      for (int i = 0; i < str.length(); i++) {
        switch (str.charAt(i))
        {
           case 0 :
              continue;
           case '\b':
              retval.append("\\b");
              continue;
           case '\t':
              retval.append("\\t");
              continue;
           case '\n':
              retval.append("\\n");
              continue;
           case '\f':
              retval.append("\\f");
              continue;
           case '\r':
              retval.append("\\r");
              continue;
           case '\"':
              retval.append("\\\"");
              continue;
           case '\'':
              retval.append("\\\'");
              continue;
           case '\\':
              retval.append("\\\\");
              continue;
           default:
              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
                 String s = "0000" + Integer.toString(ch, 16);
                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
              } else {
                 retval.append(ch);
              }
              continue;
        }
      }
      return retval.toString();
   }

   /**
    * Returns a detailed message for the Error when it is thrown by the
    * token manager to indicate a lexical error.
    * Parameters : 
    *    EOFSeen     : indicates if EOF caused the lexicl error
    *    curLexState : lexical state in which this error occured
    *    errorLine   : line number when the error occured
    *    errorColumn : column number when the error occured
    *    errorAfter  : prefix that was seen before this error occured
    *    curchar     : the offending character
    * Note: You can customize the lexical error message by modifying this method.
    */
   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
      return("Lexical error at line " +
           errorLine + ", column " +
           errorColumn + ".  Encountered: " +
           (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
           "after : \"" + addEscapes(errorAfter) + "\"");
   }

   /**
    * You can also modify the body of this method to customize your error messages.
    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
    * of end-users concern, so you can return something like : 
    *
    *     "Internal Error : Please file a bug report .... "
    *
    * from this method for such cases in the release version of your parser.
    */
   public String getMessage() {
      return super.getMessage();
   }

   /*
    * Constructors of various flavors follow.
    */

   public TokenMgrError() {
   }

   public TokenMgrError(String message, int reason) {
      super(message);
      errorCode = reason;
   }

   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
   }
}
josql-2.2/src/org/josql/utils/000077500000000000000000000000001157743651500163715ustar00rootroot00000000000000josql-2.2/src/org/josql/utils/ExpressionEvaluator.java000066400000000000000000000231101157743651500232530ustar00rootroot00000000000000/*
 * Copyright 2004-2007 Gary Bentley 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may 
 * not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 *    http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
package org.josql.utils;

import java.util.List;
import java.util.ArrayList;

import org.josql.Query;
import org.josql.QueryParseException;
import org.josql.QueryExecutionException;

import org.josql.expressions.Expression;

/**
 * This class can be used as a convenient way of evaluating an expression
 * without having to use the Query object itself.
 * 

* In this way you can easily evaluate JoSQL expressions against objects. *

* Usage: *

* Use the static methods to evaluate the expression in one call, for instance to * find out details about a file: *

* String exp = "path + ', size: ' + formatNumber(length) + ', last modified: ' + formatDate(lastModified)
* String details = ExpressionEvaluator.getValue (exp, new File ('/home/me/myfile.txt')); */ public class ExpressionEvaluator { private Expression where = null; private Query q = null; /** * Create a new expression evaluator. * * @param exp The expression to be evaluated. * @param cl The class of the object(s) that the expression will be * evaluated against. * @throws QueryParseException If the expression cannot be parsed. */ public ExpressionEvaluator (String exp, Class cl) throws QueryParseException { this (exp, cl, null); } /** * Create a new expression evaluator. * * @param exp The expression to be evaluated. * @param cl The class of the object(s) that the expression will be * evaluated against. * @param fhs A list of function handlers that contain functions that will * be used by the expression, can be null. * @throws QueryParseException If the expression cannot be parsed. */ public ExpressionEvaluator (String exp, Class cl, List fhs) throws QueryParseException { Query q = new Query (); if (fhs != null) { for (int i = 0; i < fhs.size (); i++) { q.addFunctionHandler (fhs.get (i)); } } q.parse ("SELECT * FROM " + cl.getName () + " WHERE " + exp); this.q = q; this.where = q.getWhereClause (); } /** * Get the query associated with the expression, use this to setup * bind variables, function handlers and so on, which of course must * be setup prior to evaluating the expression. * * @return The Query object. */ public Query getQuery () { return this.q; } /** * Evaluate the expression against the object passed in. * * @param o The object to evaluate the expression against. * @return The value of calling Expression.isTrue (Query, Object). * @throws QueryExecutionException If the expression cannot be executed. */ public boolean isTrue (Object o) throws QueryExecutionException { if (o == null) { throw new NullPointerException ("Object passed in is null."); } return this.where.isTrue (o, this.q); } /** * Evaluate the expression against the list of objects passed in and * return the value. * * @param l The list of objects to evaluate the expression against. * @return The values gained when evaluating the expression against all * the objects in the list. * @throws QueryExecutionException If the expression cannot be executed. */ public List getValues (List l) throws QueryExecutionException { if (l == null) { throw new NullPointerException ("List is null"); } int s = l.size (); List ret = new ArrayList (s); for (int i = s - 1; i > -1; i--) { ret.set (i, this.getValue (l.get (i))); } return ret; } /** * Evaluate the expression against the object passed in and return the * value. * * @param o The object to evaluate the expression against. * @return The value gained when evaluating the expression against * the object. * @throws QueryExecutionException If the expression cannot be executed. */ public Object getValue (Object o) throws QueryExecutionException { return this.where.getValue (o, this.q); } /** * Evaluate the expression against the object passed in. * * @param exp A string representation of the expression to evaluate. * @param o The object to evaluate the expression against. * @return The value of calling Expression.isTrue (Query, Object). * @throws QueryParseException If the expression cannot be parsed. * @throws QueryExecutionException If the expression cannot be executed. */ public static boolean isTrue (String exp, Object o) throws QueryParseException, QueryExecutionException { if (o == null) { throw new NullPointerException ("Object passed in is null."); } ExpressionEvaluator ee = new ExpressionEvaluator (exp, o.getClass ()); return ee.isTrue (o); } /** * Evaluate the expression against the list of objects passed in and * return the value. * * @param exp A string representation of the expression to evaluate. * @param l The list of objects to evaluate the expression against. * @return The values gained when evaluating the expression against all * the objects in the list. * @throws QueryParseException If the expression cannot be parsed. * @throws QueryExecutionException If the expression cannot be executed. */ public static List getValues (String exp, List l) throws QueryParseException, QueryExecutionException { if (l == null) { throw new NullPointerException ("List is null"); } if (l.size () == 0) { return new ArrayList (); } Class c = null; for (int i = 0; i < l.size (); i++) { Object o = l.get (i); if (o != null) { c = o.getClass (); if (c != null) { break; } } } if (c == null) { throw new NullPointerException ("All objects in the list are null"); } ExpressionEvaluator ee = new ExpressionEvaluator (exp, c); return ee.getValues (l); } /** * Evaluate the expression against the object passed in and return the * value. * * @param exp A string representation of the expression to evaluate. * @param o The object to evaluate the expression against. * @return The value gained when evaluating the expression against * the object. * @throws QueryParseException If the expression cannot be parsed. * @throws QueryExecutionException If the expression cannot be executed. */ public static Object getValue (String exp, Object o) throws QueryParseException, QueryExecutionException { if (o == null) { throw new NullPointerException ("Object passed in is null."); } ExpressionEvaluator ee = new ExpressionEvaluator (exp, o.getClass ()); return ee.getValue (o); } }josql-2.2/src/org/josql/utils/JoSQLComparator.java000066400000000000000000000215371157743651500222240ustar00rootroot00000000000000/* * Copyright 2004-2007 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.josql.utils; import java.util.List; import java.util.Comparator; import org.josql.Query; import org.josql.QueryParseException; import org.josql.QueryExecutionException; import org.josql.internal.ListExpressionComparator; /** * This class allows the ORDER BY clause of a JoSQL SQL clause to be used * as a Comparator. It should be noted that is the same as performing: {@link Query#execute(List)} * but there are times when having a separate comparator is desirable. * The EXECUTE ON ALL clause is supported but you must call: {@link #doExecuteOn(List)} * first to ensure that they are executed. *

* This class is basically just a thin wrapper around using the comparator gained by * calling: {@link Query#getOrderByComparator()}. *

* A note on performance, for small numbers of objects (around 1000) this comparator * has (for vanilla accessors, no function calls) pretty comparable performance against a * hand-coded Java Comparator that performs the same function. However start to scale the * numbers of objects and performance degrades, in testing for ~34000 FileWrapper objects * to order by: path DESC, lastModified, name, length took around: 1300ms. * The hand-coded Java Comparator took around: 180ms! The upshot is, if you need flexibility * and do not need to order large numbers of objects then use this kind of Comparator, if * performance and numbers of objects is an issue then hand-rolling your own Comparator * is probably best. As a side-note, to perform the following order by: * lower(path) DESC, lastModified, name, length using a JoSQLComparator took: * about: 1400ms. However modifying the hand-coded Comparator to use: * {@link String#compareToIgnoreCase(String)} then took about 860ms! And if you using: * {@link String#toLowerCase()} for each string instead, it then takes about: 1800ms! * (Meaning that in certain circumstances JoSQL can be faster!) *

*

Caching

*

* It is not uncommon for a Comparator (even using the effecient merge-sort implementation of * {@link java.util.Collections#sort(List,Comparator)}) to perform thousands (even millions!) * of comparisons.

* However since JoSQL does not automatically cache the results of calls to functions and * results of accessor accesses the performance of this kind of "dynamic" Comparator can * quickly degrade. To mitigate this it is possible to turn "caching" on whereby the * Comparator will "remember" the results of the functions on a per object basis and use those * values instead of calling them again. This is not without it's downside however. * Firstly since a reference to the object will be held it is important (if caching is used * that you call: {@link #clearCache()} once the Comparator has been used to free up those * references (it was considered using a {@link java.util.WeakHashMap} but that doesn't provide * exactly what's needed here).

* It is recommended that caching is turned on when the Comparator is to be used in a sort * operation , i.e. calling: {@link java.util.Collections#sort(List,Comparator)} or similar * (however careful consideration needs to be given to the amount of memory that this * may consume, i.e. 4 bytes = 1 object reference, plus 1 List, plus 4 bytes per order * by "column" it soon adds up)

* If the comparator is to be used in a {@link java.util.TreeMap} or {@link java.util.TreeSet} * then caching should not be used since the values may (and perhaps should) change over time * but due to caching the order won't change. */ public class JoSQLComparator implements Comparator { private Query q = null; private Exception exp = null; private ListExpressionComparator c = null; /** * Execute the EXECUTE ON ALL expressions. * * @param l The list to execute the expressions on. */ public void doExecuteOn (List l) throws QueryExecutionException { this.q.doExecuteOn (l, Query.ALL); } /** * Clear the cache, it is VITAL that you call this method before you use * the comparator (if it has been used before) otherwise data objects will * be "left around" and preventing the GC from cleaning them up. */ public void clearCache () { if (this.q != null) { this.c.clearCache (); } } /** * Return whether this comparator uses caching to improve performance. * * @return true if caching is on. * @throws IllegalStateException If the query has not yet been parsed or set. */ public boolean isCaching () throws IllegalStateException { if ((this.q == null) || (!this.q.parsed ()) ) { throw new IllegalStateException ("Query has not yet been parsed."); } return this.c.isCaching (); } /** * Set whether the comparator should use caching to improve performance. * * @param b Set to true to turn caching on. * @throws IllegalStateException If the query has not yet been parsed or set. */ public void setCaching (boolean b) throws IllegalStateException { if ((this.q == null) || (!this.q.parsed ()) ) { throw new IllegalStateException ("Query has not yet been parsed."); } this.c.setCaching (b); } /** * Init this filter with the query. * * @param q The query. * @throws QueryParseException If there is an issue with the parsing of the query. */ public JoSQLComparator (String q) throws QueryParseException { this.setQuery (q); } /** * Compares the objects as according to the ORDER BY clause. * * @param o1 The first object. * @param o2 The second object. */ public int compare (Object o1, Object o2) { try { return c.ci (o1, o2); } catch (Exception e) { this.exp = e; return 0; } } /** * Init this file filter with the query already built and parsed. * * @param q The query. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not as expected. */ public JoSQLComparator (Query q) throws IllegalStateException, QueryParseException { this.setQuery (q); } /** * The {@link Comparator#compare(Object,Object)} method does not allow for * any exceptions to be thrown however since the execution of the ORDER BY clause * on the objects can cause the throwing of a {@link QueryParseException} it should * be captured. If the exception is thrown then this method will return it. * * @return The exception thrown by the execution of the ORDER BY clause in {@link #compare(Object,Object)} * or by sub-class/interface specific methods, this may be null if no exception was thrown. */ public Exception getException () { return this.exp; } /** * Set a new Query (string form) for use in this filter. * * @param q The Query to use. * @throws QueryParseException If there is an issue with the parsing of the query, * or if the FROM class is not as expected. */ public void setQuery (String q) throws QueryParseException { this.q = new Query (); this.q.parse (q); this.c = (ListExpressionComparator) this.q.getOrderByComparator (); this.exp = null; } /** * Set a new Query object for use in this filter. * * @param q The Query to use. * @throws IllegalStateException If the Query object has not been parsed. * @throws QueryParseException If the FROM class is not as expected. */ public void setQuery (Query q) throws IllegalStateException, QueryParseException { if (!q.parsed ()) { throw new IllegalStateException ("Query has not yet been parsed."); } this.q = q; this.c = (ListExpressionComparator) this.q.getOrderByComparator (); this.exp = null; } /** * Get the Query we are using to process objects. * * @return The Query. */ public Query getQuery () { return this.q; } }