001/*
002 * Copyright (c) 2003-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2014-06-25 17:30:05 +0000 (Wed, 25 Jun 2014) $' 
007 * '$Revision: 32780 $'
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.reporting.rio.util;
031
032import java.io.IOException;
033import java.io.StringWriter;
034import java.util.Iterator;
035
036import org.apache.commons.lang.StringEscapeUtils;
037import org.apache.commons.logging.Log;
038import org.apache.commons.logging.LogFactory;
039import org.apache.xml.serialize.OutputFormat;
040import org.apache.xml.serialize.XMLSerializer;
041import org.w3c.dom.Document;
042
043import ptolemy.data.ArrayToken;
044import ptolemy.data.DateToken;
045import ptolemy.data.DoubleToken;
046import ptolemy.data.IntToken;
047import ptolemy.data.MatrixToken;
048import ptolemy.data.RecordToken;
049import ptolemy.data.ScalarToken;
050import ptolemy.data.StringToken;
051import ptolemy.data.Token;
052import ptolemy.data.XMLToken;
053import ptolemy.kernel.util.IllegalActionException;
054
055public class TokenUtil {
056
057        public static Log log = LogFactory.getLog(TokenUtil.class);
058        
059    /** Get the Token. */
060    public static Token getToken(String type, String value) {
061        
062        Token token = null;
063
064        //put it together - requires token to have a string constructor
065        try {
066                Class<?> clazz = Class.forName(type);
067                        token = (Token) clazz.getConstructor(String.class).newInstance(value);
068                } catch (Exception e) {
069                        log.error("Token could not be constructed for type: " + type + ": " + e.getMessage());
070                        e.printStackTrace();
071                }
072        
073                log.debug("Reconstructed Token (" + type + "): " + token);
074        
075        return token;
076    }
077
078    public static int getColumnCount(Token token) {
079        int cnt = 0;
080        
081        if (token instanceof RecordToken){
082                cnt = ((RecordToken)token).length();
083                log.debug("column count: " + cnt);
084        }
085        else if (token instanceof ArrayToken){
086                cnt = 1;
087        } 
088        else if (token instanceof MatrixToken){
089                cnt = ((MatrixToken)token).getColumnCount();
090        }
091        
092        return cnt;
093    }
094    
095    public static int getRowCount(Token token) {
096
097        int cnt = 0;
098                int biggestRowCount = 0;
099
100        if (token instanceof RecordToken){
101                RecordToken rt = (RecordToken) token;
102                Iterator iter = rt.labelSet().iterator();
103                
104                while (iter.hasNext()) {
105                        String label = (String) iter.next();
106                        Token t = rt.get(label);
107                        if (t instanceof ArrayToken) {
108                                cnt = ((ArrayToken) t).length();
109                                if (cnt > biggestRowCount){
110                                        biggestRowCount = cnt;
111                                }
112                        }
113                        else if (t instanceof StringToken || t instanceof ScalarToken 
114                        || t instanceof XMLToken || t instanceof DateToken ){
115                                //TODO any other token types?
116                                cnt = 1;
117                                if (cnt > biggestRowCount){
118                                        biggestRowCount = cnt;
119                                }
120                        }
121                }
122        }
123        else if (token instanceof ArrayToken){
124                biggestRowCount = ((ArrayToken)token).length();
125        }
126        else if (token instanceof MatrixToken){
127                biggestRowCount = ((MatrixToken)token).getRowCount();
128        }
129        else{
130                        log.error("not yet handling this token type:"+token.getClass());
131        }
132        
133        log.debug("row count: " + biggestRowCount);
134        return biggestRowCount;
135    }
136    
137    public static String getValue(Token token, int column, int row) {
138        Token value = null;
139        String stringValue = null;
140        
141        
142        if (token instanceof RecordToken){
143                RecordToken rt = (RecordToken) token;
144                int c = 0;
145                Iterator iter = rt.labelSet().iterator();
146        
147                while (iter.hasNext()) {
148                        String label = (String) iter.next();
149                        if (c == column) {
150                                Token t = rt.get(label);
151                                if (t instanceof ArrayToken) {
152                                        ArrayToken at = ((ArrayToken) t);
153                                        if (row < at.length()){
154                                                value = at.getElement(row);
155                                                break;
156                                        }
157                                }
158                                if (row < 1){
159                                        value = t;
160                                }
161                                
162                        }
163                        c++;
164                }
165        } else if (token instanceof ArrayToken){
166                value = ((ArrayToken)token).getElement(row);
167        }
168        else if (token instanceof MatrixToken){
169                value = ((MatrixToken)token).getElementAsToken(row, column);
170        }
171        
172        
173        if (value != null) {
174                stringValue = value.toString();
175        }
176        if (value instanceof StringToken) {
177                stringValue = ((StringToken)value).stringValue();
178                // XXX unescape here? 
179                // newlines seem to have already been turned into spaces(?) 
180                // at this point...
181                ///stringValue = StringEscapeUtils.unescapeJava(stringValue);
182        }
183        if (value instanceof IntToken) {
184                if (((IntToken)value).intValue() == IntToken.NIL.intValue()) {
185                        stringValue = "nil";
186                }
187        }
188        if (value instanceof DoubleToken) {
189                if ( Double.isNaN( ((DoubleToken)value).doubleValue() ) ) {
190                        stringValue = "nil";
191                }
192        }
193
194        log.debug("Value at (" + column + ", " + row + ") : " + stringValue);
195        return stringValue;
196    }
197    
198    public static String getLabel(Token token, int column) {
199        String label = null;
200        if (token instanceof RecordToken){
201                RecordToken rt = (RecordToken) token;
202                int c = 0;
203                Iterator iter = rt.labelSet().iterator();
204                while (iter.hasNext()) {
205                        label = (String) iter.next();
206                        if (c == column) {
207                                break;
208                        }
209                        c++;
210                }
211        }
212        if(label != null){
213                log.debug("Label at (" + column + ") : " + label);
214        }else{
215                log.debug("Label at (" + column + ") : null");
216        }
217        return label;
218    }
219    
220    public static String getStringValue(Token token) {
221        String value = null;
222        if (token instanceof StringToken) {
223                value = ((StringToken)token).stringValue();
224                value = StringEscapeUtils.unescapeJava(value);
225        }
226        if (token instanceof IntToken) {
227                value = String.valueOf( ((IntToken)token).intValue());
228        }
229        if (token instanceof DoubleToken) {
230                value = String.valueOf( ((DoubleToken)token).doubleValue());
231        }
232        if (token instanceof XMLToken) {
233        
234                //TODO this formats the xml properly, but it's only shown properly
235                // in instance due to the <fo:block settings of genericToken in xsl
236                value = null;
237                XMLToken xmlToken = (XMLToken)token;
238                Document doc = xmlToken.getDomTree();   
239                OutputFormat format = new OutputFormat(doc);
240            format.setLineWidth(65);
241            format.setIndenting(true);
242            format.setIndent(2);
243            format.setOmitXMLDeclaration(true);
244            XMLSerializer serializer = new XMLSerializer(format);
245            StringWriter strWriter = new StringWriter();
246            try {
247                serializer.setOutputCharStream(strWriter);
248                                serializer.serialize(doc);
249                                value = strWriter.toString();
250                            strWriter.close();
251                        } catch (IOException e) {
252                                // TODO Auto-generated catch block
253                                e.printStackTrace();
254                        }
255                
256        }
257        log.debug("String Value of (" + token.getClass() + ") : " + value);
258        return value;
259    }
260    
261    public static boolean isRecordOrArrayOrMatrixToken(Token token) {
262        if (token instanceof MatrixToken || token instanceof RecordToken
263                        || token instanceof ArrayToken){
264                return true;
265        }
266        return false;
267    }
268    
269    public static void main(String[] args) throws IllegalActionException {
270        RecordToken token = new RecordToken("{a = {1,2,3}, b = {4,5,6}}");
271        String value = getValue(token, 1, 2);
272        log.debug(value);
273    }
274
275}