1 17 package org.alfresco.service.cmr.repository.datatype; 18 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.HashMap ; 22 import java.util.Map ; 23 24 import org.alfresco.service.cmr.dictionary.DataTypeDefinition; 25 import org.alfresco.service.cmr.dictionary.DictionaryException; 26 import org.alfresco.util.ParameterCheck; 27 28 29 37 public class TypeConverter 38 { 39 40 49 @SuppressWarnings ("unchecked") 50 public final Object convert(DataTypeDefinition propertyType, Object value) 51 { 52 ParameterCheck.mandatory("Property type definition", propertyType); 53 54 Class javaClass = null; 56 String javaClassName = propertyType.getJavaClassName(); 57 try 58 { 59 javaClass = Class.forName(javaClassName); 60 } 61 catch (ClassNotFoundException e) 62 { 63 throw new DictionaryException("Java class " + javaClassName + " of property type " + propertyType.getName() + " is invalid", e); 64 } 65 66 return convert(javaClass, value); 67 } 68 69 80 @SuppressWarnings ("unchecked") 81 public final <T> T convert(Class <T> c, Object value) 82 { 83 if(value == null) 84 { 85 return null; 86 } 87 88 if (c.isPrimitive()) 90 { 91 throw new TypeConversionException("Can not convert direct to primitive type " + c.getName()); 93 } 94 95 if (c.isInstance(value)) 97 { 98 return c.cast(value); 99 } 100 101 Converter converter = getConverter(value, c); 103 if (converter == null) 104 { 105 throw new TypeConversionException( 106 "There is no conversion registered for the value: \n" + 107 " value class: " + value.getClass().getName() + "\n" + 108 " to class: " + c.getName() + "\n" + 109 " value: " + value.toString()); 110 } 111 112 return (T) converter.convert(value); 113 } 114 115 125 @SuppressWarnings ("unchecked") 126 public final Collection convert(DataTypeDefinition propertyType, Collection values) 127 { 128 ParameterCheck.mandatory("Property type definition", propertyType); 129 130 Class javaClass = null; 132 String javaClassName = propertyType.getJavaClassName(); 133 try 134 { 135 javaClass = Class.forName(javaClassName); 136 } 137 catch (ClassNotFoundException e) 138 { 139 throw new DictionaryException("Java class " + javaClassName + " of property type " + propertyType.getName() + " is invalid", e); 140 } 141 142 return convert(javaClass, values); 143 } 144 145 155 public final <T> Collection <T> convert(Class <T> c, Collection values) 156 { 157 if(values == null) 158 { 159 return null; 160 } 161 162 Collection <T> converted = new ArrayList <T>(values.size()); 163 for (Object value : values) 164 { 165 converted.add(convert(c, value)); 166 } 167 168 return converted; 169 } 170 171 178 public final boolean booleanValue(Object value) 179 { 180 return convert(Boolean .class, value).booleanValue(); 181 } 182 183 190 public final char charValue(Object value) 191 { 192 return convert(Character .class, value).charValue(); 193 } 194 195 202 public final byte byteValue(Object value) 203 { 204 if (value instanceof Number ) 205 { 206 return ((Number ) value).byteValue(); 207 } 208 return convert(Byte .class, value).byteValue(); 209 } 210 211 218 public final short shortValue(Object value) 219 { 220 if (value instanceof Number ) 221 { 222 return ((Number ) value).shortValue(); 223 } 224 return convert(Short .class, value).shortValue(); 225 } 226 227 234 public final int intValue(Object value) 235 { 236 if (value instanceof Number ) 237 { 238 return ((Number ) value).intValue(); 239 } 240 return convert(Integer .class, value).intValue(); 241 } 242 243 250 public final long longValue(Object value) 251 { 252 if (value instanceof Number ) 253 { 254 return ((Number ) value).longValue(); 255 } 256 return convert(Long .class, value).longValue(); 257 } 258 259 266 public final float floatValue(Object value) 267 { 268 if (value instanceof Number ) 269 { 270 return ((Number ) value).floatValue(); 271 } 272 return convert(Float .class, value).floatValue(); 273 } 274 275 282 public final double doubleValue(Object value) 283 { 284 if (value instanceof Number ) 285 { 286 return ((Number ) value).doubleValue(); 287 } 288 return convert(Double .class, value).doubleValue(); 289 } 290 291 297 public final boolean isMultiValued(Object value) 298 { 299 return (value instanceof Collection ); 300 } 301 302 308 public final int size(Object value) 309 { 310 if (value instanceof Collection ) 311 { 312 return ((Collection ) value).size(); 313 } 314 else 315 { 316 return 1; 317 } 318 } 319 320 326 private final Collection createCollection(Object value) 327 { 328 Collection coll; 329 if (isMultiValued(value)) 330 { 331 coll = (Collection ) value; 332 } 333 else 334 { 335 ArrayList <Object > list = new ArrayList <Object >(1); 336 list.add(value); 337 coll = list; 338 } 339 return coll; 340 } 341 342 349 public final <T> Collection <T> getCollection(Class <T> c, Object value) 350 { 351 Collection coll = createCollection(value); 352 return convert(c, coll); 353 } 354 355 364 public final <F, T> void addConverter(Class <F> source, Class <T> destination, Converter<F, T> converter) 365 { 366 Map <Class , Converter> map = conversions.get(source); 367 if (map == null) 368 { 369 map = new HashMap <Class , Converter>(); 370 conversions.put(source, map); 371 } 372 map.put(destination, converter); 373 } 374 375 384 public final <F, I, T> Converter<F, T> addDynamicTwoStageConverter(Class <F> source, Class <I> intermediate, Class <T> destination) 385 { 386 Converter<F, T> converter = new TypeConverter.DynamicTwoStageConverter<F, I, T>(source, intermediate, destination); 387 addConverter(source, destination, converter); 388 return converter; 389 } 390 391 403 @SuppressWarnings ("unchecked") 404 public final <T> Converter getConverter(Object value, Class <T> dest) 405 { 406 Converter converter = null; 407 if (value == null) 408 { 409 return null; 410 } 411 412 Class valueClass = value.getClass(); 414 converter = getConverter(valueClass, dest); 415 if (converter != null) 416 { 417 return converter; 418 } 419 420 do 422 { 423 Class [] ifClasses = valueClass.getInterfaces(); 424 for (Class ifClass : ifClasses) 425 { 426 converter = getConverter(ifClass, dest); 427 if (converter != null) 428 { 429 return converter; 430 } 431 } 432 valueClass = valueClass.getSuperclass(); 433 } 434 while (valueClass != null); 435 436 return null; 437 } 438 439 448 public <F, T> Converter getConverter(Class <F> source, Class <T> dest) 449 { 450 Converter<?, ?> converter = null; 451 Class clazz = source; 452 do 453 { 454 Map <Class , Converter> map = conversions.get(clazz); 455 if (map == null) 456 { 457 continue; 458 } 459 converter = map.get(dest); 460 461 if (converter == null) 462 { 463 Converter<?, ?> first = map.get(Number .class); 465 Converter<?, ?> second = null; 466 if (first != null) 467 { 468 map = conversions.get(Number .class); 469 if (map != null) 470 { 471 second = map.get(dest); 472 } 473 } 474 if (second != null) 475 { 476 converter = new TwoStageConverter<F, Number , T>(first, second); 477 } 478 } 479 } 480 while ((converter == null) && ((clazz = clazz.getSuperclass()) != null)); 481 482 return converter; 483 } 484 485 488 private Map <Class , Map <Class , Converter>> conversions = new HashMap <Class , Map <Class , Converter>>(); 489 490 491 493 501 public interface Converter<F, T> 502 { 503 public T convert(F source); 504 } 505 506 515 public static class TwoStageConverter<F, I, T> implements Converter<F, T> 516 { 517 Converter first; 518 519 Converter second; 520 521 TwoStageConverter(Converter first, Converter second) 522 { 523 this.first = first; 524 this.second = second; 525 } 526 527 @SuppressWarnings ("unchecked") 528 public T convert(F source) 529 { 530 return (T) second.convert((I) first.convert(source)); 531 } 532 } 533 534 543 protected class DynamicTwoStageConverter<F, I, T> implements Converter<F, T> 544 { 545 Class <F> from; 546 Class <I> intermediate; 547 Class <T> to; 548 549 DynamicTwoStageConverter(Class <F> from, Class <I> intermediate, Class <T> to) 550 { 551 this.from = from; 552 this.intermediate = intermediate; 553 this.to = to; 554 } 555 556 559 public Class <F> getFrom() 560 { 561 return from; 562 } 563 564 567 public Class <I> getIntermediate() 568 { 569 return intermediate; 570 } 571 572 575 public Class <T> getTo() 576 { 577 return to; 578 } 579 580 @SuppressWarnings ("unchecked") 581 public T convert(F source) 582 { 583 Converter iConverter = TypeConverter.this.getConverter(from, intermediate); 584 Converter tConverter = TypeConverter.this.getConverter(intermediate, to); 585 if (iConverter == null || tConverter == null) 586 { 587 throw new TypeConversionException("Cannot convert from " + from.getName() + " to " + to.getName()); 588 } 589 590 Object iValue = iConverter.convert(source); 591 Object tValue = tConverter.convert(iValue); 592 return (T)tValue; 593 } 594 } 595 596 } 597 | Popular Tags |