001/*
002 * Copyright (c) 2017 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2017-08-29 15:27:08 -0700 (Tue, 29 Aug 2017) $' 
007 * '$Revision: 1392 $'
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.webview.data;
031
032import java.util.Collections;
033import java.util.HashMap;
034import java.util.Map;
035
036import io.vertx.core.json.JsonArray;
037import io.vertx.core.json.JsonObject;
038import ptolemy.data.ArrayToken;
039import ptolemy.data.BooleanToken;
040import ptolemy.data.DoubleToken;
041import ptolemy.data.IntToken;
042import ptolemy.data.LongToken;
043import ptolemy.data.RecordToken;
044import ptolemy.data.StringToken;
045import ptolemy.data.Token;
046import ptolemy.data.UnsignedByteToken;
047import ptolemy.data.type.ArrayType;
048import ptolemy.data.type.BaseType;
049import ptolemy.data.type.RecordType;
050import ptolemy.data.type.Type;
051import ptolemy.kernel.util.IllegalActionException;
052
053public class TokenConverter {
054
055    public TokenConverter() {
056        // TODO Auto-generated constructor stub
057    }
058    
059    public static void addConversion(Type type, Converter converter) {
060        _conversions.put(type, converter);
061    }
062
063    /** Convert data from a Ptolemy token. */
064    public Object convertFromToken(Token token) throws IllegalActionException {
065        
066        Type type = token.getType();
067        
068        if(type == BaseType.STRING) {
069            return ((StringToken)token).stringValue();
070        } else if(type == BaseType.DOUBLE) {
071            return Double.valueOf(((DoubleToken)token).doubleValue());
072        } else if(type == BaseType.INT) {
073            return Integer.valueOf(((IntToken)token).intValue());
074        } else if(type == BaseType.LONG) {
075            return Long.valueOf(((LongToken)token).longValue());
076        } else if(type == BaseType.BOOLEAN) {
077            return Boolean.valueOf(((BooleanToken)token).booleanValue());
078        } else if(type instanceof ArrayType) {
079            //System.out.println("array = " + token);
080            ArrayToken array = (ArrayToken)token;
081            if(array.getElementType() == BaseType.UNSIGNED_BYTE) {
082                byte[] bytes = new byte[array.length()];
083                for(int i = 0; i < bytes.length; i++) {
084                    bytes[i] = ((UnsignedByteToken)array.getElement(i)).byteValue();
085                }
086                return bytes;
087            } else {
088                JsonArray json = new JsonArray();
089                for(int i = 0; i < array.length(); i++) {
090                    json.add(convertFromToken(array.getElement(i)));
091                }
092                //System.out.println("json = " + json);
093                return json;
094            }
095        } else if(type instanceof RecordType) {
096            RecordToken record = (RecordToken)token;
097            JsonObject json = new JsonObject();
098            for(String name : record.labelSet()) {
099                json.put(name, convertFromToken(record.get(name)));
100            }
101            return json;
102        } else {
103            Converter converter = _conversions.get(type);
104            if(converter != null) {
105                return converter.fromToken(token);
106            }
107        }
108
109        System.err.println("WARNING: unknown type of token for webview conversion: " + type);
110        return token.toString();
111    }
112    
113    /** Convert data to a Ptolemy token with the specified type. */
114    public Token convertToToken(String data, Type type) throws IllegalActionException {
115                
116        if(type.equals(BaseType.DOUBLE)) {
117            return new DoubleToken(data);
118        } else if(type.equals(BaseType.INT)) {
119            Double val = Double.parseDouble(data);
120            return new IntToken(val.intValue());
121        } else if(type.equals(BaseType.LONG)) {
122            Double val = Double.parseDouble(data);
123            return new LongToken(val.longValue());
124        } else if(type.equals(BaseType.STRING)) {
125            return new StringToken(data);
126        } else {
127            Converter converter = _conversions.get(type);
128            if(converter != null) {
129                return converter.toToken(data, type);
130            }
131        }
132        
133        // FIXME throw exception?
134        return null;
135    }
136    
137    private final static Map<Type,Converter> _conversions = Collections.synchronizedMap(new HashMap<Type,Converter>());
138}