001/* Trim a string, convert a string to uppercase, or convert a string to
002 lowercase depending on the user's selection.
003
004 Copyright (c) 2003-2015 The Regents of the University of California.
005 All rights reserved.
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 above
009 copyright notice and the following two paragraphs appear in all copies
010 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
028 */
029package ptolemy.actor.lib.string;
030
031import java.util.Locale;
032
033import ptolemy.actor.lib.Transformer;
034import ptolemy.data.StringToken;
035import ptolemy.data.expr.Parameter;
036import ptolemy.data.type.BaseType;
037import ptolemy.kernel.CompositeEntity;
038import ptolemy.kernel.util.Attribute;
039import ptolemy.kernel.util.IllegalActionException;
040import ptolemy.kernel.util.InternalErrorException;
041import ptolemy.kernel.util.NameDuplicationException;
042
043///////////////////////////////////////////////////////////////////
044//// StringFunction
045
046/**
047 Produce the output string generated by applying a user-specified
048 string function on a provided input string.
049
050 <p>The available string functions are a case sensitive subset of the
051 java.lang.String functions.</p>
052
053 <ul>
054 <li> <b>trim</b>: Remove leading and trailing whitespace from a string.</li>
055 <li> <b>toUpperCase</b>: Convert all letters in a string to uppercase.</li>
056 <li> <b>toLowerCase</b>: Convert all letters in a string to lowercase.</li>
057 </ul>
058
059 @see StringCompare
060 @see StringFunction
061 @see StringIndexOf
062 @see StringLength
063 @see StringMatches
064 @see StringReplace
065 @see StringSubstring
066 @author Mike Kofi Okyere, Ismael M. Sarmiento
067 @version $Id$
068 @since Ptolemy II 4.0
069 @Pt.ProposedRating Green (ismael)
070 @Pt.AcceptedRating Green (net)
071 */
072public class StringFunction extends Transformer {
073    /** Construct an actor with the given container and name.
074     *  Invoke the base class constructor and create
075     *  the <i>input</i> and <i>output</i> ports.
076     *  Set the default string function to "trim".
077     *  @param container The container.
078     *  @param name The name of this actor.
079     *  @exception IllegalActionException If the actor cannot be contained
080     *   by the proposed container.
081     *  @exception NameDuplicationException If the container already has an
082     *   actor with this name.
083     */
084    public StringFunction(CompositeEntity container, String name)
085            throws NameDuplicationException, IllegalActionException {
086        super(container, name);
087
088        // Set up ports for string input and string output.
089        input.setTypeEquals(BaseType.STRING);
090        output.setTypeEquals(BaseType.STRING);
091
092        function = new Parameter(this, "function");
093        function.setStringMode(true);
094        function.setExpression("trim");
095        function.addChoice("toLowerCase");
096        function.addChoice("toUpperCase");
097        function.addChoice("trim");
098        _function = _TRIM;
099
100        _attachText("_iconDescription",
101                "<svg>\n" + "<rect x=\"-30\" y=\"-15\" "
102                        + "width=\"80\" height=\"30\" "
103                        + "style=\"fill:white\"/>\n" + "</svg>\n");
104    }
105
106    ///////////////////////////////////////////////////////////////////
107    ////                     ports and parameters                  ////
108
109    /** Parameter that stores the string function to be performed
110     *  on the input string. The possible values are "trim" (the default),
111     * "toUpperCase", or "toLowerCase".
112     */
113    public Parameter function;
114
115    ///////////////////////////////////////////////////////////////////
116    ////                         public methods                    ////
117
118    /** Determine the string function to be performed on the input, and
119     *  set up the necessary fields for the function to be performed.
120     *  @param attribute The attribute that changed.
121     *  @exception IllegalActionException If the function is not recognized.
122     */
123    @Override
124    public void attributeChanged(Attribute attribute)
125            throws IllegalActionException {
126        if (attribute == function) {
127            // Use getToken() rather than getExpression()
128            // so substitutions occur.
129            String functionName = ((StringToken) function.getToken())
130                    .stringValue();
131
132            if (functionName.equals("trim")) {
133                _function = _TRIM;
134            } else if (functionName.equals("toUpperCase")) {
135                _function = _TOUPPERCASE;
136            } else if (functionName.equals("toLowerCase")) {
137                _function = _TOLOWERCASE;
138            } else {
139                throw new IllegalActionException(this,
140                        "Unrecognized function: " + functionName);
141            }
142        } else {
143            super.attributeChanged(attribute);
144        }
145    }
146
147    /** Perform the desired function on the input string, and send the
148     *  the resulting string to the output port. If there is no input,
149     *  then produce no output.
150     *  @exception IllegalActionException If there is no director.
151     */
152    @Override
153    public void fire() throws IllegalActionException {
154        super.fire();
155
156        if (input.hasToken(0)) {
157            StringToken inputToken = (StringToken) input.get(0);
158            String value = inputToken.stringValue();
159            output.send(0, new StringToken(_doFunction(value)));
160        }
161    }
162
163    ///////////////////////////////////////////////////////////////////
164    ////                         private methods                   ////
165
166    /** Trim the leading and trailing whitespace from a string,
167     *  convert a string to uppercase, or convert a string to lower
168     *  case depending on the function selected by the user.
169     *  @param inputString The string received from the input port.
170     */
171    private String _doFunction(String inputString) {
172        switch (_function) {
173        case _TRIM:
174            return inputString.trim();
175
176        case _TOUPPERCASE:
177            return inputString.toUpperCase(Locale.getDefault());
178
179        case _TOLOWERCASE:
180            return inputString.toLowerCase(Locale.getDefault());
181
182        default:
183            throw new InternalErrorException(
184                    "Invalid value provided as function");
185        }
186    }
187
188    ///////////////////////////////////////////////////////////////////
189    ////                         private variables                 ////
190    //The function the user wishes to perform on a string and the possible
191    //functions to perform.
192    private int _function;
193
194    private static final int _TRIM = 0;
195
196    private static final int _TOUPPERCASE = 1;
197
198    private static final int _TOLOWERCASE = 2;
199}