1/* 2 * Copyright (C) 2010 Google Inc. 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 17package com.google.clearsilver.jsilver.data; 18 19 20/** 21 * Static methods for converting stuff in a ClearSilver compatible way. 22 */ 23public class TypeConverter { 24 private TypeConverter() {} 25 26 private static final String ZERO = "0"; 27 private static final String ONE = "1"; 28 29 /** 30 * Determines if the given data node exists in a ClearSilver compatible way. 31 */ 32 public static boolean exists(Data data) { 33 return data != null && data.getValue() != null; 34 } 35 36 /** 37 * Helper method to safely convert an arbitrary data instance (including null) into a valid 38 * (non-null) string representation. 39 */ 40 public static String asString(Data data) { 41 // Non-existent variables become the empty string 42 // (the data instance will return null to us) 43 String value = data != null ? data.getValue() : null; 44 return value != null ? value : ""; 45 } 46 47 /** 48 * Parses a non-null string in a ClearSilver compatible way. 49 * 50 * The is the underlying parsing function which can fail for badly formatted strings. It is really 51 * important that anyone doing parsing of strings calls this function (rather than doing it 52 * themselves). 53 * 54 * This is an area where JSilver and ClearSilver have some notable differences. ClearSilver relies 55 * on the template compiler to parse strings in the template and a different parser at runtime for 56 * HDF values. JSilver uses the same code for both cases. 57 * 58 * In ClearSilver HDF: Numbers are parsed sequentially and partial results are returned when an 59 * invalid character is reached. This means that {@code "123abc"} parses to {@code 123}. 60 * 61 * Additionally, ClearSilver doesn't do hex in HDF values, so {@code "a.b=0x123"} will just 62 * resolve to {@code 0}. 63 * 64 * In ClearSilver templates: Hex is supported, including negative values. 65 * 66 * In JSilver: A string must be a complete, valid numeric value for parsing. This means {@code 67 * "123abc"} is invalid and will default to {@code 0}. 68 * 69 * In JSilver: Positive hex values are supported for both HDF and templates but negative values 70 * aren't. This means a template containing something like "<?cs if:foo == -0xff ?>" will parse 71 * correctly but fail to render. 72 * 73 * @throws NumberFormatException is the string is badly formatted 74 */ 75 public static int parseNumber(String value) throws NumberFormatException { 76 // NOTE: This is likely to be one of the areas we will want to optimize 77 // for speed eventually. 78 if (value.startsWith("0x") || value.startsWith("0X")) { 79 return Integer.parseInt(value.substring(2), 16); 80 } else { 81 return Integer.parseInt(value); 82 } 83 } 84 85 /** 86 * Parses and returns the given string as an integer in a ClearSilver compatible way. 87 */ 88 public static int asNumber(String value) { 89 if (value == null || value.isEmpty()) { 90 return 0; 91 } 92 // fast detection for common constants to avoid parsing common values 93 // TODO: Maybe push this down into parseNumber ?? 94 if (value.equals(ONE)) { 95 return 1; 96 } 97 if (value.equals(ZERO)) { 98 return 0; 99 } 100 try { 101 return parseNumber(value); 102 } catch (NumberFormatException e) { 103 return 0; 104 } 105 } 106 107 /** 108 * Helper method to safely convert an arbitrary data instance (including null) into a valid 109 * integer representation. 110 */ 111 public static int asNumber(Data data) { 112 // Non-existent variables become zero 113 return data != null ? data.getIntValue() : 0; 114 } 115 116 /** 117 * Parses and returns the given string as a boolean in a ClearSilver compatible way. 118 */ 119 public static boolean asBoolean(String value) { 120 if (value == null || value.isEmpty()) { 121 return false; 122 } 123 // fast detection for common constants to avoid parsing common values 124 if (value.equals(ONE)) { 125 return true; 126 } 127 if (value.equals(ZERO)) { 128 return false; 129 } 130 131 // fast detection of any string not starting with '0' 132 if (value.charAt(0) != '0') { 133 return true; 134 } 135 136 try { 137 return parseNumber(value) != 0; 138 } catch (NumberFormatException e) { 139 // Unlike number parsing, we return a positive value when the 140 // string is badly formatted (it's what clearsilver does). 141 return true; 142 } 143 } 144 145 /** 146 * Helper method to safely convert an arbitrary data instance (including null) into a valid 147 * boolean representation. 148 */ 149 public static boolean asBoolean(Data data) { 150 // Non-existent variables become false 151 return data != null ? data.getBooleanValue() : false; 152 } 153} 154