001/*
002 * Copyright (c) 2009-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2015-07-25 00:46:23 +0000 (Sat, 25 Jul 2015) $' 
007 * '$Revision: 33566 $'
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.kepler.data.conversion;
031
032import java.text.ParseException;
033import java.text.SimpleDateFormat;
034import java.util.Date;
035
036import ptolemy.actor.lib.Transformer;
037import ptolemy.data.ArrayToken;
038import ptolemy.data.DateToken;
039import ptolemy.data.DoubleToken;
040import ptolemy.data.IntToken;
041import ptolemy.data.LongToken;
042import ptolemy.data.RecordToken;
043import ptolemy.data.StringToken;
044import ptolemy.data.Token;
045import ptolemy.data.type.ArrayType;
046import ptolemy.data.type.BaseType;
047import ptolemy.data.type.RecordType;
048import ptolemy.data.type.Type;
049import ptolemy.kernel.CompositeEntity;
050import ptolemy.kernel.util.IllegalActionException;
051import ptolemy.kernel.util.NameDuplicationException;
052import ptolemy.kernel.util.Workspace;
053
054/**
055 * Convert a string or an array of strings to the type of the <i>output</i>
056 * port. (The output port type must be explicity set). If input is an array
057 * of strings, output must also be an array.
058 * 
059 * @author Daniel Crawl
060 * @version $Id: StringToN.java 33566 2015-07-25 00:46:23Z crawl $
061 */
062
063public class StringToN extends Transformer {
064        /**
065         * Construct a StringToN with the given container and name.
066         * 
067         * @param name
068         *            The name of this actor.
069         * @exception IllegalActionException
070         *                If the entity cannot be contained by the proposed
071         *                container.
072         * @exception NameDuplicationException
073         *                If the container already has an actor with this name.
074         */
075        public StringToN(CompositeEntity container, String name)
076                        throws NameDuplicationException, IllegalActionException {
077                super(container, name);
078
079                output.setMultiport(true);
080                output.setDefaultWidth(1);
081
082                _dateFormat = new SimpleDateFormat();
083
084                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
085                                + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n"
086                                + "</svg>\n");
087        }
088
089        // /////////////////////////////////////////////////////////////////
090        // // public methods ////
091
092        @Override
093    public Object clone(Workspace workspace) throws CloneNotSupportedException {
094            StringToN newObject = (StringToN) super.clone(workspace);
095            newObject._dateFormat = new SimpleDateFormat();
096            return newObject;
097        }
098        
099        @Override
100    public void fire() throws IllegalActionException {
101                super.fire();
102
103                Token outToken = null;
104                Token inToken = input.get(0);
105                Type outType = output.getType();
106
107                if (inToken.getType() instanceof ArrayType) {
108                        Type outElementType;
109
110                        if (!(outType instanceof ArrayType)) {
111                                throw new IllegalActionException(this,
112                                                "Cannot convert array of strings to non-array.");
113                        } else {
114                                outElementType = ((ArrayType) outType).getElementType();
115                        }
116
117                        Token[] array = ((ArrayToken) inToken).arrayValue();
118                        Token[] out = new Token[array.length];
119                        for (int i = 0; i < array.length; i++) {
120                                String str = ((StringToken) array[i]).stringValue();
121                                out[i] = _makeToken(str, outElementType);
122                        }
123                        outToken = new ArrayToken(out);
124                } else {
125                        String str = ((StringToken) inToken).stringValue();
126                        outToken = _makeToken(str, outType);
127                }
128
129                output.broadcast(outToken);
130        }
131
132        // /////////////////////////////////////////////////////////////////
133        // // private methods ////
134
135        /** Convert a string to a specific type. */
136    private Token _makeToken(String str, Type type)
137                        throws IllegalActionException {
138            try {
139                if (type == BaseType.DOUBLE) {
140                        return new DoubleToken(Double.valueOf(str).doubleValue());
141                } else if (type == BaseType.INT) {
142                        return new IntToken(Integer.valueOf(str).intValue());
143                } else if (type == BaseType.LONG) {
144                        return new LongToken(Long.valueOf(str).longValue());
145                } else if (type == BaseType.STRING) {
146                        return new StringToken(str);
147                } else if (type == BaseType.DATE) {
148                        try {
149                                Date date = _dateFormat.parse(str);
150                                return new DateToken(date.getTime());
151                        } catch (ParseException e) {
152                                throw new IllegalActionException(this, e, "Could not parse "
153                                                + " date string " + str);
154                        }
155                } else if(type instanceof RecordType) { 
156                    return new RecordToken(str);
157            } else {
158                        throw new IllegalActionException(this, "Conversion from string to "
159                                        + type + " not implemented.");
160                }
161            } catch(NumberFormatException e) {
162                throw new IllegalActionException(this, e, "Error converting string to number.");
163            }
164        }
165
166        /** Used to convert strings to date objects. */
167        private SimpleDateFormat _dateFormat;
168}