001: /*
002: * <copyright>
003: *
004: * Copyright 2000-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: // Adapted from Java Swing TableExample demo
028: package org.cougaar.tools.csmart.ui.community;
029:
030: import org.cougaar.tools.csmart.core.db.DBUtils;
031: import org.cougaar.tools.csmart.ui.viewer.CSMART;
032: import org.cougaar.util.log.Logger;
033:
034: import javax.swing.table.AbstractTableModel;
035: import java.sql.Connection;
036: import java.sql.ResultSet;
037: import java.sql.ResultSetMetaData;
038: import java.sql.SQLException;
039: import java.sql.Statement;
040: import java.sql.Types;
041: import java.util.ArrayList;
042: import java.util.HashMap;
043:
044: public class DatabaseTableModel extends AbstractTableModel {
045: private static final String GET_ALL_COMMUNITY_INFO_QUERY = "queryAllCommunityInfo";
046: private static final String GET_COMMUNITY_INFO_QUERY = "queryCommunityInfo";
047: private static final String GET_ENTITY_INFO_QUERY = "queryEntityInfo";
048: private static final String GET_CHILDREN_ENTITY_INFO_QUERY = "queryChildrenEntityInfo";
049:
050: private String[] columnNames = {};
051: private ArrayList rows = new ArrayList();
052: private ResultSetMetaData metaData;
053: private String communityName;
054:
055: private String assemblyId = null;
056:
057: private transient Logger log;
058:
059: private HashMap substitutions = new HashMap();
060:
061: public DatabaseTableModel() {
062: log = CSMART.createLogger(this .getClass().getName());
063: }
064:
065: public DatabaseTableModel(String assemblyId) {
066: log = CSMART.createLogger(this .getClass().getName());
067: setAssemblyId(assemblyId);
068: }
069:
070: public void setAssemblyId(String assemblyId) {
071: this .assemblyId = assemblyId;
072: substitutions = getSubstitutions(assemblyId);
073: }
074:
075: public static HashMap getSubstitutions(String assemblyId) {
076: HashMap subs = new HashMap();
077: subs.put(":assembly_id:", assemblyId);
078:
079: // FIXME: This says if assembly_id is null, use none at all
080: // Maybe instead use all?
081: if (assemblyId != null)
082: subs.put(":assembly_match:", "IN ('" + assemblyId + "')");
083: else
084: subs.put(":assembly_match:", "IS NULL");
085:
086: return subs;
087: }
088:
089: /**
090: * Methods for getting information from the database and updating the table model.
091: */
092: public void getAllCommunityInfo(String communityId) {
093: substitutions.put(":community_id", communityId);
094: String query = DBUtils.getQuery(GET_ALL_COMMUNITY_INFO_QUERY,
095: substitutions);
096: executeQuery(query);
097: }
098:
099: public void getCommunityInfo(String communityId) {
100: substitutions.put(":community_id", communityId);
101: String query = DBUtils.getQuery(GET_COMMUNITY_INFO_QUERY,
102: substitutions);
103: executeQuery(query);
104: }
105:
106: public void getEntityInfo(String communityId, String entityId) {
107: substitutions.put(":community_id", communityId);
108: substitutions.put(":entity_id", entityId);
109: String query = DBUtils.getQuery(GET_ENTITY_INFO_QUERY,
110: substitutions);
111: executeQuery(query);
112: communityName = communityId; // used if user adds parameters to this entity
113: }
114:
115: public void getChildrenEntityInfo(String communityId,
116: String childrenEntityIds) {
117: substitutions.put(":community_id", communityId);
118: substitutions.put(":children_entity_ids", childrenEntityIds);
119: String query = DBUtils.getQuery(GET_CHILDREN_ENTITY_INFO_QUERY,
120: substitutions);
121: executeQuery(query);
122: }
123:
124: private void executeQuery(String query) {
125: Connection conn = null;
126: try {
127: conn = DBUtils.getConnection();
128: if (conn == null) {
129: if (log.isErrorEnabled()) {
130: log.error("Could not get connection to database");
131: }
132: return;
133: }
134: Statement statement = conn.createStatement();
135: ResultSet resultSet = statement.executeQuery(query);
136:
137: // if it's an update or insert don't change rows, columns or metadata
138: if (!query.startsWith("update")
139: && !query.startsWith("UPDATE")
140: && !query.startsWith("INSERT")
141: && !query.startsWith("insert")) {
142: metaData = resultSet.getMetaData();
143: // get column names
144: int numberOfColumns = metaData.getColumnCount();
145: columnNames = new String[numberOfColumns];
146: for (int column = 0; column < numberOfColumns; column++)
147: columnNames[column] = metaData
148: .getColumnLabel(column + 1);
149: // if there is data (i.e. column count non-zero), get all rows
150: if (numberOfColumns != 0) {
151: rows = new ArrayList();
152: while (resultSet.next()) {
153: ArrayList newRow = new ArrayList();
154: for (int i = 1; i <= getColumnCount(); i++)
155: newRow.add(resultSet.getString(i));
156: rows.add(newRow);
157: }
158: }
159: }
160: fireTableChanged(null); // Tell the listeners a new table has arrived.
161: resultSet.close();
162: statement.close();
163: } catch (SQLException ex) {
164: if (log.isErrorEnabled()) {
165: log.error("Exception in query: " + query, ex);
166: }
167: } finally {
168: try {
169: if (conn != null)
170: conn.close();
171: } catch (SQLException e) {
172: }
173: }
174: }
175:
176: /**
177: * Return all values in the specified column; removes duplicates.
178: * @param columnIndex of column
179: * @return unique values in that column
180: */
181: public ArrayList getKnownValues(int columnIndex) {
182: ArrayList values = new ArrayList();
183: int nRows = getRowCount();
184: for (int i = 0; i < nRows; i++) {
185: Object o = getValueAt(i, columnIndex);
186: if (!values.contains(o))
187: values.add(o);
188: }
189: return values;
190: }
191:
192: /**
193: * Delete the specified row and update the database.
194: * @param row the index of the row to delete
195: */
196: public void deleteRow(int row) {
197: if (row >= rows.size())
198: return;
199: String tableName = "";
200: try {
201: tableName = metaData.getTableName(1);
202: } catch (SQLException e) {
203: if (log.isErrorEnabled()) {
204: log.error("Exception getting table name: ", e);
205: }
206: return;
207: }
208: if (tableName.equalsIgnoreCase("community_attribute")
209: || tableName.equalsIgnoreCase("ca"))
210: CommunityDBUtils.deleteCommunityAttribute(dbRepresentation(
211: 0, getValueAt(row, 0)), dbRepresentation(1,
212: getValueAt(row, 1)), dbRepresentation(2,
213: getValueAt(row, 2)), assemblyId);
214: else if (tableName
215: .equalsIgnoreCase("community_entity_attribute")
216: || tableName.equalsIgnoreCase("cea"))
217: CommunityDBUtils
218: .deleteEntityAttribute(communityName,
219: dbRepresentation(0, getValueAt(row, 0)),
220: dbRepresentation(1, getValueAt(row, 1)),
221: dbRepresentation(2, getValueAt(row, 2)),
222: assemblyId);
223: else {
224: if (log.isErrorEnabled()) {
225: log.error("Attempting to delete from unknown table: "
226: + tableName);
227: }
228: }
229: rows.remove(row);
230: fireTableRowsDeleted(row, row);
231: }
232:
233: /**
234: * Make the table empty.
235: */
236: public void clear() {
237: rows = new ArrayList();
238: columnNames = new String[0];
239: fireTableChanged(null);
240: }
241:
242: //////////////////////////////////////////////////////////////////////////
243: //
244: // Implementation of the TableModel Interface
245: // All methods here need corresponding wrapper
246: // methods in TableSorter
247: //
248: //////////////////////////////////////////////////////////////////////////
249:
250: // MetaData
251:
252: public String getColumnName(int column) {
253: if (columnNames[column] != null) {
254: return columnNames[column];
255: } else {
256: return "";
257: }
258: }
259:
260: public Class getColumnClass(int column) {
261: int type;
262: String typeName;
263: try {
264: type = metaData.getColumnType(column + 1);
265: typeName = metaData.getColumnTypeName(column + 1);
266: } catch (SQLException e) {
267: return super .getColumnClass(column);
268: }
269: switch (type) {
270: case Types.CHAR:
271: case Types.VARCHAR:
272: case Types.LONGVARCHAR:
273: return String.class;
274:
275: case Types.BIT:
276: return Boolean.class;
277:
278: case Types.TINYINT:
279: case Types.SMALLINT:
280: case Types.INTEGER:
281: return Integer.class;
282:
283: case Types.BIGINT:
284: return Long.class;
285:
286: case Types.FLOAT:
287: case Types.DOUBLE:
288: return Double.class;
289:
290: case Types.DATE:
291: return java.sql.Date.class;
292:
293: default:
294: return Object.class;
295: }
296: }
297:
298: public boolean isCellEditable(int row, int column) {
299: String columnName = getColumnName(column);
300: if (columnName != null) {
301: if (columnName.equalsIgnoreCase("ENTITY_ID")
302: || columnName.equalsIgnoreCase("COMMUNITY_ID")
303: || columnName.equalsIgnoreCase("Entity")
304: || columnName.equalsIgnoreCase("Entity ID")
305: || columnName.equalsIgnoreCase("Name")
306: || columnName.equalsIgnoreCase("Community ID")
307: || columnName.equalsIgnoreCase("Community")) {
308: if (log.isDebugEnabled()) {
309: log.debug("isCellEditable: Column " + column + "("
310: + columnName + ") not editable by name.");
311: }
312: return false;
313: }
314: }
315:
316: try {
317: return metaData.isWritable(column + 1);
318: } catch (SQLException e) {
319: if (log.isErrorEnabled()) {
320: log.error("Exception on is cell editable: " + row + ","
321: + column, e);
322: }
323: return false;
324: }
325: }
326:
327: public int getColumnCount() {
328: return columnNames.length;
329: }
330:
331: // Data methods
332:
333: public int getRowCount() {
334: return rows.size();
335: }
336:
337: public Object getValueAt(int aRow, int aColumn) {
338: ArrayList row = (ArrayList) rows.get(aRow);
339: return row.get(aColumn);
340: }
341:
342: private String dbRepresentation(int column, Object value) {
343: int type;
344:
345: if (value == null) {
346: return "null";
347: }
348:
349: try {
350: type = metaData.getColumnType(column + 1);
351: } catch (SQLException e) {
352: return value.toString();
353: }
354:
355: switch (type) {
356: case Types.INTEGER:
357: case Types.DOUBLE:
358: case Types.FLOAT:
359: return value.toString();
360: case Types.BIT:
361: return ((Boolean) value).booleanValue() ? "1" : "0";
362: case Types.DATE:
363: return value.toString(); // This will need some conversion.
364: default:
365: return value.toString();
366: }
367:
368: }
369:
370: /**
371: * Update the database table with the new information.
372: * @param value new value
373: * @param row index of row in which to set value
374: * @param column index of column in which to set value
375: */
376: public void setValueAt(Object value, int row, int column) {
377: if ((value != null && value.equals(getValueAt(row, column)))
378: || value == null && getValueAt(row, column) == null) {
379: if (log.isDebugEnabled()) {
380: log.debug("setValueAt (" + row + ", " + column
381: + ") not changing unchanged value " + value);
382: }
383: return;
384: }
385: String tableName = "";
386: try {
387: tableName = metaData.getTableName(column + 1);
388: } catch (SQLException e) {
389: if (log.isErrorEnabled()) {
390: log.error("Exception getting column name: ", e);
391: }
392: return;
393: }
394: if (tableName.equalsIgnoreCase("community_attribute")
395: || tableName.equalsIgnoreCase("ca"))
396: updateCommunityAttributeTable(value, row, column);
397: else if (tableName
398: .equalsIgnoreCase("community_entity_attribute")
399: || tableName.equalsIgnoreCase("cea"))
400: updateCommunityEntityAttributeTable(value, row, column);
401: else if (log.isErrorEnabled()) {
402: log.error("Attempting to set value for unknown table: "
403: + tableName);
404: }
405: }
406:
407: private void updateCommunityAttributeTable(Object value, int row,
408: int column) {
409: String columnName = getColumnName(column);
410: String communityId = (String) getValueAt(row, 0);
411: if (communityId == null) {
412: log.error("updateCommAtt on column " + columnName
413: + " has null commId. CommName=" + communityName
414: + " in row " + row);
415: }
416: if (columnName == null) {
417: log
418: .error("updateCommAtt has null columnName for community "
419: + communityId
420: + " and column "
421: + column
422: + " in row: " + row);
423: }
424: String dbValue = dbRepresentation(column, value);
425: if (dbValue == null) {
426: log.error("updateCommAtt has null dbValue on column "
427: + columnName + ", Comm: " + communityName
428: + ", commId: " + communityId + " in row " + row);
429: }
430:
431: if (columnName.equalsIgnoreCase("ATTRIBUTE_ID")
432: || columnName
433: .equalsIgnoreCase("COMMUNITY_ATTRIBUTE_ID")) {
434: // Bug 1905: Disallow empty values here.
435: dbValue = dbValue.trim();
436: if (dbValue.equals("") || dbValue.equals("null")) {
437: if (log.isInfoEnabled()) {
438: log
439: .info("updateCommAttribute: Empty value for Attribute_ID not allowed. Ignoring change.");
440: }
441: return;
442: }
443:
444: // This throws an exception if it looks like a duplicate
445: try {
446: CommunityDBUtils.setCommunityAttributeId(communityId,
447: dbValue,
448: dbRepresentation(1, getValueAt(row, 1)),
449: dbRepresentation(2, getValueAt(row, 2)),
450: assemblyId);
451: } catch (IllegalArgumentException iae) {
452: if (log.isWarnEnabled()) {
453: log
454: .warn("updateCommAtt failed to set the Att ID for comm "
455: + communityId
456: + ": "
457: + iae.toString());
458: }
459: // Couldnt make the edit, so dont update the UI
460: return;
461: }
462: } else if (columnName.equalsIgnoreCase("ATTRIBUTE_VALUE")
463: || columnName
464: .equalsIgnoreCase("COMMUNITY_ATTRIBUTE_VALUE")) {
465: // This throws an exception if it looks like a duplicate
466: try {
467: CommunityDBUtils.setCommunityAttributeValue(
468: communityId, dbValue, dbRepresentation(1,
469: getValueAt(row, 1)), dbRepresentation(
470: 2, getValueAt(row, 2)), assemblyId);
471: } catch (IllegalArgumentException iae) {
472: if (log.isWarnEnabled()) {
473: log
474: .warn("updateCmmAtt failed to set the Att Value for com "
475: + communityId
476: + ": "
477: + iae.toString());
478: }
479: // Couldnt make the edit, so dont update the UI
480: return;
481: }
482: } else if (columnName.equalsIgnoreCase("COMMUNITY_ID")) {
483: // Can't edit the community ID here
484: if (log.isInfoEnabled()) {
485: log.info("Cannot edit the " + columnName
486: + " column here.");
487: }
488: return;
489: } else {
490: if (log.isErrorEnabled()) {
491: log
492: .error("Attempting to set value for unknown column name: "
493: + columnName);
494: }
495: return;
496: }
497: ArrayList dataRow = (ArrayList) rows.get(row);
498: dataRow.set(column, value);
499: }
500:
501: private void updateCommunityEntityAttributeTable(Object value,
502: int row, int column) {
503: String columnName = getColumnName(column);
504: String entityId = (String) getValueAt(row, 0);
505: if (entityId == null) {
506: log.error("updateCommEntityAtt on column " + columnName
507: + " has null entityId. CommName=" + communityName
508: + " in row " + row);
509: }
510: if (communityName == null) {
511: log
512: .error("updateCommEntityAtt has null commName for entity "
513: + entityId
514: + " and column "
515: + columnName
516: + " in row: " + row);
517: }
518: String dbValue = dbRepresentation(column, value);
519: if (dbValue == null) {
520: log.error("updateCommEntityAtt has null dbValue on column "
521: + columnName + ", Comm: " + communityName
522: + ", entity: " + entityId + " in row " + row);
523: }
524:
525: if (columnName.equalsIgnoreCase("ATTRIBUTE_ID")
526: || columnName.equalsIgnoreCase("ENTITY_ATTRIBUTE_ID")) {
527: // Bug 1905: Disallow empty values here.
528: dbValue = dbValue.trim();
529: if (dbValue.equals("") || dbValue.equals("null")) {
530: if (log.isInfoEnabled()) {
531: log
532: .info("updateCommEntityAttribute: Empty value for Attribute_ID not allowed. Ignoring change.");
533: }
534: return;
535: }
536:
537: try {
538: // This throws an exception if it looks like a duplicate
539: CommunityDBUtils.setEntityAttributeId(communityName,
540: entityId, dbValue, dbRepresentation(1,
541: getValueAt(row, 1)), dbRepresentation(
542: 2, getValueAt(row, 2)), assemblyId);
543: } catch (IllegalArgumentException iae) {
544: if (log.isWarnEnabled()) {
545: log
546: .warn("updateCommEntAtt failed to set the Att ID for comm "
547: + communityName
548: + ", entity "
549: + entityId + ": " + iae.toString());
550: }
551: // Couldnt make the edit, so dont update the UI
552: return;
553: }
554: } else if (columnName.equalsIgnoreCase("ATTRIBUTE_VALUE")
555: || columnName
556: .equalsIgnoreCase("ENTITY_ATTRIBUTE_VALUE")) {
557: // This throws an exception if it looks like a duplicate
558: try {
559: CommunityDBUtils.setEntityAttributeValue(communityName,
560: entityId, dbValue, dbRepresentation(1,
561: getValueAt(row, 1)), dbRepresentation(
562: 2, getValueAt(row, 2)), assemblyId);
563: } catch (IllegalArgumentException iae) {
564: if (log.isWarnEnabled()) {
565: log
566: .warn("updateCommEntAtt failed to set the Att value for comm "
567: + communityName
568: + ", entity "
569: + entityId + ": " + iae.toString());
570: }
571: // Couldnt make the edit, so dont update the UI
572: return;
573: }
574: } else if (columnName.equalsIgnoreCase("ENTITY_ID")) {
575: // Can't edit the community ID here
576: if (log.isInfoEnabled()) {
577: log.info("Cannot edit the " + columnName
578: + " column here.");
579: }
580: return;
581: } else {
582: if (log.isErrorEnabled()) {
583: log
584: .error("Attempting to set value for unknown column name: "
585: + columnName);
586: }
587: return;
588: }
589: ArrayList dataRow = (ArrayList) rows.get(row);
590: dataRow.set(column, value);
591: }
592: }
|