001/* 002 * Copyright (c) 1998-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.geon; 031 032import java.io.ByteArrayInputStream; 033import java.io.InputStream; 034import java.util.Map; 035import java.util.Set; 036 037import javax.xml.parsers.DocumentBuilder; 038import javax.xml.parsers.DocumentBuilderFactory; 039 040import org.w3c.dom.Document; 041import org.w3c.dom.Element; 042import org.w3c.dom.NodeList; 043 044import ptolemy.actor.TypedAtomicActor; 045import ptolemy.actor.TypedIOPort; 046import ptolemy.data.ArrayToken; 047import ptolemy.data.DoubleToken; 048import ptolemy.data.StringToken; 049import ptolemy.data.Token; 050import ptolemy.data.expr.ASTPtRootNode; 051import ptolemy.data.expr.ModelScope; 052import ptolemy.data.expr.ParseTreeEvaluator; 053import ptolemy.data.expr.PtParser; 054import ptolemy.data.type.ArrayType; 055import ptolemy.data.type.BaseType; 056import ptolemy.data.type.Type; 057import ptolemy.data.type.TypeConstant; 058import ptolemy.kernel.CompositeEntity; 059import ptolemy.kernel.util.IllegalActionException; 060import ptolemy.kernel.util.NameDuplicationException; 061 062////////////////////////////////////////////////////////////////////////// 063//// Expression 064/** 065 * Get 2D classification point for rock classification. 066 * 067 * The actor Accepts coordinates expressions and an xml composition string. It 068 * evaluates the expression using the expression evaluator (PtParser as in the 069 * Expression actor) and the composition. Returns an array of doubles of length 070 * two representing the x and y values. 071 * 072 * see Expression // is ambiguous 073 * 074 * @author Efrat Jaeger 075 * @version $Id: Get2DPoint.java 24234 2010-05-06 05:21:26Z welker $ 076 * @since Ptolemy II 4.0.1 077 */ 078 079public class Get2DPoint extends TypedAtomicActor { 080 081 /** 082 * Construct an actor with the given container and name. 083 * 084 * @param container 085 * The container. 086 * @param name 087 * The name of this actor. 088 * @exception IllegalActionException 089 * If the actor cannot be contained by the proposed 090 * container. 091 * @exception NameDuplicationException 092 * If the container already has an actor with this name. 093 */ 094 public Get2DPoint(CompositeEntity container, String name) 095 throws NameDuplicationException, IllegalActionException { 096 super(container, name); 097 098 rowInfo = new TypedIOPort(this, "rowInfo", true, false); 099 rowInfo.setTypeEquals(BaseType.STRING); 100 101 coordinates = new TypedIOPort(this, "coordinates", true, false); 102 coordinates.setTypeEquals(new ArrayType(BaseType.STRING)); 103 104 point = new TypedIOPort(this, "point", false, true); 105 point.setTypeEquals(new ArrayType(BaseType.DOUBLE)); 106 } 107 108 // ///////////////////////////////////////////////////////////////// 109 // // ports and parameters //// 110 111 /** Composition info. */ 112 public TypedIOPort rowInfo; 113 114 /** 115 * An array of the coordinates to be evaluated. 116 */ 117 public TypedIOPort coordinates; 118 119 /** 120 * The classification point. 121 */ 122 public TypedIOPort point; 123 124 // ///////////////////////////////////////////////////////////////// 125 // // public methods //// 126 127 /** 128 * Accepts coordinates expressions and an xml composition string. Evaluates 129 * the expression using the expression evaluator and the composition. 130 * Returns an array of doubles of length two representing the x and y 131 * values. 132 * 133 * @exception IllegalActionException 134 * If the evaluation of the expression triggers it, or the 135 * evaluation yields a null result, or the evaluation yields 136 * an incompatible type, or if there is no director, or if a 137 * connected input has no tokens. 138 */ 139 public void fire() throws IllegalActionException { 140 141 try { 142 Token[] coordinatesTokens = ((ArrayToken) coordinates.get(0)) 143 .arrayValue(); 144 145 String compositionXML = ((StringToken) rowInfo.get(0)) 146 .stringValue(); 147 try { 148 DocumentBuilderFactory factory = DocumentBuilderFactory 149 .newInstance(); 150 factory.setValidating(false); 151 DocumentBuilder builder = factory.newDocumentBuilder(); 152 byte[] xmlBytes = compositionXML.getBytes(); 153 InputStream is = new ByteArrayInputStream(xmlBytes); 154 _composition = builder.parse(is); 155 } catch (Exception ex) { 156 throw new IllegalActionException(this, ex 157 + " xml processing exception."); 158 } 159 160 String xCoor = ((StringToken) coordinatesTokens[1]).stringValue(); 161 String yCoor = ((StringToken) coordinatesTokens[2]).stringValue(); 162 163 // Token inputToken = port.get(0); 164 // _tokenMap.put(port.getName(), inputToken); 165 166 PtParser parser = new PtParser(); 167 _parseTree = parser.generateParseTree(xCoor); 168 _parseTreeEvaluator = new ParseTreeEvaluator(); 169 _scope = new VariableScope(); 170 DoubleToken xToken = (DoubleToken) _parseTreeEvaluator 171 .evaluateParseTree(_parseTree, _scope); 172 _parseTree = parser.generateParseTree(yCoor); 173 DoubleToken yToken = (DoubleToken) _parseTreeEvaluator 174 .evaluateParseTree(_parseTree, _scope); 175 if (xToken == null || yToken == null) { 176 throw new IllegalActionException(this, 177 "One of the coordinates yields a null result: " 178 + " x : " + xCoor + " , y : " + yCoor); 179 } 180 181 double xVal = xToken.doubleValue(); 182 double yVal = yToken.doubleValue(); 183 Token arrayToken[] = new Token[2]; 184 arrayToken[0] = new DoubleToken(xVal); 185 arrayToken[1] = new DoubleToken(yVal); 186 // Point2D.Double _point = new Point2D.Double(xVal, yVal); 187 point.broadcast(new ArrayToken(arrayToken)); 188 } catch (IllegalActionException ex) { 189 // Chain exceptions to get the actor that threw the exception. 190 throw new IllegalActionException(this, ex, 191 "Invalid coordintes expression."); 192 } 193 194 } 195 196 // ///////////////////////////////////////////////////////////////// 197 // // private methods //// 198 199 private class VariableScope extends ModelScope { 200 201 /** 202 * Look up and return the attribute with the specified name in the 203 * scope. Return 0 if such an attribute does not exist. 204 * 205 * @return The attribute with the specified name in the scope. 206 */ 207 public Token get(String name) throws IllegalActionException { 208 209 String strVal = ""; 210 double value = 0; 211 NodeList minValues = _composition.getElementsByTagName(name); 212 for (int i = 0; i < minValues.getLength(); i++) { 213 Element mineral = (Element) minValues.item(i); 214 if (mineral.getChildNodes().getLength() > 0) { 215 strVal = mineral.getFirstChild().getNodeValue().trim(); 216 } 217 if (!strVal.equals("")) { 218 Double DVal = new Double(Double.parseDouble(strVal)); 219 value = DVal.doubleValue(); 220 } 221 } 222 return new DoubleToken(value); 223 } 224 225 /** 226 * Look up and return the type of the attribute with the specified name 227 * in the scope. Return null if such an attribute does not exist. 228 * 229 * @return The attribute with the specified name in the scope. 230 */ 231 public Type getType(String name) throws IllegalActionException { 232 return BaseType.DOUBLE; 233 } 234 235 /** 236 * Look up and return the type term for the specified name in the scope. 237 * Return null if the name is not defined in this scope, or is a 238 * constant type. 239 * 240 * @return The InequalityTerm associated with the given name in the 241 * scope. 242 * @exception IllegalActionException 243 * If a value in the scope exists with the given name, 244 * but cannot be evaluated. 245 */ 246 public ptolemy.graph.InequalityTerm getTypeTerm(String name) 247 throws IllegalActionException { 248 return new TypeConstant(BaseType.DOUBLE); 249 } 250 251 /** 252 * Return the list of identifiers within the scope. 253 * 254 * @return The list of identifiers within the scope. 255 */ 256 public Set identifierSet() { 257 return getAllScopedVariableNames(null, Get2DPoint.this); 258 } 259 } 260 261 // ///////////////////////////////////////////////////////////////// 262 // // private variables //// 263 264 private Document _composition = null; 265 private int _iterationCount = 1; 266 private ASTPtRootNode _parseTree = null; 267 private ParseTreeEvaluator _parseTreeEvaluator = null; 268 private VariableScope _scope = null; 269 private Map _tokenMap; 270}