1 19 package org.netbeans.mdr.storagemodel; 20 21 import org.netbeans.mdr.handlers.AssociationHandler; 22 import org.netbeans.mdr.handlers.BaseObjectHandler; 23 import org.netbeans.mdr.persistence.MOFID; 24 import org.netbeans.mdr.persistence.MultivaluedIndex; 25 import org.netbeans.mdr.persistence.StorageException; 26 import org.netbeans.mdr.persistence.Streamable; 27 import org.netbeans.mdr.util.DebugException; 28 import org.netbeans.mdr.util.IOUtils; 29 import org.netbeans.mdr.util.Logger; 30 import javax.jmi.reflect.JmiException; 31 import javax.jmi.reflect.RefFeatured; 32 import javax.jmi.reflect.RefObject; 33 import javax.jmi.reflect.WrongSizeException; 34 import java.util.*; 35 36 41 public class StorableObject extends StorableFeatured implements Streamable { 42 43 45 protected Object values[]; 46 47 static final String INDEX_KEY_DELIMITER = "@"; 48 static final String INDEX_KEY_DELIMITER_2 = "#"; 49 static final String NULL_VALUE_SUBSTITUTE = "NULL"; 50 51 private MOFID classProxyId; 52 private transient StorableClass classProxy = null; 53 55 private MOFID attribComposite = null; 56 57 protected void replaceValues(Map table) { 58 objectWillChange(); 59 super.replaceValues(table); 60 objectChanged(); 61 } 62 63 66 public StorableObject(MdrStorage mdrStorage, org.netbeans.mdr.persistence.MOFID immediatePackage, org.netbeans.mdr.persistence.MOFID meta, org.netbeans.mdr.persistence.MOFID classProxy) throws StorageException { 67 this(mdrStorage, immediatePackage, meta, classProxy, null, null); 68 } 69 70 public StorableObject (MdrStorage mdrStorage, org.netbeans.mdr.persistence.MOFID immediatePackage, org.netbeans.mdr.persistence.MOFID meta, org.netbeans.mdr.persistence.MOFID classProxy, Object params[]) throws StorageException { 71 this (mdrStorage, immediatePackage, meta, classProxy, params, null); 72 } 73 74 75 public StorableObject(MdrStorage mdrStorage, org.netbeans.mdr.persistence.MOFID immediatePackage, org.netbeans.mdr.persistence.MOFID meta, org.netbeans.mdr.persistence.MOFID classProxy, Object params[], String storageId) throws StorageException { 76 super(mdrStorage, immediatePackage, meta, storageId); 77 this.classProxyId = classProxy; 78 this.classProxy = (StorableClass) mdrStorage.getObject(classProxyId); 79 80 if (params != null) { 81 check(); 82 for (int i = 0; i < params.length; i++) { 83 StorableClass.AttributeDescriptor desc = getClassProxy().getAttrDesc(i); 84 values[i] = getInitialValue(desc, params[i]); 85 } } this.addInstance (); 89 if (params != null) { 90 modifyIndex (getClassProxy().getIndexDescriptors(), false); 91 } 92 initFinished = true; 93 } 94 95 public StorableObject(StorableObject storable) throws StorageException { 96 super(storable.getMdrStorage(), storable.getImmediatePackageId(), storable.getMetaObjectId(), null); 97 this.classProxyId = storable.getClassProxyId(); 98 this.classProxy = storable.getClassProxy(); 99 copyValues(storable); 100 this.addInstance(); 101 modifyIndex(getClassProxy().getIndexDescriptors(), false); 102 StorableFeatured composite = storable.getImmediateComposite(); 103 if (composite != null) { 104 attribComposite = composite.getMofId(); 105 } 106 initFinished = true; 107 } 108 109 public StorableObject() { 110 super(); 111 } 112 113 protected void copyValues(StorableObject storable) { 114 if (storable.values == null) return; 115 this.values = new Object [storable.values.length]; 116 for (int i = 0; i < values.length; i++) { 117 values[i] = storable.values[i]; 118 if (values[i] instanceof AttrCollection) { 119 ((AttrCollection) values[i]).mdrObject = this; 120 } 121 } 122 } 123 124 public void setAttribute(String featureName, Object value) throws StorageException { 125 setAttribute(getClassProxy().getAttrIndex(featureName), value); 127 } 128 129 public void setAttribute(int attrIndex, Object value) throws StorageException { 130 Object oldValue = getAttribute(attrIndex); 131 StorableClass.AttributeDescriptor attribute = getClassProxy().getAttrDesc(attrIndex); 132 133 137 objectWillChange(); 138 values[attrIndex] = value; 139 140 if (!attribute.isMultivalued() && (value instanceof RefObject)) { 141 StorableObject storableObj = (StorableObject) ((BaseObjectHandler) value)._getDelegate(); 142 storableObj.setComposite(getMofId(), storableObj.getMofId(), attribute.getMofId()); 143 if (oldValue != null) { 144 storableObj = (StorableObject) ((BaseObjectHandler) oldValue)._getDelegate(); 145 storableObj.clearComposite(); 146 } 147 } 148 149 modifyIndex(attrIndex, oldValue, value); 151 objectChanged(); 152 } 153 154 public Object getAttribute(String featureName) throws StorageException { 155 return getAttribute(getClassProxy().getAttrIndex(featureName)); 156 } 157 158 public Object getAttribute(int attrIndex) throws StorageException { 159 check(); 160 Object result = values[attrIndex]; 161 if (result instanceof MOFID) { 162 result = getMdrStorage().getRepository().getByMofId((MOFID) result); 163 } 164 return result; 165 } 166 167 public void verify(Collection violations) throws StorageException { 168 int count = getClassProxy().getAttrCount(); 169 for (int i = 0; i < count; i++) { 170 StorableClass.AttributeDescriptor desc = getClassProxy().getAttrDesc(i); 171 Object result = getAttribute(i); 172 if ((desc.getMaxSize() == 1 && desc.getMinSize() == 1 && result == null) || 173 (desc.getMaxSize() != 1 && ((Collection) result).size() < desc.getMinSize())) 174 violations.add(new WrongSizeException( 175 (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(desc.getMofId())) 176 )); 177 } 178 for (Iterator it = getClassProxy().getAllReferenceDescriptors().iterator(); it.hasNext();) { 179 StorableClass.ReferenceDescriptor desc = (StorableClass.ReferenceDescriptor) it.next(); 180 desc.getAssociation().verifyEnd(violations, desc.getEndName(), getMofId()); 181 } 182 } 183 184 189 void addReference(String referenceName, org.netbeans.mdr.persistence.MOFID referencedObjectId) throws StorageException { 190 org.netbeans.mdr.persistence.MOFID objA; 191 org.netbeans.mdr.persistence.MOFID objB; 192 StorableClass.ReferenceDescriptor reference = getClassProxy().getReferenceDescriptor(referenceName); 193 StorableAssociation assocObj = (StorableAssociation) getMdrStorage().getObject(reference.getAssociationId()); 194 195 if (reference.getEndName().equals(assocObj.getEnd1Name())) { 196 objB = referencedObjectId; 197 objA = getMofId(); 198 } else { 199 objA = referencedObjectId; 200 objB = getMofId(); 201 } 202 203 assocObj.addLink(objA, objB); 204 } 205 206 209 public Object getReference(String referenceName) throws StorageException { 210 StorableAssociation asocObj1; 211 StorableClass.ReferenceDescriptor reference = getClassProxy().getReferenceDescriptor(referenceName); 212 asocObj1 = (StorableAssociation) getMdrStorage().getObject(reference.getAssociationId()); 213 return asocObj1.queryObjects(reference.getEndName(), getMofId()); 214 } 215 216 protected void check() throws StorageException { 217 if (values == null) { 218 values = new Object [getClassProxy().getAttrCount()]; 219 } 220 } 221 222 public MOFID getImmediateCompositeId() { 223 return attribComposite; 224 } 225 226 230 public StorableFeatured getImmediateComposite() throws StorageException { 231 if (attribComposite != null) { 232 StorableFeatured sf = (StorableFeatured) getMdrStorage().getObject(attribComposite); 233 return sf; 234 } else { 235 return null; 236 } 237 } 238 239 public StorableFeatured getOutermostComposite() throws StorageException { 240 StorableFeatured result = getImmediateComposite(); 241 StorableFeatured composite = this; 242 243 while (result != null) { 244 composite = result; 245 if (result instanceof StorableObject) { 246 result = ((StorableObject) result).getImmediateComposite(); 247 } else { 248 result = null; 249 } 250 } 251 252 return composite; 253 } 254 255 public void clearComposite() throws StorageException { 256 setComposite((org.netbeans.mdr.persistence.MOFID) null, null, null); 257 } 258 259 public void setComposite(org.netbeans.mdr.persistence.MOFID composite, org.netbeans.mdr.persistence.MOFID objectId, org.netbeans.mdr.persistence.MOFID elementId) throws StorageException { 260 setComposite(getMdrStorage().getObject(composite), objectId, elementId); 261 } 262 263 268 public void setComposite(StorableBaseObject composite, org.netbeans.mdr.persistence.MOFID objectId, org.netbeans.mdr.persistence.MOFID elementId) throws StorageException { 269 objectWillChange(); 270 if (composite == null) { 271 attribComposite = null; 272 } else { 273 org.netbeans.mdr.persistence.MOFID id = composite.getMofId(); 274 if (!id.equals(attribComposite)) { 275 if (attribComposite != null) { 277 throw new javax.jmi.reflect.CompositionViolationException(getMdrStorage().getRepository().getHandler(this), (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(elementId))); 278 } 279 if ((composite instanceof StorableObject) && (((StorableObject) composite).getOutermostComposite().equals(this))) { 281 throw new javax.jmi.reflect.CompositionCycleException(getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(objectId)), (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(elementId))); 282 } 283 if (!composite.getOutermostPackageId().equals(getOutermostPackageId())) { 285 throw new javax.jmi.reflect.ClosureViolationException(getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(objectId)), (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(elementId))); 286 } 287 attribComposite = id; 288 } 289 } 290 objectChanged (); 291 } 292 293 public void deleteInstance() throws StorageException { 294 modifyIndex (getClassProxy().getIndexDescriptors(), true); 295 getMdrStorage().removeInstance(this); 296 } 297 298 301 public void delete() throws StorageException { 302 deleteAttributes(); 303 deleteLinksAndComponents(); 304 deleteFromComposite(); 305 deleteInstance(); 306 } 307 308 protected void deleteFromComposite() throws StorageException { 309 StorableFeatured composite = getImmediateComposite(); 310 if (composite != null) { 311 StorableClass cls = composite.getClassProxy(); 312 for (int i = 0; i < cls.getAttrCount(); i++) { 313 StorableClass.AttributeDescriptor desc = cls.getAttrDesc(i); 314 if (RefObject.class.isAssignableFrom(desc.getType())) { 315 RefFeatured obj = (RefFeatured) getMdrStorage().getRepository().getHandler(composite); 316 Object value = obj.refGetValue(desc.getName()); 317 if (this.equals(value)) { 318 obj.refSetValue(desc.getName(), null); 319 } else if (value instanceof Collection && ((Collection) value).contains(this)) { 320 ((Collection) value).remove(this); 321 } 322 } 323 } 324 } 325 } 326 327 protected void deleteLinksAndComponents() throws StorageException { 328 RefObject thisObject = (RefObject) getMdrStorage().getRepository().getHandler(this); 329 ArrayList associationEnds = new ArrayList(); 330 getClassProxy().collectAssociationEnds(associationEnds, new HashSet()); 331 for (Iterator it = associationEnds.iterator(); it.hasNext();) { 332 StorableClass.AssocEndDescriptor item = (StorableClass.AssocEndDescriptor) it.next(); 333 StorableAssociation assocStorable = (StorableAssociation) getMdrStorage().getObject(item.mofId); 334 if (assocStorable == null) continue; 335 AssociationHandler assoc = (AssociationHandler) getMdrStorage().getRepository().getHandler(assocStorable); 336 Object temp; 337 try { 338 temp = assoc._query(item.endName, thisObject); 339 } catch (ClassCastException e) { 340 temp = null; 341 } catch (JmiException e) { 342 temp = assoc._handleQuery(item.endName, thisObject); 343 } 344 if (temp != null) { 345 if (temp instanceof Collection) { 346 for (Iterator itt = ((Collection)temp).iterator(); itt.hasNext();) { 347 RefObject obj = (RefObject) itt.next(); 348 itt.remove(); 349 if (item.isAggregate) 350 obj.refDelete(); 351 } 352 } else { 353 if (item.endName.equals(assocStorable.getEnd2Name())) { 354 assoc.refRemoveLink((RefObject) temp, thisObject); 355 } else { 356 assoc.refRemoveLink(thisObject, (RefObject) temp); 357 if (item.isAggregate) 358 ((RefObject) temp).refDelete(); 359 } 360 } 361 } 362 } 363 } 364 365 368 public org.netbeans.mdr.persistence.MOFID getClassProxyId() { 369 return classProxyId; 370 } 371 372 376 public StorableClass getClassProxy() throws StorageException { 377 return classProxy; 378 } 379 380 383 public void write(java.io.OutputStream outputStream) { 384 super.write(outputStream); 385 try { 386 IOUtils.write (outputStream, classProxyId, this); 387 IOUtils.write (outputStream, attribComposite, this); 388 if (values == null) { 389 IOUtils.writeInt(outputStream, 0); 390 } else { 391 IOUtils.writeInt(outputStream, values.length + 1); 392 for (int i = 0; i < values.length; i++) { 393 IOUtils.write(outputStream, values[i], this); 394 } 395 } 396 } catch (java.io.IOException e) { 397 Logger.getDefault().notify(Logger.INFORMATIONAL, e); 398 } 399 } 400 401 404 public void read(java.io.InputStream inputStream) { 405 super.read(inputStream); 406 try { 407 classProxyId = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this); 408 attribComposite = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this); 409 } catch (java.io.IOException e) { 411 throw (RuntimeException ) Logger.getDefault().annotate(new RuntimeException (e.getMessage()), e); 412 } 413 try { 415 classProxy = (StorableClass) getMdrStorage().getObject(classProxyId); 416 meta = classProxy.getMetaObjectId(); 417 immediatePackage = classProxy.getImmediatePackageId(); 418 } catch (StorageException e) { 419 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 420 } 421 422 try { 423 int objCount = IOUtils.readInt(inputStream); 424 if (objCount != 0) { 425 int count = objCount - 1; 426 values = new Object [count]; 427 for (int i = 0; i < count; i++) { 428 values[i] = IOUtils.read(inputStream, this, getClassProxy().getAttrDesc(i).getType().getName()); 429 } 431 } 432 } catch (Exception e) { 433 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 434 } 435 } 436 437 438 protected void addInstance () throws StorageException { 439 this.getMdrStorage().addInstance(this); 440 } 441 442 447 protected void modifyIndex(int attrIdx, Object oldValue, Object newValue) throws StorageException { 448 MultivaluedIndex attrIndex = null; 449 StorableClass proxy = getClassProxy(); 450 StorableClass.AttributeDescriptor attrDesc = proxy.getAttrDesc(attrIdx); 451 org.netbeans.mdr.persistence.MOFID attribId = attrDesc.getMofId(); 452 Collection indexes; 453 if (attrDesc.isIndexed() && (indexes = proxy.getIndexes(attribId)) != null) { 454 455 Iterator iter = indexes.iterator(); 456 org.netbeans.mdr.persistence.MOFID outermostPackageId = getOutermostPackageId(); 457 org.netbeans.mdr.persistence.MOFID mofId = getMofId(); 458 459 while (iter.hasNext()) { 460 StorableClass.IndexDescriptor indexDesc = (StorableClass.IndexDescriptor) iter.next(); 461 try { 462 attrIndex = getMdrStorage().acquireAdditionalIndex(outermostPackageId, indexDesc.getName()); 463 464 if (attrIndex == null) { 465 return; 466 } 467 468 if ((oldValue == null) && (newValue == null)) { 469 return; 470 } 471 if ((oldValue != null) && oldValue.equals(newValue)) { 472 return; 473 } 474 475 StorableClass.IndexDescriptor.Field [] fields = indexDesc.getFields (); 476 int currPosition = -1; 477 for (int x = 0; x < fields.length; x++) { 478 if (fields[x] instanceof StorableClass.IndexDescriptor.Attrib) { 479 if (fields[x].getId().equals(attribId)) { 480 currPosition = x; 481 break; 482 } 483 } 484 } 485 486 String oldValStr = objectToString(oldValue, fields[currPosition].isOrdered()); 487 String newValStr = objectToString(newValue, fields[currPosition].isOrdered()); 488 String prefix = valuesToKey(fields, 0, currPosition - 1); 489 String suffix = valuesToKey(fields, currPosition + 1, fields.length - 1); 490 491 StringBuffer buf = new StringBuffer (); 492 if (prefix.length() > 0) { 493 buf.append(prefix); 494 buf.append(INDEX_KEY_DELIMITER); 495 } 496 buf.append(oldValStr); 497 if (suffix.length() > 0) { 498 buf.append(INDEX_KEY_DELIMITER); 499 buf.append(suffix); 500 } 501 attrIndex.remove(buf.toString(), mofId); 502 504 buf = new StringBuffer (); 505 if (prefix.length() > 0) { 506 buf.append(prefix); 507 buf.append(INDEX_KEY_DELIMITER); 508 } 509 buf.append(newValStr); 510 if (suffix.length() > 0) { 511 buf.append(INDEX_KEY_DELIMITER); 512 buf.append(suffix); 513 } 514 attrIndex.add(buf.toString(), mofId); 515 517 } finally { 518 if (attrIndex != null) getMdrStorage().releaseAdditionalIndex(); 519 } 520 } 522 } } 524 525 528 protected void deleteAttributes() throws StorageException { 529 for (int i = 0; i < values.length; i++) { 530 Object value = getAttribute(i); 532 if (value instanceof RefObject) { 533 RefObject obj = (RefObject) value; 534 setAttribute(i, null); 535 obj.refDelete(); 536 } else if (value instanceof Collection) { 537 for (Iterator it = ((Collection)value).iterator(); it.hasNext();) { 538 Object obj = it.next(); 539 if (!(obj instanceof RefObject)) 540 break; 541 it.remove(); 542 ((RefObject)obj).refDelete(); 543 } 544 } 545 } 546 } 547 548 void addToIndex (org.netbeans.mdr.persistence.MOFID id) { 549 try { 550 StorableClass proxy = getClassProxy(); 551 modifyIndex (proxy.getIndexes(id), false); 552 } catch (StorageException e) { 553 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 554 } 555 } 556 557 void removeFromIndex (org.netbeans.mdr.persistence.MOFID id) { 558 try { 559 StorableClass proxy = getClassProxy(); 560 modifyIndex (proxy.getIndexes(id), true); 561 } catch (StorageException e) { 562 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 563 } 564 } 565 566 private void modifyIndex(List descriptors, boolean remove) throws StorageException { 567 if (descriptors == null) 568 return; 569 MultivaluedIndex attrIndex = null; 570 org.netbeans.mdr.persistence.MOFID outermostPackageId = getOutermostPackageId(); 571 org.netbeans.mdr.persistence.MOFID mofId = getMofId(); 572 Iterator iter = descriptors.iterator(); 573 while (iter.hasNext()) { 574 StorableClass.IndexDescriptor desc = (StorableClass.IndexDescriptor) iter.next(); 575 StorableClass.IndexDescriptor.Field [] fields = desc.getFields(); 576 try { 577 attrIndex = getMdrStorage().acquireAdditionalIndex(outermostPackageId, desc.getName()); 578 if (remove) { 579 attrIndex.remove(valuesToKey(fields, 0, fields.length - 1), mofId); 581 } else { 582 attrIndex.add(valuesToKey(fields, 0, fields.length - 1), mofId); 584 } 585 } finally { 586 if (attrIndex != null) getMdrStorage().releaseAdditionalIndex(); 587 } 588 } } 590 591 private static String objectToString(Object o, boolean isOrdered) { 592 if (o == null) 593 return NULL_VALUE_SUBSTITUTE; 594 if (o instanceof RefObject) 595 return ((RefObject) o).refMofId (); 596 if (o instanceof StorableObject) 597 return ((StorableObject) o).getMofId().toString (); 598 if (o instanceof Collection) { 599 StringBuffer buf = new StringBuffer (); 600 Iterator iter = ((Collection) o).iterator(); 601 List list = new LinkedList (); 602 while (iter.hasNext ()) { 603 list.add (objectToString(iter.next(), true)); 604 } 605 if (!isOrdered) { 606 Collections.sort (list); 607 } 608 iter = list.iterator (); 609 if (iter.hasNext()) 610 buf.append(iter.next()); 611 while (iter.hasNext()) { 612 buf.append(INDEX_KEY_DELIMITER); 613 buf.append(iter.next()); 614 } return buf.toString(); 616 } return o.toString(); 618 } 619 620 private String valuesToKey (StorableClass.IndexDescriptor.Field [] fields, int pos_1, int pos_2) throws StorageException { 621 StringBuffer buf = new StringBuffer (); 622 for (int x = pos_1; x <= pos_2; x++) { 623 String res; 624 if (fields[x] instanceof StorableClass.IndexDescriptor.Attrib) { 625 String name = fields[x].getName(); 626 res = objectToString(values[getClassProxy().getAttrIndex(name)], fields[x].isOrdered()); 627 } else { 629 StorableClass.IndexDescriptor.AssocEnd endDesc = (StorableClass.IndexDescriptor.AssocEnd)fields[x]; 630 StorableAssociation sa = (StorableAssociation) getMdrStorage().getObject(endDesc.getAssociation()); 631 String otherEndName = sa.getEnd1Name (); 632 if (otherEndName.equals (endDesc.getName())) 633 otherEndName = sa.getEnd2Name (); 634 res = objectToString(sa.queryObjects(otherEndName, getMofId()), fields[x].isOrdered()); 638 } 640 buf.append(res); 641 if (x < pos_2) 642 buf.append(INDEX_KEY_DELIMITER_2); 643 } 644 return buf.toString(); 645 } 646 647 public static String valuesToKey (Map map, StorableClass.IndexDescriptor.Field [] fields) { 648 StringBuffer buf = new StringBuffer (); 649 if (map.size () != fields.length) { 650 throw new DebugException ("Wrong query on additional index, incorrect number of passed parameters."); 651 } 652 for (int x = 0; x < fields.length; x++) { 653 String name = fields[x].getName (); 654 if (!map.containsKey (name)) { 655 throw new DebugException ("Wrong query on additional index, value of field " + name + " not specified."); 656 } 657 Object value = map.get (name); 658 String str = objectToString (value, fields[x].isOrdered()); 659 buf.append(str); 660 if (x < fields.length - 1) 661 buf.append(INDEX_KEY_DELIMITER_2); 662 } return buf.toString (); 664 } 665 666 public static String valueToKey (Object value, StorableClass.IndexDescriptor.Field [] fields) { 667 if (fields.length != 1) { 668 throw new DebugException ("Wrong query on additional index, more than one parameter expected."); 669 } 670 return objectToString (value, fields[0].isOrdered()); 671 } 672 673 public byte[] getClassFile() { 674 return (byte[]) getSlot1(); 675 } 676 677 public void setClassFile(byte[] bytecode) { 678 setSlot1(bytecode); 679 } 680 681 public byte[] getInstanceClassFile() { 682 return (byte[]) getSlot2(); 683 } 684 685 public void setInstanceClassFile(byte[] bytecode) { 686 setSlot2(bytecode); 687 } 688 689 } 690 | Popular Tags |