001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.util; 029 030import java.io.ByteArrayInputStream; 031import java.io.ByteArrayOutputStream; 032import java.io.IOException; 033import java.io.ObjectInputStream; 034import java.io.ObjectOutputStream; 035import java.util.Date; 036import java.util.Hashtable; 037import java.util.Iterator; 038import java.util.Map; 039import java.util.Map.Entry; 040 041import org.apache.commons.codec.binary.Base64; 042 043/** 044 * 045 * Utilities to handle basic data types.<p> 046 * 047 * @since 6.5.6 048 */ 049public final class CmsDataTypeUtil { 050 051 /** 052 * Hides the public constructor.<p> 053 */ 054 private CmsDataTypeUtil() { 055 056 // noop 057 } 058 059 /** 060 * Returns the deserialized (if needed) object.<p> 061 * 062 * @param data the data to deserialize 063 * @param type the data type 064 * 065 * @return the deserialized object 066 * 067 * @throws IOException if the inputstream fails 068 * @throws ClassNotFoundException if the serialized object fails 069 */ 070 public static Object dataDeserialize(byte[] data, String type) throws IOException, ClassNotFoundException { 071 072 // check the type of the stored data 073 Class<?> clazz = Class.forName(type); 074 075 if (isParseable(clazz)) { 076 // this is parseable data 077 return parse(new String(data), clazz); 078 } 079 080 // this is a serialized object 081 ByteArrayInputStream bin = new ByteArrayInputStream(data); 082 ObjectInputStream oin = new ObjectInputStream(bin); 083 return oin.readObject(); 084 } 085 086 /** 087 * Returns a ready to export string representation of the given object.<p> 088 * 089 * For not parseable objects, base64 encoded string with the serialized object is generated.<p> 090 * 091 * @param data the object to export 092 * 093 * @return the string representation 094 * 095 * @throws IOException if something goes wrong 096 */ 097 public static String dataExport(Object data) throws IOException { 098 099 if (CmsDataTypeUtil.isParseable(data.getClass())) { 100 return CmsDataTypeUtil.format(data); 101 } 102 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 103 ObjectOutputStream oout = new ObjectOutputStream(bout); 104 oout.writeObject(data); 105 oout.close(); 106 return new String(Base64.encodeBase64(bout.toByteArray())); 107 } 108 109 /** 110 * Returns the import data object.<p> 111 * 112 * @param value the exported value 113 * @param type the expected data type 114 * 115 * @return the import data object 116 * 117 * @throws ClassNotFoundException if something goes wrong 118 * @throws IOException if something goes wrong 119 */ 120 public static Object dataImport(String value, String type) throws ClassNotFoundException, IOException { 121 122 Class<?> clazz = Class.forName(type); 123 if (CmsDataTypeUtil.isParseable(clazz)) { 124 return CmsDataTypeUtil.parse(value, clazz); 125 } 126 byte[] data = Base64.decodeBase64(value.getBytes()); 127 return dataDeserialize(data, type); 128 } 129 130 /** 131 * Serialize the given data.<p> 132 * 133 * @param data the data to serialize 134 * 135 * @return byte[] the serailized data 136 * 137 * @throws IOException if something goes wrong 138 */ 139 public static byte[] dataSerialize(Object data) throws IOException { 140 141 if (isParseable(data.getClass())) { 142 return format(data).getBytes(); 143 } 144 145 // serialize the data 146 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 147 ObjectOutputStream oout = new ObjectOutputStream(bout); 148 Object obj = data; 149 if (data instanceof Map) { 150 Hashtable<Object, Object> ht = new Hashtable<Object, Object>(); 151 @SuppressWarnings("unchecked") 152 Iterator<Entry<Object, Object>> it = ((Map<Object, Object>)data).entrySet().iterator(); 153 while (it.hasNext()) { 154 Entry<Object, Object> entry = it.next(); 155 if ((entry.getKey() != null) && (entry.getValue() != null)) { 156 ht.put(entry.getKey(), entry.getValue()); 157 } 158 } 159 obj = ht; 160 } 161 oout.writeObject(obj); 162 oout.close(); 163 return bout.toByteArray(); 164 } 165 166 /** 167 * Formats the given data into a string value.<p> 168 * 169 * @param data the data to format 170 * 171 * @return a string representation of the given data 172 */ 173 public static String format(boolean data) { 174 175 return String.valueOf(data); 176 } 177 178 /** 179 * Formats the given data into a string value.<p> 180 * 181 * @param data the data to format 182 * 183 * @return a string representation of the given data 184 */ 185 public static String format(byte data) { 186 187 return Byte.valueOf(data).toString(); 188 } 189 190 /** 191 * Formats the given data into a string value.<p> 192 * 193 * @param data the data to format 194 * 195 * @return a string representation of the given data 196 */ 197 public static String format(char data) { 198 199 return Character.valueOf(data).toString(); 200 } 201 202 /** 203 * Formats the given data into a string value.<p> 204 * 205 * @param data the data to format 206 * 207 * @return a string representation of the given data 208 */ 209 public static String format(Date data) { 210 211 return Long.valueOf(data.getTime()).toString(); 212 } 213 214 /** 215 * Formats the given data into a string value.<p> 216 * 217 * @param data the data to format 218 * 219 * @return a string representation of the given data 220 */ 221 public static String format(double data) { 222 223 return Double.valueOf(data).toString(); 224 } 225 226 /** 227 * Formats the given data into a string value.<p> 228 * 229 * @param data the data to format 230 * 231 * @return a string representation of the given data 232 */ 233 public static String format(float data) { 234 235 return Float.valueOf(data).toString(); 236 } 237 238 /** 239 * Formats the given data into a string value.<p> 240 * 241 * @param data the data to format 242 * 243 * @return a string representation of the given data 244 */ 245 public static String format(int data) { 246 247 return Integer.valueOf(data).toString(); 248 } 249 250 /** 251 * Formats the given data into a string value.<p> 252 * 253 * @param data the data to format 254 * 255 * @return a string representation of the given data 256 */ 257 public static String format(long data) { 258 259 return Long.valueOf(data).toString(); 260 } 261 262 /** 263 * Formats the given data into a string value depending on the data type.<p> 264 * 265 * @param data the data to format 266 * 267 * @return a string representation of the given data 268 */ 269 public static String format(Object data) { 270 271 if (data == null) { 272 return null; 273 } 274 Class<?> clazz = data.getClass(); 275 if (clazz.equals(Date.class)) { 276 return format(((Date)data).getTime()); 277 } 278 return data.toString(); 279 } 280 281 /** 282 * Formats the given data into a string value.<p> 283 * 284 * @param data the data to format 285 * 286 * @return a string representation of the given data 287 */ 288 public static String format(short data) { 289 290 return Short.valueOf(data).toString(); 291 } 292 293 /** 294 * Checks if the given class is representable as a string.<p> 295 * 296 * @param clazz the type to test 297 * 298 * @return if the given class is representable as a string 299 */ 300 public static boolean isParseable(Class<?> clazz) { 301 302 boolean parseable = false; 303 parseable = parseable || (clazz.equals(byte.class)); 304 parseable = parseable || (clazz.equals(Byte.class)); 305 parseable = parseable || (clazz.equals(short.class)); 306 parseable = parseable || (clazz.equals(Short.class)); 307 parseable = parseable || (clazz.equals(int.class)); 308 parseable = parseable || (clazz.equals(Integer.class)); 309 parseable = parseable || (clazz.equals(long.class)); 310 parseable = parseable || (clazz.equals(Long.class)); 311 parseable = parseable || (clazz.equals(float.class)); 312 parseable = parseable || (clazz.equals(Float.class)); 313 parseable = parseable || (clazz.equals(double.class)); 314 parseable = parseable || (clazz.equals(Double.class)); 315 parseable = parseable || (clazz.equals(boolean.class)); 316 parseable = parseable || (clazz.equals(Boolean.class)); 317 parseable = parseable || (clazz.equals(char.class)); 318 parseable = parseable || (clazz.equals(Character.class)); 319 parseable = parseable || (clazz.equals(String.class)); 320 parseable = parseable || (clazz.equals(Date.class)); 321 parseable = parseable || (clazz.equals(CmsUUID.class)); 322 return parseable; 323 } 324 325 /** 326 * Converts Number to int.<p> 327 * 328 * @param n the number object 329 * 330 * @return Number.inValue(), 0 - if the parameter is null 331 */ 332 public static int numberToInt(Number n) { 333 334 return (n == null ? 0 : n.intValue()); 335 } 336 337 /** 338 * Returns an object of the given type (or a wrapper for base types) 339 * with the value of the given data.<p> 340 * 341 * @param data the data to parse 342 * @param clazz the data type 343 * 344 * @return the value of the given data 345 */ 346 public static Object parse(String data, Class<?> clazz) { 347 348 if (data == null) { 349 return null; 350 } 351 if (clazz.equals(byte.class) || clazz.equals(Byte.class)) { 352 return parseByte(data); 353 } 354 if (clazz.equals(short.class) || clazz.equals(Short.class)) { 355 return parseShort(data); 356 } 357 if (clazz.equals(long.class) || clazz.equals(Long.class)) { 358 return parseLong(data); 359 } 360 if (clazz.equals(int.class) || clazz.equals(Integer.class)) { 361 return parseInt(data); 362 } 363 if (clazz.equals(float.class) || clazz.equals(Float.class)) { 364 return parseFloat(data); 365 } 366 if (clazz.equals(double.class) || clazz.equals(Double.class)) { 367 return parseDouble(data); 368 } 369 if (clazz.equals(boolean.class) || clazz.equals(Boolean.class)) { 370 return parseBoolean(data); 371 } 372 if (clazz.equals(char.class) || clazz.equals(Character.class)) { 373 return parseChar(data); 374 } 375 if (clazz.equals(CmsUUID.class)) { 376 return parseUUID(data); 377 } 378 if (clazz.equals(Date.class)) { 379 return parseDate(data); 380 } 381 return data; 382 } 383 384 /** 385 * Parses the given data as a boolean.<p> 386 * 387 * @param data the data to parse 388 * 389 * @return the converted data value 390 */ 391 public static Boolean parseBoolean(String data) { 392 393 return Boolean.valueOf(data); 394 } 395 396 /** 397 * Parses the given data as a byte.<p> 398 * 399 * @param data the data to parse 400 * 401 * @return the converted data value 402 */ 403 public static Byte parseByte(String data) { 404 405 return Byte.valueOf(data); 406 } 407 408 /** 409 * Parses the given data as a char.<p> 410 * 411 * @param data the data to parse 412 * 413 * @return the converted data value 414 */ 415 public static Character parseChar(String data) { 416 417 return Character.valueOf(data.charAt(0)); 418 } 419 420 /** 421 * Parses the given data as a date.<p> 422 * 423 * @param data the data to parse 424 * 425 * @return the converted data value 426 */ 427 public static Date parseDate(String data) { 428 429 return new Date(parseLong(data).longValue()); 430 } 431 432 /** 433 * Parses the given data as a double.<p> 434 * 435 * @param data the data to parse 436 * 437 * @return the converted data value 438 */ 439 public static Double parseDouble(String data) { 440 441 return Double.valueOf(data); 442 } 443 444 /** 445 * Parses the given data as a float.<p> 446 * 447 * @param data the data to parse 448 * 449 * @return the converted data value 450 */ 451 public static Float parseFloat(String data) { 452 453 return Float.valueOf(data); 454 } 455 456 /** 457 * Parses the given data as an integer.<p> 458 * 459 * @param data the data to parse 460 * 461 * @return the converted data value 462 */ 463 public static Integer parseInt(String data) { 464 465 return Integer.valueOf(data); 466 } 467 468 /** 469 * Parses the given data as a long.<p> 470 * 471 * @param data the data to parse 472 * 473 * @return the converted data value 474 */ 475 public static Long parseLong(String data) { 476 477 return Long.valueOf(data); 478 } 479 480 /** 481 * Parses the given data as a short.<p> 482 * 483 * @param data the data to parse 484 * 485 * @return the converted data value 486 */ 487 public static Short parseShort(String data) { 488 489 return Short.valueOf(data); 490 } 491 492 /** 493 * Parses the given data as an uuid.<p> 494 * 495 * @param data the data to parse 496 * 497 * @return the converted data value 498 */ 499 public static CmsUUID parseUUID(String data) { 500 501 return new CmsUUID(data); 502 } 503}