Source for org.jfree.report.data.ReportDataRow

   1: /**
   2:  * ========================================
   3:  * JFreeReport : a free Java report library
   4:  * ========================================
   5:  *
   6:  * Project Info:  http://reporting.pentaho.org/
   7:  *
   8:  * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
   9:  *
  10:  * This library is free software; you can redistribute it and/or modify it under the terms
  11:  * of the GNU Lesser General Public License as published by the Free Software Foundation;
  12:  * either version 2.1 of the License, or (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  15:  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16:  * See the GNU Lesser General Public License for more details.
  17:  *
  18:  * You should have received a copy of the GNU Lesser General Public License along with this
  19:  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20:  * Boston, MA 02111-1307, USA.
  21:  *
  22:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  23:  * in the United States and other countries.]
  24:  *
  25:  * ------------
  26:  * $Id: ReportDataRow.java 2890 2007-06-10 15:54:22Z taqua $
  27:  * ------------
  28:  * (C) Copyright 2000-2005, by Object Refinery Limited.
  29:  * (C) Copyright 2005-2007, by Pentaho Corporation.
  30:  */
  31: package org.jfree.report.data;
  32: 
  33: import java.util.Collections;
  34: import java.util.HashMap;
  35: import java.util.Map;
  36: 
  37: import org.jfree.report.DataFlags;
  38: import org.jfree.report.DataRow;
  39: import org.jfree.report.DataSet;
  40: import org.jfree.report.DataSourceException;
  41: import org.jfree.report.ReportData;
  42: import org.jfree.report.ReportDataFactory;
  43: import org.jfree.report.ReportDataFactoryException;
  44: import org.jfree.report.util.IntegerCache;
  45: import org.jfree.util.ObjectUtilities;
  46: 
  47: /**
  48:  * Creation-Date: 20.02.2006, 15:32:32
  49:  *
  50:  * @author Thomas Morgner
  51:  */
  52: public final class ReportDataRow implements DataRow
  53: {
  54:   private Map nameCache;
  55:   private DataFlags[] data;
  56:   private ReportData reportData;
  57:   private int cursor;
  58: 
  59:   private ReportDataRow(final ReportData reportData) throws DataSourceException
  60:   {
  61:     if (reportData == null)
  62:     {
  63:       throw new NullPointerException();
  64:     }
  65: 
  66:     synchronized (reportData)
  67:     {
  68:       this.reportData = reportData;
  69: 
  70:       reportData.setCursorPosition(ReportData.BEFORE_FIRST_ROW);
  71:       final boolean readable;
  72:       if (reportData.isAdvanceable())
  73:       {
  74:         readable = reportData.next() && reportData.isReadable();
  75:         cursor = reportData.getCursorPosition();
  76:       }
  77:       else
  78:       {
  79:         readable = false;
  80:         cursor = 0;
  81:       }
  82: 
  83:       final HashMap nameCache = new HashMap();
  84:       final int columnCount = reportData.getColumnCount();
  85:       this.data = new DataFlags[columnCount];
  86: 
  87:       for (int i = 0; i < columnCount; i++)
  88:       {
  89:         final String columnName = reportData.getColumnName(i);
  90:         if (columnName != null)
  91:         {
  92:           nameCache.put(columnName, IntegerCache.getInteger(i));
  93:         }
  94: 
  95:         if (readable)
  96:         {
  97:           final Object value = reportData.get(i);
  98:           this.data[i] = new DefaultDataFlags(columnName, value, true);
  99:         }
 100:         else
 101:         {
 102:           this.data[i] = new DefaultDataFlags(columnName, null, true);
 103:         }
 104:       }
 105:       this.nameCache = Collections.unmodifiableMap(nameCache);
 106:     }
 107:   }
 108: 
 109:   private ReportDataRow(final ReportData reportData,
 110:                         final ReportDataRow reportDataRow)
 111:       throws DataSourceException
 112:   {
 113:     if (reportData == null)
 114:     {
 115:       throw new NullPointerException();
 116:     }
 117: 
 118:     if (reportDataRow == null)
 119:     {
 120:       throw new NullPointerException();
 121:     }
 122: 
 123:     synchronized (reportData)
 124:     {
 125:       this.reportData = reportData;
 126:       this.cursor = reportData.getCursorPosition();
 127:       final int columnCount = reportData.getColumnCount();
 128:       this.data = new DataFlags[columnCount];
 129: 
 130:       for (int i = 0; i < columnCount; i++)
 131:       {
 132:         final String columnName = reportData.getColumnName(i);
 133:         final Object value = reportData.get(i);
 134:         final boolean changed = ObjectUtilities.equal(value, reportDataRow.get(i));
 135:         this.data[i] = new DefaultDataFlags(columnName, value, changed);
 136:       }
 137:       this.nameCache = reportDataRow.nameCache;
 138:     }
 139:   }
 140: 
 141:   public static ReportDataRow createDataRow(final ReportDataFactory dataFactory,
 142:                                             final String query,
 143:                                             final DataSet parameters)
 144:       throws DataSourceException, ReportDataFactoryException
 145:   {
 146:     final ReportData reportData = dataFactory.queryData(query, parameters);
 147:     return new ReportDataRow(reportData);
 148:   }
 149: 
 150:   /**
 151:    * Returns the value of the expression or column in the tablemodel using the given column number as index. For
 152:    * functions and expressions, the <code>getValue()</code> method is called and for columns from the tablemodel the
 153:    * tablemodel method <code>getValueAt(row, column)</code> gets called.
 154:    *
 155:    * @param col the item index.
 156:    * @return the value.
 157:    * @throws IllegalStateException if the datarow detected a deadlock.
 158:    */
 159:   public Object get(final int col) throws DataSourceException
 160:   {
 161:     return data[col].getValue();
 162:   }
 163: 
 164:   /**
 165:    * Returns the value of the function, expression or column using its specific name. The given name is translated into
 166:    * a valid column number and the the column is queried. For functions and expressions, the <code>getValue()</code>
 167:    * method is called and for columns from the tablemodel the tablemodel method <code>getValueAt(row, column)</code>
 168:    * gets called.
 169:    *
 170:    * @param col the item index.
 171:    * @return the value.
 172:    * @throws IllegalStateException if the datarow detected a deadlock.
 173:    */
 174:   public Object get(final String col) throws DataSourceException
 175:   {
 176:     final Integer colIdx = (Integer) nameCache.get(col);
 177:     if (colIdx == null)
 178:     {
 179:       throw new DataSourceException
 180:           ("Invalid name specified. There is no such column.");
 181:     }
 182: 
 183:     return data[colIdx.intValue()].getValue();
 184:   }
 185: 
 186:   /**
 187:    * Returns the name of the column, expression or function. For columns from the tablemodel, the tablemodels
 188:    * <code>getColumnName</code> method is called. For functions, expressions and report properties the assigned name is
 189:    * returned.
 190:    *
 191:    * @param col the item index.
 192:    * @return the name.
 193:    */
 194:   public String getColumnName(final int col)
 195:   {
 196:     return data[col].getName();
 197:   }
 198: 
 199:   /**
 200:    * Returns the number of columns, expressions and functions and marked ReportProperties in the report.
 201:    *
 202:    * @return the item count.
 203:    */
 204:   public int getColumnCount()
 205:   {
 206:     return data.length;
 207:   }
 208: 
 209:   public DataFlags getFlags(final String col) throws DataSourceException
 210:   {
 211:     final Integer colIdx = (Integer) nameCache.get(col);
 212:     if (colIdx == null)
 213:     {
 214:       throw new DataSourceException
 215:           ("Invalid name specified. There is no such column.");
 216:     }
 217: 
 218:     return data[colIdx.intValue()];
 219:   }
 220: 
 221:   public DataFlags getFlags(final int col)
 222:   {
 223:     return data[col];
 224:   }
 225: 
 226:   /**
 227:    * Advances to the next row and attaches the given master row to the objects contained in that client data row.
 228:    *
 229:    * @param master
 230:    * @return
 231:    */
 232:   public ReportDataRow advance() throws DataSourceException
 233:   {
 234:     synchronized (reportData)
 235:     {
 236:       if (reportData.getCursorPosition() != cursor)
 237:       {
 238:         // directly go to the position we need.
 239:         if (reportData.setCursorPosition(cursor + 1) == false)
 240:         {
 241:           throw new DataSourceException("Unable to advance cursor position");
 242:         }
 243:       }
 244:       else
 245:       {
 246:         if (reportData.next() == false)
 247:         {
 248:           throw new DataSourceException("Unable to advance cursor position");
 249:         }
 250:       }
 251:       return new ReportDataRow(reportData, this);
 252:     }
 253:   }
 254: 
 255:   public boolean isAdvanceable() throws DataSourceException
 256:   {
 257:     synchronized (reportData)
 258:     {
 259:       if (reportData.getCursorPosition() != cursor)
 260:       {
 261:         // directly go to the position we need.
 262:         if (reportData.setCursorPosition(cursor) == false)
 263:         {
 264:           return false;
 265:         }
 266:       }
 267:       return reportData.isAdvanceable();
 268:     }
 269:   }
 270: 
 271:   public ReportData getReportData()
 272:   {
 273:     return reportData;
 274:   }
 275: 
 276:   public int getCursor()
 277:   {
 278:     return cursor;
 279:   }
 280: }