001/* 002 * Copyright (c) 2002-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.geon; 031 032import java.io.BufferedReader; 033import java.io.IOException; 034import java.util.Vector; 035 036import ptolemy.actor.lib.Source; 037import ptolemy.data.ArrayToken; 038import ptolemy.data.IntToken; 039import ptolemy.data.Token; 040import ptolemy.data.expr.FileParameter; 041import ptolemy.data.expr.Parameter; 042import ptolemy.data.expr.Variable; 043import ptolemy.data.type.ArrayType; 044import ptolemy.data.type.BaseType; 045import ptolemy.kernel.CompositeEntity; 046import ptolemy.kernel.util.Attribute; 047import ptolemy.kernel.util.IllegalActionException; 048import ptolemy.kernel.util.NameDuplicationException; 049import ptolemy.kernel.util.Workspace; 050 051////////////////////////////////////////////////////////////////////////// 052//// FileToArray 053/** 054 * This actor reads a file or URL and outputs an array of the evaluations of all 055 * lines read. The file or URL is specified using any form acceptable to 056 * FileParameter. 057 * 058 * This actor can skip some lines at the beginning of the file or URL, with the 059 * number specified by the numberOfLinesToSkip parameter. The default value of 060 * this parameter is 0. 061 * 062 * @author Efrat Jaeger 063 * @version $Id: FileToArray.java 24234 2010-05-06 05:21:26Z welker $ 064 * @since Ptolemy II 3.0.2 065 */ 066public class FileToArray extends Source { 067 068 /** 069 * Construct an actor with the given container and name. 070 * 071 * @param container 072 * The container. 073 * @param name 074 * The name of this actor. 075 * @exception IllegalActionException 076 * If the actor cannot be contained by the proposed 077 * container. 078 * @exception NameDuplicationException 079 * If the container already has an actor with this name. 080 */ 081 public FileToArray(CompositeEntity container, String name) 082 throws IllegalActionException, NameDuplicationException { 083 super(container, name); 084 085 _expressionEvaluator = new Variable(this, "_expressionEvaluator"); 086 087 fileOrURL = new FileParameter(this, "fileOrURL"); 088 089 numberOfLinesToSkip = new Parameter(this, "numberOfLinesToSkip", 090 new IntToken(0)); 091 numberOfLinesToSkip.setTypeEquals(BaseType.INT); 092 093 _attachText("_iconDescription", "<svg>\n" 094 + "<rect x=\"-25\" y=\"-20\" " + "width=\"50\" height=\"40\" " 095 + "style=\"fill:white\"/>\n" 096 + "<polygon points=\"-15,-10 -12,-10 -8,-14 -1,-14 3,-10" 097 + " 15,-10 15,10, -15,10\" " + "style=\"fill:red\"/>\n" 098 + "</svg>\n"); 099 } 100 101 // ///////////////////////////////////////////////////////////////// 102 // // ports and parameters //// 103 104 /** 105 * The file name or URL from which to read. This is a string with any form 106 * accepted by FileParameter. 107 * 108 * @see FileParameter 109 */ 110 public FileParameter fileOrURL; 111 112 /** 113 * The number of lines to skip at the beginning of the file or URL. This 114 * parameter contains an IntToken, initially with value 0. The value of this 115 * parameter must be non-negative. 116 */ 117 public Parameter numberOfLinesToSkip; 118 119 // ///////////////////////////////////////////////////////////////// 120 // // public methods //// 121 122 /** 123 * If the specified attribute is <i>fileOrURL</i> and there is an open file 124 * being read, then close that file and open the new one; if the attribute 125 * is <i>numberOfLinesToSkip</i> and its value is negative, then throw an 126 * exception. In the case of <i>fileOrURL</i>, do nothing if the file name 127 * is the same as the previous value of this attribute. 128 * 129 * @param attribute 130 * The attribute that has changed. 131 * @exception IllegalActionException 132 * If the specified attribute is <i>fileOrURL</i> and the 133 * file cannot be opened, or the previously opened file 134 * cannot be closed; or if the attribute is 135 * <i>numberOfLinesToSkip</i> and its value is negative. 136 */ 137 public void attributeChanged(Attribute attribute) 138 throws IllegalActionException { 139 if (attribute == fileOrURL) { 140 // NOTE: We do not want to close the file if the file 141 // has not in fact changed. We check this by just comparing 142 // name, which is not perfect... 143 if (_previousFileOrURL != null 144 && !fileOrURL.getExpression().equals(_previousFileOrURL)) { 145 _previousFileOrURL = fileOrURL.getExpression(); 146 fileOrURL.close(); 147 // Ignore if the fileOrUL is blank. 148 if (fileOrURL.getExpression().trim().equals("")) { 149 _reader = null; 150 } else { 151 _reader = fileOrURL.openForReading(); 152 } 153 } 154 } else if (attribute == numberOfLinesToSkip) { 155 int linesToSkip = ((IntToken) numberOfLinesToSkip.getToken()) 156 .intValue(); 157 if (linesToSkip < 0) { 158 throw new IllegalActionException(this, "The number of lines " 159 + "to skip cannot be negative."); 160 } 161 } else { 162 super.attributeChanged(attribute); 163 } 164 } 165 166 /** 167 * Clone the actor into the specified workspace. 168 * 169 * @return A new actor. 170 * @exception CloneNotSupportedException 171 * If a derived class contains an attribute that cannot be 172 * cloned. 173 */ 174 public Object clone(Workspace workspace) throws CloneNotSupportedException { 175 FileToArray newObject = (FileToArray) super.clone(workspace); 176 newObject._currentLine = null; 177 newObject._reader = null; 178 return newObject; 179 } 180 181 /** 182 * Output the data lines into an array. 183 * 184 * @exception IllegalActionException 185 * If there's no director. 186 */ 187 188 public void fire() throws IllegalActionException { 189 super.fire(); 190 Vector lines = new Vector(); 191 while (_currentLine != null) { 192 _expressionEvaluator.setExpression(_currentLine); 193 lines.addElement(_expressionEvaluator.getToken()); 194 try { 195 _currentLine = _reader.readLine(); 196 } catch (IOException ex) { 197 throw new IllegalActionException(this, ex, 198 "fire failed reading line"); 199 } 200 } 201 Token expressions[] = new Token[lines.size()]; 202 lines.toArray(expressions); 203 output.send(0, new ArrayToken(expressions)); 204 } 205 206 /** 207 * Post fire the actor. Return false to indicate that the process has 208 * finished. If it returns true, the process will continue indefinitely. 209 */ 210 public boolean postfire() { 211 return false; 212 } 213 214 /** 215 * Open the file or URL and read the first line, and use the first line to 216 * set the type of the output. 217 * 218 * @exception IllegalActionException 219 * If the file or URL cannot be opened, or if the first line 220 * cannot be read. 221 */ 222 public void preinitialize() throws IllegalActionException { 223 super.preinitialize(); 224 _openAndReadFirstLine(); 225 226 // Set the output type. 227 _expressionEvaluator.setExpression(_currentLine); 228 output.setTypeEquals(new ArrayType(_expressionEvaluator.getType())); 229 } 230 231 /** 232 * Close the reader if there is one. 233 * 234 * @exception IllegalActionException 235 * If an IO error occurs. 236 */ 237 public void wrapup() throws IllegalActionException { 238 fileOrURL.close(); 239 _reader = null; 240 } 241 242 // ///////////////////////////////////////////////////////////////// 243 // // protected members //// 244 245 /** Cache of most recently read data. */ 246 protected String _currentLine; 247 248 /** The current reader for the input file. */ 249 protected BufferedReader _reader; 250 251 // ///////////////////////////////////////////////////////////////// 252 // // private methods //// 253 254 /** 255 * Open the file and read the first line. 256 */ 257 private void _openAndReadFirstLine() throws IllegalActionException { 258 _reader = fileOrURL.openForReading(); 259 try { 260 // Read (numberOfLinesToSkip + 1) lines 261 int numberOfLines = ((IntToken) numberOfLinesToSkip.getToken()) 262 .intValue(); 263 for (int i = 0; i <= numberOfLines; i++) { 264 _currentLine = _reader.readLine(); 265 if (_currentLine == null) { 266 throw new IllegalActionException(this, "The file does not " 267 + "have enough lines."); 268 } 269 } 270 } catch (IOException ex) { 271 throw new IllegalActionException(this, ex, "Preinitialize failed."); 272 } 273 } 274 275 // ///////////////////////////////////////////////////////////////// 276 // // private members //// 277 278 /** Previous value of fileOrURL parameter. */ 279 private String _previousFileOrURL; 280 281 /** Variable used to evaluate expressions. */ 282 private Variable _expressionEvaluator; 283 284}