001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.jxpath.ri;
018
019 import org.apache.commons.jxpath.Pointer;
020 import org.apache.commons.jxpath.ri.model.NodePointer;
021 import org.apache.commons.jxpath.ri.model.VariablePointer;
022
023 /**
024 * Type conversions, XPath style.
025 *
026 * @author Dmitri Plotnikov
027 * @version $Revision: 652845 $ $Date: 2008-05-02 12:46:46 -0500 (Fri, 02 May 2008) $
028 */
029 public class InfoSetUtil {
030
031 private static final Double ZERO = new Double(0);
032 private static final Double ONE = new Double(1);
033 private static final Double NOT_A_NUMBER = new Double(Double.NaN);
034
035 /**
036 * Converts the supplied object to String.
037 * @param object to convert
038 * @return String value
039 */
040 public static String stringValue(Object object) {
041 if (object instanceof String) {
042 return (String) object;
043 }
044 if (object instanceof Number) {
045 double d = ((Number) object).doubleValue();
046 long l = ((Number) object).longValue();
047 return d == l ? String.valueOf(l) : String.valueOf(d);
048 }
049 if (object instanceof Boolean) {
050 return ((Boolean) object).booleanValue() ? "true" : "false";
051 }
052 if (object == null) {
053 return "";
054 }
055 if (object instanceof NodePointer) {
056 return stringValue(((NodePointer) object).getValue());
057 }
058 if (object instanceof EvalContext) {
059 EvalContext ctx = (EvalContext) object;
060 Pointer ptr = ctx.getSingleNodePointer();
061 return ptr == null ? "" : stringValue(ptr);
062 }
063 return String.valueOf(object);
064 }
065
066 /**
067 * Converts the supplied object to Number.
068 * @param object to convert
069 * @return Number result
070 */
071 public static Number number(Object object) {
072 if (object instanceof Number) {
073 return (Number) object;
074 }
075 if (object instanceof Boolean) {
076 return ((Boolean) object).booleanValue() ? ONE : ZERO;
077 }
078 if (object instanceof String) {
079 try {
080 return new Double((String) object);
081 }
082 catch (NumberFormatException ex) {
083 return NOT_A_NUMBER;
084 }
085 }
086 if (object instanceof EvalContext) {
087 EvalContext ctx = (EvalContext) object;
088 Pointer ptr = ctx.getSingleNodePointer();
089 return ptr == null ? NOT_A_NUMBER : number(ptr);
090 }
091 if (object instanceof NodePointer) {
092 return number(((NodePointer) object).getValue());
093 }
094 return number(stringValue(object));
095 }
096
097 /**
098 * Converts the supplied object to double.
099 * @param object to convert
100 * @return double
101 */
102 public static double doubleValue(Object object) {
103 if (object instanceof Number) {
104 return ((Number) object).doubleValue();
105 }
106 if (object instanceof Boolean) {
107 return ((Boolean) object).booleanValue() ? 0.0 : 1.0;
108 }
109 if (object instanceof String) {
110 if (object.equals("")) {
111 return 0.0;
112 }
113 try {
114 return Double.parseDouble((String) object);
115 }
116 catch (NumberFormatException ex) {
117 return Double.NaN;
118 }
119 }
120 if (object instanceof NodePointer) {
121 return doubleValue(((NodePointer) object).getValue());
122 }
123 if (object instanceof EvalContext) {
124 EvalContext ctx = (EvalContext) object;
125 Pointer ptr = ctx.getSingleNodePointer();
126 return ptr == null ? Double.NaN : doubleValue(ptr);
127 }
128 return doubleValue(stringValue(object));
129 }
130
131 /**
132 * Converts the supplied object to boolean.
133 * @param object to convert
134 * @return boolean
135 */
136 public static boolean booleanValue(Object object) {
137 if (object instanceof Number) {
138 double value = ((Number) object).doubleValue();
139 final int negZero = -0;
140 return value != 0 && value != negZero && !Double.isNaN(value);
141 }
142 if (object instanceof Boolean) {
143 return ((Boolean) object).booleanValue();
144 }
145 if (object instanceof EvalContext) {
146 EvalContext ctx = (EvalContext) object;
147 Pointer ptr = ctx.getSingleNodePointer();
148 return ptr == null ? false : booleanValue(ptr);
149 }
150 if (object instanceof String) {
151 return ((String) object).length() != 0;
152 }
153 if (object instanceof NodePointer) {
154 NodePointer pointer = (NodePointer) object;
155 if (pointer instanceof VariablePointer) {
156 return booleanValue(pointer.getNode());
157 }
158 pointer = pointer.getValuePointer();
159 return pointer.isActual();
160 }
161 return object != null;
162 }
163 }