Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/tripi/asp/Types.java


1   /**
2    * ArrowHead ASP Server 
3    * This is a source file for the ArrowHead ASP Server - an 100% Java
4    * VBScript interpreter and ASP server.
5    *
6    * For more information, see http://www.tripi.com/arrowhead
7    *
8    * Copyright (C) 2002  Terence Haddock
9    *
10   * This program is free software; you can redistribute it and/or modify
11   * it under the terms of the GNU General Public License as published by
12   * the Free Software Foundation; either version 2 of the License, or
13   * (at your option) any later version.
14   *
15   * This program is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   * GNU General Public License for more details.
19   *
20   * You should have received a copy of the GNU General Public License
21   * along with this program; if not, write to the Free Software
22   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23   *
24   */
25  package com.tripi.asp;
26  
27  import java.util.Date;
28  import java.util.Enumeration;
29  import java.util.Vector;
30  
31  import jregex.Pattern;
32  import jregex.Replacer;
33  
34  import org.apache.log4j.Category;
35  
36  /**
37   * The Types class contains utilities for conversion between data types.
38   * 
39   * @author Terence Haddock
40   * @version 0.9
41   */
42  public class Types
43  {
44      /** Debugging instance */
45      static private final Category DBG = Category.getInstance(Types.class);
46  
47      /**
48       * Coerces a data type into an Integer type.
49       * <ul>
50       * <li><i>null</i> = 0
51       * <li><i>undefined</i> = 0
52       * <li><i>Integer</i> = self
53       * <li><i>Double</i> = Cast to integer
54       * <li><i>String</i> = Parsed to integer, errors are passed through
55       * <li>Everything else causes a AspCastException
56       * </ul>
57       *
58       * @param obj Object to cast
59       * @return Integer representation of the cast.
60       * @throws AspException if an error occurs.
61       */
62      static public Integer coerceToInteger(Object obj) throws AspException
63      {
64          if (obj instanceof SimpleReference)
65          {
66              return coerceToInteger(((SimpleReference)obj).getValue());
67          } else
68          if (obj == null || obj instanceof NullNode ||
69              obj instanceof UndefinedValueNode)
70          {
71              return new Integer(0);
72          } else if (obj instanceof Integer)
73          {
74              return (Integer)obj;
75          } else if (obj instanceof Double)
76          {
77              return new Integer((int)((Double)obj).doubleValue());
78          } else if (obj instanceof Long)
79          {
80              return new Integer((int)((Long)obj).doubleValue());
81          } else if (obj instanceof Short)
82          {
83              return new Integer((int)((Short)obj).doubleValue());
84          } else if (obj instanceof Boolean)
85          {
86              boolean boolValue = ((Boolean)obj).booleanValue();
87              if (boolValue) return new Integer(-1);
88              return new Integer(0);
89          } else if (obj instanceof String)
90          {
91              String strValue = ((String)obj).trim();
92              if (strValue.equals("")) return new Integer(0);
93              try {
94                  return new Integer(strValue);
95              } catch (NumberFormatException ex) {
96                  throw new AspCastException(ex.toString());
97              }
98          } else {
99              throw new AspCastException(obj.getClass().toString());
100         }
101     }
102 
103     /**
104      * Coerces an object to a string.
105      * <ul>
106      * <li><i>null</i> = ""
107      * <li><i>undefined</i> = ""
108      * <li><i>String</i> = self
109      * <li><i>Integer</i> = cast to string
110      * <li><i>Boolean</i> = cast to "true"/"false"
111      * </ul>
112      *
113      * @param obj Object to cast to string.
114      * @return Object casted to string
115      * @throws AspException is a casting error occurs.
116      */
117     static public String coerceToString(Object obj) throws AspException
118     {
119         if (obj instanceof SimpleReference)
120         {
121             return coerceToString(((SimpleReference)obj).getValue());
122         } else
123         if (obj == null || obj instanceof NullNode ||
124             obj instanceof UndefinedValueNode)
125         {
126             return "";
127         } else if (obj instanceof String)
128         {
129             return (String)obj;
130         } else if (obj instanceof Integer)
131         {
132             return obj.toString();
133         } else if (obj instanceof Boolean)
134         {
135             Boolean b = (Boolean)obj;
136             if (b.booleanValue()) return "True";
137                 return "False";
138         } else if (obj instanceof Double)
139         {
140             /* If a double value contains an integer number, do not print
141                decimal places. */
142             Double doub = (Double)obj;
143             if (DBG.isDebugEnabled())
144             {
145                 DBG.debug("int value: " + doub.intValue());
146                 DBG.debug("doub value: " + doub.doubleValue());
147             }
148             if (doub.intValue() == doub.doubleValue())
149                 return "" + doub.intValue();
150             return doub.toString();
151         } else if (obj instanceof AspDate)
152         {
153             AspDate date = (AspDate)obj;
154             return date.toString();
155         } else if (obj instanceof JavaObjectNode)
156         {
157             return coerceToString(((JavaObjectNode)obj).
158                     getSubObject());
159         } else {
160             //throw new AspCastException(obj.getClass().toString());
161             return obj.toString();
162         }
163     }
164 
165     /**
166      * Converts a data object to a boolean type.
167      * <ul>
168      * <li><i>null</i> = false
169      * <li><i>undefined</i> = false
170      * <li><i>Boolean</i> = self
171      * </ul>
172      *
173      * @param obj Object to cast.
174      * @return boolean value of object.
175      * @throws AspException if exception occurs.
176      */
177     static Boolean coerceToBoolean(Object obj) throws AspException
178     {
179         if (DBG.isDebugEnabled()) {
180             DBG.debug("coerceToBoolean: " + obj);
181         }
182         if (obj instanceof SimpleReference)
183         {
184             return coerceToBoolean(((SimpleReference)obj).getValue());
185         } else
186         if (obj == null || obj instanceof NullNode ||
187                 obj instanceof UndefinedValueNode) {
188             return new Boolean(false);
189         } else if (obj instanceof Boolean)
190         {
191             return (Boolean)obj;
192         } else if (obj instanceof String)
193         {
194             String str = (String)obj;
195             if (str.equalsIgnoreCase("true"))
196                 return new Boolean(true);
197             else if (str.equalsIgnoreCase("false"))
198                 return new Boolean(false);
199             else 
200                 return new Boolean(coerceToInteger(obj).intValue() != 0);
201         } else {
202             return new Boolean(coerceToInteger(obj).intValue() != 0);
203         }
204     }
205 
206     /**
207      * Casts an object to a double value.
208      * <ul>
209      * <li><i>null</i> - 0.0
210      * <li><i>undefined</i> - 0.0
211      * <li><i>Double</i> - self
212      * <li><i>Integer</i> - Casted to double
213      * <li><i>String</i> - Parsed to double
214      * </ul>
215      *
216      * @param obj Object to cast to double.
217      * @return obj as a double value.
218      * @throws AspException if an error occurs.
219      */
220     static Double coerceToDouble(Object obj) throws AspException
221     {
222         if (obj instanceof SimpleReference)
223         {
224             return coerceToDouble(((SimpleReference)obj).getValue());
225         } else
226         if (obj == null || obj instanceof NullNode)
227         {
228             throw new AspCastException("NULL");
229         } else if (obj instanceof UndefinedValueNode)
230         {
231             return new Double(0);
232         } else
233         if (obj instanceof Double)
234         {
235             return (Double)obj;
236         } else if (obj instanceof Integer)
237         {
238             return new Double((double)((Integer)obj).intValue());
239         } else if (obj instanceof Long)
240         {
241             return new Double((double)((Long)obj).intValue());
242         } else if (obj instanceof Short)
243         {
244             return new Double((double)((Short)obj).intValue());
245         } else if (obj instanceof String)
246         {
247             try {
248                 String str = (String)obj;
249                 if (str.indexOf(",") != -1)
250                 {
251                     /* Have to ignore commas */
252                     final Pattern p = new Pattern(",");
253                     /* XXX It would be nice to make Replacer final, but there is no
254                       mention of the thread safely of replacer */
255                     Replacer r = p.replacer("");   
256                     str = r.replace((String)obj);
257                 }
258                 return new Double(str);
259             } catch (NumberFormatException ex) {
260                 throw new AspCastException(ex.toString());
261             }
262         } else if (obj instanceof Boolean) {
263             Boolean b = (Boolean)obj;
264             if (b.booleanValue()) return new Double(-1);
265                 return new Double(0);
266         } else {
267             if (DBG.isDebugEnabled()) {
268                 DBG.debug("Cast Exception for object: " + obj);
269             }
270             throw new AspCastException(obj.getClass().toString());
271         }
272     }
273 
274     /**
275      * Coerces a data value to a Date value.
276      * <ul>
277      * <li><i>Date</i> - Self
278      * </ul>
279      *
280      * @param obj Object to convert to date.
281      * @return obj casted to a date value
282      * @throws AspException if the type cannot be casted.
283      */
284     static AspDate coerceToDate(Object obj) throws AspException
285     {
286         if (obj instanceof SimpleReference)
287         {
288             return coerceToDate(((SimpleReference)obj).getValue());
289         } else if (obj instanceof AspDate)
290         {
291             return (AspDate)obj;
292         } else if (obj instanceof Date)
293         {
294             return new AspDate((Date)obj);
295         } else {
296             String objStr = coerceToString(obj).trim();
297             return new AspDate(objStr);
298         }
299     }
300 
301     /**
302      * Coerces an object to a "node".
303      * All of the known base types (Integer, Boolean, Double, String)
304      * are left as-is, but other Java objects are wrapped into    
305      * a JavaObjectNode-type class to handle ASP-&gt;Java calls.
306      * <ul>
307      * <li><i>null</i> - null
308      * <li><i>Node</i> - self
309      * <li><i>Double</i> - self
310      * <li><i>Integer</i> - self
311      * <li><i>Boolean</i> - self
312      * <li><i>Byte</i> - self
313      * <li><i>String</i> - self
314      * <li><i>SimpleMap + SimpleReference</i> - Wrapped in a JavaReferenceMapNode
315      * <li><i>SimpleMap</i> - Wrapped in a JavaMapNode
316      * <li><i>SimpleReference</i> - Wrapped in a JavaReferenceNode
317      * <li>Other - Wrapped in a JavaObjectNode
318      * </ul>
319      *
320      * @param obj Object to map
321      * @return Node object, or base type.
322      * @throws AspException if a casting error occurs
323      */
324     static Object coerceToNode(Object obj) throws AspException
325     {
326         if (DBG.isDebugEnabled())
327             DBG.debug("coerceToNode: " + obj);
328         if (obj == null) {
329             if (DBG.isDebugEnabled())
330                 DBG.debug("=null");
331             return Constants.undefinedValueNode;
332         } else if (obj instanceof Node) {
333             if (DBG.isDebugEnabled())
334                 DBG.debug("=Node");
335             return obj;
336         } else if (obj instanceof Double) {
337             if (DBG.isDebugEnabled())
338                 DBG.debug("=Double");
339             return obj;
340         } else if (obj instanceof Integer) {
341             if (DBG.isDebugEnabled())
342                 DBG.debug("=Integer");
343             return obj;
344         } else if (obj instanceof Long) {
345             if (DBG.isDebugEnabled())
346                 DBG.debug("=Long");
347             return obj;
348         } else if (obj instanceof Boolean) {
349             if (DBG.isDebugEnabled())
350                 DBG.debug("=Boolean");
351             return obj;
352         } else if (obj instanceof Short) {
353             if (DBG.isDebugEnabled())
354                 DBG.debug("=Short");
355             return obj;
356         } else if (obj instanceof Byte) {
357             return new Integer(((Byte)obj).byteValue());
358         } else if (obj instanceof String) {
359             if (DBG.isDebugEnabled())
360                 DBG.debug("=String");
361             return obj;
362         // XXX Problem with objects like java.sql.Timestamp
363         //} else if (obj instanceof java.util.Date) {
364         //      return new AspDate((java.util.Date)obj);
365         } else if (obj instanceof SimpleMap) {
366             if (obj instanceof SimpleReference) {
367                 if (DBG.isDebugEnabled())
368                     DBG.debug("=ObjectReferenceMap(" +
369                         obj.toString() + ")");
370                 return new JavaReferenceMapNode(obj);
371             }
372             if (DBG.isDebugEnabled())
373                 DBG.debug("=ObjectMap(" + obj.toString() + ")");
374             return new JavaMapNode((SimpleMap)obj);
375         } else if (obj instanceof SimpleReference) {
376             if (DBG.isDebugEnabled())
377                 DBG.debug("=ObjectReference(" + obj.toString() + ")");
378             return new JavaReferenceNode((SimpleReference)obj);
379         } else {
380             if (DBG.isDebugEnabled())
381                 DBG.debug("=Object(" + obj.toString() + ")");
382             /* Test for character array */
383             if (obj.getClass().isArray())
384             {
385                 if (obj.getClass().getComponentType() == char.class) {
386                     return new PackedCharArrayNode((char[])obj);
387                 }
388                 else if (obj.getClass().getComponentType() == byte.class) {
389                     return new PackedByteArrayNode((byte[])obj);
390                 }
391             }
392             return new JavaObjectNode(obj);
393         }
394     }
395 
396     /**
397      * Coerce a type to a SimpleMap object.
398      * @param obj Object to coerce.
399      * @return SimpleMap object.
400      */
401     //public static SimpleMap coerceToMap(Object obj) throws AspException
402     //{
403     //    while (obj instanceof SimpleReference && 
404     //        !(obj instanceof SimpleMap))
405     //    {
406     //        if (DBG.isDebugEnabled()) DBG.debug("Dereferencing: " 
407     //                + obj);
408     //        obj = ((SimpleReference)obj).getValue();
409     //    }
410     //    if (obj instanceof SimpleMap) return (SimpleMap)obj;
411     //    throw new AspCastException("Map");
412     //}
413 
414     /**
415      * Obtains an integer value from a hex string line &amp;FF.
416      * @param str String to convert
417      * @return Integer value of string
418      */
419     static public Integer integerFromHex(String str)
420     {
421         return new Integer(Integer.parseInt(str.substring(2),16));
422     }
423 
424     /**
425      * Determines if this object is a number.
426      * @param obj Object to test
427      * @return <b>true</b> if this object is a number, <b>false</b> otherwise.
428      */
429     static public boolean isNumber(Object obj)
430         throws AspException
431     {
432         Object deref = dereference(obj);
433         if (deref instanceof Integer) return true;
434         if (deref instanceof Double) return true;
435         if (deref instanceof Long) return true;
436         return false;
437     }
438 
439     /**
440      * Derefernces the given object. If the object is a SimpleReference
441      * object, it will dereference it, and keep dereferencing it until
442      * a non-SimpleReference object is found.
443      * @param obj Object to dereference.    
444      * @return Non-SimpleReference object.
445      */
446     public static Object dereference(Object obj) throws AspException
447     {
448         while (obj instanceof SimpleReference) {
449             if (DBG.isDebugEnabled())
450                 DBG.debug("Dereferencing: " + obj);
451             obj = ((SimpleReference)obj).getValue();
452         }
453         return obj;
454     }
455 
456     /**
457      * This function tests an object to see if it is a date object.
458      * @param testObject object to test
459      * @return <b>true</b> if this is a date object, <b>false</b> otherwise.
460      */
461     public static boolean isDate(Object testObject)
462     {
463         return testObject instanceof AspDate;
464     }
465 }