001: /*
002: * Created on 23/04/2004
003: *
004: * ============================================================================
005: * GNU Lesser General Public License
006: * ============================================================================
007: *
008: * Swing Components - visit http://sf.net/projects/gfd
009: *
010: * Copyright (C) 2004 Igor Regis da Silva Simões
011: *
012: * This library is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU Lesser General Public
014: * License as published by the Free Software Foundation; either
015: * version 2.1 of the License, or (at your option) any later version.
016: *
017: * This library is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
020: * Lesser General Public License for more details.
021: *
022: * You should have received a copy of the GNU Lesser General Public
023: * License along with this library; if not, write to the Free Software
024: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
025: */
026:
027: package br.com.igor.beans;
028:
029: import java.math.BigDecimal;
030: import java.sql.Date;
031: import java.sql.ResultSet;
032: import java.sql.ResultSetMetaData;
033: import java.sql.SQLException;
034: import java.sql.Timestamp;
035: import java.util.HashMap;
036: import java.util.Map;
037:
038: import javax.swing.AbstractListModel;
039: import javax.swing.ComboBoxModel;
040:
041: import br.com.igor.db.Controller;
042: import br.com.igor.db.ControllerCreationException;
043: import br.com.igor.db.ControllerEvent;
044: import br.com.igor.db.ControllerListener;
045: import br.com.igor.db.ControllerProvider;
046: import br.com.igor.db.PersistentObject;
047:
048: /**
049: * Modelo de dados que deverão ser representados através de um DBComboBox
050: * @author Igor Regis da Silva Simoes
051: */
052: public class DBComboBoxModel extends AbstractListModel implements
053: ComboBoxModel, DBCollectionModel, ControllerListener {
054: /**
055: * Dados que compoem o modelo
056: */
057: private ResultSet dados = null;
058:
059: /**
060: * Objeto atualmente selecionado
061: */
062: private Object selectedObject = null;
063:
064: /**
065: * Tipo de dados carregados no modelo
066: */
067: private PersistentObject dataType = null;
068:
069: public static final String INSERT_NEW = "< INSERT NEW >";
070:
071: /**
072: * Gerencia o cache de dados deste componente
073: */
074: private CacheManager cacheManager = new CacheManager();
075:
076: /**
077: * Controller usado para acessar a tabela de dados
078: */
079: private Controller controller = null;
080:
081: /**
082: * Cria um modelo com um determinado tipo de dados
083: * @param dataType Tipo de dados do modelo
084: */
085: public DBComboBoxModel(PersistentObject dataType) {
086: this .dataType = dataType;
087: }
088:
089: /**
090: * @see br.com.igor.beans.DBCollectionModel#loadDados()
091: */
092: public void loadDados() throws ControllerCreationException,
093: SQLException {
094: cacheManager.resetCache();
095: if (getDataType() != null) {
096: if (controller != null) {
097: controller.removeControllerListener(this );
098: }
099: String classe = dataType.getClass().getName();
100: controller = ControllerProvider
101: .getControllerProvider()
102: .getController(
103: classe
104: .substring(classe.lastIndexOf('.') + 1));
105: controller.addControllerListener(this );
106: dados = controller.getAll(dados, dataType);
107: fireContentsChanged(this , -1, -1);
108: } else
109: dados = null;
110: }
111:
112: /**
113: * @see br.com.igor.beans.DBCollectionModel#getDados()
114: */
115: public ResultSet getDados() {
116: try {
117: if (dados != null)
118: dados.isFirst();
119: } catch (SQLException e) {
120: //Fazemos o tratamento do erro pos do contrário a tela pode
121: //tentar exibir o conteúdo de um ResultSet que esteja fechado
122: if (e.getErrorCode() == -158)//ResultSet fechado
123: this .dados = null;
124: try {
125: loadDados();
126: } catch (ControllerCreationException e1) {
127: // //TODO Auto-generated catch block
128: e1.printStackTrace();
129: } catch (SQLException e1) {
130: // //TODO Auto-generated catch block
131: e1.printStackTrace();
132: }
133: }
134: return this .dados;
135: }
136:
137: /**
138: * @see br.com.igor.beans.DBCollectionModel#getDataAt(int)
139: */
140: public Map<String, Object> getDataAt(int index) throws SQLException {
141: index--;
142: HashMap<String, Object> data = new HashMap<String, Object>(1);
143:
144: if (index == 0 || getDados() == null)
145: return null;
146:
147: Map<String, Object> c = cacheManager.getMap(index);
148: if (c != null)
149: return c;
150:
151: ResultSetMetaData metaData = dados.getMetaData();
152:
153: dados.beforeFirst();
154: for (int i = 0; i < index; i++) {
155: dados.next();
156: }
157:
158: for (int i = 1; i <= metaData.getColumnCount(); i++) {
159: Object campo = dados.getObject(i) == null ? null : dados
160: .getObject(i);
161:
162: if (campo instanceof Date)
163: campo = new java.util.Date(((Date) campo).getTime());
164: else if (campo instanceof Timestamp)
165: campo = new java.util.Date(((Timestamp) campo)
166: .getTime());
167: else if (campo instanceof BigDecimal)
168: campo = new Double(((BigDecimal) campo).doubleValue());
169:
170: data.put(metaData.getColumnName(i), campo);
171: }
172: cacheManager.add(index, data);
173: return data;
174:
175: }
176:
177: /**
178: * @see br.com.igor.beans.DBCollectionModel#getPersistentObject(int)
179: */
180: public PersistentObject getPersistentObject(int index)
181: throws SQLException {
182: if (index == 0 || getDados() == null)
183: return null;
184:
185: PersistentObject dado = (PersistentObject) cacheManager
186: .get(index);
187: if (dado != null)
188: return dado;
189: try {
190: dado = getDataType().getClass().newInstance();
191: } catch (InstantiationException ie) {
192: //TODO Excecao
193: ie.printStackTrace();
194: } catch (IllegalAccessException iae) {
195: //TODO Excecao
196: iae.printStackTrace();
197: }
198:
199: Map dados = getDataAt(index);
200: if (dados == null)
201: return null;
202:
203: dado.setDados(dados);
204: cacheManager.add(index, dado);
205: return dado;
206: }
207:
208: /**
209: * @see javax.swing.ListModel#getElementAt(int)
210: */
211: public Object getElementAt(int index) {
212: if (index == 1) {
213: return INSERT_NEW;
214: }
215: try {
216: return getPersistentObject(index);
217: } catch (SQLException sqle) {
218: //TODO Excecao
219: }
220: return null;
221: }
222:
223: /**
224: * @see javax.swing.ListModel#getSize()
225: */
226: public int getSize() {
227: if (getDados() == null)
228: return 0;
229:
230: if (cacheManager.isCachedSizeClear())
231: try {
232: dados.last();
233: cacheManager.setSizeCached(dados.getRow() + 2);
234: } catch (SQLException sqle) {
235: //TODO Exceção
236: sqle.printStackTrace();
237: }
238: return cacheManager.getSizeCached();
239: }
240:
241: /**
242: * @see javax.swing.ComboBoxModel#getSelectedItem()
243: */
244: public Object getSelectedItem() {
245: return selectedObject;
246: }
247:
248: /**
249: * Retorna o indice selecionado deste data model
250: * @return
251: */
252: public int getSelectedIndex() {
253: return cacheManager.getSelectedIndex();
254: }
255:
256: /**
257: * Seleciona um determinado PersistentObject da combobox
258: * @param item Item a ser selecionado
259: * @throws SQLException
260: */
261: public void setSelectedItem(PersistentObject item)
262: throws SQLException {
263: for (int i = getSize() - 1; i > 0; i--) {
264: if (getPersistentObject(i) != null
265: && getPersistentObject(i).toString().equals(
266: item.toString())) {
267: cacheManager.setSelectedIndex(i);
268: selectedObject = item;
269: fireContentsChanged(this , -1, -1);
270: return;
271: }
272: }
273: cacheManager.setSelectedIndex(-1);
274: selectedObject = null;
275: fireContentsChanged(this , -1, -1);
276: return;
277: }
278:
279: /**
280: * Determina o item selecionado na combobox
281: * @param anObject Objeto que deve ser selecionado
282: * @param key Chave usada parafazer a comparação de citério de seleção
283: * @throws SQLException
284: */
285: public void setSelectedItem(Object anObject, String key)
286: throws SQLException {
287: if (getDados() == null || anObject == null)
288: return;
289:
290: if (selectedObject != null
291: && ((PersistentObject) selectedObject).getAsMap().get(
292: key).equals(anObject))
293: return;
294: for (int i = 2; i < getSize(); i++) {
295: if (getDataAt(i) != null
296: && getDataAt(i).get(key) != null
297: && getDataAt(i).get(key).toString().equals(
298: anObject.toString())) {
299: cacheManager.setSelectedIndex(i);
300: selectedObject = getPersistentObject(i);
301: fireContentsChanged(this , -1, -1);
302: return;
303: }
304: }
305:
306: cacheManager.setSelectedIndex(-1);
307: selectedObject = null;
308: fireContentsChanged(this , -1, -1);
309: return;
310: }
311:
312: /**
313: * @see javax.swing.ComboBoxModel#setSelectedItem(java.lang.Object)
314: */
315: public void setSelectedItem(Object anObject) {
316: if (anObject instanceof PersistentObject) {
317: try {
318: setSelectedItem((PersistentObject) anObject);
319: } catch (SQLException sqle) {
320: //TODO Excecao
321: }
322: return;
323: }
324:
325: cacheManager.setSelectedIndex(-1);
326: selectedObject = null;
327: fireContentsChanged(this , -1, -1);
328: }
329:
330: /**
331: * Seta o indice selecionado neste model
332: * @param index
333: */
334: public void setSelectedIndex(int index) {
335: selectedObject = getElementAt(index);
336: cacheManager.setSelectedIndex(index);
337: cacheManager.add(index, selectedObject);
338: fireContentsChanged(this , -1, -1);
339: }
340:
341: /**
342: * @see br.com.igor.beans.DBCollectionModel#setDataType(br.com.igor.db.PersistentObject)
343: */
344: public void setDataType(PersistentObject dataType) {
345: this .dataType = dataType;
346: try {
347: loadDados();
348: } catch (ControllerCreationException cce) {
349: throw new RuntimeException(cce);
350: } catch (SQLException sqle) {
351: throw new RuntimeException(sqle);
352: }
353:
354: }
355:
356: /**
357: * @see br.com.igor.beans.DBCollectionModel#getDataType()
358: */
359: public PersistentObject getDataType() {
360: return dataType;
361: }
362:
363: /**
364: * @see br.com.igor.beans.DBCollectionModel#filter()
365: */
366: public void filter() throws ControllerCreationException,
367: SQLException {
368: cacheManager.resetCache();
369: if (getDataType() != null) {
370: String classe = dataType.getClass().getName();
371: Controller controller = ControllerProvider
372: .getControllerProvider()
373: .getController(
374: classe
375: .substring(classe.lastIndexOf('.') + 1));
376: dados = controller.filterBy(dados, dataType);
377: fireContentsChanged(this , -1, -1);
378: } else
379: dados = null;
380:
381: }
382:
383: /**
384: * @see java.lang.Object#finalize()
385: */
386: @Override
387: protected void finalize() throws Throwable {
388: super .finalize();
389: if (dados != null) {
390: String classe = dataType.getClass().getName();
391: Controller controller = ControllerProvider
392: .getControllerProvider()
393: .getController(
394: classe
395: .substring(classe.lastIndexOf('.') + 1));
396: controller.freeResource(dados);
397: }
398: }
399:
400: private class CacheManager {
401: private Map<Integer, Object> cacheBO = new HashMap<Integer, Object>();
402:
403: private Map<Integer, Map<String, Object>> cacheMapToColumn = new HashMap<Integer, Map<String, Object>>();
404:
405: private int sizeCache = -1;
406:
407: private int selectedIndex = -1;
408:
409: void resetCache() {
410: cacheBO.clear();
411: cacheMapToColumn.clear();
412: sizeCache = -1;
413: }
414:
415: void add(Integer i, Object bo) {
416: cacheBO.put(i, bo);
417: }
418:
419: Object get(Integer i) {
420: return cacheBO.get(i);
421: }
422:
423: void add(Integer i, Map<String, Object> bo) {
424: cacheMapToColumn.put(i, bo);
425: }
426:
427: Map<String, Object> getMap(Integer i) {
428: return cacheMapToColumn.get(i);
429: }
430:
431: void setSizeCached(int i) {
432: sizeCache = i;
433: }
434:
435: int getSizeCached() {
436: return sizeCache;
437: }
438:
439: boolean isCachedSizeClear() {
440: return sizeCache == -1;
441: }
442:
443: public int getSelectedIndex() {
444: return selectedIndex;
445: }
446:
447: public void setSelectedIndex(int selectedIndex) {
448: this .selectedIndex = selectedIndex;
449: }
450: }
451:
452: public void adicionadoNovo(ControllerEvent e) {
453: try {
454: loadDados();
455: } catch (ControllerCreationException e1) {
456: // TODO Auto-generated catch block
457: e1.printStackTrace();
458: } catch (SQLException e1) {
459: // TODO Auto-generated catch block
460: e1.printStackTrace();
461: }
462: }
463:
464: public void atualizado(ControllerEvent e) {
465: try {
466: loadDados();
467: } catch (ControllerCreationException e1) {
468: // TODO Auto-generated catch block
469: e1.printStackTrace();
470: } catch (SQLException e1) {
471: // TODO Auto-generated catch block
472: e1.printStackTrace();
473: }
474: }
475:
476: public void deletado(ControllerEvent e) {
477: try {
478: loadDados();
479: } catch (ControllerCreationException e1) {
480: // TODO Auto-generated catch block
481: e1.printStackTrace();
482: } catch (SQLException e1) {
483: // TODO Auto-generated catch block
484: e1.printStackTrace();
485: }
486: }
487:
488: public void filtrado(ControllerEvent e) {
489: //------------------------------------------------
490: // TODO Auto-generated method stub
491:
492: }
493:
494: public void selecionado(ControllerEvent e) {
495: //------------------------------------------------
496: // TODO Auto-generated method stub
497:
498: }
499: }
|