1 17 package org.alfresco.repo.domain; 18 19 import java.io.Serializable ; 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.Date ; 23 import java.util.HashMap ; 24 import java.util.Map ; 25 26 import org.alfresco.error.AlfrescoRuntimeException; 27 import org.alfresco.service.cmr.dictionary.DataTypeDefinition; 28 import org.alfresco.service.cmr.repository.ContentData; 29 import org.alfresco.service.cmr.repository.NodeRef; 30 import org.alfresco.service.cmr.repository.Path; 31 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; 32 import org.alfresco.service.namespace.QName; 33 import org.alfresco.util.EqualsHelper; 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 37 44 public class PropertyValue implements Cloneable , Serializable 45 { 46 private static final long serialVersionUID = -497902497351493075L; 47 48 49 private static final String STRING_EMPTY = ""; 50 51 private static Log logger = LogFactory.getLog(PropertyValue.class); 52 private static Log loggerOracle = LogFactory.getLog(PropertyValue.class.getName() + ".oracle"); 53 54 55 private static enum ValueType 56 { 57 NULL 58 { 59 @Override 60 Serializable convert(Serializable value) 61 { 62 return null; 63 } 64 }, 65 BOOLEAN 66 { 67 @Override 68 Serializable convert(Serializable value) 69 { 70 return DefaultTypeConverter.INSTANCE.convert(Boolean .class, value); 71 } 72 }, 73 INTEGER 74 { 75 @Override 76 protected ValueType getPersistedType(Serializable value) 77 { 78 return ValueType.LONG; 79 } 80 81 @Override 82 Serializable convert(Serializable value) 83 { 84 return DefaultTypeConverter.INSTANCE.convert(Integer .class, value); 85 } 86 }, 87 LONG 88 { 89 @Override 90 Serializable convert(Serializable value) 91 { 92 return DefaultTypeConverter.INSTANCE.convert(Long .class, value); 93 } 94 }, 95 FLOAT 96 { 97 @Override 98 Serializable convert(Serializable value) 99 { 100 return DefaultTypeConverter.INSTANCE.convert(Float .class, value); 101 } 102 }, 103 DOUBLE 104 { 105 @Override 106 Serializable convert(Serializable value) 107 { 108 return DefaultTypeConverter.INSTANCE.convert(Double .class, value); 109 } 110 }, 111 STRING 112 { 113 116 @Override 117 protected ValueType getPersistedType(Serializable value) 118 { 119 if (value instanceof String ) 120 { 121 String valueStr = (String ) value; 122 if (valueStr.length() > 1024) 123 { 124 return ValueType.SERIALIZABLE; 125 } 126 } 127 return ValueType.STRING; 128 } 129 130 @Override 131 Serializable convert(Serializable value) 132 { 133 return DefaultTypeConverter.INSTANCE.convert(String .class, value); 134 } 135 }, 136 DATE 137 { 138 @Override 139 protected ValueType getPersistedType(Serializable value) 140 { 141 return ValueType.STRING; 142 } 143 144 @Override 145 Serializable convert(Serializable value) 146 { 147 return DefaultTypeConverter.INSTANCE.convert(Date .class, value); 148 } 149 }, 150 SERIALIZABLE 151 { 152 @Override 153 Serializable convert(Serializable value) 154 { 155 return value; 156 } 157 }, 158 CONTENT 159 { 160 @Override 161 protected ValueType getPersistedType(Serializable value) 162 { 163 return ValueType.STRING; 164 } 165 166 @Override 167 Serializable convert(Serializable value) 168 { 169 return DefaultTypeConverter.INSTANCE.convert(ContentData.class, value); 170 } 171 }, 172 NODEREF 173 { 174 @Override 175 protected ValueType getPersistedType(Serializable value) 176 { 177 return ValueType.STRING; 178 } 179 180 @Override 181 Serializable convert(Serializable value) 182 { 183 return DefaultTypeConverter.INSTANCE.convert(NodeRef.class, value); 184 } 185 }, 186 QNAME 187 { 188 @Override 189 protected ValueType getPersistedType(Serializable value) 190 { 191 return ValueType.STRING; 192 } 193 194 @Override 195 Serializable convert(Serializable value) 196 { 197 return DefaultTypeConverter.INSTANCE.convert(QName.class, value); 198 } 199 }, 200 PATH 201 { 202 @Override 203 protected ValueType getPersistedType(Serializable value) 204 { 205 return ValueType.SERIALIZABLE; 206 } 207 208 @Override 209 Serializable convert(Serializable value) 210 { 211 return DefaultTypeConverter.INSTANCE.convert(Path.class, value); 212 } 213 }; 214 215 220 protected ValueType getPersistedType(Serializable value) 221 { 222 return this; 223 } 224 225 228 abstract Serializable convert(Serializable value); 229 230 protected ArrayList <Serializable > convert(Collection collection) 231 { 232 ArrayList <Serializable > arrayList = new ArrayList <Serializable >(collection.size()); 233 for (Object object : collection) 234 { 235 Serializable newValue = null; 236 if (object != null) 237 { 238 if (!(object instanceof Serializable )) 239 { 240 throw new AlfrescoRuntimeException("Collection values must contain Serializable instances: \n" + 241 " value type: " + this + "\n" + 242 " collection: " + collection + "\n" + 243 " value: " + object); 244 } 245 Serializable value = (Serializable ) object; 246 newValue = convert(value); 247 } 248 arrayList.add(newValue); 249 } 250 return arrayList; 252 } 253 } 254 255 261 private static ValueType getActualType(Serializable value) 262 { 263 if (value == null) 264 { 265 return ValueType.NULL; 266 } 267 else if (value instanceof Boolean ) 268 { 269 return ValueType.BOOLEAN; 270 } 271 else if ((value instanceof Integer ) || (value instanceof Long )) 272 { 273 return ValueType.LONG; 274 } 275 else if (value instanceof Float ) 276 { 277 return ValueType.FLOAT; 278 } 279 else if (value instanceof Double ) 280 { 281 return ValueType.DOUBLE; 282 } 283 else if (value instanceof String ) 284 { 285 return ValueType.STRING; 286 } 287 else if (value instanceof Date ) 288 { 289 return ValueType.DATE; 290 } 291 else if (value instanceof ContentData) 292 { 293 return ValueType.CONTENT; 294 } 295 else if (value instanceof NodeRef) 296 { 297 return ValueType.NODEREF; 298 } 299 else if (value instanceof QName) 300 { 301 return ValueType.QNAME; 302 } 303 else if (value instanceof Path) 304 { 305 return ValueType.PATH; 306 } 307 else 308 { 309 return ValueType.SERIALIZABLE; 311 } 312 } 313 314 315 private static Map <QName, ValueType> valueTypesByPropertyType; 316 static 317 { 318 valueTypesByPropertyType = new HashMap <QName, ValueType>(17); 319 valueTypesByPropertyType.put(DataTypeDefinition.ANY, ValueType.SERIALIZABLE); 320 valueTypesByPropertyType.put(DataTypeDefinition.BOOLEAN, ValueType.BOOLEAN); 321 valueTypesByPropertyType.put(DataTypeDefinition.INT, ValueType.INTEGER); 322 valueTypesByPropertyType.put(DataTypeDefinition.LONG, ValueType.LONG); 323 valueTypesByPropertyType.put(DataTypeDefinition.DOUBLE, ValueType.DOUBLE); 324 valueTypesByPropertyType.put(DataTypeDefinition.FLOAT, ValueType.FLOAT); 325 valueTypesByPropertyType.put(DataTypeDefinition.DATE, ValueType.DATE); 326 valueTypesByPropertyType.put(DataTypeDefinition.DATETIME, ValueType.DATE); 327 valueTypesByPropertyType.put(DataTypeDefinition.CATEGORY, ValueType.NODEREF); 328 valueTypesByPropertyType.put(DataTypeDefinition.CONTENT, ValueType.CONTENT); 329 valueTypesByPropertyType.put(DataTypeDefinition.TEXT, ValueType.STRING); 330 valueTypesByPropertyType.put(DataTypeDefinition.NODE_REF, ValueType.NODEREF); 331 valueTypesByPropertyType.put(DataTypeDefinition.PATH, ValueType.PATH); 332 valueTypesByPropertyType.put(DataTypeDefinition.QNAME, ValueType.QNAME); 333 } 334 335 336 private ValueType actualType; 337 338 private boolean isMultiValued; 339 340 private ValueType persistedType; 341 342 private Boolean booleanValue; 343 private Long longValue; 344 private Float floatValue; 345 private Double doubleValue; 346 private String stringValue; 347 private Serializable serializableValue; 348 349 352 public PropertyValue() 353 { 354 } 355 356 366 public PropertyValue(QName typeQName, Serializable value) 367 { 368 this.actualType = PropertyValue.getActualType(value); 369 if (value == null) 370 { 371 setPersistedValue(ValueType.NULL, null); 372 setMultiValued(false); 373 } 374 else if (value instanceof Collection ) 375 { 376 Collection collection = (Collection ) value; 377 ValueType collectionValueType = makeValueType(typeQName); 378 ArrayList <Serializable > convertedCollection = collectionValueType.convert(collection); 381 setPersistedValue(ValueType.SERIALIZABLE, convertedCollection); 383 setMultiValued(true); 384 } 385 else 386 { 387 ValueType persistedValueType = this.actualType.getPersistedType(value); 389 value = persistedValueType.convert(value); 391 setPersistedValue(persistedValueType, value); 392 setMultiValued(false); 393 } 394 } 395 396 401 private ValueType makeValueType(QName typeQName) 402 { 403 ValueType valueType = valueTypesByPropertyType.get(typeQName); 404 if (valueType == null) 405 { 406 throw new AlfrescoRuntimeException( 407 "Property type not recognised: \n" + 408 " type: " + typeQName + "\n" + 409 " property: " + this); 410 } 411 return valueType; 412 } 413 414 @Override 415 public boolean equals(Object obj) 416 { 417 if (this == obj) 418 { 419 return true; 420 } 421 if (obj == null) 422 { 423 return false; 424 } 425 if (obj instanceof PropertyValue) 426 { 427 PropertyValue that = (PropertyValue) obj; 428 return (this.actualType.equals(that.actualType) && 429 EqualsHelper.nullSafeEquals(this.booleanValue, that.booleanValue) && 430 EqualsHelper.nullSafeEquals(this.longValue, that.longValue) && 431 EqualsHelper.nullSafeEquals(this.floatValue, that.floatValue) && 432 EqualsHelper.nullSafeEquals(this.doubleValue, that.doubleValue) && 433 EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue) && 434 EqualsHelper.nullSafeEquals(this.serializableValue, that.serializableValue) 435 ); 436 437 } 438 else 439 { 440 return false; 441 } 442 } 443 444 @Override 445 public int hashCode() 446 { 447 int h = 0; 448 if (actualType != null) 449 h = actualType.hashCode(); 450 Serializable persistedValue = getPersistedValue(); 451 if (persistedValue != null) 452 h += 17 * persistedValue.hashCode(); 453 return h; 454 } 455 456 @Override 457 public Object clone() throws CloneNotSupportedException 458 { 459 return super.clone(); 460 } 461 462 @Override 463 public String toString() 464 { 465 StringBuilder sb = new StringBuilder (128); 466 sb.append("PropertyValue") 467 .append("[actual-type=").append(actualType) 468 .append(", multi-valued=").append(isMultiValued) 469 .append(", value-type=").append(persistedType) 470 .append(", value=").append(getPersistedValue()) 471 .append("]"); 472 return sb.toString(); 473 } 474 475 public String getActualType() 476 { 477 return actualType.toString(); 478 } 479 480 public void setActualType(String actualType) 481 { 482 this.actualType = ValueType.valueOf(actualType); 483 } 484 485 public boolean isMultiValued() 486 { 487 return isMultiValued; 488 } 489 490 public void setMultiValued(boolean isMultiValued) 491 { 492 this.isMultiValued = isMultiValued; 493 } 494 495 public String getPersistedType() 496 { 497 return persistedType.toString(); 498 } 499 public void setPersistedType(String persistedType) 500 { 501 this.persistedType = ValueType.valueOf(persistedType); 502 } 503 504 511 public void setPersistedValue(ValueType persistedType, Serializable value) 512 { 513 switch (persistedType) 514 { 515 case NULL: 516 if (value != null) 517 { 518 throw new AlfrescoRuntimeException("Value must be null for persisted type: " + persistedType); 519 } 520 break; 521 case BOOLEAN: 522 this.booleanValue = (Boolean ) value; 523 break; 524 case LONG: 525 this.longValue = (Long ) value; 526 break; 527 case FLOAT: 528 this.floatValue = (Float ) value; 529 break; 530 case DOUBLE: 531 this.doubleValue = (Double ) value; 532 break; 533 case STRING: 534 this.stringValue = (String ) value; 535 break; 536 case SERIALIZABLE: 537 this.serializableValue = (Serializable ) value; 538 break; 539 default: 540 throw new AlfrescoRuntimeException("Unrecognised value type: " + persistedType); 541 } 542 this.persistedType = persistedType; 544 } 545 546 549 private Serializable getPersistedValue() 550 { 551 switch (persistedType) 552 { 553 case NULL: 554 return null; 555 case BOOLEAN: 556 return this.booleanValue; 557 case LONG: 558 return this.longValue; 559 case FLOAT: 560 return this.floatValue; 561 case DOUBLE: 562 return this.doubleValue; 563 case STRING: 564 if (this.stringValue == null) 566 { 567 if (loggerOracle.isDebugEnabled()) 570 { 571 logger.debug("string_value is 'null'. Forcing to empty String"); 572 } 573 return PropertyValue.STRING_EMPTY; 574 } 575 else 576 { 577 return this.stringValue; 578 } 579 case SERIALIZABLE: 580 return this.serializableValue; 581 default: 582 throw new AlfrescoRuntimeException("Unrecognised value type: " + persistedType); 583 } 584 } 585 586 600 public Serializable getValue(QName typeQName) 601 { 602 604 ValueType requiredType = makeValueType(typeQName); 605 if (requiredType == ValueType.SERIALIZABLE) 606 { 607 requiredType = this.actualType; 609 } 610 611 Serializable ret = null; 613 if (persistedType == ValueType.NULL) 614 { 615 ret = null; 616 } 617 else if (this.isMultiValued) 618 { 619 Collection collection = (Collection ) this.serializableValue; 621 ArrayList <Serializable > convertedCollection = requiredType.convert(collection); 624 ret = convertedCollection; 625 } 626 else 627 { 628 Serializable persistedValue = getPersistedValue(); 629 ret = requiredType.convert(persistedValue); 631 } 632 if (logger.isDebugEnabled()) 634 { 635 logger.debug("Fetched value: \n" + 636 " property value: " + this + "\n" + 637 " requested type: " + requiredType + "\n" + 638 " result: " + ret); 639 } 640 return ret; 641 } 642 643 public boolean getBooleanValue() 644 { 645 if (booleanValue == null) 646 return false; 647 else 648 return booleanValue.booleanValue(); 649 } 650 public void setBooleanValue(boolean value) 651 { 652 this.booleanValue = Boolean.valueOf(value); 653 } 654 655 public long getLongValue() 656 { 657 if (longValue == null) 658 return 0; 659 else 660 return longValue.longValue(); 661 } 662 public void setLongValue(long value) 663 { 664 this.longValue = Long.valueOf(value); 665 } 666 667 public float getFloatValue() 668 { 669 if (floatValue == null) 670 return 0.0F; 671 else 672 return floatValue.floatValue(); 673 } 674 public void setFloatValue(float value) 675 { 676 this.floatValue = Float.valueOf(value); 677 } 678 679 public double getDoubleValue() 680 { 681 if (doubleValue == null) 682 return 0.0; 683 else 684 return doubleValue.doubleValue(); 685 } 686 public void setDoubleValue(double value) 687 { 688 this.doubleValue = Double.valueOf(value); 689 } 690 691 public String getStringValue() 692 { 693 return stringValue; 694 } 695 public void setStringValue(String value) 696 { 697 this.stringValue = value; 698 } 699 700 public Serializable getSerializableValue() 701 { 702 return serializableValue; 703 } 704 public void setSerializableValue(Serializable value) 705 { 706 this.serializableValue = value; 707 } 708 } 709 | Popular Tags |