001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: //Copyright (C) 1999 - 2004, Salmon LLC
004: //
005: //This program is free software; you can redistribute it and/or
006: //modify it under the terms of the GNU General Public License version 2
007: //as published by the Free Software Foundation;
008: //
009: //This program is distributed in the hope that it will be useful,
010: //but WITHOUT ANY WARRANTY; without even the implied warranty of
011: //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: //GNU General Public License for more details.
013: //
014: //You should have received a copy of the GNU General Public License
015: //along with this program; if not, write to the Free Software
016: //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: //For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020: package com.salmonllc.hibernate;
021:
022: import java.lang.reflect.Method;
023: import java.math.BigDecimal;
024: import java.util.ArrayList;
025: import java.util.List;
026: import java.util.StringTokenizer;
027:
028: import net.sf.hibernate.HibernateException;
029: import net.sf.hibernate.Query;
030: import net.sf.hibernate.Session;
031: import net.sf.hibernate.SessionFactory;
032: import net.sf.hibernate.Transaction;
033: import net.sf.hibernate.metadata.ClassMetadata;
034: import net.sf.hibernate.type.Type;
035:
036: import com.salmonllc.properties.Props;
037: import com.salmonllc.sql.AutoRetrieveCriteria;
038: import com.salmonllc.sql.BeanDataStore;
039: import com.salmonllc.sql.ColumnDefinition;
040: import com.salmonllc.sql.DSColumnDescriptor;
041: import com.salmonllc.sql.DSDataRow;
042: import com.salmonllc.sql.DSDataStoreDescriptor;
043: import com.salmonllc.sql.DataStoreBuffer;
044: import com.salmonllc.sql.DataStoreException;
045: import com.salmonllc.sql.DataStoreQBEInterface;
046: import com.salmonllc.util.MessageLog;
047: import com.salmonllc.util.Util;
048:
049: /**
050: * A bean datastore that can automatically retrieve and persist data via
051: * Hibernate HQL and session API
052: *
053: */
054: public class HibernateDataStore extends BeanDataStore implements
055: DataStoreQBEInterface {
056: private HibernateException _updateException;
057: private BeanClassInfo _beanInfo[] = new BeanClassInfo[0];
058: private BeanClassInfo _beanFrom[] = new BeanClassInfo[0];
059: private String _where, _order, _from, _join;
060: private boolean _distinct = true;
061:
062: /**
063: * Construct a new Hibernate DataStore. The DataStore must then be
064: * configured by calling addClass, setFrom, setWhere, setOrder, setJoin,
065: * etc.. before it can be used.
066: */
067: public HibernateDataStore() {
068: super ();
069: initValues();
070: }
071:
072: /**
073: * Constuct a new HibernateDataStore passing a BeanDataStore.BeanClassInfo
074: * object and a string of extra information from the JSP tag
075: *
076: * @throws ClassNotFoundException
077: */
078: public HibernateDataStore(BeanClassInfo inf, String extraInfo)
079: throws ClassNotFoundException {
080: super (inf);
081: initValues();
082: _beanInfo = new BeanClassInfo[1];
083: _beanInfo[0] = inf;
084: inf.setIndex(0);
085: parseExtraInfo(extraInfo);
086: }
087:
088: /**
089: * Constuct a new HibernateDataStore passing an array of
090: * BeanDataStore.BeanClassInfo objects (so the DataStore can handle multiple
091: * objects in it's select) and a string of extra information from the JSP
092: * tag
093: *
094: * @throws ClassNotFoundException
095: */
096:
097: public HibernateDataStore(BeanClassInfo inf[], String extraInfo)
098: throws ClassNotFoundException {
099: super (inf);
100: initValues();
101: _beanInfo = inf;
102: parseExtraInfo(extraInfo);
103: }
104:
105: protected void initValues() {
106: setBooleanDataType(DataStoreBuffer.DATATYPE_STRING, "true",
107: "false");
108: setLowerCaseFirstLetter(true);
109: }
110:
111: /**
112: * Loads the data into the DataStore
113: *
114: * @param criteriaString:
115: * The selection criteria to use or null for all possible values
116: */
117: public void retrieve(String criteriaString)
118: throws DataStoreException {
119: String query = "select ";
120: if (_distinct)
121: query += "distinct ";
122: String comma = "";
123: for (int i = 0; i < _beanInfo.length; i++) {
124: query += comma + _beanInfo[i].getAlias();
125: comma = ",";
126: }
127: query = buildQuery(query, criteriaString);
128:
129: MessageLog.writeSQLMessage("HQL Query:", query, this );
130: try {
131: execute(query);
132: } catch (Exception ex) {
133: throw new DataStoreException(ex.getMessage(), ex);
134: }
135: }
136:
137: private String buildQuery(String query, String criteriaString) {
138: query += " from ";
139: String comma = "";
140: for (int i = 0; i < _beanInfo.length; i++) {
141: query += comma + _beanInfo[i].getBeanClass().getName()
142: + " " + _beanInfo[i].getAlias();
143: comma = ", ";
144: }
145: if (_from != null)
146: query += ", " + _from;
147: if (_join != null)
148: query += " " + _join;
149:
150: if (criteriaString != null || _where != null)
151: query += " where ";
152: if (_where != null)
153: query += _where;
154: if (criteriaString != null)
155: query += (_where == null ? criteriaString
156: : (" and " + criteriaString));
157: if (_order != null)
158: query += " order by " + _order;
159: return query;
160: }
161:
162: /**
163: * Execute an arbitrary HSQL query, loading the results into the datastore
164: * buffer. The objects retrieved must match the classes specifed when the
165: * datastore was created.
166: *
167: * @throws Exception
168: */
169: public void execute(String query) throws Exception {
170: Session sess = HibernateSessionFactory.getSession();
171: Query q = sess.createQuery(query);
172: List l = q.list();
173: reset();
174: insertRows(l);
175: }
176:
177: /**
178: * Loads the data into the DataStore
179: */
180: public void retrieve() throws Exception {
181: retrieve(null);
182: }
183:
184: /**
185: * Persists the changes made to the database back to the beans and also to
186: * the database. Transaction's will be handled automatically from within the
187: * datastore.
188: */
189: public synchronized void update() throws Exception {
190: update(true);
191: }
192:
193: /**
194: * Persists the changes made to the database back to the beans and also to
195: * the database. Transaction's will be handled automatically from within the
196: * datastore if the handleTrans argument is true, otherwise you must handle
197: * it yourself outside the datastore using the Hibernate session object.
198: */
199: public void update(boolean handleTrans) throws Exception {
200: _updateException = null;
201: Session sess = HibernateSessionFactory.getSession();
202: Transaction trans = null;
203: if (handleTrans)
204: trans = sess.beginTransaction();
205:
206: super .update(false);
207: try {
208: sess.flush();
209: } catch (HibernateException ex) {
210: _updateException = ex;
211: }
212:
213: if (trans != null) {
214: if (_updateException == null) {
215: trans.commit();
216: DSDataStoreDescriptor desc = getDescriptor();
217: for (int i = 0; i < getRowCount(); i++) {
218: if (getRowStatus(i) == STATUS_NEW_MODIFIED
219: || getRowStatus(i) == STATUS_MODIFIED) {
220: Object o = getBean(i);
221: DSDataRow r = getDataRow(i);
222: r
223: .populateFromBean(desc, o,
224: STATUS_NOT_MODIFIED);
225: }
226: }
227: resetStatus();
228: } else
229: trans.rollback();
230: }
231: if (_updateException != null)
232: throw (_updateException);
233: }
234:
235: /**
236: * Called when a bean should be deleted from the database, subclasses may
237: * override
238: */
239:
240: public void beanDeleted(Object bean) {
241: try {
242: Session sess = HibernateSessionFactory.getSession();
243: sess.delete(bean);
244: } catch (HibernateException e) {
245: _updateException = e;
246: }
247: }
248:
249: /**
250: * Called when a bean should be added or updated in the database, subclasses
251: * may override
252: */
253: public void beanUpdated(Object bean, boolean newBean)
254: throws Exception {
255: try {
256: Session sess = HibernateSessionFactory.getSession();
257: if (newBean)
258: sess.save(bean);
259: else
260: sess.update(bean);
261: } catch (HibernateException e) {
262: _updateException = e;
263: }
264:
265: }
266:
267: /**
268: * Builds selection criteria for the primary key field for the specified row
269: */
270: public String buildCriteriaStringForRow(int row) {
271: try {
272: SessionFactory fact = HibernateSessionFactory
273: .getSessionFactory();
274: Session sess = HibernateSessionFactory.getSession();
275: String exp = "";
276: String and = "";
277: for (int i = 0; i < _beanInfo.length; i++) {
278: ClassMetadata md = fact.getClassMetadata(_beanInfo[i]
279: .getBeanClass());
280: Object bean = getBean(row);
281: if (bean instanceof Object[])
282: bean = ((Object[]) bean)[_beanInfo[i].getIndex()];
283: if (bean != null) {
284: Object id = md.getIdentifier(bean);
285: String propName = md.getIdentifierPropertyName();
286: String fragment = net.sf.hibernate.expression.Expression
287: .eq(
288: _beanInfo[i].getAlias() + "."
289: + propName, id).toString();
290: exp += fragment + and;
291: and = " and ";
292: }
293: }
294: return exp;
295: } catch (HibernateException e) {
296: MessageLog.writeErrorMessage("buildCriteriaStringForRow()",
297: e, this );
298: } catch (DataStoreException e) {
299: MessageLog.writeErrorMessage("buildCriteriaStringForRow()",
300: e, this );
301: }
302:
303: return super .buildCriteriaStringForRow(row);
304: }
305:
306: /**
307: * Builds and loads the datastore using AutoRetrieve selection criteria from
308: * the JSP
309: */
310: public void autoRetrieve() throws Exception {
311: AutoRetrieveCriteria crit = getAutoRetrieveCriteria();
312: if (crit == null || crit.getCriteriaCount() == 0)
313: retrieve();
314: else {
315: String critString = buildCriteriaString(crit);
316: retrieve(critString);
317: }
318: }
319:
320: private static String buildCriteriaString(AutoRetrieveCriteria crit) {
321: StringBuffer ret = new StringBuffer();
322:
323: for (int i = 0; i < crit.getCriteriaCount(); i++) {
324: if (crit.getPrefix(i) != null)
325: ret.append(crit.getPrefix(i));
326: ret.append(lowerCaseFirstLetter(crit.getColumn(i)));
327: ret.append(' ');
328: ret.append(crit.getOperator(i));
329: ret.append(' ');
330: ret.append(crit.getValue(i));
331: if (crit.getSuffix(i) != null)
332: ret.append(crit.getSuffix(i));
333: if (crit.getConnector(i) != null) {
334: ret.append(' ');
335: ret.append(crit.getConnector(i));
336: ret.append(' ');
337: }
338: }
339:
340: if (ret.length() == 0)
341: return null;
342: else
343: return ret.toString();
344: }
345:
346: /**
347: * Get a list of aliaes for the objects used in this datastore
348: */
349: public String[] getTableList(boolean updateable) {
350: String ret[] = new String[_beanInfo.length];
351: for (int i = 0; i < _beanInfo.length; i++)
352: ret[i] = _beanInfo[i].getAlias();
353: return ret;
354: }
355:
356: /**
357: * For HQL joins in the from clause of the query. Joins may also go in the
358: * where clause as well.
359: */
360: public String getJoin() {
361: return _join;
362: }
363:
364: /**
365: * For HQL joins in the from clause of the query. Joins may also go in the
366: * where clause as well.
367: */
368: public void setJoin(String join) {
369: _join = join;
370: }
371:
372: /**
373: * the order by clause for the HQL query
374: */
375: public String getOrderBy() {
376: return _order;
377: }
378:
379: /**
380: * the order by clause for the HQL query
381: */
382: public void setOrderBy(String order) {
383: _order = order;
384: }
385:
386: /**
387: * the from clause for the HQL query. Should contain tables and aliases for
388: * this query for classes that are being used to query the data (joins,
389: * selection criteria), but not actually loaded when the query is executed.
390: * Classes that should be loaded should be specified using the addBean
391: * method
392: */
393: public String getFrom() {
394: return _from;
395: }
396:
397: /**
398: * the from clause for the HQL query. Should contain tables and aliases for
399: * this query for classes that are being used to query the data (joins,
400: * selection criteria), but not actually loaded when the query is executed.
401: * Classes that should be loaded should be specified using the addBean
402: * method
403: *
404: * @throws ClassNotFoundException
405: */
406: public void setFrom(String from) throws ClassNotFoundException {
407: _from = from;
408: if (_from == null || from.length() == 0)
409: _beanFrom = new BeanClassInfo[0];
410: else {
411: ArrayList l = new ArrayList();
412: StringTokenizer tok = new StringTokenizer(from, ",");
413: while (tok.hasMoreTokens()) {
414: String tab = tok.nextToken();
415: int pos = tab.indexOf(" ");
416: String alias = null;
417: if (pos != -1) {
418: alias = tab.substring(pos + 1);
419: tab = tab.substring(0, pos);
420: }
421: Class c = Class.forName(tab);
422: BeanClassInfo inf = newBeanInfo(c, alias, -1);
423: l.add(inf);
424: }
425: _beanFrom = new BeanClassInfo[l.size()];
426: l.toArray(_beanFrom);
427: }
428: }
429:
430: /**
431: * selection or join criteria used when this datastore is loaded
432: */
433: public String getWhere() {
434: return _where;
435: }
436:
437: /**
438: * selection or join criteria used when this datastore is loaded
439: */
440: public void setWhere(String where) {
441: _where = where;
442: }
443:
444: /**
445: * Add a bean to the DataStore's buffer. The contents of each bean added
446: * will be loaded when retrieve() is called.
447: * @param beanType The class name for the bean
448: * @param alias The name the bean is referenced by
449: */
450: public void addBeanDefinition(Class beanType, String alias) {
451: if (_beanInfo == null || _beanInfo.length == 0) {
452: _beanInfo = new BeanClassInfo[1];
453: _beanInfo[0] = newBeanInfo(beanType, alias, 0);
454: } else {
455: BeanClassInfo inf[] = new BeanClassInfo[_beanInfo.length + 1];
456: System.arraycopy(_beanInfo, 0, inf, 0, _beanInfo.length);
457: inf[inf.length - 1] = newBeanInfo(beanType, alias,
458: inf.length - 1);
459: _beanInfo = inf;
460: }
461: super .addBeanDefinition(beanType, alias);
462: }
463:
464: /**
465: * Parses an beanextrainfo attribute string from the datasource into from,where, orderby etc...
466: */
467: protected void parseExtraInfo(String extraInfo) {
468: if (extraInfo == null)
469: return;
470: extraInfo = " " + extraInfo;
471: String work = extraInfo.toUpperCase();
472: int fromPos = work.indexOf(" FROM ");
473: int wherePos = work.indexOf(" WHERE ");
474: int orderPos = work.indexOf(" ORDER BY ");
475: int joinPos = -1;
476: int jp = work.indexOf(" LEFT JOIN ");
477: if (jp != -1 && (jp < joinPos || joinPos == -1))
478: joinPos = jp;
479: jp = work.indexOf(" LEFT OUTER JOIN ");
480: if (jp != -1 && (jp < joinPos || joinPos == -1))
481: joinPos = jp;
482: jp = work.indexOf(" INNER JOIN ");
483: if (jp != -1 && (jp < joinPos || joinPos == -1))
484: joinPos = jp;
485: jp = work.indexOf(" JOIN ");
486: if (jp != -1 && (jp < joinPos || joinPos == -1))
487: joinPos = jp;
488:
489: if (fromPos != -1) {
490: int end = findEnd(fromPos, wherePos, orderPos, joinPos,
491: extraInfo.length());
492: _from = extraInfo.substring(fromPos + 6, end);
493: }
494: if (wherePos != -1) {
495: int end = findEnd(wherePos, fromPos, orderPos, joinPos,
496: extraInfo.length());
497: _where = extraInfo.substring(wherePos + 7, end);
498: }
499: if (orderPos != -1) {
500: int end = findEnd(orderPos, fromPos, wherePos, joinPos,
501: extraInfo.length());
502: _order = extraInfo.substring(orderPos + 10, end);
503: }
504: if (joinPos != -1) {
505: int end = findEnd(joinPos, fromPos, wherePos, orderPos,
506: extraInfo.length());
507: _join = extraInfo.substring(joinPos, end);
508: }
509: }
510:
511: private int findEnd(int start, int pos1, int pos2, int pos3,
512: int length) {
513: int end = length;
514:
515: if (pos1 > start)
516: end = pos1;
517:
518: if (pos2 > start && pos2 < end)
519: end = pos2;
520:
521: if (pos3 > start && pos3 < end)
522: end = pos3;
523:
524: return end;
525: }
526:
527: /**
528: * Returns the number of classes the datastore accesses
529: */
530: public int getAliasCount() {
531: return _beanFrom.length + _beanInfo.length;
532: }
533:
534: /**
535: * Returns Props.DBMSTYPE_HIBERNATE
536: */
537: public String getDBMS() {
538: return Props.DBMSTYPE_HIBERNATE;
539: }
540:
541: /**
542: * Returns the alias used for a particular class
543: */
544: public String getAlias(int tableNo) throws DataStoreException {
545: BeanClassInfo inf = getBeanInfo(tableNo);
546: if (inf == null)
547: return null;
548: else
549: return inf.getAlias();
550: }
551:
552: /**
553: * Returns the class name at the specified index
554: */
555: public String getTable(int tableNo) throws DataStoreException {
556: BeanClassInfo inf = getBeanInfo(tableNo);
557: if (inf == null)
558: return null;
559: else
560: return inf.getBeanClass().getName();
561: }
562:
563: private BeanClassInfo getBeanInfo(int tableNo) {
564: if (tableNo < _beanInfo.length)
565: return _beanInfo[tableNo];
566: else {
567: tableNo = tableNo - _beanInfo.length;
568: if (tableNo < _beanFrom.length)
569: return _beanFrom[tableNo];
570: }
571: return null;
572: }
573:
574: /**
575: * Returns the name of the specified column in the database query
576: */
577: public String getColumnDatabaseName(int col)
578: throws DataStoreException {
579: DSDataStoreDescriptor desc = getDescriptor();
580: DSColumnDescriptor colDesc = desc.getColumn(col);
581: return lowerCaseFirstLetter(colDesc.getInternalName());
582: }
583:
584: /**
585: * @see com.salmonllc.sql.DataStoreQBEInterface#getColumnTableName(int)
586: */
587: public String getColumnTableName(int col) throws DataStoreException {
588: DSDataStoreDescriptor desc = getDescriptor();
589: DSColumnDescriptor colDesc = desc.getColumn(col);
590: return colDesc.getBeanInfo().getAlias();
591: }
592:
593: /**
594: * Return all the available attributes for a particular class
595: */
596: public ColumnDefinition[] getColumnsForTable(String table) {
597: ArrayList l = new ArrayList();
598: getColumnsForTable(table, l);
599: ColumnDefinition def[] = new ColumnDefinition[l.size()];
600: l.toArray(def);
601: return def;
602: }
603:
604: private void getColumnsForTable(String table, ArrayList l) {
605: try {
606: SessionFactory fact = HibernateSessionFactory
607: .getSessionFactory();
608: int count = getAliasCount();
609: Class c = null;
610: String searchTable = table;
611: for (int i = 0; i < count; i++) {
612: if (getTable(i).equals(searchTable)) {
613: BeanClassInfo inf = getBeanInfo(i);
614: c = inf.getBeanClass();
615: break;
616: }
617: }
618:
619: if (c == null) {
620: DSDataStoreDescriptor desc = getDescriptor();
621: int colCount = desc.getColumnCount();
622: for (int i = 0; i < colCount; i++) {
623: DSColumnDescriptor colDesc = desc.getColumn(i);
624: String colName = colDesc.getInternalName();
625: if (colName.startsWith(table)) {
626: int dotCount = 0;
627: for (int j = table.length(); j < colName
628: .length(); j++) {
629: if (colName.charAt(j) == '.')
630: dotCount++;
631: }
632: if (dotCount == 1) {
633: Method parentGetters[] = colDesc
634: .getParentGetMethods();
635: if (parentGetters != null
636: && parentGetters.length > 0) {
637: c = parentGetters[parentGetters.length - 1]
638: .getReturnType();
639: table = lowerCaseFirstLetter(table);
640: break;
641: }
642: }
643: }
644: }
645: }
646:
647: if (c == null)
648: return;
649:
650: ClassMetadata md = fact.getClassMetadata(c);
651: String names[] = md.getPropertyNames();
652: Type types[] = md.getPropertyTypes();
653: String tableName = table;
654:
655: for (int i = 0; i < names.length; i++) {
656: ColumnDefinition def = new ColumnDefinition(tableName,
657: names[i],
658: getDsType(types[i].getReturnedClass()), false);
659: l.add(def);
660: }
661: ColumnDefinition def = new ColumnDefinition(tableName, md
662: .getIdentifierPropertyName(), getDsType(md
663: .getIdentifierType().getReturnedClass()), true);
664:
665: l.add(def);
666: return;
667: } catch (HibernateException e) {
668: MessageLog.writeErrorMessage("getColumnsForTable()", e,
669: this );
670: } catch (DataStoreException e) {
671: MessageLog.writeErrorMessage("getColumnsForTable()", e,
672: this );
673: }
674: return;
675: }
676:
677: private int getDsType(Class c) {
678: if (Util.instanceOf(c, Integer.class)
679: || Util.instanceOf(c, Integer.TYPE))
680: return DATATYPE_INT;
681: else if (Util.instanceOf(c, String.class))
682: return DATATYPE_STRING;
683: else if (Util.instanceOf(c, Character.class)
684: || Util.instanceOf(c, Character.TYPE))
685: return DATATYPE_STRING;
686: else if (Util.instanceOf(c, Float.class)
687: || Util.instanceOf(c, Float.TYPE))
688: return DATATYPE_FLOAT;
689: else if (Util.instanceOf(c, Double.class)
690: || Util.instanceOf(c, Double.TYPE))
691: return DATATYPE_DOUBLE;
692: else if (Util.instanceOf(c, Long.class)
693: || Util.instanceOf(c, Long.TYPE))
694: return DATATYPE_LONG;
695: else if (c.isAssignableFrom(byte[].class))
696: return DATATYPE_BYTEARRAY;
697: else if (Util.instanceOf(c, Short.class)
698: || Util.instanceOf(c, Short.TYPE))
699: return DATATYPE_SHORT;
700: else if (Util.instanceOf(c, Boolean.class)
701: || Util.instanceOf(c, Boolean.TYPE))
702: return DATATYPE_ANY;
703: else if (Util.instanceOf(c, java.sql.Timestamp.class))
704: return DATATYPE_DATETIME;
705: else if (Util.instanceOf(c, java.sql.Time.class))
706: return DATATYPE_TIME;
707: else if (Util.instanceOf(c, java.util.Date.class))
708: return DATATYPE_DATE;
709: else if (Util.instanceOf(c, BigDecimal.class))
710: return DATATYPE_DOUBLE;
711: else
712: return DATATYPE_ANY;
713: }
714:
715: /**
716: * Estimate the number of rows retrieved for a particular selection criteria
717: * string
718: */
719: public int estimateRowsRetrieved(String criteria) throws Exception {
720: String query = buildQuery("select count(*)", criteria);
721: Session sess = HibernateSessionFactory.getSession();
722: MessageLog.writeSQLMessage("HQL Query:", query, this );
723: Integer count = (Integer) sess.createQuery(query)
724: .uniqueResult();
725: return count.intValue();
726: }
727:
728: /**
729: * Override this method to provide your own creation logic when a new bean is added to the datastore
730: * @return the bean to add
731: */
732: protected Object createBean() {
733: int count = _beanInfo.length;
734: if (count == 1) {
735: Class c = _beanInfo[0].getBeanClass();
736: try {
737: return c.newInstance();
738: } catch (Exception e) {
739: MessageLog.writeErrorMessage("createBean()", e, this );
740: return null;
741: }
742: } else {
743: Object o[] = new Object[count];
744: for (int i = 0; i < count; i++) {
745: Class c = _beanInfo[i].getBeanClass();
746: try {
747: o[i] = c.newInstance();
748: } catch (Exception e) {
749: MessageLog.writeErrorMessage("createBean()", e,
750: this );
751: return null;
752: }
753: return o;
754: }
755: }
756: return null;
757: }
758:
759: public int insertRow() {
760: return insertRow(createBean(), true);
761: }
762:
763: public int insertRow(int atPosition) {
764: return insertRow(createBean(), atPosition, true);
765: }
766:
767: protected int getDataTypeForMethod(Class beanType, Method getMethod) {
768: String methName = getMethod.getName();
769: String attName = null;
770: if (methName.startsWith("get"))
771: attName = methName.substring(3);
772: else
773: attName = methName.substring(2);
774: attName = Character.toLowerCase(attName.charAt(0))
775: + attName.substring(1);
776: try {
777: SessionFactory fact = HibernateSessionFactory
778: .getSessionFactory();
779: ClassMetadata md = fact.getClassMetadata(beanType);
780: Type t = null;
781: if (attName.equals(md.getIdentifierPropertyName()))
782: t = md.getIdentifierType();
783: else
784: t = md.getPropertyType(attName);
785: return getDsType(t.getReturnedClass());
786: } catch (HibernateException e) {
787: MessageLog.writeErrorMessage("getDataTypeForMethod()", e,
788: this );
789: return -1;
790: }
791: }
792:
793: /**
794: * @return Returns whether or not a distinct will be added before each query.
795: */
796: public boolean getDistinct() {
797: return _distinct;
798: }
799:
800: /**
801: * @return sets whether or not a distinct will be added before each query.
802: */
803: public void setDistinct(boolean distinct) {
804: _distinct = distinct;
805: }
806: }
|