package org.litesoft.orsup.selection; // Copyright Status: // // All Software available from LiteSoft.org (including this file) is // hereby released into the public domain. // // It is free! As in, you may use it freely in both commercial and // non-commercial applications, bundle it with your software // distribution, include it on a CD-ROM, list the source code in a book, // mirror the documentation at your own web site, or use it in any other // way you see fit. // // NO Warranty! // // All software is provided "as is". // // There is ABSOLUTELY NO WARRANTY OF ANY KIND: not for the design, fitness // (for a particular purpose), level of errors (or lack thereof), or // applicability of this software. The entire risk as to the quality // and performance of this software is with you. Should this software // prove defective, you assume the cost of all necessary servicing, repair // or correction. // // In no event unless required by applicable law or agreed to in writing // will any party who created or may modify and/or redistribute this // software, be liable to you for damages, including any general, // special, incidental or consequential damages arising out of the use or // inability to use this software (including but not limited to loss of // data or data being rendered inaccurate or losses sustained by you or // third parties or a failure of this software to operate with any // other programs), even if such holder or other party has been advised // of the possibility of such damages. // // NOTE: Should you discover a bug, have a recogmendation for a change, wish // to submit modifications, or wish to add new classes/functionality, // please email them to: // // changes44@litesoft.org // /** * A Factory to generate a representation of a SQL WHERE clause.

* * Using this Factory a complex SQL WHERE clause can be generated. * The concrete extensions of WhereClause generated by this Factory * can form a tree that represents any arbitrarily complex expression.

* * If you need to create/support a specific SQL WHERE clause that * is not provided, you would need to extend this class and probably one of * the abstract WhereClause helper classes listed in WhereClause.

* * See WhereClause

