001/* Finds index of a string contained in a given text
002
003 Copyright (c) 2003-2014 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
027
028 */
029package ptolemy.actor.lib.string;
030
031import java.util.Locale;
032
033import ptolemy.actor.TypedAtomicActor;
034import ptolemy.actor.TypedIOPort;
035import ptolemy.actor.parameters.PortParameter;
036import ptolemy.data.BooleanToken;
037import ptolemy.data.IntToken;
038import ptolemy.data.StringToken;
039import ptolemy.data.expr.Parameter;
040import ptolemy.data.expr.SingletonParameter;
041import ptolemy.data.type.BaseType;
042import ptolemy.kernel.CompositeEntity;
043import ptolemy.kernel.util.IllegalActionException;
044import ptolemy.kernel.util.NameDuplicationException;
045
046///////////////////////////////////////////////////////////////////
047//// StringIndexOf
048
049/**
050 Output the index of a <i>searchFor</i> string contained in a given
051 <i>inText</i>.  The search begins at the index given by
052 <i>startIndex</i> and ends at either the end or the beginning of the
053 string, depending on whether <i>searchForwards</i> is true or false,
054 respectively. If the string is not found, then the output is -1.  If
055 the string is found, then the output is the index of the start of the
056 string, where index 0 refers to the first character in the string.
057
058 @author Rakesh Reddy, Philip Baldwin, Edward A. Lee
059 @version $Id$
060 @since Ptolemy II 4.0
061 @Pt.ProposedRating Green (pjb2e)
062 @Pt.AcceptedRating Green (eal)
063 */
064public class StringIndexOf extends TypedAtomicActor {
065    /** Construct an actor with the given container and name.
066     *  @param container The container.
067     *  @param name The name of this actor.
068     *  @exception IllegalActionException If the actor cannot be contained
069     *   by the proposed container.
070     *  @exception NameDuplicationException If the container already has an
071     *   actor with this name.
072     */
073    public StringIndexOf(CompositeEntity container, String name)
074            throws NameDuplicationException, IllegalActionException {
075        super(container, name);
076
077        searchFor = new PortParameter(this, "searchFor");
078        searchFor.setStringMode(true);
079        searchFor.setExpression("");
080        new SingletonParameter(searchFor.getPort(), "_showName")
081                .setToken(BooleanToken.TRUE);
082
083        inText = new PortParameter(this, "inText");
084        inText.setStringMode(true);
085        inText.setExpression("");
086        new SingletonParameter(inText.getPort(), "_showName")
087                .setToken(BooleanToken.TRUE);
088
089        ignoreCase = new Parameter(this, "ignoreCase");
090        ignoreCase.setTypeEquals(BaseType.BOOLEAN);
091        ignoreCase.setToken(new BooleanToken(false));
092
093        startIndex = new PortParameter(this, "startIndex");
094        startIndex.setTypeEquals(BaseType.INT);
095        startIndex.setExpression("0");
096        new SingletonParameter(startIndex.getPort(), "_showName")
097                .setToken(BooleanToken.TRUE);
098
099        // Create new parameters and ports, then set default values and/or
100        // types of parameters and ports.
101        searchForwards = new Parameter(this, "searchForwards");
102        searchForwards.setTypeEquals(BaseType.BOOLEAN);
103        searchForwards.setExpression("true");
104
105        output = new TypedIOPort(this, "output", false, true);
106        output.setTypeEquals(BaseType.INT);
107    }
108
109    ///////////////////////////////////////////////////////////////////
110    ////                     ports and parameters                  ////
111
112    /** The parameter to state whether to ignore case. This is a
113     *  boolean that defaults to false.
114     */
115    public Parameter ignoreCase;
116
117    /** Port and parameter specifying the string that will be searched.
118     *  This has type string and defaults to the empty string.
119     */
120    public PortParameter inText;
121
122    /** Output producing the index of the <i>searchFor</i> string, if
123     *  it is found, and -1 otherwise. This has type int.
124     */
125    public TypedIOPort output;
126
127    /** Port and parameter specifying a string to find in
128     *  the <i>inText</i> string.  This has type string and
129     *  defaults to an empty string.
130     */
131    public PortParameter searchFor;
132
133    /** Boolean parameter indicating the direction in which to search.
134     *  This is true to find the first occurrence and false to find the last.
135     *  The default value is true.
136     */
137    public Parameter searchForwards;
138
139    /** Port and parameter that determines where to start the search.
140     *  This has type int and defaults to 0.
141     */
142    public PortParameter startIndex;
143
144    ///////////////////////////////////////////////////////////////////
145    ////                         public methods                    ////
146
147    /** Perform the specified search and output either -1 (the string is not
148     *  found) or the index of the string that is found.
149     *  @exception IllegalActionException If there is no director.
150     */
151    @Override
152    public void fire() throws IllegalActionException {
153        super.fire();
154
155        searchFor.update();
156        inText.update();
157        startIndex.update();
158
159        String searchForString = ((StringToken) searchFor.getToken())
160                .stringValue();
161        String inTextString = ((StringToken) inText.getToken()).stringValue();
162        int startIndexValue = ((IntToken) startIndex.getToken()).intValue();
163        boolean forwards = ((BooleanToken) searchForwards.getToken())
164                .booleanValue();
165
166        if (((BooleanToken) ignoreCase.getToken()).booleanValue()) {
167            searchForString = searchForString.toLowerCase(Locale.getDefault());
168            inTextString = inTextString.toLowerCase(Locale.getDefault());
169        }
170
171        int returnValue;
172
173        if (forwards) {
174            returnValue = inTextString.indexOf(searchForString,
175                    startIndexValue);
176        } else {
177            returnValue = inTextString.lastIndexOf(searchForString,
178                    startIndexValue);
179        }
180
181        output.send(0, new IntToken(returnValue));
182    }
183}