1 package org.apache.torque.util; 2 3 21 22 import java.io.IOException ; 23 import java.io.ObjectInputStream ; 24 import java.io.ObjectOutputStream ; 25 import java.io.Serializable ; 26 import java.lang.reflect.Array ; 27 import java.math.BigDecimal ; 28 import java.util.ArrayList ; 29 import java.util.Arrays ; 30 import java.util.GregorianCalendar ; 31 import java.util.HashMap ; 32 import java.util.Hashtable ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 37 import org.apache.commons.collections.OrderedMap; 38 import org.apache.commons.collections.map.ListOrderedMap; 39 import org.apache.commons.lang.ObjectUtils; 40 import org.apache.commons.lang.StringUtils; 41 import org.apache.commons.logging.Log; 42 import org.apache.commons.logging.LogFactory; 43 import org.apache.torque.Torque; 44 import org.apache.torque.TorqueException; 45 import org.apache.torque.adapter.DB; 46 import org.apache.torque.om.DateKey; 47 import org.apache.torque.om.ObjectKey; 48 49 69 public class Criteria extends Hashtable 70 { 71 72 private static final long serialVersionUID = -9001666575933085601L; 73 74 75 public static final SqlEnum EQUAL = SqlEnum.EQUAL; 76 77 78 public static final SqlEnum NOT_EQUAL = SqlEnum.NOT_EQUAL; 79 80 81 public static final SqlEnum ALT_NOT_EQUAL = SqlEnum.ALT_NOT_EQUAL; 82 83 84 public static final SqlEnum GREATER_THAN = SqlEnum.GREATER_THAN; 85 86 87 public static final SqlEnum LESS_THAN = SqlEnum.LESS_THAN; 88 89 90 public static final SqlEnum GREATER_EQUAL = SqlEnum.GREATER_EQUAL; 91 92 93 public static final SqlEnum LESS_EQUAL = SqlEnum.LESS_EQUAL; 94 95 96 public static final SqlEnum LIKE = SqlEnum.LIKE; 97 98 99 public static final SqlEnum NOT_LIKE = SqlEnum.NOT_LIKE; 100 101 102 public static final SqlEnum ILIKE = SqlEnum.ILIKE; 103 104 105 public static final SqlEnum NOT_ILIKE = SqlEnum.NOT_ILIKE; 106 107 108 public static final SqlEnum CUSTOM = SqlEnum.CUSTOM; 109 110 111 public static final SqlEnum DISTINCT = SqlEnum.DISTINCT; 112 113 114 public static final SqlEnum IN = SqlEnum.IN; 115 116 117 public static final SqlEnum NOT_IN = SqlEnum.NOT_IN; 118 119 120 public static final SqlEnum ALL = SqlEnum.ALL; 121 122 123 public static final SqlEnum JOIN = SqlEnum.JOIN; 124 125 126 private static final SqlEnum ASC = SqlEnum.ASC; 127 128 129 private static final SqlEnum DESC = SqlEnum.DESC; 130 131 132 public static final SqlEnum ISNULL = SqlEnum.ISNULL; 133 134 135 public static final SqlEnum ISNOTNULL = SqlEnum.ISNOTNULL; 136 137 138 public static final SqlEnum CURRENT_DATE = SqlEnum.CURRENT_DATE; 139 140 141 public static final SqlEnum CURRENT_TIME = SqlEnum.CURRENT_TIME; 142 143 144 public static final SqlEnum LEFT_JOIN = SqlEnum.LEFT_JOIN; 145 146 147 public static final SqlEnum RIGHT_JOIN = SqlEnum.RIGHT_JOIN; 148 149 150 public static final SqlEnum INNER_JOIN = SqlEnum.INNER_JOIN; 151 152 private static final int DEFAULT_CAPACITY = 10; 153 154 private boolean ignoreCase = false; 155 private boolean singleRecord = false; 156 private boolean cascade = false; 157 private UniqueList selectModifiers = new UniqueList(); 158 private UniqueList selectColumns = new UniqueList(); 159 private UniqueList orderByColumns = new UniqueList(); 160 private UniqueList groupByColumns = new UniqueList(); 161 private Criterion having = null; 162 private OrderedMap asColumns = ListOrderedMap.decorate(new HashMap ()); 163 private transient List joins = null; 164 165 166 private String dbName; 167 168 169 private String originalDbName; 170 171 175 private int limit = -1; 176 177 178 private int offset = 0; 179 180 private HashMap aliases = null; 181 182 private boolean useTransaction = false; 183 184 185 private static Log log = LogFactory.getLog(Criteria.class); 186 187 190 public Criteria() 191 { 192 this(DEFAULT_CAPACITY); 193 } 194 195 200 public Criteria(int initialCapacity) 201 { 202 this(Torque.getDefaultDB(), initialCapacity); 203 } 204 205 211 public Criteria(String dbName) 212 { 213 this(dbName, DEFAULT_CAPACITY); 214 } 215 216 223 public Criteria(String dbName, int initialCapacity) 224 { 225 super(initialCapacity); 226 this.dbName = dbName; 227 this.originalDbName = dbName; 228 } 229 230 235 public void clear() 236 { 237 super.clear(); 238 ignoreCase = false; 239 singleRecord = false; 240 cascade = false; 241 selectModifiers.clear(); 242 selectColumns.clear(); 243 orderByColumns.clear(); 244 groupByColumns.clear(); 245 having = null; 246 asColumns.clear(); 247 joins = null; 248 dbName = originalDbName; 249 offset = 0; 250 limit = -1; 251 aliases = null; 252 useTransaction = false; 253 } 254 255 272 public Criteria addAsColumn(String name, String clause) 273 { 274 asColumns.put(name, clause); 275 return this; 276 } 277 278 284 public Map getAsColumns() 285 { 286 return asColumns; 287 } 288 289 294 public Map getAliases() 295 { 296 return aliases; 297 } 298 299 306 public void addAlias(String alias, String table) 307 { 308 if (aliases == null) 309 { 310 aliases = new HashMap (8); 311 } 312 aliases.put(alias, table); 313 } 314 315 321 public String getTableForAlias(String alias) 322 { 323 if (aliases == null) 324 { 325 return null; 326 } 327 return (String ) aliases.get(alias); 328 } 329 330 337 public boolean containsKey(String table, String column) 338 { 339 return containsKey(table + '.' + column); 340 } 341 342 348 public boolean getBoolean(String column) 349 { 350 return ((Boolean ) getCriterion(column).getValue()).booleanValue(); 351 } 352 353 360 public boolean getBoolean(String table, String column) 361 { 362 return getBoolean(new StringBuffer (table.length() + column.length() + 1) 363 .append(table).append('.').append(column) 364 .toString()); 365 } 366 367 373 public void setUseTransaction(boolean v) 374 { 375 useTransaction = v; 376 } 377 378 384 protected boolean isUseTransaction() 385 { 386 return useTransaction; 387 } 388 389 395 public Criterion getCriterion(String column) 396 { 397 return (Criterion) super.get(column); 398 } 399 400 407 public Criterion getCriterion(String table, String column) 408 { 409 return getCriterion( 410 new StringBuffer (table.length() + column.length() + 1) 411 .append(table).append('.').append(column) 412 .toString()); 413 } 414 415 423 public Criterion getNewCriterion(String column, Object value, 424 SqlEnum comparison) 425 { 426 return new Criterion(column, value, comparison); 427 } 428 429 438 public Criterion getNewCriterion(String table, String column, 439 Object value, SqlEnum comparison) 440 { 441 return new Criterion(table, column, value, comparison); 442 } 443 444 462 public Criteria add(Criterion c) 463 { 464 StringBuffer sb = new StringBuffer (c.getTable().length() 465 + c.getColumn().length() + 1); 466 sb.append(c.getTable()); 467 sb.append('.'); 468 sb.append(c.getColumn()); 469 super.put(sb.toString(), c); 470 return this; 471 } 472 473 479 public String getColumnName(String name) 480 { 481 return getCriterion(name).getColumn(); 482 } 483 484 490 public SqlEnum getComparison(String key) 491 { 492 return getCriterion(key).getComparison(); 493 } 494 495 502 public SqlEnum getComparison(String table, String column) 503 { 504 return getComparison( 505 new StringBuffer (table.length() + column.length() + 1) 506 .append(table).append('.').append(column) 507 .toString()); 508 } 509 510 516 public java.util.Date getDate(String name) 517 { 518 return (java.util.Date ) getCriterion(name).getValue(); 519 } 520 521 528 public java.util.Date getDate(String table, String column) 529 { 530 return getDate( 531 new StringBuffer (table.length() + column.length() + 1) 532 .append(table).append('.').append(column) 533 .toString()); 534 } 535 536 542 public String getDbName() 543 { 544 return dbName; 545 } 546 547 553 public void setDbName(String dbName) 554 { 555 this.dbName = (dbName == null ? Torque.getDefaultDB() : dbName.trim()); 556 } 557 558 564 public double getDouble(String name) 565 { 566 Object obj = getCriterion(name).getValue(); 567 if (obj instanceof String ) 568 { 569 return new Double ((String ) obj).doubleValue(); 570 } 571 return ((Double ) obj).doubleValue(); 572 } 573 574 581 public double getDouble(String table, String column) 582 { 583 return getDouble(new StringBuffer (table.length() + column.length() + 1) 584 .append(table).append('.').append(column) 585 .toString()); 586 } 587 588 594 public float getFloat(String name) 595 { 596 Object obj = getCriterion(name).getValue(); 597 if (obj instanceof String ) 598 { 599 return new Float ((String ) obj).floatValue(); 600 } 601 return ((Float ) obj).floatValue(); 602 } 603 604 611 public float getFloat(String table, String column) 612 { 613 return getFloat(new StringBuffer (table.length() + column.length() + 1) 614 .append(table).append('.').append(column) 615 .toString()); 616 } 617 618 624 public Integer getInteger(String name) 625 { 626 Object obj = getCriterion(name).getValue(); 627 if (obj instanceof String ) 628 { 629 return new Integer ((String ) obj); 630 } 631 return ((Integer ) obj); 632 } 633 634 641 public Integer getInteger(String table, String column) 642 { 643 return getInteger( 644 new StringBuffer (table.length() + column.length() + 1) 645 .append(table).append('.').append(column) 646 .toString()); 647 } 648 649 655 public int getInt(String name) 656 { 657 Object obj = getCriterion(name).getValue(); 658 if (obj instanceof String ) 659 { 660 return new Integer ((String ) obj).intValue(); 661 } 662 return ((Integer ) obj).intValue(); 663 } 664 665 672 public int getInt(String table, String column) 673 { 674 return getInt( 675 new StringBuffer (table.length() + column.length() + 1) 676 .append(table).append('.').append(column) 677 .toString()); 678 } 679 680 686 public BigDecimal getBigDecimal(String name) 687 { 688 Object obj = getCriterion(name).getValue(); 689 if (obj instanceof String ) 690 { 691 return new BigDecimal ((String ) obj); 692 } 693 return (BigDecimal ) obj; 694 } 695 696 703 public BigDecimal getBigDecimal(String table, String column) 704 { 705 return getBigDecimal( 706 new StringBuffer (table.length() + column.length() + 1) 707 .append(table).append('.').append(column) 708 .toString()); 709 } 710 711 717 public long getLong(String name) 718 { 719 Object obj = getCriterion(name).getValue(); 720 if (obj instanceof String ) 721 { 722 return new Long ((String ) obj).longValue(); 723 } 724 return ((Long ) obj).longValue(); 725 } 726 727 734 public long getLong(String table, String column) 735 { 736 return getLong( 737 new StringBuffer (table.length() + column.length() + 1) 738 .append(table).append('.').append(column) 739 .toString()); 740 } 741 742 748 public String getString(String name) 749 { 750 return (String ) getCriterion(name).getValue(); 751 } 752 753 760 public String getString(String table, String column) 761 { 762 return getString( 763 new StringBuffer (table.length() + column.length() + 1) 764 .append(table).append('.').append(column) 765 .toString()); 766 } 767 768 774 public String getTableName(String name) 775 { 776 return getCriterion(name).getTable(); 777 } 778 779 785 public List getList(String name) 786 { 787 return (List ) getCriterion(name).getValue(); 788 } 789 790 797 public List getList(String table, String column) 798 { 799 return getList( 800 new StringBuffer (table.length() + column.length() + 1) 801 .append(table).append('.').append(column) 802 .toString()); 803 } 804 805 811 public Object getValue(String name) 812 { 813 return getCriterion(name).getValue(); 814 } 815 816 823 public Object getValue(String table, String column) 824 { 825 return getValue( 826 new StringBuffer (table.length() + column.length() + 1) 827 .append(table).append('.').append(column) 828 .toString()); 829 } 830 831 837 public ObjectKey getObjectKey(String name) 838 { 839 return (ObjectKey) getCriterion(name).getValue(); 840 } 841 842 849 public ObjectKey getObjectKey(String table, String column) 850 { 851 return getObjectKey( 852 new StringBuffer (table.length() + column.length() + 1) 853 .append(table).append('.').append(column) 854 .toString()); 855 } 856 857 864 public Object get(Object key) 865 { 866 return getValue((String ) key); 867 } 868 869 884 public Object put(Object key, Object value) 885 { 886 if (!(key instanceof String )) 887 { 888 throw new NullPointerException ( 889 "Criteria: Key must be a String object."); 890 } 891 return add((String ) key, value); 892 } 893 894 904 public synchronized void putAll(Map t) 905 { 906 Iterator i = t.entrySet().iterator(); 907 while (i.hasNext()) 908 { 909 Map.Entry e = (Map.Entry ) i.next(); 910 Object val = e.getValue(); 911 if (val instanceof Criteria.Criterion) 912 { 913 super.put(e.getKey(), val); 914 } 915 else 916 { 917 put(e.getKey(), val); 918 } 919 } 920 if (t instanceof Criteria) 921 { 922 Criteria c = (Criteria) t; 923 this.joins = c.joins; 924 } 925 942 } 943 944 966 public Criteria add (String column, Object value) 967 { 968 add(column, value, EQUAL); 969 return this; 970 } 971 972 996 public Criteria add(String column, Object value, SqlEnum comparison) 997 { 998 super.put(column, new Criterion(column, value, comparison)); 999 return this; 1000 } 1001 1002 1022 public Criteria add(String table, String column, Object value) 1023 { 1024 add(table, column, value, EQUAL); 1025 return this; 1026 } 1027 1028 1050 public Criteria add(String table, 1051 String column, 1052 Object value, 1053 SqlEnum comparison) 1054 { 1055 StringBuffer sb = new StringBuffer (table.length() 1056 + column.length() + 1); 1057 sb.append(table); 1058 sb.append('.'); 1059 sb.append(column); 1060 super.put(sb.toString(), 1061 new Criterion(table, column, value, comparison)); 1062 return this; 1063 } 1064 1065 1079 public Criteria add(String column, boolean value) 1080 { 1081 add(column, (value ? Boolean.TRUE : Boolean.FALSE)); 1082 return this; 1083 } 1084 1085 1100 public Criteria add(String column, boolean value, SqlEnum comparison) 1101 { 1102 add(column, new Boolean (value), comparison); 1103 return this; 1104 } 1105 1106 1119 public Criteria add(String column, int value) 1120 { 1121 add(column, new Integer (value)); 1122 return this; 1123 } 1124 1125 1140 public Criteria add(String column, int value, SqlEnum comparison) 1141 { 1142 add(column, new Integer (value), comparison); 1143 return this; 1144 } 1145 1146 1159 public Criteria add(String column, long value) 1160 { 1161 add(column, new Long (value)); 1162 return this; 1163 } 1164 1165 1180 public Criteria add(String column, long value, SqlEnum comparison) 1181 { 1182 add(column, new Long (value), comparison); 1183 return this; 1184 } 1185 1186 1199 public Criteria add(String column, float value) 1200 { 1201 add(column, new Float (value)); 1202 return this; 1203 } 1204 1205 1220 public Criteria add(String column, float value, SqlEnum comparison) 1221 { 1222 add(column, new Float (value), comparison); 1223 return this; 1224 } 1225 1226 1239 public Criteria add(String column, double value) 1240 { 1241 add(column, new Double (value)); 1242 return this; 1243 } 1244 1245 1260 public Criteria add(String column, double value, SqlEnum comparison) 1261 { 1262 add(column, new Double (value), comparison); 1263 return this; 1264 } 1265 1266 1283 public Criteria addDate(String column, int year, int month, int date) 1284 { 1285 add(column, new GregorianCalendar (year, month, date).getTime()); 1286 return this; 1287 } 1288 1289 1308 public Criteria addDate(String column, int year, int month, int date, 1309 SqlEnum comparison) 1310 { 1311 add(column, new GregorianCalendar (year, month, date).getTime(), 1312 comparison); 1313 return this; 1314 } 1315 1316 1331 public Criteria addJoin(String left, String right) 1332 { 1333 return addJoin(left, right, null); 1334 } 1335 1336 1354 public Criteria addJoin(String left, String right, SqlEnum operator) 1355 { 1356 if (joins == null) 1357 { 1358 joins = new ArrayList (3); 1359 } 1360 joins.add(new Join(left, right, operator)); 1361 1362 return this; 1363 } 1364 1365 1371 public List getJoins() 1372 { 1373 return joins; 1374 } 1375 1376 1382 public List getJoinL() 1383 { 1384 throw new RuntimeException ("getJoinL() in Criteria is no longer supported!"); 1385 } 1386 1387 1393 public List getJoinR() 1394 { 1395 throw new RuntimeException ("getJoinL() in Criteria is no longer supported!"); 1396 } 1397 1398 1416 public Criteria addIn(String column, Object [] values) 1417 { 1418 add(column, (Object ) values, Criteria.IN); 1419 return this; 1420 } 1421 1422 1439 public Criteria addIn(String column, int[] values) 1440 { 1441 add(column, (Object ) values, Criteria.IN); 1442 return this; 1443 } 1444 1445 1463 public Criteria addIn(String column, List values) 1464 { 1465 add(column, (Object ) values, Criteria.IN); 1466 return this; 1467 } 1468 1469 1487 public Criteria addNotIn(String column, Object [] values) 1488 { 1489 add(column, (Object ) values, Criteria.NOT_IN); 1490 return this; 1491 } 1492 1493 1510 public Criteria addNotIn(String column, int[] values) 1511 { 1512 add(column, (Object ) values, Criteria.NOT_IN); 1513 return this; 1514 } 1515 1516 1534 public Criteria addNotIn(String column, List values) 1535 { 1536 add(column, (Object ) values, Criteria.NOT_IN); 1537 return this; 1538 } 1539 1540 1543 public void setAll() 1544 { 1545 selectModifiers.add(ALL.toString()); 1546 } 1547 1548 1551 public void setDistinct() 1552 { 1553 selectModifiers.add(DISTINCT.toString()); 1554 } 1555 1556 1562 public Criteria setIgnoreCase(boolean b) 1563 { 1564 ignoreCase = b; 1565 return this; 1566 } 1567 1568 1573 public boolean isIgnoreCase() 1574 { 1575 return ignoreCase; 1576 } 1577 1578 1591 public Criteria setSingleRecord(boolean b) 1592 { 1593 singleRecord = b; 1594 return this; 1595 } 1596 1597 1602 public boolean isSingleRecord() 1603 { 1604 return singleRecord; 1605 } 1606 1607 1613 public Criteria setCascade(boolean b) 1614 { 1615 cascade = b; 1616 return this; 1617 } 1618 1619 1624 public boolean isCascade() 1625 { 1626 return cascade; 1627 } 1628 1629 1635 public Criteria setLimit(int limit) 1636 { 1637 this.limit = limit; 1638 return this; 1639 } 1640 1641 1646 public int getLimit() 1647 { 1648 return limit; 1649 } 1650 1651 1657 public Criteria setOffset(int offset) 1658 { 1659 this.offset = offset; 1660 return this; 1661 } 1662 1663 1668 public int getOffset() 1669 { 1670 return offset; 1671 } 1672 1673 1679 public Criteria addSelectColumn(String name) 1680 { 1681 selectColumns.add(name); 1682 return this; 1683 } 1684 1685 1691 public UniqueList getSelectColumns() 1692 { 1693 return selectColumns; 1694 } 1695 1696 1701 public UniqueList getSelectModifiers() 1702 { 1703 return selectModifiers; 1704 } 1705 1706 1712 public Criteria addGroupByColumn(String groupBy) 1713 { 1714 groupByColumns.add(groupBy); 1715 return this; 1716 } 1717 1718 1724 public Criteria addAscendingOrderByColumn(String name) 1725 { 1726 orderByColumns.add(name + ' ' + ASC); 1727 return this; 1728 } 1729 1730 1736 public Criteria addDescendingOrderByColumn(String name) 1737 { 1738 orderByColumns.add(name + ' ' + DESC); 1739 return this; 1740 } 1741 1742 1747 public UniqueList getOrderByColumns() 1748 { 1749 return orderByColumns; 1750 } 1751 1752 1757 public UniqueList getGroupByColumns() 1758 { 1759 return groupByColumns; 1760 } 1761 1762 1767 public Criterion getHaving() 1768 { 1769 return having; 1770 } 1771 1772 1778 public Object remove(String key) 1779 { 1780 Object foo = super.remove(key); 1781 if (foo instanceof Criterion) 1782 { 1783 return ((Criterion) foo).getValue(); 1784 } 1785 return foo; 1786 } 1787 1788 1793 public String toString() 1794 { 1795 StringBuffer sb = new StringBuffer ("Criteria:: "); 1796 Iterator it = keySet().iterator(); 1797 while (it.hasNext()) 1798 { 1799 String key = (String ) it.next(); 1800 sb.append(key).append("<=>") 1801 .append(super.get(key).toString()).append(": "); 1802 } 1803 1804 try 1805 { 1806 sb.append("\nCurrent Query SQL (may not be complete or applicable): ") 1807 .append(BasePeer.createQueryDisplayString(this)); 1808 } 1809 catch (Exception exc) 1810 { 1811 log.debug("Exception when evaluating a Criteria", exc); 1812 } 1813 1814 return sb.toString(); 1815 } 1816 1817 1821 public boolean equals(Object crit) 1822 { 1823 boolean isEquiv = false; 1824 if (crit == null || !(crit instanceof Criteria)) 1825 { 1826 isEquiv = false; 1827 } 1828 else if (this == crit) 1829 { 1830 isEquiv = true; 1831 } 1832 else if (this.size() == ((Criteria) crit).size()) 1833 { 1834 Criteria criteria = (Criteria) crit; 1835 if (this.offset == criteria.getOffset() 1836 && this.limit == criteria.getLimit() 1837 && ignoreCase == criteria.isIgnoreCase() 1838 && singleRecord == criteria.isSingleRecord() 1839 && cascade == criteria.isCascade() 1840 && dbName.equals(criteria.getDbName()) 1841 && selectModifiers.equals(criteria.getSelectModifiers()) 1842 && selectColumns.equals(criteria.getSelectColumns()) 1843 && orderByColumns.equals(criteria.getOrderByColumns()) 1844 && ObjectUtils.equals(aliases, criteria.getAliases()) 1845 && asColumns.equals(criteria.getAsColumns()) 1846 && joins.equals(criteria.getJoins()) 1847 ) 1848 { 1849 isEquiv = true; 1850 for (Iterator it = criteria.keySet().iterator(); it.hasNext();) 1851 { 1852 String key = (String ) it.next(); 1853 if (this.containsKey(key)) 1854 { 1855 Criterion a = this.getCriterion(key); 1856 Criterion b = criteria.getCriterion(key); 1857 if (!a.equals(b)) 1858 { 1859 isEquiv = false; 1860 break; 1861 } 1862 } 1863 else 1864 { 1865 isEquiv = false; 1866 break; 1867 } 1868 } 1869 } 1870 } 1871 return isEquiv; 1872 } 1873 1874 1879 public int hashCode() 1880 { 1881 int result = 16; 1882 result = 37 * result + offset; 1883 result = 37 * result + limit; 1884 result = 37 * result + (ignoreCase ? 0 : 1); 1885 result = 37 * result + (singleRecord ? 0 : 1); 1886 result = 37 * result + (cascade ? 0 : 1); 1887 result = 37 * result + dbName.hashCode(); 1888 result = 37 * result + selectModifiers.hashCode(); 1889 result = 37 * result + selectColumns.hashCode(); 1890 result = 37 * result + orderByColumns.hashCode(); 1891 result = 37 * result + (aliases == null ? 0 : aliases.hashCode()); 1892 result = 37 * result + asColumns.hashCode(); 1893 result = 37 * result + joins.hashCode(); 1894 result = 37 * result + super.hashCode(); 1895 return result; 1896 } 1897 1898 1905 1906 1922 public Criteria addHaving(Criterion having) 1923 { 1924 this.having = having; 1925 return this; 1926 } 1927 1928 1946 public Criteria and(Criterion c) 1947 { 1948 Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn()); 1949 1950 if (oc == null) 1951 { 1952 add(c); 1953 } 1954 else 1955 { 1956 oc.and(c); 1957 } 1958 return this; 1959 } 1960 1961 1983 public Criteria and(String column, Object value) 1984 { 1985 and(column, value, EQUAL); 1986 return this; 1987 } 1988 1989 2013 public Criteria and(String column, Object value, SqlEnum comparison) 2014 { 2015 Criterion oc = getCriterion(column); 2016 Criterion nc = new Criterion(column, value, comparison); 2017 2018 if (oc == null) 2019 { 2020 super.put(column, nc); 2021 } 2022 else 2023 { 2024 oc.and(nc); 2025 } 2026 return this; 2027 } 2028 2029 2048 public Criteria and(String table, String column, Object value) 2049 { 2050 and(table, column, value, EQUAL); 2051 return this; 2052 } 2053 2054 2076 public Criteria and(String table, String column, Object value, 2077 SqlEnum comparison) 2078 { 2079 StringBuffer sb = new StringBuffer (table.length() 2080 + column.length() + 1); 2081 sb.append(table); 2082 sb.append('.'); 2083 sb.append(column); 2084 2085 Criterion oc = getCriterion(table, column); 2086 Criterion nc = new Criterion(table, column, value, comparison); 2087 2088 if (oc == null) 2089 { 2090 super.put(sb.toString(), nc); 2091 } 2092 else 2093 { 2094 oc.and(nc); 2095 } 2096 return this; 2097 } 2098 2099 2112 public Criteria and(String column, boolean value) 2113 { 2114 and(column, new Boolean (value)); 2115 return this; 2116 } 2117 2118 2133 public Criteria and(String column, boolean value, SqlEnum comparison) 2134 { 2135 and(column, new Boolean (value), comparison); 2136 return this; 2137 } 2138 2139 2152 public Criteria and(String column, int value) 2153 { 2154 and(column, new Integer (value)); 2155 return this; 2156 } 2157 2158 2172 public Criteria and(String column, int value, SqlEnum comparison) 2173 { 2174 and(column, new Integer (value), comparison); 2175 return this; 2176 } 2177 2178 2191 public Criteria and(String column, long value) 2192 { 2193 and(column, new Long (value)); 2194 return this; 2195 } 2196 2197 2212 public Criteria and(String column, long value, SqlEnum comparison) 2213 { 2214 and(column, new Long (value), comparison); 2215 return this; 2216 } 2217 2218 2231 public Criteria and(String column, float value) 2232 { 2233 and(column, new Float (value)); 2234 return this; 2235 } 2236 2237 2252 public Criteria and(String column, float value, SqlEnum comparison) 2253 { 2254 and(column, new Float (value), comparison); 2255 return this; 2256 } 2257 2258 2271 public Criteria and(String column, double value) 2272 { 2273 and(column, new Double (value)); 2274 return this; 2275 } 2276 2277 2292 public Criteria and(String column, double value, SqlEnum comparison) 2293 { 2294 and(column, new Double (value), comparison); 2295 return this; 2296 } 2297 2298 2314 public Criteria andDate(String column, int year, int month, int date) 2315 { 2316 and(column, new GregorianCalendar (year, month, date).getTime()); 2317 return this; 2318 } 2319 2320 2338 public Criteria andDate(String column, int year, int month, int date, 2339 SqlEnum comparison) 2340 { 2341 and(column, new GregorianCalendar (year, month, date).getTime(), comparison); 2342 return this; 2343 } 2344 2345 2363 public Criteria andIn(String column, Object [] values) 2364 { 2365 and(column, (Object ) values, Criteria.IN); 2366 return this; 2367 } 2368 2369 2386 public Criteria andIn(String column, int[] values) 2387 { 2388 and(column, (Object ) values, Criteria.IN); 2389 return this; 2390 } 2391 2392 2410 public Criteria andIn(String column, List values) 2411 { 2412 and(column, (Object ) values, Criteria.IN); 2413 return this; 2414 } 2415 2416 2434 public Criteria andNotIn(String column, Object [] values) 2435 { 2436 and(column, (Object ) values, Criteria.NOT_IN); 2437 return this; 2438 } 2439 2440 2457 public Criteria andNotIn(String column, int[] values) 2458 { 2459 and(column, (Object ) values, Criteria.NOT_IN); 2460 return this; 2461 } 2462 2463 2481 public Criteria andNotIn(String column, List values) 2482 { 2483 and(column, (Object ) values, Criteria.NOT_IN); 2484 return this; 2485 } 2486 2487 2494 2495 2512 public Criteria or(Criterion c) 2513 { 2514 Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn()); 2515 2516 if (oc == null) 2517 { 2518 add(c); 2519 } 2520 else 2521 { 2522 oc.or(c); 2523 } 2524 return this; 2525 } 2526 2527 2549 public Criteria or(String column, Object value) 2550 { 2551 or(column, value, EQUAL); 2552 return this; 2553 } 2554 2555 2578 public Criteria or(String column, Object value, SqlEnum comparison) 2579 { 2580 Criterion oc = getCriterion(column); 2581 Criterion nc = new Criterion(column, value, comparison); 2582 2583 if (oc == null) 2584 { 2585 super.put(column, nc); 2586 } 2587 else 2588 { 2589 oc.or(nc); 2590 } 2591 return this; 2592 } 2593 2594 2613 public Criteria or(String table, String column, Object value) 2614 { 2615 or(table, column, value, EQUAL); 2616 return this; 2617 } 2618 2619 2640 public Criteria or(String table, String column, Object value, 2641 SqlEnum comparison) 2642 { 2643 StringBuffer sb = new StringBuffer (table.length() + column.length() + 1); 2644 sb.append(table); 2645 sb.append('.'); 2646 sb.append(column); 2647 2648 Criterion oc = getCriterion(table, column); 2649 Criterion nc = new Criterion(table, column, value, comparison); 2650 if (oc == null) 2651 { 2652 super.put(sb.toString(), nc); 2653 } 2654 else 2655 { 2656 oc.or(nc); 2657 } 2658 return this; 2659 } 2660 2661 2674 public Criteria or(String column, boolean value) 2675 { 2676 or(column, new Boolean (value)); 2677 return this; 2678 } 2679 2680 2695 public Criteria or(String column, boolean value, SqlEnum comparison) 2696 { 2697 or(column, new Boolean (value), comparison); 2698 return this; 2699 } 2700 2701 2715 public Criteria or(String column, int value) 2716 { 2717 or(column, new Integer (value)); 2718 return this; 2719 } 2720 2721 2737 public Criteria or(String column, int value, SqlEnum comparison) 2738 { 2739 or(column, new Integer (value), comparison); 2740 return this; 2741 } 2742 2743 2756 public Criteria or(String column, long value) 2757 { 2758 or(column, new Long (value)); 2759 return this; 2760 } 2761 2762 2777 public Criteria or(String column, long value, SqlEnum comparison) 2778 { 2779 or(column, new Long (value), comparison); 2780 return this; 2781 } 2782 2783 2796 public Criteria or(String column, float value) 2797 { 2798 or(column, new Float (value)); 2799 return this; 2800 } 2801 2802 2817 public Criteria or(String column, float value, SqlEnum comparison) 2818 { 2819 or(column, new Float (value), comparison); 2820 return this; 2821 } 2822 2823 2836 public Criteria or(String column, double value) 2837 { 2838 or(column, new Double (value)); 2839 return this; 2840 } 2841 2842 2857 public Criteria or(String column, double value, SqlEnum comparison) 2858 { 2859 or(column, new Double (value), comparison); 2860 return this; 2861 } 2862 2863 2879 public Criteria orDate(String column, int year, int month, int date) 2880 { 2881 or(column, new GregorianCalendar (year, month, date)); 2882 return this; 2883 } 2884 2885 2903 public Criteria orDate(String column, int year, int month, int date, 2904 SqlEnum comparison) 2905 { 2906 or(column, new GregorianCalendar (year, month, date), comparison); 2907 return this; 2908 } 2909 2910 2928 public Criteria orIn(String column, Object [] values) 2929 { 2930 or(column, (Object ) values, Criteria.IN); 2931 return this; 2932 } 2933 2934 2951 public Criteria orIn(String column, int[] values) 2952 { 2953 or(column, (Object ) values, Criteria.IN); 2954 return this; 2955 } 2956 2957 2975 public Criteria orIn(String column, List values) 2976 { 2977 or(column, (Object ) values, Criteria.IN); 2978 return this; 2979 } 2980 2981 2999 public Criteria orNotIn(String column, Object [] values) 3000 { 3001 or(column, (Object ) values, Criteria.NOT_IN); 3002 return this; 3003 } 3004 3005 3022 public Criteria orNotIn(String column, int[] values) 3023 { 3024 or(column, (Object ) values, Criteria.NOT_IN); 3025 return this; 3026 } 3027 3028 3046 public Criteria orNotIn(String column, List values) 3047 { 3048 or(column, (Object ) values, Criteria.NOT_IN); 3049 return this; 3050 } 3051 3052 3058 private void writeObject(ObjectOutputStream s) throws IOException 3059 { 3060 s.defaultWriteObject(); 3061 3062 ArrayList serializableJoins = null; 3064 if (joins != null && joins.size() > 0) 3065 { 3066 serializableJoins = new ArrayList (joins.size()); 3067 3068 for (Iterator jonisIter = joins.iterator(); jonisIter.hasNext();) 3069 { 3070 Join join = (Join) jonisIter.next(); 3071 3072 ArrayList joinContent = new ArrayList (3); 3073 joinContent.add(join.getLeftColumn()); 3074 joinContent.add(join.getRightColumn()); 3075 joinContent.add(join.getJoinType()); 3076 3077 serializableJoins.add(joinContent); 3078 } 3079 } 3080 3081 s.writeObject(serializableJoins); 3082 } 3083 3084 3091 private void readObject(ObjectInputStream s) 3092 throws IOException , ClassNotFoundException 3093 { 3094 s.defaultReadObject(); 3095 3096 for (Iterator iter = keySet().iterator(); iter.hasNext();) 3099 { 3100 Object key = iter.next(); 3101 Object value = get(key); 3102 if (value instanceof Criteria.Criterion) 3103 { 3104 super.put(key, value); 3105 } 3106 } 3107 3108 ArrayList joins = (ArrayList ) s.readObject(); 3110 if (joins != null) 3111 { 3112 for (int i = 0; i < joins.size(); i++) 3113 { 3114 ArrayList joinContent = (ArrayList ) joins.get(i); 3115 3116 String leftColumn = (String ) joinContent.get(0); 3117 String rightColumn = (String ) joinContent.get(1); 3118 SqlEnum joinType = null; 3119 Object joinTypeObj = joinContent.get(2); 3120 if (joinTypeObj != null) 3121 { 3122 joinType = (SqlEnum) joinTypeObj; 3123 } 3124 addJoin(leftColumn, rightColumn, joinType); 3125 } 3126 } 3127 } 3128 3129 3132 public final class Criterion implements Serializable 3133 { 3134 3135 private static final long serialVersionUID = 7157097965404611710L; 3136 3137 public static final String AND = " AND "; 3138 public static final String OR = " OR "; 3139 3140 3141 private Object value; 3142 3143 3144 private SqlEnum comparison; 3145 3146 3147 private String table; 3148 3149 3150 private String column; 3151 3152 3153 private boolean ignoreStringCase = false; 3154 3155 3159 private DB db; 3160 3161 3164 private List clauses = new ArrayList (); 3165 private List conjunctions = new ArrayList (); 3166 3167 3170 private Criterion(Object val, SqlEnum comp) 3171 { 3172 this.value = val; 3173 this.comparison = comp; 3174 } 3175 3176 3184 Criterion(String table, String column, Object val, SqlEnum comp) 3185 { 3186 this(val, comp); 3187 this.table = (table == null ? "" : table); 3188 this.column = (column == null ? "" : column); 3189 } 3190 3191 3199 Criterion(String tableColumn, Object val, SqlEnum comp) 3200 { 3201 this(val, comp); 3202 int dot = tableColumn.lastIndexOf('.'); 3203 if (dot == -1) 3204 { 3205 table = ""; 3206 column = tableColumn; 3207 } 3208 else 3209 { 3210 table = tableColumn.substring(0, dot); 3211 column = tableColumn.substring(dot + 1); 3212 } 3213 } 3214 3215 3222 Criterion(String table, String column, Object val) 3223 { 3224 this(table, column, val, EQUAL); 3225 } 3226 3227 3234 Criterion(String tableColumn, Object val) 3235 { 3236 this(tableColumn, val, EQUAL); 3237 } 3238 3239 3244 public String getColumn() 3245 { 3246 return this.column; 3247 } 3248 3249 3254 public void setTable(String name) 3255 { 3256 this.table = name; 3257 } 3258 3259 3264 public String getTable() 3265 { 3266 return this.table; 3267 } 3268 3269 3274 public SqlEnum getComparison() 3275 { 3276 return this.comparison; 3277 } 3278 3279 3284 public Object getValue() 3285 { 3286 return this.value; 3287 } 3288 3289 3294 public void setValue(Object value) 3295 { 3296 this.value = value; 3297 } 3298 3299 3305 public DB getDb() 3306 { 3307 DB db = null; 3308 if (this.db == null) 3309 { 3310 try 3313 { 3314 db = Torque.getDB(getDbName()); 3315 } 3316 catch (Exception e) 3317 { 3318 log.error( 3321 "Could not get a DB adapter, so sql may be wrong"); 3322 } 3323 } 3324 else 3325 { 3326 db = this.db; 3327 } 3328 3329 return db; 3330 } 3331 3332 3338 public void setDB(DB v) 3339 { 3340 this.db = v; 3341 3342 for (int i = 0; i < this.clauses.size(); i++) 3343 { 3344 ((Criterion) (clauses.get(i))).setDB(v); 3345 } 3346 } 3347 3348 3354 public Criterion setIgnoreCase(boolean b) 3355 { 3356 ignoreStringCase = b; 3357 return this; 3358 } 3359 3360 3365 public boolean isIgnoreCase() 3366 { 3367 return ignoreStringCase; 3368 } 3369 3370 3373 private List getClauses() 3374 { 3375 return clauses; 3376 } 3377 3378 3381 private List getConjunctions() 3382 { 3383 return conjunctions; 3384 } 3385 3386 3389 public Criterion and(Criterion criterion) 3390 { 3391 this.clauses.add(criterion); 3392 this.conjunctions.add(AND); 3393 return this; 3394 } 3395 3396 3399 public Criterion or(Criterion criterion) 3400 { 3401 this.clauses.add(criterion); 3402 this.conjunctions.add(OR); 3403 return this; 3404 } 3405 3406 3409 public void appendTo(StringBuffer sb) throws TorqueException 3410 { 3411 3415 if (column == null) 3416 { 3417 return; 3418 } 3419 3420 Criterion clause = null; 3421 for (int j = 0; j < this.clauses.size(); j++) 3422 { 3423 sb.append('('); 3424 } 3425 if (CUSTOM == comparison) 3426 { 3427 if (value != null && !"".equals(value)) 3428 { 3429 sb.append((String ) value); 3430 } 3431 } 3432 else 3433 { 3434 String field = null; 3435 if (table == null) 3436 { 3437 field = column; 3438 } 3439 else 3440 { 3441 field = new StringBuffer ( 3442 table.length() + 1 + column.length()) 3443 .append(table).append('.').append(column) 3444 .toString(); 3445 } 3446 SqlExpression.build(field, value, comparison, 3447 ignoreStringCase || ignoreCase, getDb(), sb); 3448 } 3449 3450 for (int i = 0; i < this.clauses.size(); i++) 3451 { 3452 sb.append(this.conjunctions.get(i)); 3453 clause = (Criterion) (this.clauses.get(i)); 3454 clause.appendTo(sb); 3455 sb.append(')'); 3456 } 3457 } 3458 3459 3467 public void appendPsTo(StringBuffer sb, List params) 3468 { 3469 if (column == null || value == null) 3470 { 3471 return; 3472 } 3473 3474 DB db = getDb(); 3475 3476 for (int j = 0; j < this.clauses.size(); j++) 3477 { 3478 sb.append('('); 3479 } 3480 if (CUSTOM == comparison) 3481 { 3482 if (!"".equals(value)) 3483 { 3484 sb.append((String ) value); 3485 } 3486 } 3487 else 3488 { 3489 String field = null; 3490 if (table == null) 3491 { 3492 field = column; 3493 } 3494 else 3495 { 3496 field = new StringBuffer ( 3497 table.length() + 1 + column.length()) 3498 .append(table).append('.').append(column) 3499 .toString(); 3500 } 3501 3502 if (comparison.equals(Criteria.IN) 3503 || comparison.equals(Criteria.NOT_IN)) 3504 { 3505 sb.append(field) 3506 .append(comparison); 3507 3508 UniqueList inClause = new UniqueList(); 3509 3510 if (value instanceof List ) 3511 { 3512 value = ((List ) value).toArray (new Object [0]); 3513 } 3514 3515 for (int i = 0; i < Array.getLength(value); i++) 3516 { 3517 Object item = Array.get(value, i); 3518 3519 inClause.add(SqlExpression.processInValue(item, 3520 ignoreStringCase || ignoreCase, 3521 db)); 3522 } 3523 3524 StringBuffer inString = new StringBuffer (); 3525 inString.append('(').append(StringUtils.join( 3526 inClause.iterator(), (","))).append(')'); 3527 sb.append(inString.toString()); 3528 } 3529 else 3530 { 3531 if (ignoreStringCase || ignoreCase) 3532 { 3533 sb.append(db.ignoreCase(field)) 3534 .append(comparison) 3535 .append(db.ignoreCase("?")); 3536 } 3537 else 3538 { 3539 sb.append(field) 3540 .append(comparison) 3541 .append(" ? "); 3542 } 3543 3544 if (value instanceof java.util.Date ) 3545 { 3546 params.add(new java.sql.Date ( 3547 ((java.util.Date ) value).getTime())); 3548 } 3549 else if (value instanceof DateKey) 3550 { 3551 params.add(new java.sql.Date ( 3552 ((DateKey) value).getDate().getTime())); 3553 } 3554 else 3555 { 3556 params.add(value.toString()); 3557 } 3558 } 3559 } 3560 3561 for (int i = 0; i < this.clauses.size(); i++) 3562 { 3563 sb.append(this.conjunctions.get(i)); 3564 Criterion clause = (Criterion) (this.clauses.get(i)); 3565 clause.appendPsTo(sb, params); 3566 sb.append(')'); 3567 } 3568 } 3569 3570 3575 public String toString() 3576 { 3577 if (column == null) 3581 { 3582 return ""; 3583 } 3584 3585 StringBuffer expr = new StringBuffer (25); 3586 try 3587 { 3588 appendTo(expr); 3589 } 3590 catch (TorqueException e) 3591 { 3592 return "Criterion cannot be evaluated"; 3593 } 3594 return expr.toString(); 3595 } 3596 3597 3601 public boolean equals(Object obj) 3602 { 3603 if (this == obj) 3604 { 3605 return true; 3606 } 3607 3608 if ((obj == null) || !(obj instanceof Criterion)) 3609 { 3610 return false; 3611 } 3612 3613 Criterion crit = (Criterion) obj; 3614 3615 boolean isEquiv = ((table == null && crit.getTable() == null) 3616 || (table != null && table.equals(crit.getTable())) 3617 ) 3618 && column.equals(crit.getColumn()) 3619 && comparison.equals(crit.getComparison()); 3620 3621 if (isEquiv) 3623 { 3624 Object b = crit.getValue(); 3625 if (value instanceof Object [] && b instanceof Object []) 3626 { 3627 isEquiv &= Arrays.equals((Object []) value, (Object []) b); 3628 } 3629 else if (value instanceof int[] && b instanceof int[]) 3630 { 3631 isEquiv &= Arrays.equals((int[]) value, (int[]) b); 3632 } 3633 else 3634 { 3635 isEquiv &= value.equals(b); 3636 } 3637 } 3638 3639 3641 isEquiv &= this.clauses.size() == crit.getClauses().size(); 3642 for (int i = 0; i < this.clauses.size(); i++) 3643 { 3644 isEquiv &= ((String ) (conjunctions.get(i))) 3645 .equals((String ) (crit.getConjunctions().get(i))); 3646 isEquiv &= ((Criterion) (clauses.get(i))) 3647 .equals((Criterion) (crit.getClauses().get(i))); 3648 } 3649 3650 return isEquiv; 3651 } 3652 3653 3656 public int hashCode() 3657 { 3658 int h = value.hashCode() ^ comparison.hashCode(); 3659 3660 if (table != null) 3661 { 3662 h ^= table.hashCode(); 3663 } 3664 3665 if (column != null) 3666 { 3667 h ^= column.hashCode(); 3668 } 3669 3670 for (int i = 0; i < this.clauses.size(); i++) 3671 { 3672 h ^= ((Criterion) (clauses.get(i))).hashCode(); 3673 } 3674 3675 return h; 3676 } 3677 3678 3683 public List getAllTables() 3684 { 3685 UniqueList tables = new UniqueList(); 3686 addCriterionTable(this, tables); 3687 return tables; 3688 } 3689 3690 3694 private void addCriterionTable(Criterion c, UniqueList s) 3695 { 3696 if (c != null) 3697 { 3698 s.add(c.getTable()); 3699 for (int i = 0; i < c.getClauses().size(); i++) 3700 { 3701 addCriterionTable((Criterion) (c.getClauses().get(i)), s); 3702 } 3703 } 3704 } 3705 3706 3710 public Criterion[] getAttachedCriterion() 3711 { 3712 ArrayList crits = new ArrayList (); 3713 traverseCriterion(this, crits); 3714 Criterion[] crita = new Criterion[crits.size()]; 3715 for (int i = 0; i < crits.size(); i++) 3716 { 3717 crita[i] = (Criterion) crits.get(i); 3718 } 3719 3720 return crita; 3721 } 3722 3723 3727 private void traverseCriterion(Criterion c, ArrayList a) 3728 { 3729 if (c != null) 3730 { 3731 a.add(c); 3732 for (int i = 0; i < c.getClauses().size(); i++) 3733 { 3734 traverseCriterion((Criterion) (c.getClauses().get(i)), a); 3735 } 3736 } 3737 } 3738 } 3740 3748 public static class Join 3749 { 3750 3751 private String leftColumn = null; 3752 3753 3754 private String rightColumn = null; 3755 3756 3757 private SqlEnum joinType = null; 3758 3759 3769 public Join( 3770 final String leftColumn, 3771 final String rightColumn, 3772 final SqlEnum joinType) 3773 { 3774 this.leftColumn = leftColumn; 3775 this.rightColumn = rightColumn; 3776 this.joinType = joinType; 3777 } 3778 3779 3783 public final SqlEnum getJoinType() 3784 { 3785 return joinType; 3786 } 3787 3788 3791 public final String getLeftColumn() 3792 { 3793 return leftColumn; 3794 } 3795 3796 3799 public final String getRightColumn() 3800 { 3801 return rightColumn; 3802 } 3803 3804 3809 public String toString() 3810 { 3811 StringBuffer result = new StringBuffer (); 3812 if (joinType != null) 3813 { 3814 result.append(joinType) 3815 .append(" : "); 3816 } 3817 result.append(leftColumn) 3818 .append("=") 3819 .append(rightColumn) 3820 .append(" (ignoreCase not considered)"); 3821 3822 return result.toString(); 3823 } 3824 3825 3829 public boolean equals(Object obj) 3830 { 3831 if (this == obj) 3832 { 3833 return true; 3834 } 3835 3836 if ((obj == null) || !(obj instanceof Join)) 3837 { 3838 return false; 3839 } 3840 3841 Join join = (Join) obj; 3842 3843 return ObjectUtils.equals(leftColumn, join.getLeftColumn()) 3844 && ObjectUtils.equals(rightColumn, join.getRightColumn()) 3845 && ObjectUtils.equals(joinType, join.getJoinType()); 3846 } 3847 3848 3853 public int hashCode() 3854 { 3855 int result = 13; 3856 result = 37 * result + leftColumn.hashCode(); 3857 result = 37 * result + rightColumn.hashCode(); 3858 result = 37 * result + (null == joinType ? 0 : joinType.hashCode()); 3859 return result; 3860 } 3861 3862 } } 3864 | Popular Tags |