001/* Pattern match a string to a regular expression. 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 */ 028package ptolemy.actor.lib.string; 029 030import java.util.regex.Matcher; 031import java.util.regex.Pattern; 032import java.util.regex.PatternSyntaxException; 033 034import ptolemy.actor.TypedAtomicActor; 035import ptolemy.actor.TypedIOPort; 036import ptolemy.actor.parameters.PortParameter; 037import ptolemy.data.BooleanToken; 038import ptolemy.data.StringToken; 039import ptolemy.data.expr.SingletonParameter; 040import ptolemy.data.type.BaseType; 041import ptolemy.kernel.CompositeEntity; 042import ptolemy.kernel.util.Attribute; 043import ptolemy.kernel.util.IllegalActionException; 044import ptolemy.kernel.util.InternalErrorException; 045import ptolemy.kernel.util.NameDuplicationException; 046import ptolemy.kernel.util.Workspace; 047 048/////////////////////////////////////////////////////////////////// 049//// StringMatches 050 051/** 052 Pattern match a string to a regular expression and output a true if it 053 matches and a false if it does not. For a reference on regular 054 expression syntax see: 055 <a href="http://download.oracle.com/javase/tutorial/essential/regex/#in_browser"> 056 http://download.oracle.com/javase/tutorial/essential/regex/</a>. 057 058 @author Antonio Yordan-Nones, Colin Cochran, Contributor: Edward A. Lee 059 @version $Id$ 060 @since Ptolemy II 4.0 061 @Pt.ProposedRating Green (djstone) 062 @Pt.AcceptedRating Green (eal) 063 */ 064public class StringMatches extends TypedAtomicActor { 065 /** Construct an actor with the given container and name. 066 * In addition to invoking the base class constructors, this constructs 067 * the <i>pattern</i> and <i>matchString</i> PortParameters, 068 * and the <i>output</i> port. 069 * @param container The container. 070 * @param name The name of this actor. 071 * @exception IllegalActionException If the actor cannot be contained 072 * by the proposed container. 073 * @exception NameDuplicationException If the container already has an 074 * actor with this name. 075 */ 076 public StringMatches(CompositeEntity container, String name) 077 throws NameDuplicationException, IllegalActionException { 078 super(container, name); 079 080 // Create one matchString portParameter, one matchString port, 081 // and one output port. 082 pattern = new PortParameter(this, "pattern"); 083 pattern.setStringMode(true); 084 pattern.setExpression(""); 085 new SingletonParameter(pattern.getPort(), "_showName") 086 .setToken(BooleanToken.TRUE); 087 088 matchString = new PortParameter(this, "matchString"); 089 matchString.setStringMode(true); 090 matchString.setExpression(""); 091 new SingletonParameter(matchString.getPort(), "_showName") 092 .setToken(BooleanToken.TRUE); 093 094 output = new TypedIOPort(this, "output", false, true); 095 output.setTypeEquals(BaseType.BOOLEAN); 096 } 097 098 /////////////////////////////////////////////////////////////////// 099 //// ports and parameters //// 100 101 /** The string to be pattern matched to the regular expression. 102 */ 103 public PortParameter matchString; 104 105 /** Output is true if the pattern exists in the string, false otherwise. 106 * Its type is boolean. 107 */ 108 public TypedIOPort output; 109 110 /** The regular expression to be pattern matched with the 111 * matchString string. 112 * Its default parameter is an empty string that matches no strings. 113 */ 114 public PortParameter pattern; 115 116 /////////////////////////////////////////////////////////////////// 117 //// public methods //// 118 119 /** Override the base class to compile the regular expression if 120 * it has changed. 121 * @param attribute The attribute that changed. 122 * @exception IllegalActionException If the pattern cannot be compiled 123 * into a regular expression. 124 */ 125 @Override 126 public void attributeChanged(Attribute attribute) 127 throws IllegalActionException { 128 if (attribute == pattern) { 129 try { 130 String patternValue = ((StringToken) pattern.getToken()) 131 .stringValue(); 132 _pattern = Pattern.compile(patternValue); 133 } catch (PatternSyntaxException ex) { 134 String patternValue = ((StringToken) pattern.getToken()) 135 .stringValue(); 136 throw new IllegalActionException(this, ex, 137 "Failed to compile regular expression \"" + patternValue 138 + "\""); 139 } 140 } else { 141 super.attributeChanged(attribute); 142 } 143 } 144 145 /** Clone the actor into the specified workspace. This calls the 146 * base class and initializes private variables. 147 * @param workspace The workspace for the new object. 148 * @return A new actor. 149 * @exception CloneNotSupportedException If a derived class has 150 * an attribute that cannot be cloned. 151 */ 152 @Override 153 public Object clone(Workspace workspace) throws CloneNotSupportedException { 154 StringMatches newObject = (StringMatches) super.clone(workspace); 155 String patternValue = null; 156 try { 157 patternValue = ((StringToken) newObject.pattern.getToken()) 158 .stringValue(); 159 newObject._pattern = Pattern.compile(patternValue); 160 } catch (Exception ex) { 161 throw new InternalErrorException(this, ex, 162 "Failed to compile regular expression \"" + patternValue 163 + "\""); 164 } 165 return newObject; 166 } 167 168 /** Pattern match a regular expression against a supplied 169 * matchString and output a true if they match and a false 170 * otherwise. 171 * @exception IllegalActionException If there is no director. 172 */ 173 @Override 174 public void fire() throws IllegalActionException { 175 super.fire(); 176 pattern.update(); 177 matchString.update(); 178 179 String matchStringValue = ((StringToken) matchString.getToken()) 180 .stringValue(); 181 Matcher match = _pattern.matcher(matchStringValue); 182 output.send(0, new BooleanToken(match.find())); 183 } 184 185 /////////////////////////////////////////////////////////////////// 186 //// private variables //// 187 // The pattern for the regular expression. 188 private Pattern _pattern; 189}