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.igor.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.igor.beans.DBCollectionModel;
039: import br.com.igor.db.Coluna;
040: import br.com.igor.db.CondicaoSQL;
041: import br.com.igor.db.Controller;
042: import br.com.igor.db.ControllerCreationException;
043: import br.com.igor.db.ControllerProvider;
044: import br.com.igor.db.PersistentObject;
045: import br.com.igor.db.CondicaoSQL.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.igor.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.igor.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: //TODO Exceção
110: sqle.printStackTrace();
111: }
112: return null;
113: }
114:
115: /**
116: * Reotrna o numero total de linhas da tabela
117: * @return Numero de linhas
118: */
119: public int getRowCount() {
120: if (getDados() == null)
121: return 0;
122:
123: try {
124: dados.last();
125: return dados.getRow();
126: } catch (SQLException sqle) {
127: //TODO Exceção
128: }
129: return -1;
130: }
131:
132: /**
133: * @see br.com.igor.beans.table.TreeTableModel#getValueAt(java.lang.Object, int)
134: */
135: public Object getValueAt(Object node, int column) {
136: if (((DefaultMutableTreeNode) node).getUserObject() instanceof ResultSet) {
137: return "";
138: } else if (((DefaultMutableTreeNode) node).getUserObject() instanceof PersistentObject) {
139: return ((PersistentObject) ((DefaultMutableTreeNode) node)
140: .getUserObject()).getAsMap().get(
141: getColumnName(column));
142: }
143: return null;
144: }
145:
146: /**
147: * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
148: */
149: public Object getChild(Object parent, int index) {
150: if (((DefaultMutableTreeNode) parent).getUserObject() instanceof ResultSet) {
151: try {
152: return new DefaultMutableTreeNode(
153: getPersistentObject(index));
154: } catch (SQLException e) {
155: // TODO Auto-generated catch block
156: e.printStackTrace();
157: }
158: } else if (((DefaultMutableTreeNode) parent).getUserObject() instanceof PersistentObject) {
159: return ((DefaultMutableTreeNode) parent).getChildAt(index);
160: }
161: return "";
162: }
163:
164: /**
165: * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
166: */
167: @SuppressWarnings("unchecked")
168: public int getChildCount(Object parent) {
169: if (((DefaultMutableTreeNode) parent).getUserObject() instanceof ResultSet) {
170: return getRowCount();
171: } else if (((DefaultMutableTreeNode) parent).getUserObject() instanceof PersistentObject) {
172: int i = 0;
173: if ((i = ((DefaultMutableTreeNode) parent).getChildCount()) == 0) {
174: try {
175: String classe = dataType.getClass().getName();
176: Controller controller = ControllerProvider
177: .getControllerProvider().getController(
178: classe.substring(classe
179: .lastIndexOf('.') + 1));
180: PersistentObject filtro = dataType.getClass()
181: .newInstance();
182:
183: Object param = ((PersistentObject) ((DefaultMutableTreeNode) parent)
184: .getUserObject()).getAsMap().get("Id");
185: if (param != null) {
186: Field[] fields = filtro.getClass()
187: .getDeclaredFields();
188: Method metodo = null;
189: Coluna annotation = null;
190: for (Field field : fields)
191: if ((annotation = field
192: .getAnnotation(Coluna.class)) != null)
193: if (annotation.nome().equals(
194: fieldParentName))
195: metodo = filtro
196: .getClass()
197: .getMethod(
198: annotation
199: .writeMethodName(),
200: new Class[] { field
201: .getType() });
202: metodo.invoke(filtro, new Object[] { Integer
203: .parseInt(param.toString()) });
204: }
205: //filtro.addCondicaoExtra(SQLParser.ENVOLVE_COLUNA + fieldParentName + SQLParser.ENVOLVE_COLUNA + " = " + ((PersistentObject)((DefaultMutableTreeNode)parent).getUserObject()).getAsMap().get("Id"));
206: dadosDosFilhos = controller.filterBy(
207: dadosDosFilhos, filtro);
208: ResultSet swap = dados;
209: dados = dadosDosFilhos;
210: for (i = 0; i < getRowCount(); i++) {
211: ((DefaultMutableTreeNode) parent)
212: .add(new DefaultMutableTreeNode(
213: getPersistentObject(i)));
214: }
215: dados = swap;
216: controller.freeResource(dadosDosFilhos);
217: dadosDosFilhos = null;
218: return i;
219: } catch (Exception e) {
220: // TODO Auto-generated catch block
221: e.printStackTrace();
222: }
223: }
224: return i;
225: }
226: return 0;
227: }
228:
229: /**
230: * @see br.com.igor.beans.DBCollectionModel#loadDados()
231: */
232: public void loadDados() throws ControllerCreationException,
233: SQLException {
234: if (getDataType() != null) {
235: String classe = dataType.getClass().getName();
236: Controller controller = ControllerProvider
237: .getControllerProvider()
238: .getController(
239: classe
240: .substring(classe.lastIndexOf('.') + 1));
241:
242: PersistentObject filtro = null;
243: try {
244: filtro = dataType.getClass().newInstance();
245: } catch (InstantiationException e) {
246: // TODO Auto-generated catch block
247: e.printStackTrace();
248: } catch (IllegalAccessException e) {
249: // TODO Auto-generated catch block
250: e.printStackTrace();
251: }
252: filtro.addCondicaoExtra(new CondicaoSQL<Object>(
253: fieldParentName, Condicao.IS_NULL));
254:
255: dados = controller.getAll(dados, filtro);
256: fireTreeStructureChanged(this , new Object[] { "" },
257: new int[] { 0 }, new Object[] { "" });
258: }
259: }
260:
261: /**
262: * @see br.com.igor.beans.DBCollectionModel#filter()
263: */
264: public void filter() throws ControllerCreationException,
265: SQLException {
266: if (getDataType() != null) {
267: String classe = dataType.getClass().getName();
268: Controller controller = ControllerProvider
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 CondicaoSQL<Object>(
285: fieldParentName, Condicao.IS_NULL));
286:
287: dados = controller.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.igor.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 (ControllerCreationException 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.igor.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.igor.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.igor.beans.DBCollectionModel#setDataType(br.com.igor.db.PersistentObject)
418: */
419: public void setDataType(PersistentObject dataType) {
420: this .dataType = dataType;
421: try {
422: loadDados();
423: } catch (ControllerCreationException cce) {
424: throw new RuntimeException(cce);
425: } catch (SQLException sqle) {
426: throw new RuntimeException(sqle);
427: }
428: }
429:
430: /**
431: * @see br.com.igor.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: Controller controller = ControllerProvider
446: .getControllerProvider()
447: .getController(
448: classe
449: .substring(classe.lastIndexOf('.') + 1));
450: controller.freeResource(dados);
451: }
452: }
453: }
|