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 018package org.apache.commons.jxpath.ri; 019 020import org.apache.commons.jxpath.Pointer; 021import org.apache.commons.jxpath.ri.model.NodePointer; 022import org.apache.commons.jxpath.ri.model.VariablePointer; 023 024/** 025 * Type conversions, XPath style. 026 */ 027public class InfoSetUtil { 028 029 private static final Double ZERO = Double.valueOf(0); 030 private static final Double ONE = Double.valueOf(1); 031 private static final Double NOT_A_NUMBER = Double.valueOf(Double.NaN); 032 033 /** 034 * Converts the supplied object to boolean. 035 * 036 * @param object to convert 037 * @return boolean 038 */ 039 public static boolean booleanValue(final Object object) { 040 if (object instanceof Number) { 041 final double value = ((Number) object).doubleValue(); 042 final int negZero = -0; 043 return value != 0 && value != negZero && !Double.isNaN(value); 044 } 045 if (object instanceof Boolean) { 046 return ((Boolean) object).booleanValue(); 047 } 048 if (object instanceof EvalContext) { 049 final EvalContext ctx = (EvalContext) object; 050 final Pointer ptr = ctx.getSingleNodePointer(); 051 return ptr != null && booleanValue(ptr); 052 } 053 if (object instanceof String) { 054 return ((String) object).length() != 0; 055 } 056 if (object instanceof NodePointer) { 057 NodePointer pointer = (NodePointer) object; 058 if (pointer instanceof VariablePointer) { 059 return booleanValue(pointer.getNode()); 060 } 061 pointer = pointer.getValuePointer(); 062 return pointer.isActual(); 063 } 064 return object != null; 065 } 066 067 /** 068 * Converts the supplied object to double. 069 * 070 * @param object to convert 071 * @return double 072 */ 073 public static double doubleValue(final Object object) { 074 if (object instanceof Number) { 075 return ((Number) object).doubleValue(); 076 } 077 if (object instanceof Boolean) { 078 return ((Boolean) object).booleanValue() ? 0.0 : 1.0; 079 } 080 if (object instanceof String) { 081 if (object.equals("")) { 082 return 0.0; 083 } 084 try { 085 return Double.parseDouble((String) object); 086 } catch (final NumberFormatException ex) { 087 return Double.NaN; 088 } 089 } 090 if (object instanceof NodePointer) { 091 return doubleValue(((NodePointer) object).getValue()); 092 } 093 if (object instanceof EvalContext) { 094 final EvalContext ctx = (EvalContext) object; 095 final Pointer ptr = ctx.getSingleNodePointer(); 096 return ptr == null ? Double.NaN : doubleValue(ptr); 097 } 098 return doubleValue(stringValue(object)); 099 } 100 101 /** 102 * Converts the supplied object to Number. 103 * 104 * @param object to convert 105 * @return Number result 106 */ 107 public static Number number(final Object object) { 108 if (object instanceof Number) { 109 return (Number) object; 110 } 111 if (object instanceof Boolean) { 112 return ((Boolean) object).booleanValue() ? ONE : ZERO; 113 } 114 if (object instanceof String) { 115 try { 116 return Double.valueOf((String) object); 117 } catch (final NumberFormatException ex) { 118 return NOT_A_NUMBER; 119 } 120 } 121 if (object instanceof EvalContext) { 122 final EvalContext ctx = (EvalContext) object; 123 final Pointer ptr = ctx.getSingleNodePointer(); 124 return ptr == null ? NOT_A_NUMBER : number(ptr); 125 } 126 if (object instanceof NodePointer) { 127 return number(((NodePointer) object).getValue()); 128 } 129 return number(stringValue(object)); 130 } 131 132 /** 133 * Converts the supplied object to String. 134 * 135 * @param object to convert 136 * @return String value 137 */ 138 public static String stringValue(final Object object) { 139 if (object instanceof String) { 140 return (String) object; 141 } 142 if (object instanceof Number) { 143 final double d = ((Number) object).doubleValue(); 144 final long l = ((Number) object).longValue(); 145 return d == l ? String.valueOf(l) : String.valueOf(d); 146 } 147 if (object instanceof Boolean) { 148 return ((Boolean) object).booleanValue() ? "true" : "false"; 149 } 150 if (object == null) { 151 return ""; 152 } 153 if (object instanceof NodePointer) { 154 return stringValue(((NodePointer) object).getValue()); 155 } 156 if (object instanceof EvalContext) { 157 final EvalContext ctx = (EvalContext) object; 158 final Pointer ptr = ctx.getSingleNodePointer(); 159 return ptr == null ? "" : stringValue(ptr); 160 } 161 return String.valueOf(object); 162 } 163 164 /** 165 * Constructs a new instance. 166 * 167 * @deprecated Will be private in the next major version. 168 */ 169 @Deprecated 170 public InfoSetUtil() { 171 // empty 172 } 173}