1 package org.myoodb.core; 25 26 import java.io.*; 27 import java.util.*; 28 import java.lang.reflect.*; 29 30 import org.myoodb.*; 31 import org.myoodb.exception.*; 32 33 public abstract class AbstractObjectContainer implements Externalizable 34 { 35 private static transient HashMap m_classTable = new HashMap(128); 36 private static transient HashMap m_methodTable = new HashMap(128); 37 38 public transient static String IMPL_NAME_SUFFIX = "@implExtension@"; 39 public transient static String BEAN_NAME_SUFFIX = "@beanExtension@"; 40 public transient static String PROXY_NAME_SUFFIX = "@proxyExtension@"; 41 42 public final transient static int STATE_UNKNOWN = 0; 43 public final transient static int STATE_CREATED = 1; 44 public final transient static int STATE_ACTIVE = 2; 45 public final transient static int STATE_DELETED = 3; 46 47 private int m_state; 48 private Identifier m_objectId; 49 private MyOodbLocal[] m_targets; 50 private boolean m_deactivationFlag; 51 protected AbstractCluster m_cluster; 52 53 private transient MyOodbBean m_myBean; 54 private transient MyOodbProxy m_myProxy; 55 56 public static Method ifThisIsAJavaBeanSetMethodThenReturnItsGetMethod(Method method, Method[] methods) 57 { 58 String name = method.getName(); 59 60 if ((name.length() <= 3) || 61 (name.equals("setXML") == true) || (name.equals("getXML") == true) || 62 (name.equals("setBean") == true) || (name.equals("getBean") == true)) 63 { 64 return null; 65 } 66 67 String suffix = name.substring(0, 3); 68 69 if ((suffix.equals("set") == true) && (method.getParameterTypes().length == 1)) 70 { 71 String setMethod = "get" + name.substring(3); 72 73 for (int methodIndex = 0; methodIndex < methods.length; methodIndex++) 74 { 75 method = methods[methodIndex]; 76 77 if ((method.getName().equals(setMethod) == true) && (method.getParameterTypes().length == 0)) 78 { 79 return method; 80 } 81 } 82 } 83 84 return null; 85 } 86 87 public AbstractObjectContainer() 88 { 89 } 91 92 public AbstractObjectContainer(int state, Identifier objectId) 93 { 94 m_state = state; 95 m_objectId = objectId; 96 97 } 99 100 protected Method[] getMethods(Class classType) 101 { 102 Method[] methods = (Method[]) m_classTable.get(classType); 103 104 if (methods == null) 105 { 106 synchronized(m_classTable) 107 { 108 methods = (Method[]) m_classTable.get(classType); 109 110 if (methods == null) 111 { 112 Class interfaceType = null; 113 114 try 115 { 116 String className = classType.getName(); 117 className = className.substring(0, className.length() - IMPL_NAME_SUFFIX.length()); 118 interfaceType = Class.forName(className); 119 } 120 catch (java.lang.ClassNotFoundException e) 121 { 122 e.printStackTrace(); 124 } 125 126 methods = MethodHelper.getMethods(classType, interfaceType); 127 m_classTable.put(classType, methods); 128 } 129 } 130 } 131 132 return methods; 133 } 134 135 protected final Constructor getConstructor(Class classType, String sig) throws ClassNotFoundException , NoSuchMethodException 136 { 137 MethodSignature def = new MethodSignature(classType.getName(), "CONSTRUCTOR", sig); 138 Constructor constructor = (Constructor) m_methodTable.get(def); 139 140 if (constructor == null) 141 { 142 synchronized(m_methodTable) 143 { 144 constructor = (Constructor) m_methodTable.get(def); 145 146 if (constructor == null) 147 { 148 Class [] classes; 149 if (sig == null) 150 { 151 classes = new Class [0]; 152 } 153 else 154 { 155 StringTokenizer st = new StringTokenizer(sig, MethodHelper.SIGNATURE_DELIMITER); 156 classes = new Class [st.countTokens()]; 157 for (int i = 0; st.hasMoreTokens(); ++i) 158 { 159 classes[i] = MyOodbManager.getTheManager().getClassManager().getClass(st.nextToken()); 160 } 161 } 162 163 constructor = classType.getConstructor(classes); 164 165 m_methodTable.put(def, constructor); 166 } 167 } 168 } 169 170 return constructor; 171 } 172 173 protected final Method getMethod(Object obj, String methodName, String sig, Object [] args) throws Exception 174 { 175 Method method = null; 176 177 for (int i = 0; i < m_targets.length; i++) 178 { 179 MethodSignature def = new MethodSignature(m_targets[i].getClass().getName(), methodName, sig); 180 method = (Method) m_methodTable.get(def); 181 182 if (method == null) 183 { 184 synchronized(m_methodTable) 185 { 186 if (method == null) 187 { 188 Class [] classes = new Class [args.length]; 189 StringTokenizer st = new StringTokenizer(sig, MethodHelper.SIGNATURE_DELIMITER); 190 for (int j = 0; st.hasMoreTokens(); ++j) 191 { 192 classes[j] = MyOodbManager.getTheManager().getClassManager().getClass(st.nextToken()); 193 } 194 195 try 196 { 197 method = obj.getClass().getMethod(methodName, classes); 198 199 m_methodTable.put(def, method); 200 } 201 catch (java.lang.NoSuchMethodException e) 202 { 203 } 205 } 206 } 207 } 208 209 if (method != null) 210 { 211 break; 212 } 213 } 214 215 return method; 216 } 217 218 public int getState() 219 { 220 return m_state; 221 } 222 223 public void raiseState(int newState) 224 { 225 m_state = newState > m_state ? newState : m_state; 226 } 227 228 public AbstractLock getLock() 229 { 230 return (m_cluster != null) ? m_cluster.getLock() : null; 231 } 232 233 public void setCluster(AbstractCluster cluster) 234 { 235 m_cluster = cluster; 236 } 237 238 public AbstractCluster getCluster() 239 { 240 return m_cluster; 241 } 242 243 public boolean isDeleted() 244 { 245 return (getState() == STATE_DELETED); 246 } 247 248 public boolean isCreated() 249 { 250 return (getState() == STATE_CREATED); 251 } 252 253 public void setObjectId(Identifier objectId) 254 { 255 m_objectId = objectId; 256 } 257 258 public Identifier getObjectId() 259 { 260 return m_objectId; 261 } 262 263 public void setDeactivationFlag(boolean flag) throws Exception 264 { 265 m_deactivationFlag = flag; 266 } 267 268 public boolean getDeactivationFlag() 269 { 270 return m_deactivationFlag; 271 } 272 273 public MyOodbLocal getTarget() 274 { 275 return m_targets[0]; 276 } 277 278 public MyOodbLocal getTarget(int index) 279 { 280 return m_targets[index]; 281 } 282 283 public MyOodbLocal[] getTargets() 284 { 285 return m_targets; 286 } 287 288 public void createTarget(Class [] classTypes, String sig, Object [] args) throws Exception 289 { 290 m_targets = new MyOodbLocal[classTypes.length]; 291 292 if (sig != null) 293 { 294 Constructor constructor = getConstructor(classTypes[0], sig); 295 m_targets[0] = (MyOodbLocal) constructor.newInstance(args); 296 } 297 else 298 { 299 m_targets[0] = (MyOodbLocal) classTypes[0].newInstance(); 300 } 301 302 m_targets[0].setContainer(this); 303 304 for (int i = 1; i < m_targets.length; i++) 305 { 306 try 308 { 309 Constructor constructor = getConstructor(classTypes[i], sig); 310 m_targets[i] = (MyOodbLocal) constructor.newInstance(args); 311 } 312 catch (NoSuchMethodException e) 313 { 314 m_targets[i] = (MyOodbLocal) classTypes[i].newInstance(); 315 } 316 317 m_targets[i].setContainer(this); 318 } 319 320 if (MyOodbManager.getTheManager().m_postObjectMethodCallback != null) 321 { 322 MyOodbManager.getTheManager().m_postObjectMethodCallback.invoke(null, new Object [] {m_targets[0], "CONSTRUCTOR", new Object []{}}); 323 } 324 325 for (int i = 0; i < m_targets.length; i++) 326 { 327 m_targets[i].onCreate(); 328 } 329 330 raiseState(STATE_CREATED); 331 } 332 333 public Object invokeTarget(String methodName, String sig, Object [] args, int accessLevel) throws Exception 334 { 335 Method primaryMethod = getMethod(m_targets[0], methodName, sig, args); 336 337 if (primaryMethod == null) 338 { 339 throw new NoSuchMethodException ("Target( " + m_objectId + " ) Method Name: " + methodName); 340 } 341 342 if ((accessLevel > Lock.ACCESS_READ) && (MyOodbManager.getTheManager().m_preObjectMethodCallback != null)) 343 { 344 MyOodbManager.getTheManager().m_preObjectMethodCallback.invoke(null, new Object [] {m_targets[0], primaryMethod.getName(), args}); 345 } 346 347 Object result = primaryMethod.invoke(m_targets[0], args); 348 349 if ((accessLevel > Lock.ACCESS_READ) && (MyOodbManager.getTheManager().m_postObjectMethodCallback != null)) 350 { 351 MyOodbManager.getTheManager().m_postObjectMethodCallback.invoke(null, new Object [] {m_targets[0], primaryMethod.getName(), args}); 352 } 353 354 if ((m_targets.length != 1) && (accessLevel > Lock.ACCESS_READ)) 355 { 356 try 357 { 358 m_targets[0].getClass().getDeclaredMethod(primaryMethod.getName(), primaryMethod.getParameterTypes()); 359 } 360 catch (java.lang.NoSuchMethodException e1) 361 { 362 for (int i = 1; i < m_targets.length; i++) 363 { 364 Method secondaryMethod = getMethod(m_targets[i], methodName, sig, args); 365 366 if (secondaryMethod == null) 367 { 368 continue; 369 } 370 371 try 372 { 373 secondaryMethod.invoke(m_targets[i], args); 374 } 375 catch (java.lang.IllegalArgumentException e2) 376 { 377 } 379 } 380 } 381 } 382 383 return result; 384 } 385 386 public Object invokeTarget(int methodIndex, Object [] args, int accessLevel) throws Exception 387 { 388 Class classType = m_targets[0].getClass(); 389 390 Method[] primaryMethods = getMethods(classType); 391 Method primaryMethod = primaryMethods[methodIndex]; 392 393 if (primaryMethod == null) 394 { 395 throw new NoSuchMethodException ("Target( " + m_objectId + " ) Method index: " + methodIndex); 396 } 397 398 if ((accessLevel > Lock.ACCESS_READ) && (MyOodbManager.getTheManager().m_preObjectMethodCallback != null)) 399 { 400 MyOodbManager.getTheManager().m_preObjectMethodCallback.invoke(null, new Object [] {m_targets[0], primaryMethod.getName(), args}); 401 } 402 403 Object result = primaryMethod.invoke(m_targets[0],args); 404 405 if ((accessLevel > Lock.ACCESS_READ) && (MyOodbManager.getTheManager().m_postObjectMethodCallback != null)) 406 { 407 MyOodbManager.getTheManager().m_postObjectMethodCallback.invoke(null, new Object [] {m_targets[0], primaryMethod.getName(), args}); 408 } 409 410 if ((m_targets.length != 1) && (accessLevel > Lock.ACCESS_READ)) 411 { 412 try 413 { 414 m_targets[0].getClass().getDeclaredMethod(primaryMethod.getName(), primaryMethod.getParameterTypes()); 415 } 416 catch (java.lang.NoSuchMethodException e1) 417 { 418 for (int i = 1; i < m_targets.length; i++) 419 { 420 classType = m_targets[i].getClass(); 421 422 try 423 { 424 Method secondaryMethod = classType.getMethod(primaryMethod.getName(), primaryMethod.getParameterTypes()); 425 426 secondaryMethod.invoke(m_targets[i], args); 427 } 428 catch (java.lang.NoSuchMethodException e2) 429 { 430 } 432 catch (java.lang.IllegalArgumentException e3) 433 { 434 } 436 } 437 } 438 } 439 440 return result; 441 } 442 443 public void deleteTarget() throws Exception 444 { 445 if (getDeactivationFlag() == true) 446 { 447 throw new PermissionException("Target( " + m_objectId + " ) Invalid delete (deactived): " + m_targets[0]); 448 } 449 450 if (MyOodbManager.getTheManager().m_preObjectMethodCallback != null) 451 { 452 MyOodbManager.getTheManager().m_preObjectMethodCallback.invoke(null, new Object [] {m_targets[0], "DESTRUCTOR", new Object []{}}); 453 } 454 455 for (int i = 0; i < m_targets.length; i++) 456 { 457 m_targets[i].onDelete(); 458 } 459 460 raiseState(STATE_DELETED); 461 } 462 463 public void setBean(MyOodbBean bean) 464 { 465 if (m_myBean == null) 466 { 467 getBean(); 468 } 469 470 if (m_myBean.getClass().equals(bean.getClass()) == false) 471 { 472 throw new PermissionException("Target( " + m_objectId + " ) Invalid set (bean mismatch): " + bean.getClass()); 473 } 474 475 try 476 { 477 480 synchronized(this) 481 { 482 Method[] methods = getMethods(m_targets[0].getClass()); 483 for (int methodIndex = 0; methodIndex < methods.length; methodIndex++) 484 { 485 Method setMethod = methods[methodIndex]; 486 Method getMethod = ifThisIsAJavaBeanSetMethodThenReturnItsGetMethod(setMethod, methods); 487 488 if (getMethod == null) 489 { 490 continue; 491 } 492 493 try 494 { 495 getMethod = bean.getClass().getDeclaredMethod(getMethod.getName(), getMethod.getParameterTypes()); 496 Object retval = getMethod.invoke(bean, new Object []{}); 497 setMethod.invoke(m_targets[0], new Object []{retval}); 498 } 499 catch (java.lang.NoSuchMethodException e) 500 { 501 } 503 } 504 } 505 } 506 catch (Exception e) 507 { 508 throw new InternalException("Target( " + m_objectId + " ) Caught during set bean: " + e, e); 509 } 510 } 511 512 public MyOodbBean getBean() 513 { 514 try 515 { 516 if (m_myBean == null) 517 { 518 synchronized(m_classTable) 519 { 520 if (m_myBean == null) 521 { 522 String beanName = m_targets[0].getClass().getName(); 523 beanName = beanName.substring(0, beanName.length() - IMPL_NAME_SUFFIX.length()) + BEAN_NAME_SUFFIX; 524 525 MethodSignature def = new MethodSignature(beanName, "CONSTRUCTOR", "org.myoodb.core.Identifier"); 526 Constructor constructor = (Constructor) m_methodTable.get(def); 527 528 if (constructor == null) 529 { 530 synchronized(m_methodTable) 531 { 532 constructor = (Constructor) m_methodTable.get(def); 533 534 if (constructor == null) 535 { 536 Class classType = MyOodbManager.getTheManager().getClassManager().getClass(beanName); 537 constructor = classType.getConstructor(new Class []{Identifier.class}); 538 539 m_methodTable.put(def, constructor); 540 } 541 } 542 } 543 544 m_myBean = (MyOodbBean)constructor.newInstance(new Object []{getObjectId()}); 545 } 546 } 547 } 548 549 552 synchronized(this) 553 { 554 Method[] methods = getMethods(m_targets[0].getClass()); 555 for (int methodIndex = 0; methodIndex < methods.length; methodIndex++) 556 { 557 Method setMethod = methods[methodIndex]; 558 Method getMethod = ifThisIsAJavaBeanSetMethodThenReturnItsGetMethod(setMethod, methods); 559 560 if (getMethod == null) 561 { 562 continue; 563 } 564 565 try 566 { 567 setMethod = m_myBean.getClass().getDeclaredMethod(setMethod.getName(), setMethod.getParameterTypes()); 568 Object retval = getMethod.invoke(m_targets[0], new Object []{}); 569 setMethod.invoke(m_myBean, new Object []{retval}); 570 } 571 catch (java.lang.NoSuchMethodException e) 572 { 573 } 575 } 576 } 577 578 return m_myBean; 579 } 580 catch (Exception e) 581 { 582 throw new InternalException("Target( " + m_objectId + " ) Caught during get bean: " + e, e); 583 } 584 } 585 586 public void setXML(String xml) 587 { 588 org.myoodb.MyOodbLocal[] targets = m_targets; 589 590 try 591 { 592 594 synchronized(this) 595 { 596 com.thoughtworks.xstream.XStream xstream = new com.thoughtworks.xstream.XStream(); 597 m_targets = (org.myoodb.MyOodbLocal[]) xstream.fromXML(xml); 598 599 for (int i = 0; i < m_targets.length; i++) 600 { 601 m_targets[i].setContainer(this); 602 } 603 604 m_cluster.write(); 605 } 606 } 607 catch (Exception e) 608 { 609 m_targets = targets; 610 611 throw new InternalException("Target( " + m_objectId + " ) Caught during set xml: " + e, e); 612 } 613 } 614 615 public String getXML() 616 { 617 try 618 { 619 621 synchronized(this) 622 { 623 com.thoughtworks.xstream.XStream xstream = new com.thoughtworks.xstream.XStream(); 624 return xstream.toXML(m_targets); 625 } 626 } 627 catch (Exception e) 628 { 629 throw new InternalException("Target( " + m_objectId + " ) Caught during get xml: " + e, e); 630 } 631 } 632 633 public MyOodbProxy getProxy() 634 { 635 try 636 { 637 if (m_myProxy == null) 638 { 639 synchronized(m_classTable) 640 { 641 if (m_myProxy == null) 642 { 643 String proxyName = m_targets[0].getClass().getName(); 644 proxyName = proxyName.substring(0, proxyName.length() - IMPL_NAME_SUFFIX.length()) + PROXY_NAME_SUFFIX; 645 646 Class classType = MyOodbManager.getTheManager().getClassManager().getClass(proxyName); 647 Constructor constructor = (Constructor) classType.getConstructor(new Class []{Identifier.class, AbstractDatabase.class}); 648 649 m_myProxy = (MyOodbProxy) constructor.newInstance(new Object []{getObjectId(), MyOodbManager.getTheManager().getDatabase()}); 650 } 651 } 652 } 653 654 return m_myProxy; 655 } 656 catch (Exception e) 657 { 658 throw new InternalException("Target( " + m_objectId + " ) Caught during set proxy: " + e, e); 659 } 660 } 661 662 public int hashCode() 663 { 664 return getObjectId().hashCode(); 665 } 666 667 public boolean equals(Object obj) 668 { 669 if (this == obj) 670 { 671 return true; 672 } 673 else if (obj instanceof AbstractObjectContainer) 674 { 675 return getObjectId().equals(((AbstractObjectContainer) obj).getObjectId()); 676 } 677 else 678 { 679 return false; 680 } 681 } 682 683 public String toString() 684 { 685 return "ObjectContainer [target="+getTarget()+", objectId="+getObjectId()+", cluster="+getCluster()+"]"; 686 } 687 688 public void writeExternal(ObjectOutput out) throws IOException 689 { 690 out.writeByte((byte) m_state); 691 out.writeBoolean(m_deactivationFlag); 692 out.writeObject(m_objectId); 693 694 if (m_targets != null) 695 { 696 for (int i = 0; i < m_targets.length; i++) 697 { 698 ((MyOodbLocal) m_targets[i]).setConvertFlag(false); 699 } 700 } 701 702 out.writeObject(m_targets); 704 } 705 706 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 707 { 708 m_state = (int) in.readByte(); 709 m_deactivationFlag = in.readBoolean(); 710 m_objectId = (Identifier) in.readObject(); 711 m_targets = (MyOodbLocal[]) in.readObject(); 712 713 MyOodbManager manager = MyOodbManager.getTheManager(); 715 if ((m_targets == null) && ((manager == null) || (manager.getStoreManager().isVerifyingDatabase() == false))) 716 { 717 return; 718 } 719 720 for (int i = 0; i < m_targets.length; i++) 721 { 722 m_targets[i].setContainer(this); 723 } 724 } 725 } 726 | Popular Tags |