001/* 002 * Copyright (c) 2009-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.actor.io; 031 032import java.util.Arrays; 033import java.util.LinkedList; 034import java.util.List; 035import java.util.Set; 036 037import org.geon.FileWrite; 038 039import ptolemy.data.ArrayToken; 040import ptolemy.data.DoubleToken; 041import ptolemy.data.RecordToken; 042import ptolemy.data.StringToken; 043import ptolemy.data.Token; 044import ptolemy.data.expr.StringParameter; 045import ptolemy.data.type.ArrayType; 046import ptolemy.data.type.RecordType; 047import ptolemy.kernel.CompositeEntity; 048import ptolemy.kernel.util.IllegalActionException; 049import ptolemy.kernel.util.NameDuplicationException; 050 051/** 052 053 Write an array of records to a table. 054 055 @author Daniel Crawl 056 @version $Id: ArrayOfRecordsWriter.java 24234 2010-05-06 05:21:26Z welker $ 057 058 */ 059 060public class ArrayOfRecordsWriter extends FileWrite 061{ 062 /** Construct an ArrayOfRecordsWriter. */ 063 public ArrayOfRecordsWriter(CompositeEntity container, String name) 064 throws NameDuplicationException, IllegalActionException 065 { 066 super(container, name); 067 068 tableType = new StringParameter(this, "table type"); 069 tableType.setExpression("text"); 070 tableType.addChoice("text"); 071 tableType.addChoice("HTML"); 072 073 columns = new StringParameter(this, "columns"); 074 columnNames = new StringParameter(this, "columnNames"); 075 076 format = new StringParameter(this, "format"); 077 } 078 079 /////////////////////////////////////////////////////////////////// 080 //// public methods //// 081 082 083 /** Read the formatting parameter. */ 084 public void preinitialize() throws IllegalActionException 085 { 086 super.preinitialize(); 087 088 _formatStr = format.stringValue(); 089 } 090 091 /** The type of table output. */ 092 public StringParameter tableType; 093 094 /** Comma-separated list of name and order of columns to output. */ 095 public StringParameter columns; 096 097 /** Comma-separated list of column names to write in header of 098 * table. Note: if not empty, the number of names must be the 099 * same as the number of names in <i>columns</i>. 100 */ 101 public StringParameter columnNames; 102 103 /** Formatting string for numeric data. */ 104 public StringParameter format; 105 106 /////////////////////////////////////////////////////////////////// 107 //// protected methods //// 108 109 /** Set the type constraints and multiport property of the input 110 * port. This is done here so that derived classes can override it. 111 */ 112 protected void _setInputConstraints() throws IllegalActionException 113 { 114 input.setTypeAtMost(new ArrayType(RecordType.EMPTY_RECORD)); 115 } 116 117 /** Write the specified token to the current writer. 118 * This is protected so that derived classes can modify the 119 * format in which the token is written. 120 * @param token The token to write. 121 */ 122 protected void _writeToken(Token token) throws IllegalActionException 123 { 124 ArrayToken arrayToken = (ArrayToken)token; 125 126 // determine the columns to output 127 String columnStr = ((StringToken)columns.getToken()).stringValue(); 128 List<String> columnsList = null; 129 List<String> headersList = null; 130 131 // see if anything in columns parameter 132 if(columnStr.length() > 0) 133 { 134 // put the names in an ordered list 135 String[] columnsArray = columnStr.split("\\s*,\\s*"); 136 columnsList = Arrays.asList(columnsArray); 137 138 String columnNamesStr = ((StringToken)columnNames.getToken()).stringValue(); 139 140 if(columnNamesStr.length() > 0) 141 { 142 String[] headersArray = columnNamesStr.split("\\s*,\\s*"); 143 144 // make sure sizes match 145 if(headersArray.length != columnsArray.length) 146 { 147 throw new IllegalActionException(this, "Different number " + 148 " of columns and column names."); 149 } 150 151 headersList = Arrays.asList(headersArray); 152 } 153 else 154 { 155 headersList = columnsList; 156 } 157 158 } 159 else 160 { 161 // get the first record and put the labels in an 162 // ordered list 163 Set<String> labels = ((RecordToken)arrayToken.getElement(0)).labelSet(); 164 columnsList = new LinkedList<String>(labels); 165 } 166 167 String tableTypeStr = ((StringToken)tableType.getToken()).stringValue(); 168 169 if(tableTypeStr.equals("text")) 170 { 171 // output the header 172 for(String header: headersList) 173 { 174 _writer.print(header + " "); 175 } 176 _writer.println(); 177 178 // output the data 179 for(int i = 0; i < arrayToken.length(); i++) 180 { 181 RecordToken recordToken = 182 (RecordToken)arrayToken.getElement(i); 183 for(String str : columnsList) 184 { 185 String output = _formatValue(recordToken.get(str)); 186 _writer.print(output + " "); 187 } 188 _writer.println(); 189 } 190 } 191 else if(tableTypeStr.equals("HTML")) 192 { 193 _writer.println("<TABLE BORDER=1>"); 194 195 // output the column names 196 _writer.print("<TR>"); 197 for(String header : headersList) 198 { 199 _writer.print("<TD><B>" + header + "</B></TD>"); 200 } 201 _writer.println("</TR>"); 202 203 // output the data 204 for(int i = 0; i < arrayToken.length(); i++) 205 { 206 _writer.print("<TR>"); 207 RecordToken recordToken = 208 (RecordToken)arrayToken.getElement(i); 209 for(String str : columnsList) 210 { 211 String output = _formatValue(recordToken.get(str)); 212 _writer.print("<TD>" + output + "</TD>"); 213 } 214 _writer.println("</TR>"); 215 } 216 217 _writer.println("</TABLE>"); 218 } 219 else 220 { 221 throw new IllegalActionException(this, "Unsupported table type: " + 222 tableTypeStr); 223 } 224 } 225 226 /////////////////////////////////////////////////////////////////// 227 //// private methods //// 228 229 /** Format a value based on the format parameter. */ 230 private String _formatValue(Token token) 231 { 232 String retval = token.toString(); 233 // XXX what about other types of tokens? 234 if(_formatStr.length() > 0 && (token instanceof DoubleToken)) 235 { 236 double val = ((DoubleToken)token).doubleValue(); 237 retval = String.format(_formatStr, val); 238 } 239 return retval; 240 } 241 242 /** Value of format parameter. */ 243 private String _formatStr; 244}