001/* An actor that reads a string from a file or URL, parses it assuming it is defining a record, and outputs the record. 002 003 Copyright (c) 2003-2015 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 */ 027package ptolemy.actor.lib.io; 028 029import java.util.Set; 030 031import ptolemy.data.Token; 032import ptolemy.data.expr.ASTPtRootNode; 033import ptolemy.data.expr.Parameter; 034import ptolemy.data.expr.ParseTreeEvaluator; 035import ptolemy.data.expr.PtParser; 036import ptolemy.data.expr.StringParameter; 037import ptolemy.data.type.BaseType; 038import ptolemy.graph.Inequality; 039import ptolemy.kernel.CompositeEntity; 040import ptolemy.kernel.util.IllegalActionException; 041import ptolemy.kernel.util.NameDuplicationException; 042 043/////////////////////////////////////////////////////////////////// 044//// TokenReader 045 046/** 047 An actor that reads a string expression from a file or URL upon receiving a 048 signal on its <i>trigger</i> input port, and outputs a token that is the 049 result of evaluating the read string. The file or URL is specified by the 050 <i>FileOrURL</i> parameter or set using the <i>FileOrURL</i> port. If the 051 file or URL cannot be read, the expression cannot be parsed successfully, 052 or the resulting token does not match the type constraint of the output port, 053 the value of the <i>errorHandlingStrategy</i> parameter determines the 054 behavior of this actor. 055 TODO: describe automatic port constraint setting 056 FIXME: More here. Particularly, document output type handling. 057 058 @author Edward A. Lee, Marten Lohstroh 059 @version $Id$ 060 @since Ptolemy II 10.0 061 @deprecated Use LineReader followed by ExpressionToToken. 062 @Pt.ProposedRating Red (eal) 063 @Pt.AcceptedRating Red (reviewmoderator) 064 */ 065@Deprecated 066public class TokenReader extends FileReader { 067 068 /** Construct an actor with a name and a container. 069 * The container argument must not be null, or a NullPointerException 070 * will be thrown. 071 * @param container The container. 072 * @param name The name of this actor. 073 * @exception IllegalActionException If the container is incompatible 074 * with this actor. 075 * @exception NameDuplicationException If the name coincides with 076 * an actor already in the container. 077 */ 078 public TokenReader(CompositeEntity container, String name) 079 throws IllegalActionException, NameDuplicationException { 080 super(container, name); 081 outputType = new Parameter(this, "outputType"); 082 // must reset the output type to unknown (base class sets it to string) 083 output.setTypeEquals(BaseType.UNKNOWN); 084 085 errorHandlingStrategy = new StringParameter(this, 086 "errorHandlingStrategy"); 087 errorHandlingStrategy.addChoice("Throw Exception"); 088 errorHandlingStrategy.addChoice("Do Nothing"); 089 090 // Show the firingCountLimit parameter last. 091 firingCountLimit.moveToLast(); 092 } 093 094 /////////////////////////////////////////////////////////////////// 095 //// public variables //// 096 097 /** The error handled strategy. The strategy to use if: 098 * <ul> 099 * <li> the file or URL cannot be read,</li> 100 * <li> the data read from the file or the URL cannot be parsed,</li> 101 * <li> the parsed token cannot be converted into a token of the type 102 * given by <i>outputType</i>, if such a type is given, or</li> 103 * <li> the parsed token cannot 104 * be converted to a token of the resolved type of the output, if no <i>outputType</i> 105 * is given.</li> 106 * </ul> 107 * This is a string that has the following 108 * possible values: "Do Nothing" or "Throw Exception", where 109 * "Throw Exception" is the default. 110 */ 111 public StringParameter errorHandlingStrategy; 112 113 /** If this parameter has a value, then the value specifies the 114 * type of the output port. When the actor reads from the file 115 * or URL, it expects the data read to be a string that can be 116 * parsed into a token that is convertible to (or identical to) 117 * this output type. If it is not, then the action taken is 118 * specified by the <i>errorHandlingStrategy</i> parameter. 119 * If this parameter has no value (the default), then the 120 * output type will be set to match whatever is first read from the 121 * file or URL and will be updated on each subsequent firing if 122 * the data read from the file or URL cannot be converted to the 123 * type determined by the first read. 124 */ 125 public Parameter outputType; 126 127 /////////////////////////////////////////////////////////////////// 128 //// public methods //// 129 130 /** Not implemented entirely yet. FIXME 131 * @exception IllegalActionException If thrown by the base class. 132 */ 133 @Override 134 public void fire() throws IllegalActionException { 135 try { 136 super.fire(); 137 } catch (IllegalActionException exception) { 138 String errorHandlingStrategyValue = errorHandlingStrategy 139 .stringValue(); 140 if (errorHandlingStrategyValue.equals("Throw Exception")) { 141 throw exception; 142 } 143 } 144 } 145 146 /////////////////////////////////////////////////////////////////// 147 //// protected methods //// 148 149 /** Do not establish the usual default type constraints. 150 * @return null 151 */ 152 @Override 153 protected Set<Inequality> _defaultTypeConstraints() { 154 return null; 155 } 156 157 /** FIXME: Send the specified string to the output. 158 * @param fileContents The contents of the file or URL that was read. 159 * @exception IllegalActionException If sending the data fails. 160 */ 161 @Override 162 protected void _handleFileData(String fileContents) 163 throws IllegalActionException { 164 165 if (_parser == null) { 166 _parser = new PtParser(); 167 } 168 ASTPtRootNode parseTree = _parser.generateParseTree(fileContents); 169 170 if (_parseTreeEvaluator == null) { 171 _parseTreeEvaluator = new ParseTreeEvaluator(); 172 } 173 174 // FIXME: Evaluating a parse tree that comes from an untrusted 175 // source creates a security problem. 176 Token result = _parseTreeEvaluator.evaluateParseTree(parseTree); 177 178 if (result == null) { 179 throw new IllegalActionException(this, 180 "Expression yields a null result: " + fileContents); 181 } 182 183 if (!output.getType().isCompatible(result.getType())) { 184 // Handle the error according to the error policy. 185 // FIXME: Fall through to the broadcast, which will throw 186 // an exception. 187 } 188 output.broadcast(result); 189 } 190 191 /////////////////////////////////////////////////////////////////// 192 //// private members //// 193 194 /** The parser to use. */ 195 private PtParser _parser = null; 196 197 /** The parse tree evaluator to use. */ 198 private ParseTreeEvaluator _parseTreeEvaluator = null; 199 200}