001/* An actor that outputs data read from a URL. 002 003 @Copyright (c) 1998-2015 The Regents of the University of California. 004 All rights reserved. 005 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the 009 above copyright notice and the following two paragraphs appear in all 010 copies of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION 2 026 COPYRIGHTENDKEY 027 */ 028package ptolemy.actor.lib; 029 030import java.io.BufferedReader; 031import java.io.IOException; 032import java.io.InputStreamReader; 033import java.net.URL; 034import java.util.StringTokenizer; 035 036import ptolemy.data.BooleanToken; 037import ptolemy.data.DoubleToken; 038import ptolemy.data.StringToken; 039import ptolemy.data.expr.Parameter; 040import ptolemy.data.type.BaseType; 041import ptolemy.kernel.CompositeEntity; 042import ptolemy.kernel.util.Attribute; 043import ptolemy.kernel.util.IllegalActionException; 044import ptolemy.kernel.util.NameDuplicationException; 045 046//import java.io.Reader; 047/////////////////////////////////////////////////////////////////// 048//// Reader 049 050/** 051 This actor reads tokens from an URL, and output them. Each entry in 052 the file corresponds to one iteration. If there are multiple fires in 053 the iteration, the same token will be repeated. This actor has a 054 multiport, where each port corresponds to one column in the data file. 055 056 <p> The file format at the URL is assumed as the following. A newline 057 character separates the rows, and a tab or a space character separates 058 the columns. 059 060 <p> The <i>sourceURL</i> parameter should be set to the name of the 061 file, specified as a fully qualified URL. If the <i>sourceURL</i> 062 parameter is an empty string, then the System.in is used for input. 063 064 It is possible to load a file from the local file system by using the 065 prefix "file://" instead of "http://". Relative file paths are 066 allowed. To specify a file relative to the current directory, use 067 "../" or "./". For example, if the current directory contains a file 068 called "test.txt", then <i>sourceURL</i> should be set to 069 "file:./test.txt". If the parent directory contains a file called 070 "test.txt", then <i>sourceURL</i> should be set to 071 "file:../test.txt". To reference the file test.txt, located at 072 "/tmp/test.txt", <i>sourceURL</i> should be set to 073 "file:///tmp/test.txt" The default value is "file:///tmp/test.txt". 074 075 <p>FIXME: The type of the output ports is set to Double for now. 076 It should read a line in the prefire() and refer the type 077 from there. 078 <p>FIXME: Reader should read in expressions and serialized tokens 079 080 @author Jie Liu 081 @deprecated Use ExpressionReader instead. 082 @version $Id$ 083 @since Ptolemy II 1.0 084 @Pt.ProposedRating Red (liuj) 085 @Pt.AcceptedRating Red (liuj) 086 */ 087@Deprecated 088public class Reader extends Source { 089 /** Construct an actor with the given container and name. 090 * @param container The container. 091 * @param name The name of this actor. 092 * @exception IllegalActionException If the actor cannot be contained 093 * by the proposed container. 094 * @exception NameDuplicationException If the container already has an 095 * actor with this name. 096 */ 097 public Reader(CompositeEntity container, String name) 098 throws IllegalActionException, NameDuplicationException { 099 super(container, name); 100 101 // Set the type of the input port. 102 output.setMultiport(true); 103 output.setTypeEquals(BaseType.DOUBLE); 104 sourceURL = new Parameter(this, "sourceURL", new StringToken("")); 105 sourceURL.setTypeEquals(BaseType.STRING); 106 107 refresh = new Parameter(this, "refresh", new BooleanToken(false)); 108 refresh.setTypeEquals(BaseType.BOOLEAN); 109 110 if (_stdIn == null) { 111 _stdIn = new BufferedReader(new InputStreamReader(System.in, 112 java.nio.charset.Charset.defaultCharset())); 113 } 114 115 setReader(_stdIn); 116 } 117 118 /////////////////////////////////////////////////////////////////// 119 //// ports and parameters //// 120 121 /** The URL of the file to read from. This parameter contains 122 * a StringToken. By default, it contains an empty string, which 123 * is interpreted to mean that input should be directed to the 124 * standard input. 125 * FIXME: Should this bring up a dialog box to type (or select) a URL? 126 */ 127 public Parameter sourceURL; 128 129 /** Refresh between each readings. Default is false. 130 */ 131 public Parameter refresh; 132 133 /////////////////////////////////////////////////////////////////// 134 //// public methods //// 135 136 /** If the specified attribute is <i>URL</i>, then close 137 * the current file (if there is one) and open the new one. 138 * @param attribute The attribute that has changed. 139 * @exception IllegalActionException If the specified attribute 140 * is <i>URL</i> and the file cannot be opened. 141 */ 142 @Override 143 public void attributeChanged(Attribute attribute) 144 throws IllegalActionException { 145 if (attribute == sourceURL) { 146 try { 147 StringToken URLToken = (StringToken) sourceURL.getToken(); 148 149 if (URLToken == null) { 150 _source = null; 151 setReader(null); 152 } else { 153 _source = URLToken.stringValue(); 154 155 if (_source.equals("")) { 156 setReader(null); 157 } else { 158 URL url = new URL(_source); 159 java.io.BufferedReader reader = new BufferedReader( 160 new InputStreamReader(url.openStream())); 161 setReader(reader); 162 } 163 } 164 } catch (IOException ex) { 165 throw new IllegalActionException(this, ex, 166 "attributeChanged(" + attribute + ") failed"); 167 } 168 } 169 170 super.attributeChanged(attribute); 171 } 172 173 /** Output the data read in the prefire. 174 * @exception IllegalActionException If there's no director. 175 */ 176 @Override 177 public void fire() throws IllegalActionException { 178 super.fire(); 179 180 for (int i = 0; i < _dataSize; i++) { 181 output.send(i, new DoubleToken(_data[i])); 182 } 183 } 184 185 /** Open the file at the URL, and set the width of the output. 186 * @exception IllegalActionException Not thrown in this base class 187 */ 188 @Override 189 public void initialize() throws IllegalActionException { 190 super.initialize(); 191 System.out.println("actor.lib.Reader is obsolete, " 192 + "use actor.lib.io.ExpressionReader instead"); 193 _dataSize = output.getWidth(); 194 _data = new double[_dataSize]; 195 attributeChanged(sourceURL); 196 } 197 198 /** Read one row from the input and prepare for output them. 199 * @exception IllegalActionException If an IO error occurs. 200 */ 201 @Override 202 public boolean prefire() throws IllegalActionException { 203 try { 204 _dataSize = output.getWidth(); 205 206 if (_data.length != _dataSize) { 207 _data = new double[_dataSize]; 208 } 209 210 String oneRow = _reader.readLine(); 211 212 if (oneRow == null) { 213 return false; 214 } 215 216 StringTokenizer tokenizer = new StringTokenizer(oneRow); 217 int columnCount = tokenizer.countTokens(); 218 219 if (_dataSize > columnCount) { 220 _dataSize = columnCount; 221 } 222 223 for (int i = 0; i < _dataSize; i++) { 224 _data[i] = Double.valueOf(tokenizer.nextToken()).doubleValue(); 225 } 226 227 return super.prefire(); 228 } catch (IOException ex) { 229 throw new IllegalActionException(this, ex, "prefire() failed"); 230 } 231 } 232 233 /** Set the reader. If there was a previous reader, close it. 234 * To set standard input, call this method with argument null. 235 * @param reader The reader to read to. 236 * @exception IllegalActionException If an IO error occurs. 237 */ 238 public void setReader(java.io.BufferedReader reader) 239 throws IllegalActionException { 240 try { 241 if (_reader != null && _reader != _stdIn) { 242 _reader.close(); 243 } 244 } catch (IOException ex) { 245 throw new IllegalActionException(this, ex, 246 "setReader(" + reader + ") failed"); 247 } 248 249 if (reader != null) { 250 _reader = reader; 251 } else { 252 _reader = _stdIn; 253 } 254 } 255 256 /** Close the reader if there is one. 257 * @exception IllegalActionException If an IO error occurs. 258 */ 259 @Override 260 public void wrapup() throws IllegalActionException { 261 try { 262 if (_reader != null && _reader != _stdIn) { 263 _reader.close(); 264 } 265 } catch (IOException ex) { 266 throw new IllegalActionException(this, ex, 267 "wrapup(" + _reader + ") failed"); 268 } 269 } 270 271 /////////////////////////////////////////////////////////////////// 272 //// private members //// 273 // The writer to write to. 274 private java.io.BufferedReader _reader = null; 275 276 // Standard out as a writer. 277 private static java.io.BufferedReader _stdIn = null; 278 279 // String for the URL. 280 private String _source; 281 282 // Cache of one row. 283 private double[] _data; 284 285 // Valid enties in the data array. 286 private int _dataSize; 287}