1   /*
2    * Copyright 1999-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jxpath.ri;
17  
18  import org.apache.commons.jxpath.Pointer;
19  import org.apache.commons.jxpath.ri.model.NodePointer;
20  
21  /***
22   * Type conversions, XPath style.
23   *
24   * @author Dmitri Plotnikov
25   * @version $Revision: 1.10 $ $Date: 2004/05/08 20:07:09 $
26   */
27  public class InfoSetUtil {
28  
29      private static final Double ZERO = new Double(0);
30      private static final Double ONE = new Double(1);
31      private static final Double NOT_A_NUMBER = new Double(Double.NaN);
32  
33  
34      /***
35       * Converts the supplied object to String
36       */
37      public static String stringValue(Object object) {
38          if (object instanceof String) {
39              return (String) object;
40          }
41          else if (object instanceof Number) {
42              double d = ((Number) object).doubleValue();
43              long l = ((Number) object).longValue();
44              if (d == l) {
45                  return String.valueOf(l);
46              }
47              return String.valueOf(d);
48          }
49          else if (object instanceof Boolean) {
50              return ((Boolean) object).booleanValue() ? "true" : "false";
51          }
52          else if (object == null) {
53              return "";
54          }
55          else if (object instanceof NodePointer) {
56              return stringValue(((NodePointer) object).getValue());
57          }
58          else if (object instanceof EvalContext) {
59              EvalContext ctx = (EvalContext) object;
60              Pointer ptr = ctx.getSingleNodePointer();
61              if (ptr != null) {
62                  return stringValue(ptr);
63              }
64              return "";
65          }
66          return String.valueOf(object);
67      }
68  
69      /***
70       * Converts the supplied object to Number
71       */
72      public static Number number(Object object) {
73          if (object instanceof Number) {
74              return (Number) object;
75          }
76          else if (object instanceof Boolean) {
77              return ((Boolean) object).booleanValue() ? ONE : ZERO;
78          }
79          else if (object instanceof String) {
80              Double value;
81              try {
82                  value = new Double((String) object);
83              }
84              catch (NumberFormatException ex) {
85                  value = NOT_A_NUMBER;
86              }
87              return value;
88          }
89          else if (object instanceof EvalContext) {
90              EvalContext ctx = (EvalContext) object;
91              Pointer ptr = ctx.getSingleNodePointer();
92              if (ptr != null) {
93                  return number(ptr);
94              }
95              return NOT_A_NUMBER;
96          }
97          else if (object instanceof NodePointer) {
98              return number(((NodePointer) object).getValue());
99          }
100         return number(stringValue(object));
101     }
102 
103     /***
104      * Converts the supplied object to double
105      */
106     public static double doubleValue(Object object) {
107         if (object instanceof Number) {
108             return ((Number) object).doubleValue();
109         }
110         else if (object instanceof Boolean) {
111             return ((Boolean) object).booleanValue() ? 0.0 : 1.0;
112         }
113         else if (object instanceof String) {
114             if (object.equals("")) {
115                 return 0.0;
116             }
117 
118             double value;
119             try {
120                 value = Double.parseDouble((String) object);
121             }
122             catch (NumberFormatException ex) {
123                 value = Double.NaN;
124             }
125             return value;
126         }
127         else if (object instanceof NodePointer) {
128             return doubleValue(((NodePointer) object).getValue());
129         }
130         else if (object instanceof EvalContext) {
131             EvalContext ctx = (EvalContext) object;
132             Pointer ptr = ctx.getSingleNodePointer();
133             if (ptr != null) {
134                 return doubleValue(ptr);
135             }
136             return Double.NaN;
137         }
138         return doubleValue(stringValue(object));
139     }
140 
141     /***
142      * Converts the supplied object to boolean
143      */
144     public static boolean booleanValue(Object object) {
145         if (object instanceof Number) {
146             double value = ((Number) object).doubleValue();
147             return value != 0 && value != -0 && !Double.isNaN(value);
148         }
149         else if (object instanceof Boolean) {
150             return ((Boolean) object).booleanValue();
151         }
152         else if (object instanceof EvalContext) {
153             EvalContext ctx = (EvalContext) object;
154             return ctx.nextSet() && ctx.nextNode();
155         }
156         else if (object instanceof String) {
157             return ((String) object).length() != 0;
158         }
159         else if (object instanceof NodePointer) {
160             return ((NodePointer) object).isActual();
161         }
162         else if (object == null) {
163             return false;
164         }
165         return true;
166     }
167 }