001: /*
002: * Created on 24/10/2004
003: *
004: * Swing Components - visit http://sf.net/projects/gfd
005: *
006: * Copyright (C) 2004 Igor Regis da Silva Simões
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or (at your option) any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: *
022: */
023: package br.com.gfpshare.beans.table;
024:
025: import java.lang.reflect.Field;
026: import java.lang.reflect.Method;
027: import java.math.BigDecimal;
028: import java.sql.Date;
029: import java.sql.ResultSet;
030: import java.sql.ResultSetMetaData;
031: import java.sql.SQLException;
032: import java.sql.Timestamp;
033: import java.util.HashMap;
034: import java.util.Map;
035:
036: import javax.swing.tree.DefaultMutableTreeNode;
037:
038: import br.com.gfpshare.beans.DBCollectionModel;
039: import br.com.gfpshare.db.Column;
040: import br.com.gfpshare.db.DAO;
041: import br.com.gfpshare.db.DAOCreationException;
042: import br.com.gfpshare.db.DAOProvider;
043: import br.com.gfpshare.db.PersistentObject;
044: import br.com.gfpshare.db.SQLCondition;
045: import br.com.gfpshare.db.SQLCondition.Condicao;
046:
047: /**
048: * @author Igor Regis da Silva Simoes
049: */
050: public class DBTreeTableModel extends AbstractTreeTableModel implements
051: DBCollectionModel {
052: /**
053: * Dados que compoem o modelo
054: */
055: private ResultSet dados = null;
056:
057: /**
058: * Dados que compoem o modelo
059: */
060: private ResultSet dadosDosFilhos = null;
061:
062: /**
063: * Tipo de dados carregados no modelo
064: */
065: private PersistentObject dataType = null;
066:
067: /**
068: * Campo que se refere a quem é o parent de um dado
069: */
070: private String fieldParentName = null;
071:
072: /**
073: * @param dataType
074: * @param fieldParentName
075: */
076: public DBTreeTableModel(PersistentObject dataType,
077: String fieldParentName) {
078: this .fieldParentName = fieldParentName;
079: setDataType(dataType);
080: setRoot(new DefaultMutableTreeNode(dados));
081: }
082:
083: /**
084: * @see br.com.gfpshare.beans.table.TreeTableModel#getColumnCount()
085: */
086: public int getColumnCount() {
087: if (getDados() == null)
088: return 0;
089:
090: try {
091: return dados.getMetaData().getColumnCount();
092: } catch (SQLException sqle) {
093: //TODO Exceção
094: sqle.printStackTrace();
095: }
096: return -1;
097: }
098:
099: /**
100: * @see br.com.gfpshare.beans.table.TreeTableModel#getColumnName(int)
101: */
102: public String getColumnName(int columnIndex) {
103: if (getDados() == null)
104: return "";
105:
106: try {
107: return dados.getMetaData().getColumnName(++columnIndex);
108: } catch (SQLException sqle) {
109: }
110: return null;
111: }
112:
113: /**
114: * Reotrna o numero total de linhas da tabela
115: * @return Numero de linhas
116: */
117: public int getRowCount() {
118: if (getDados() == null)
119: return 0;
120:
121: try {
122: dados.last();
123: return dados.getRow();
124: } catch (SQLException sqle) {
125: //TODO Exceção
126: }
127: return -1;
128: }
129:
130: /**
131: * @see br.com.gfpshare.beans.table.TreeTableModel#getValueAt(java.lang.Object, int)
132: */
133: public Object getValueAt(Object node, int column) {
134: if (((DefaultMutableTreeNode) node).getUserObject() instanceof ResultSet) {
135: return "";
136: } else if (((DefaultMutableTreeNode) node).getUserObject() instanceof PersistentObject) {
137: try {
138: return ((PersistentObject) ((DefaultMutableTreeNode) node)
139: .getUserObject()).getAsMap().get(
140: getColumnName(column));
141: } catch (Exception e) {
142: return null;
143: }
144: }
145: return null;
146: }
147:
148: /**
149: * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
150: */
151: public Object getChild(Object parent, int index) {
152: if (((DefaultMutableTreeNode) parent).getUserObject() instanceof ResultSet) {
153: try {
154: return new DefaultMutableTreeNode(
155: getPersistentObject(index));
156: } catch (SQLException e) {
157: // TODO Auto-generated catch block
158: e.printStackTrace();
159: }
160: } else if (((DefaultMutableTreeNode) parent).getUserObject() instanceof PersistentObject) {
161: return ((DefaultMutableTreeNode) parent).getChildAt(index);
162: }
163: return "";
164: }
165:
166: /**
167: * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
168: */
169: @SuppressWarnings("unchecked")
170: public int getChildCount(Object parent) {
171: if (((DefaultMutableTreeNode) parent).getUserObject() instanceof ResultSet) {
172: return getRowCount();
173: } else if (((DefaultMutableTreeNode) parent).getUserObject() instanceof PersistentObject) {
174: int i = 0;
175: if ((i = ((DefaultMutableTreeNode) parent).getChildCount()) == 0) {
176: try {
177: String classe = dataType.getClass().getName();
178: DAO dAO = DAOProvider.getControllerProvider()
179: .getController(
180: classe.substring(classe
181: .lastIndexOf('.') + 1));
182: PersistentObject filtro = dataType.getClass()
183: .newInstance();
184:
185: Object param = ((PersistentObject) ((DefaultMutableTreeNode) parent)
186: .getUserObject()).getAsMap().get("Id");
187: if (param != null) {
188: Field[] fields = filtro.getClass()
189: .getDeclaredFields();
190: Method metodo = null;
191: Column annotation = null;
192: for (Field field : fields)
193: if ((annotation = field
194: .getAnnotation(Column.class)) != null)
195: if (annotation.nome().equals(
196: fieldParentName))
197: metodo = filtro
198: .getClass()
199: .getMethod(
200: annotation
201: .writeMethodName(),
202: new Class[] { field
203: .getType() });
204: metodo.invoke(filtro, new Object[] { Integer
205: .parseInt(param.toString()) });
206: }
207: //filtro.addCondicaoExtra(SQLParser.ENVOLVE_COLUNA + fieldParentName + SQLParser.ENVOLVE_COLUNA + " = " + ((PersistentObject)((DefaultMutableTreeNode)parent).getUserObject()).getAsMap().get("Id"));
208: dadosDosFilhos = dAO.filterBy(dadosDosFilhos,
209: filtro);
210: ResultSet swap = dados;
211: dados = dadosDosFilhos;
212: for (i = 0; i < getRowCount(); i++) {
213: ((DefaultMutableTreeNode) parent)
214: .add(new DefaultMutableTreeNode(
215: getPersistentObject(i)));
216: }
217: dados = swap;
218: dAO.freeResource(dadosDosFilhos);
219: dadosDosFilhos = null;
220: return i;
221: } catch (Exception e) {
222: // TODO Auto-generated catch block
223: e.printStackTrace();
224: }
225: }
226: return i;
227: }
228: return 0;
229: }
230:
231: /**
232: * @see br.com.gfpshare.beans.DBCollectionModel#loadDados()
233: */
234: public void loadDados() throws DAOCreationException, SQLException {
235: if (getDataType() != null) {
236: String classe = dataType.getClass().getName();
237: DAO dAO = DAOProvider
238: .getControllerProvider()
239: .getController(
240: classe
241: .substring(classe.lastIndexOf('.') + 1));
242:
243: PersistentObject filtro = null;
244: try {
245: filtro = dataType.getClass().newInstance();
246: } catch (InstantiationException e) {
247: // TODO Auto-generated catch block
248: e.printStackTrace();
249: } catch (IllegalAccessException e) {
250: // TODO Auto-generated catch block
251: e.printStackTrace();
252: }
253: filtro.addCondicaoExtra(new SQLCondition<Object>(
254: fieldParentName, Condicao.IS_NULL));
255:
256: dados = dAO.getAll(dados, filtro);
257: fireTreeStructureChanged(this , new Object[] { "" },
258: new int[] { 0 }, new Object[] { "" });
259: }
260: }
261:
262: /**
263: * @see br.com.gfpshare.beans.DBCollectionModel#filter()
264: */
265: public void filter() throws DAOCreationException, SQLException {
266: if (getDataType() != null) {
267: String classe = dataType.getClass().getName();
268: DAO dAO = DAOProvider
269: .getControllerProvider()
270: .getController(
271: classe
272: .substring(classe.lastIndexOf('.') + 1));
273:
274: PersistentObject filtro = null;
275: try {
276: filtro = dataType.getClass().newInstance();
277: } catch (InstantiationException e) {
278: // TODO Auto-generated catch block
279: e.printStackTrace();
280: } catch (IllegalAccessException e) {
281: // TODO Auto-generated catch block
282: e.printStackTrace();
283: }
284: filtro.addCondicaoExtra(new SQLCondition<Object>(
285: fieldParentName, Condicao.IS_NULL));
286:
287: dados = dAO.filterBy(dados, filtro);
288:
289: //TODO Como disparar este evento?
290: fireTreeStructureChanged(this , new Object[] { "" },
291: new int[] { 0 }, new Object[] { "" });
292: }
293: }
294:
295: /**
296: * @see br.com.gfpshare.beans.DBCollectionModel#getDados()
297: */
298: public ResultSet getDados() {
299: try {
300: if (dados != null)
301: dados.isFirst();
302: } catch (SQLException e) {
303: //Fazemos o tratamento do erro pos do contrário a tela pode
304: //tentar exibir o conteúdo de um ResultSet que esteja fechado
305: if (e.getErrorCode() == -158)//ResultSet fechado
306: this .dados = null;
307: try {
308: loadDados();
309: } catch (DAOCreationException e1) {
310: // //TODO Auto-generated catch block
311: e1.printStackTrace();
312: } catch (SQLException e1) {
313: // //TODO Auto-generated catch block
314: e1.printStackTrace();
315: }
316: }
317: return this .dados;
318: }
319:
320: /**
321: * @see br.com.gfpshare.beans.DBCollectionModel#getDataAt(int)
322: */
323: public Map getDataAt(int index) throws SQLException {
324: if (getRowCount() == 0)
325: return null;
326: HashMap data = new HashMap(1);
327:
328: ResultSetMetaData metaData = dados.getMetaData();
329:
330: int coluna;
331: for (int i = 0; i < metaData.getColumnCount(); i++)
332: if ((coluna = findColumn(metaData.getColumnName(i + 1)) - 1) != -2)
333: data.put(metaData.getColumnName(i + 1), getValueAt(
334: index, coluna) == null ? null : getValueAt(
335: index, coluna));
336: return data;
337: }
338:
339: /**
340: * Retorna o valor de uma determinada célula
341: * @param rowIndex Linha
342: * @param columnIndex Coluna
343: * @return Valor
344: */
345: public Object getValueAt(int rowIndex, int columnIndex) {
346: if (getDados() == null || getRowCount() == 0)
347: return null;
348:
349: try {
350: dados.first();
351: for (int i = 0; i < rowIndex; i++) {
352: dados.next();
353: }
354: Object dado = dados.getObject(++columnIndex);
355:
356: if (dado instanceof Date)
357: return new java.util.Date(((Date) dado).getTime());
358: else if (dado instanceof Timestamp)
359: return new java.util.Date(((Timestamp) dado).getTime());
360: else if (dado instanceof BigDecimal)
361: return new Double(((BigDecimal) dado).doubleValue());
362:
363: return dado;
364: } catch (SQLException sqle) {
365: //TODO Exceção
366: sqle.printStackTrace();
367: return null;
368: }
369: }
370:
371: /**
372: * Reotrna o indice de uma coluna
373: * @param columnName Nome da coluna
374: * @return indice inteiro
375: */
376: public int findColumn(String columnName) {
377: if (getDados() == null)
378: return -1;
379:
380: try {
381: for (int i = 1; i <= dados.getMetaData().getColumnCount(); i++) {
382: if (dados.getMetaData().getColumnName(i).equals(
383: columnName))
384: return i;
385: }
386: } catch (SQLException sqle) {
387: //TODO Exceção
388: sqle.printStackTrace();
389: }
390: return -1;
391: }
392:
393: /**
394: * @see br.com.gfpshare.beans.DBCollectionModel#getPersistentObject(int)
395: */
396: public PersistentObject getPersistentObject(int index)
397: throws SQLException {
398: if (getRowCount() == 0)
399: return null;
400: PersistentObject dado = null;
401:
402: try {
403: dado = getDataType().getClass().newInstance();
404: } catch (InstantiationException ie) {
405: //TODO Excecao
406: ie.printStackTrace();
407: } catch (IllegalAccessException iae) {
408: //TODO Excecao
409: iae.printStackTrace();
410: }
411:
412: dado.setDados(getDataAt(index));
413: return dado;
414: }
415:
416: /**
417: * @see br.com.gfpshare.beans.DBCollectionModel#setDataType(br.com.gfpshare.db.PersistentObject)
418: */
419: public void setDataType(PersistentObject dataType) {
420: this .dataType = dataType;
421: try {
422: loadDados();
423: } catch (DAOCreationException cce) {
424: throw new RuntimeException(cce);
425: } catch (SQLException sqle) {
426: throw new RuntimeException(sqle);
427: }
428: }
429:
430: /**
431: * @see br.com.gfpshare.beans.DBCollectionModel#getDataType()
432: */
433: public PersistentObject getDataType() {
434: return dataType;
435: }
436:
437: /**
438: * @see java.lang.Object#finalize()
439: */
440: @Override
441: protected void finalize() throws Throwable {
442: super .finalize();
443: if (getDados() != null) {
444: String classe = dataType.getClass().getName();
445: DAO dAO = DAOProvider
446: .getControllerProvider()
447: .getController(
448: classe
449: .substring(classe.lastIndexOf('.') + 1));
450: dAO.freeResource(dados);
451: }
452: }
453: }
|