001/* Abstract base class for actors that read in data 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; 034 035import ptolemy.data.BooleanToken; 036import ptolemy.data.StringToken; 037import ptolemy.data.expr.Parameter; 038import ptolemy.data.type.BaseType; 039import ptolemy.kernel.CompositeEntity; 040import ptolemy.kernel.util.Attribute; 041import ptolemy.kernel.util.IllegalActionException; 042import ptolemy.kernel.util.NameDuplicationException; 043 044/////////////////////////////////////////////////////////////////// 045//// URLReader 046 047/** 048 This actor reads tokens from an URL, and output them. Each entry in 049 the file corresponds to one iteration. If there are multiple fires in 050 the iteration, the same token will be repeated. This actor has a 051 multiport, where each port corresponds to one column in the data file. 052 053 <p> The file format at the URL is assumed as the following. A newline 054 character separates the rows, and a tab or a space character separates 055 the columns. 056 057 <p> The <i>sourceURL</i> parameter should be set to the name of the 058 file, specified as a fully qualified URL. If the <i>sourceURL</i> 059 parameter is an empty string, then the System.in is used for input. 060 061 It is possible to load a file from the local file system by using the 062 prefix "file://" instead of "http://". Relative file paths are 063 allowed. To specify a file relative to the current directory, use 064 "../" or "./". For example, if the current directory contains a file 065 called "test.txt", then <i>sourceURL</i> should be set to 066 "file:./test.txt". If the parent directory contains a file called 067 "test.txt", then <i>sourceURL</i> should be set to 068 "file:../test.txt". To reference the file test.txt, located at 069 "/tmp/test.txt", <i>sourceURL</i> should be set to 070 "file:///tmp/test.txt" The default value is "file:///tmp/test.txt". 071 072 <p>FIXME: The type of the output ports is set to Double for now. 073 It should read a line in the prefire() and refer the type 074 from there. 075 <p>FIXME: URLReader should read in expressions and serialized tokens 076 077 @see ptolemy.actor.lib.javasound.AudioReader 078 @author Jie Liu 079 @version $Id$ 080 @since Ptolemy II 2.0 081 @Pt.ProposedRating Red (liuj) 082 @Pt.AcceptedRating Red (liuj) 083 */ 084public abstract class URLReader extends Source { 085 /** Construct an actor with the given container and name. 086 * @param container The container. 087 * @param name The name of this actor. 088 * @exception IllegalActionException If the actor cannot be contained 089 * by the proposed container. 090 * @exception NameDuplicationException If the container already has an 091 * actor with this name. 092 */ 093 public URLReader(CompositeEntity container, String name) 094 throws IllegalActionException, NameDuplicationException { 095 super(container, name); 096 097 // Set the type of the output port. 098 output.setMultiport(true); 099 output.setTypeEquals(BaseType.DOUBLE); 100 101 sourceURL = new Parameter(this, "sourceURL", new StringToken("")); 102 sourceURL.setTypeEquals(BaseType.STRING); 103 104 refresh = new Parameter(this, "refresh", new BooleanToken(false)); 105 refresh.setTypeEquals(BaseType.BOOLEAN); 106 107 if (_stdIn == null) { 108 _stdIn = new BufferedReader(new InputStreamReader(System.in, 109 java.nio.charset.Charset.defaultCharset())); 110 } 111 112 _setURLReader(_stdIn); 113 } 114 115 /////////////////////////////////////////////////////////////////// 116 //// ports and parameters //// 117 118 /** The URL of the file to read from. This parameter contains 119 * a StringToken. By default, it contains an empty string, which 120 * is interpreted to mean that input should be directed to the 121 * standard input. 122 * FIXME: Should this bring up a dialog box to type (or select) a URL? 123 */ 124 public Parameter sourceURL; 125 126 /** The flag that indicates whether to refresh between each reading. 127 * This is a boolean, and defaults to false. 128 */ 129 public Parameter refresh; 130 131 /////////////////////////////////////////////////////////////////// 132 //// public methods //// 133 134 /** If the specified attribute is <i>URL</i>, then close 135 * the current file (if there is one) and open the new one. 136 * @param attribute The attribute that has changed. 137 * @exception IllegalActionException If the specified attribute 138 * is <i>URL</i> and the file cannot be opened. 139 */ 140 @Override 141 public void attributeChanged(Attribute attribute) 142 throws IllegalActionException { 143 if (attribute == sourceURL) { 144 StringToken urlToken = null; 145 146 try { 147 urlToken = (StringToken) sourceURL.getToken(); 148 149 if (urlToken == null) { 150 _source = null; 151 _setURLReader(null); 152 } else { 153 _source = urlToken.stringValue(); 154 155 if (_source.equals("")) { 156 _setURLReader(null); 157 } else { 158 URL url = new URL(_source); 159 java.io.BufferedReader reader = new BufferedReader( 160 new InputStreamReader(url.openStream())); 161 _setURLReader(reader); 162 } 163 } 164 } catch (IOException ex) { 165 throw new IllegalActionException(this, ex, 166 "Failed to evaluate sourceURL '" + urlToken + "'"); 167 } 168 } else if (attribute == refresh) { 169 _refreshFlag = ((BooleanToken) refresh.getToken()).booleanValue(); 170 } 171 172 super.attributeChanged(attribute); 173 } 174 175 /** Open the file at the URL, and set the width of the output. 176 * @exception IllegalActionException Not thrown in this base class 177 */ 178 @Override 179 public void initialize() throws IllegalActionException { 180 super.initialize(); 181 attributeChanged(sourceURL); 182 } 183 184 /** Close the reader if there is one. 185 * @exception IllegalActionException If an IO error occurs. 186 */ 187 @Override 188 public void wrapup() throws IllegalActionException { 189 try { 190 if (_reader != null && _reader != _stdIn) { 191 _reader.close(); 192 } 193 } catch (IOException ex) { 194 throw new IllegalActionException(this, ex, "Failed to close"); 195 } 196 } 197 198 /////////////////////////////////////////////////////////////////// 199 //// protected methods ///// 200 201 /** Set the reader. If there was a previous reader, close it. 202 * To set standard input, call this method with argument null. 203 * @param reader The reader to read to. 204 * @exception IllegalActionException If an IO error occurs. 205 */ 206 protected void _setURLReader(java.io.BufferedReader reader) 207 throws IllegalActionException { 208 try { 209 if (_reader != null && _reader != _stdIn) { 210 _reader.close(); 211 } 212 } catch (IOException ex) { 213 throw new IllegalActionException(this, ex, "Failed to close"); 214 } 215 216 if (reader != null) { 217 _reader = reader; 218 } else { 219 _reader = _stdIn; 220 } 221 } 222 223 /////////////////////////////////////////////////////////////////// 224 //// protected members //// 225 226 /** The reader to read from. */ 227 protected java.io.BufferedReader _reader = null; 228 229 /** Standard in as a reader. */ 230 protected static java.io.BufferedReader _stdIn = null; 231 232 /** String for the URL. */ 233 protected String _source; 234 235 /** Flag to indicate whether or not to refresh the data 236 * between readings. 237 */ 238 protected boolean _refreshFlag; 239}