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}