001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * ObjectReferenceTableModel.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.modules.misc.referencedoc;
030:
031: import java.io.Serializable;
032: import java.util.ArrayList;
033: import java.util.Collections;
034: import java.util.Comparator;
035: import java.util.Iterator;
036: import javax.swing.table.AbstractTableModel;
037:
038: import org.jfree.report.modules.parser.ext.factory.base.ClassFactory;
039: import org.jfree.report.modules.parser.ext.factory.base.ClassFactoryCollector;
040: import org.jfree.report.modules.parser.ext.factory.base.ObjectDescription;
041:
042: /**
043: * A table model for the objects referenced by the class factories.
044: *
045: * @author Thomas Morgner.
046: */
047: public class ObjectReferenceTableModel extends AbstractTableModel {
048: /**
049: * Used to represent each row in the table model.
050: */
051: private static class ObjectDescriptionRow {
052: /**
053: * The class factory.
054: */
055: private final ClassFactory classFactory;
056:
057: /**
058: * The object class.
059: */
060: private final Class object;
061:
062: /**
063: * The parameter name.
064: */
065: private final String paramName;
066:
067: /**
068: * The parameter type.
069: */
070: private final Class paramType;
071:
072: /**
073: * Creates a new row.
074: *
075: * @param classFactory the class factory.
076: * @param object the object class.
077: * @param paramName the parameter name.
078: * @param paramType the parameter type.
079: */
080: public ObjectDescriptionRow(final ClassFactory classFactory,
081: final Class object, final String paramName,
082: final Class paramType) {
083: this .classFactory = classFactory;
084: this .object = object;
085: this .paramName = paramName;
086: this .paramType = paramType;
087: }
088:
089: /**
090: * Returns the class factory.
091: *
092: * @return The class factory.
093: */
094: public ClassFactory getClassFactory() {
095: return classFactory;
096: }
097:
098: /**
099: * Returns the object class.
100: *
101: * @return The class.
102: */
103: public Class getObject() {
104: return object;
105: }
106:
107: /**
108: * Returns the parameter name.
109: *
110: * @return the parameter name.
111: */
112: public String getParamName() {
113: return paramName;
114: }
115:
116: /**
117: * Returns the parameter type.
118: *
119: * @return the parameter type.
120: */
121: public Class getParamType() {
122: return paramType;
123: }
124: }
125:
126: /**
127: * A class name comparator.
128: */
129: private static class ClassNameComparator implements Comparator,
130: Serializable {
131: /**
132: * Default-Constructor.
133: */
134: public ClassNameComparator() {
135: }
136:
137: /**
138: * Compares its two arguments for order. Returns a negative integer, zero, or a
139: * positive integer as the first argument is less than, equal to, or greater than the
140: * second.<p>
141: *
142: * @param o1 the first object to be compared.
143: * @param o2 the second object to be compared.
144: * @return a negative integer, zero, or a positive integer as the first argument is
145: * less than, equal to, or greater than the second.
146: *
147: * @throws ClassCastException if the arguments' types prevent them from being compared
148: * by this Comparator.
149: */
150: public int compare(final Object o1, final Object o2) {
151: final Class c1 = (Class) o1;
152: final Class c2 = (Class) o2;
153: return c1.getName().compareTo(c2.getName());
154: }
155: }
156:
157: /**
158: * The table model column names.
159: */
160: private static final String[] COLUMN_NAMES = { "object-factory", //$NON-NLS-1$
161: "object-class", //$NON-NLS-1$
162: "parameter-name", //$NON-NLS-1$
163: "parameter-class" //$NON-NLS-1$
164: };
165:
166: /**
167: * Storage for the rows.
168: */
169: private final ArrayList rows;
170:
171: /**
172: * Creates a new table model for a set of class factories.
173: *
174: * @param cf the class factories.
175: */
176: public ObjectReferenceTableModel(final ClassFactoryCollector cf) {
177: rows = new ArrayList();
178: addClassFactoryCollector(cf);
179: }
180:
181: /**
182: * Adds a class factory collector.
183: *
184: * @param cf the class factory collector.
185: */
186: private void addClassFactoryCollector(final ClassFactoryCollector cf) {
187: final Iterator it = cf.getFactories();
188: while (it.hasNext()) {
189: final ClassFactory cfact = (ClassFactory) it.next();
190: if (cfact instanceof ClassFactoryCollector) {
191: addClassFactoryCollector((ClassFactoryCollector) cfact);
192: } else {
193: addClassFactory(cfact);
194: }
195: }
196: }
197:
198: /**
199: * Adds a class factory.
200: *
201: * @param cf the class factory.
202: */
203: private void addClassFactory(final ClassFactory cf) {
204: Iterator it = cf.getRegisteredClasses();
205: final ArrayList factories = new ArrayList();
206:
207: while (it.hasNext()) {
208: final Class c = (Class) it.next();
209: factories.add(c);
210: }
211:
212: Collections.sort(factories, new ClassNameComparator());
213: it = factories.iterator();
214:
215: while (it.hasNext()) {
216: final Class c = (Class) it.next();
217: final ObjectDescription od = cf.getDescriptionForClass(c);
218: Iterator itNames = od.getParameterNames();
219: final ArrayList nameList = new ArrayList();
220: while (itNames.hasNext()) {
221: nameList.add(itNames.next());
222: }
223: // sort the parameter names
224: Collections.sort(nameList);
225: itNames = nameList.iterator();
226: while (itNames.hasNext()) {
227: final String name = (String) itNames.next();
228: rows.add(new ObjectDescriptionRow(cf, c, name, od
229: .getParameterDefinition(name)));
230: }
231: }
232: }
233:
234: /**
235: * Returns the number of rows in the model. A <code>JTable</code> uses this method to
236: * determine how many rows it should display. This method should be quick, as it is
237: * called frequently during rendering.
238: *
239: * @return the number of rows in the model
240: *
241: * @see #getColumnCount
242: */
243: public int getRowCount() {
244: return rows.size();
245: }
246:
247: /**
248: * Returns the number of columns in the model. A <code>JTable</code> uses this method to
249: * determine how many columns it should create and display by default.
250: *
251: * @return the number of columns in the model
252: *
253: * @see #getRowCount
254: */
255: public int getColumnCount() {
256: return COLUMN_NAMES.length;
257: }
258:
259: /**
260: * Returns the column name.
261: *
262: * @param column the column being queried
263: * @return a string containing the default name of <code>column</code>
264: */
265: public String getColumnName(final int column) {
266: return COLUMN_NAMES[column];
267: }
268:
269: /**
270: * Returns <code>String.class</code> regardless of <code>columnIndex</code>.
271: *
272: * @param columnIndex the column being queried
273: * @return the Object.class
274: */
275: public Class getColumnClass(final int columnIndex) {
276: return String.class;
277: }
278:
279: /**
280: * Returns the value for the cell at <code>columnIndex</code> and
281: * <code>rowIndex</code>.
282: *
283: * @param rowIndex the row whose value is to be queried
284: * @param columnIndex the column whose value is to be queried
285: * @return the value Object at the specified cell
286: */
287: public Object getValueAt(final int rowIndex, final int columnIndex) {
288: final ObjectDescriptionRow or = (ObjectDescriptionRow) rows
289: .get(rowIndex);
290: switch (columnIndex) {
291: case 0:
292: return String.valueOf(or.getClassFactory().getClass()
293: .getName());
294: case 1:
295: return String.valueOf(or.getObject().getName());
296: case 2:
297: return String.valueOf(or.getParamName());
298: case 3:
299: return String.valueOf(or.getParamType().getName());
300: default:
301: return null;
302: }
303: }
304:
305: }
|