* * Exceptions: All problems caught when the parameter(s) are checked (as * indicated/implied in the @param tags) will generate an IllegalArgumentException, * and means the API user has a problem. If a NullPointerException (or some * others, like: ClassCastException or ArrayIndexOutOfBoundsException) is thrown, * it means the API developer has a problem. Any Exception that is explicitly * thrown in the API, but unrelated to a parameter, will be listed in the throws * clause (and hopefully in the tag @throws). These may (but probably won't) be * checked Exceptions. * * @author George Smith * @version 1.03 02/07/02 Exception Policy, Use of IllegalArgument class. * @version 1.02 11/05/01 Completed? JavaDocs * @version 1.01 10/10/01 * @version 1.0 10/07/01 */ public class WhereClauseFactory { /** * Constructor that simply instantiates this Factory.

*/ public WhereClauseFactory() { } /** * Return an OR SQL WHERE clause of two other WHERE clauses.

* * Note: If either (or both) of the two WhereClauses are them selves * OR WhereClauses then, the WhereClause(s) are * merged (collapsed to this new one).

* * @param pWhereClause1 First of the two WHERE clauses (!null). * @param pWhereClause2 Second of the two WHERE clauses (!null).

* * @return OR merged WhereClauses. */ public WhereClause or( WhereClause pWhereClause1 , WhereClause pWhereClause2 ) { return new WC_OR( pWhereClause1 , pWhereClause2 ); } /** * Return an AND SQL WHERE clause of two other WHERE clauses.

* * Note: If either (or both) of the two WhereClauses are them selves * AND WhereClauses then, the WhereClause(s) are * merged (collapsed to this new one).

* * @param pWhereClause1 First of the two WHERE clauses (!null). * @param pWhereClause2 Second of the two WHERE clauses (!null).

* * @return AND merged WhereClauses. */ public WhereClause and( WhereClause pWhereClause1 , WhereClause pWhereClause2 ) { return new WC_AND( pWhereClause1 , pWhereClause2 ); } /** * Return a NOTed SQL WHERE clause.

* * @param pWhereClause The WhereClause that is to be NOTed (!null).

* * @return NOTed WhereClause. */ public WhereClause not( WhereClause pWhereClause ) { if ( !(pWhereClause instanceof WhereClauseNotable) ) return new WC_NOT( pWhereClause ); ((WhereClauseNotable) pWhereClause).switchNot(); return pWhereClause; } /** * Create a SQL WHERE clause that checks that a column is * NULL.

* * @param pColumnDefinition Column Definition (!null).

* * @return NULL WhereClause. */ public WhereClause isNull( SimpleColumnDefinition pColumnDefinition ) { return new WC_IS_NULL( pColumnDefinition ); } /** * Create a SQL WHERE clause that checks that a column is * NOT NULL.

* * @param pColumnDefinition Column Definition (!null).

* * @return NOT NULL WhereClause.

* * @see #not(WhereClause) * @see #isNull(SimpleColumnDefinition) */ public WhereClause isNotNull( SimpleColumnDefinition pColumnDefinition ) { return not( isNull( pColumnDefinition ) ); } /** * Create a SQL WHERE clause that checks that a column is * equal to an Object value.

* * Note: Due to the pecular nature of Java's null and the SQL NULL, * the resulting SQL WHERE clause may become "IS NULL".

* * @param pColumnDefinition Column Definition (!null). * @param pValue Compare with value (!null).

* * @return equal to WhereClause.

* * @see #isNull(SimpleColumnDefinition) */ public WhereClause isEqual( SimpleColumnDefinition pColumnDefinition , Object pValue ) { if ( pValue == null ) return isNull( pColumnDefinition ); return new WC_EQUALS( pColumnDefinition , pValue ); } /** * Create a SQL WHERE clause that checks that a column is * equal to an int value.

* * @param pColumnDefinition Column Definition (!null). * @param pInt Compare with int.

* * @return equal to WhereClause.

* * @see #isEqual(SimpleColumnDefinition,Object) */ public WhereClause isEqual( SimpleColumnDefinition pColumnDefinition , int pInt ) { return isEqual( pColumnDefinition , new Integer( pInt ) ); } /** * Create a SQL WHERE clause that checks that a column is * NOT equal to an Object value.

* * Note: Due to the pecular nature of Java's null and the SQL NULL, * the resulting SQL WHERE clause will either be "IS NOT NULL" or * will or in an "IS NULL".

* * @param pColumnDefinition Column Definition (!null). * @param pValue Compare with value (!null).

* * @return NOT equal to WhereClause.

* * @see #not(WhereClause) * @see #isEqual(SimpleColumnDefinition,Object) * @see #isNotNull(SimpleColumnDefinition) * @see #isNull(SimpleColumnDefinition) * @see #or(WhereClause,WhereClause) */ public WhereClause isNotEqual( SimpleColumnDefinition pColumnDefinition , Object pValue ) { return not( isEqual( pColumnDefinition , pValue ) ); } /** * Create a SQL WHERE clause that checks that a column is * NOT equal to an int value.

* * Note: Due to the pecular nature of SQL NULLs, the resulting SQL * WHERE clause will or in an "IS NULL".

* * @param pColumnDefinition Column Definition (!null). * @param pInt Compare with int.

* * @return NOT equal to WhereClause.

* * @see #not(WhereClause) * @see #isEqual(SimpleColumnDefinition,int) * @see #isNull(SimpleColumnDefinition) * @see #or(WhereClause,WhereClause) */ public WhereClause isNotEqual( SimpleColumnDefinition pColumnDefinition , int pInt ) { return not( isEqual( pColumnDefinition , pInt ) ); } /** * Create a SQL WHERE clause that checks that a column is * less than an Object value.

* * @param pColumnDefinition Column Definition (!null). * @param pValue Compare with value (!null).

* * @return less than WhereClause. */ public WhereClause isLessThan( SimpleColumnDefinition pColumnDefinition , Object pValue ) { return new WC_LESSTHAN( pColumnDefinition , pValue ); } /** * Create a SQL WHERE clause that checks that a column is * less than an int value.

* * @param pColumnDefinition Column Definition (!null). * @param pInt Compare with int.

* * @return less than to WhereClause.

* * @see #isLessThan(SimpleColumnDefinition,Object) */ public WhereClause isLessThan( SimpleColumnDefinition pColumnDefinition , int pInt ) { return isLessThan( pColumnDefinition , new Integer( pInt ) ); } /** * Create a SQL WHERE clause that checks that a column is * greater than or equal to an Object value.

* * @param pColumnDefinition Column Definition (!null). * @param pValue Compare with value (!null).

* * @return greater than or equal to WhereClause.

* * @see #not(WhereClause) * @see #isLessThan(SimpleColumnDefinition,Object) */ public WhereClause isNotLessThan( SimpleColumnDefinition pColumnDefinition , Object pValue ) { return not( isLessThan( pColumnDefinition , pValue ) ); } /** * Create a SQL WHERE clause that checks that a column is * greater than or equal to an int value.

* * @param pColumnDefinition Column Definition (!null). * @param pInt Compare with int.

* * @return greater than or equal to WhereClause.

* * @see #not(WhereClause) * @see #isLessThan(SimpleColumnDefinition,int) */ public WhereClause isNotLessThan( SimpleColumnDefinition pColumnDefinition , int pInt ) { return not( isLessThan( pColumnDefinition , pInt ) ); } /** * Create a SQL WHERE clause that checks that a column is * greater than an Object value.

* * @param pColumnDefinition Column Definition (!null). * @param pValue Compare with value (!null).

* * @return greater than to WhereClause. */ public WhereClause isGreaterThan( SimpleColumnDefinition pColumnDefinition , Object pValue ) { return new WC_GREATERTHAN( pColumnDefinition , pValue ); } /** * Create a SQL WHERE clause that checks that a column is * greater than an int value.

* * @param pColumnDefinition Column Definition (!null). * @param pInt Compare with int.

* * @return greater than to WhereClause.

* * @see #isGreaterThan(SimpleColumnDefinition,Object) */ public WhereClause isGreaterThan( SimpleColumnDefinition pColumnDefinition , int pInt ) { return isGreaterThan( pColumnDefinition , new Integer( pInt ) ); } /** * Create a SQL WHERE clause that checks that a column is * less than or equal to an Object value.

* * @param pColumnDefinition Column Definition (!null). * @param pValue Compare with value (!null).

* * @return less than or equal to WhereClause.

* * @see #not(WhereClause) * @see #isGreaterThan(SimpleColumnDefinition,Object) */ public WhereClause isNotGreaterThan( SimpleColumnDefinition pColumnDefinition , Object pValue ) { return not( isGreaterThan( pColumnDefinition , pValue ) ); } /** * Create a SQL WHERE clause that checks that a column is * less than or equal to an int value.

* * @param pColumnDefinition Column Definition (!null). * @param pInt Compare with int.

* * @return less than or equal to WhereClause.

* * @see #not(WhereClause) * @see #isGreaterThan(SimpleColumnDefinition,int) */ public WhereClause isNotGreaterThan( SimpleColumnDefinition pColumnDefinition , int pInt ) { return not( isGreaterThan( pColumnDefinition , pInt ) ); } /** * Create a SQL WHERE clause that checks that a column is * between (INCLUSIVE) two (Object) values.

* * Note: if the left and right values are equal, then the * WhereClause is of type isEqual.

* * @param pColumnDefinition Column Definition (!null). * @param pGEvalue Greater Than or Equal (left) value (!null). * @param pLEvalue Less Than or Equal (right) value (!null).

* * @return BETWEEN (or equal) WhereClause.

* * @see #isEqual(SimpleColumnDefinition,Object) */ public WhereClause isBetween( SimpleColumnDefinition pColumnDefinition , Object pGEvalue , Object pLEvalue ) { if ( (pGEvalue == pLEvalue) || ((pGEvalue != null) && pGEvalue.equals( pLEvalue )) ) return isEqual( pColumnDefinition , pGEvalue ); return new WC_BETWEEN( pColumnDefinition , pGEvalue , pLEvalue ); } /** * Create a SQL WHERE clause that checks that a column is * between (INCLUSIVE) two int values.

* * Note: if the left and right ints are equal, then the * WhereClause is of type isEqual.

* * @param pColumnDefinition Column Definition (!null). * @param pGEint Greater Than or Equal (left) value. * @param pLEint Less Than or Equal (right) value.

* * @return BETWEEN (or equal) WhereClause.

* * @see #isBetween(SimpleColumnDefinition,Object,Object) * @see #isEqual(SimpleColumnDefinition,int) */ public WhereClause isBetween( SimpleColumnDefinition pColumnDefinition , int pGEint , int pLEint ) { if ( pGEint == pLEint ) return isEqual( pColumnDefinition , pGEint ); return isBetween( pColumnDefinition , new Integer( pGEint ) , new Integer( pLEint ) ); } /** * Create a SQL WHERE clause that checks that a column is Not * between (INCLUSIVE) two (Object) values.

* * Note: if the left and right values are equal, then the * WhereClause is of type isNotEqual.

* * @param pColumnDefinition Column Definition (!null). * @param pGEvalue Greater Than or Equal (left) value (!null). * @param pLEvalue Less Than or Equal (right) value (!null).

* * @return NOT BETWEEN (or not equal) WhereClause.

* * @see #not(WhereClause) * @see #isBetween(SimpleColumnDefinition,Object,Object) * @see #isNotEqual(SimpleColumnDefinition,Object) */ public WhereClause isNotBetween( SimpleColumnDefinition pColumnDefinition , Object pGEvalue , Object pLEvalue ) { return not( isBetween( pColumnDefinition , pGEvalue , pLEvalue ) ); } /** * Create a SQL WHERE clause that checks that a column is Not * between (INCLUSIVE) two int values.

* * Note: if the left and right ints are equal, then the * WhereClause is of type isNotEqual.

* * @param pColumnDefinition Column Definition (!null). * @param pGEint Greater Than or Equal (left) value. * @param pLEint Less Than or Equal (right) value.

* * @return NOT BETWEEN (or not equal) WhereClause.

* * @see #not(WhereClause) * @see #isBetween(SimpleColumnDefinition,int,int) * @see #isNotEqual(SimpleColumnDefinition,int) */ public WhereClause isNotBetween( SimpleColumnDefinition pColumnDefinition , int pGEint , int pLEint ) { return not( isBetween( pColumnDefinition , pGEint , pLEint ) ); } /** * Create a SQL WHERE clause that checks that a String column * contains a particular set of characters.

* * @param pColumnDefinition Column Definition (!null). * @param pValue String that carries the particular set of characters for checking (!null).

* * @return LIKE (any where) WhereClause. */ public WhereClause contains( SimpleColumnDefinition pColumnDefinition , String pValue ) { return new WC_CONTAINS( pColumnDefinition , pValue ); } /** * Create a SQL WHERE clause that checks that a String column * does Not contain a particular set of characters.

* * @param pColumnDefinition Column Definition (!null). * @param pValue String that carries the particular set of characters for checking (!null).

* * @return NOT LIKE (any where) WhereClause.

* * @see #not(WhereClause) * @see #contains(SimpleColumnDefinition,String) */ public WhereClause doesNotContain( SimpleColumnDefinition pColumnDefinition , String pValue ) { return not( contains( pColumnDefinition , pValue ) ); } /** * Create a SQL WHERE clause that checks that a String column * Starts With a particular set of characters.

* * @param pColumnDefinition Column Definition (!null). * @param pValue String that carries the particular set of characters for checking (!null).

* * @return LIKE (on front) WhereClause. */ public WhereClause startsWith( SimpleColumnDefinition pColumnDefinition , String pValue ) { return new WC_STARTS_WITH( pColumnDefinition , pValue ); } /** * Create a SQL WHERE clause that checks that a String column * does Not Start With a particular set of characters.

* * @param pColumnDefinition Column Definition (!null). * @param pValue String that carries the particular set of characters for checking (!null).

* * @return NOT LIKE (on front) WhereClause.

* * @see #not(WhereClause) * @see #startsWith(SimpleColumnDefinition,String) */ public WhereClause doesNotStartWith( SimpleColumnDefinition pColumnDefinition , String pValue ) { return not( startsWith( pColumnDefinition , pValue ) ); } /** * Create a SQL WHERE clause that checks that a String column * Ends With a particular set of characters.

* * @param pColumnDefinition Column Definition (!null). * @param pValue String that carries the particular set of characters for checking (!null).

* * @return LIKE (on end) WhereClause. */ public WhereClause endsWith( SimpleColumnDefinition pColumnDefinition , String pValue ) { return new WC_ENDS_WITH( pColumnDefinition , pValue ); } /** * Create a SQL WHERE clause that checks that a String column * does Not End With a particular set of characters.

* * @param pColumnDefinition Column Definition (!null). * @param pValue String that carries the particular set of characters for checking (!null).

* * @return NOT LIKE (on end) WhereClause.

* * @see #not(WhereClause) * @see #endsWith(SimpleColumnDefinition,String) */ public WhereClause doesNotEndWith( SimpleColumnDefinition pColumnDefinition , String pValue ) { return not( endsWith( pColumnDefinition , pValue ) ); } /** * Create a SQL IN WHERE clause.

* * Note: the Column Types of the ColumnDefinition and selected column of * the SingleColumnSelect MUST be equal, otherwise an IllegalArgumentException * is thrown.

* * @param pColumnDefinition Column Definition (!null). * @param pSingleColumnSelect A single column mini-SELECT command (!null).

* * @return IN WhereClause. */ public WhereClause isIn( SimpleColumnDefinition pColumnDefinition , SingleColumnSelect pSingleColumnSelect ) { return new WC_IS_IN( pColumnDefinition , pSingleColumnSelect ); } /** * Create a SQL NOT IN WHERE clause.

* * Note: the Column Types of the ColumnDefinition and selected column of * the SingleColumnSelect MUST be equal, otherwise an IllegalArgumentException * is thrown.

* * @param pColumnDefinition Column Definition (!null). * @param pSingleColumnSelect A single column mini-SELECT command (!null).

* * @return NOT IN WhereClause.

* * @see #not(WhereClause) * @see #isIn(SimpleColumnDefinition,SingleColumnSelect) */ public WhereClause isNotIn( SimpleColumnDefinition pColumnDefinition , SingleColumnSelect pSingleColumnSelect ) { return not( isIn( pColumnDefinition , pSingleColumnSelect ) ); } // static inner classes to "leverage" the automatic namespacing... private static class WC_OR extends AbstractWhereClauseAssociativeList { WC_OR( WhereClause pWhereClause1 , WhereClause pWhereClause2 ) { super( WhereClause.OR , "OR" , "OR" , pWhereClause1 , pWhereClause2 ); } } private static class WC_AND extends AbstractWhereClauseAssociativeList { WC_AND( WhereClause pWhereClause1 , WhereClause pWhereClause2 ) { super( WhereClause.AND , "AND" , "AND" , pWhereClause1 , pWhereClause2 ); } } private static class WC_NOT extends AbstractWhereClauseWrapper { WC_NOT( WhereClause pWrappedWhereClause ) { super( WhereClause.NOT , "NOT" , "NOT" , pWrappedWhereClause ); } } private static class WC_IS_NULL extends AbstractWhereClauseColumnReference { WC_IS_NULL( SimpleColumnDefinition pColumnDefinition ) { super( WhereClause.IS_NULL , pColumnDefinition ); } protected void toStringHelper( StringBuffer pSB ) { toStringColumnReference( pSB ); pSB.append( isNot() ? " != null" : " == null" ); } protected void toSqlHelper( StringBuffer pSB ) { toSqlColumnReference( pSB ); pSB.append( isNot() ? " IS NOT NULL" : " IS NULL" ); } } private static class WC_EQUALS extends AbstractWhereClauseColumnAndValue { WC_EQUALS( SimpleColumnDefinition pColumnDefinition , Object pValue ) { super( WhereClause.EQUALS , pColumnDefinition , "==" , "=" , // String , SQL "!=" , "<>" , // String , SQL pValue ); } protected void toSqlHelper( StringBuffer pSB ) { if ( !isNot() ) // Regular super.toSqlHelper( pSB ); else { pSB.append( '(' ); super.toSqlHelper( pSB ); pSB.append( ") OR (" ); toSqlColumnReference( pSB ); pSB.append( " IS NULL)" ); } } } private static class WC_LESSTHAN extends AbstractWhereClauseColumnAndValue { WC_LESSTHAN( SimpleColumnDefinition pColumnDefinition , Object pValue ) { super( WhereClause.LESSTHAN , pColumnDefinition , "<" , "<" , // String , SQL ">=" , ">=" , // String , SQL pValue ); } } private static class WC_GREATERTHAN extends AbstractWhereClauseColumnAndValue { WC_GREATERTHAN( SimpleColumnDefinition pColumnDefinition , Object pValue ) { super( WhereClause.GREATERTHAN , pColumnDefinition , ">" , ">" , // String , SQL "<=" , "<=" , // String , SQL pValue ); } } private static class WC_BETWEEN extends AbstractWhereClauseColumnAndTwoValues { WC_BETWEEN( SimpleColumnDefinition pColumnDefinition , Object pLeftValue , Object pRightValue ) { super( WhereClause.BETWEEN , pColumnDefinition , pLeftValue , pRightValue ); } protected void toStringHelper( StringBuffer pSB ) { if ( !isNot() ) cuteStringHelper( pSB ); else { pSB.append( "NOT (" ); cuteStringHelper( pSB ); pSB.append( ')' ); } } private void cuteStringHelper( StringBuffer pSB ) { WhereClauseColumnSupport.makeStringValue( pSB , getColumnDefinition() , getLeftValue() ); pSB.append( " <= " ); toStringColumnReference( pSB ); pSB.append( " <= " ); WhereClauseColumnSupport.makeStringValue( pSB , getColumnDefinition() , getRightValue() ); } protected void toSqlHelper( StringBuffer pSB ) { toSqlColumnReference( pSB ); pSB.append( isNot() ? " NOT BETWEEN " : " BETWEEN " ); WhereClauseColumnSupport.makeSqlValue( pSB , getColumnDefinition() , getLeftValue() ); pSB.append( " AND " ); WhereClauseColumnSupport.makeSqlValue( pSB , getColumnDefinition() , getRightValue() ); } } private static class WC_CONTAINS extends AbstractWhereClauseColumnAndLikeValue { WC_CONTAINS( SimpleColumnDefinition pColumnDefinition , String pValue ) { super( WhereClause.CONTAINS , pColumnDefinition , true , true , "Contains" , pValue ); } } private static class WC_STARTS_WITH extends AbstractWhereClauseColumnAndLikeValue { WC_STARTS_WITH( SimpleColumnDefinition pColumnDefinition , String pValue ) { super( WhereClause.STARTS_WITH , pColumnDefinition , false , true , "StartsWith" , pValue ); } } private static class WC_ENDS_WITH extends AbstractWhereClauseColumnAndLikeValue { WC_ENDS_WITH( SimpleColumnDefinition pColumnDefinition , String pValue ) { super( WhereClause.ENDS_WITH , pColumnDefinition , true , false , "EndsWith" , pValue ); } } private static class WC_IS_IN extends AbstractWhereClauseColumnIsIn { WC_IS_IN( SimpleColumnDefinition pColumnDefinition , SingleColumnSelect pSingleColumnSelect ) { super( WhereClause.IS_IN , pColumnDefinition , pSingleColumnSelect ); } } }