1 7 8 package java.beans.beancontext; 9 10 import java.awt.Component ; 11 import java.awt.Container ; 12 13 import java.beans.Beans ; 14 import java.beans.AppletInitializer ; 15 16 import java.beans.DesignMode ; 17 18 import java.beans.PropertyChangeEvent ; 19 import java.beans.PropertyChangeListener ; 20 import java.beans.PropertyChangeSupport ; 21 22 import java.beans.VetoableChangeListener ; 23 import java.beans.VetoableChangeSupport ; 24 import java.beans.PropertyVetoException ; 25 26 import java.beans.Visibility ; 27 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.io.ObjectInputStream ; 31 import java.io.ObjectOutputStream ; 32 import java.io.Serializable ; 33 34 import java.net.URL ; 35 36 import java.util.ArrayList ; 37 import java.util.Collection ; 38 import java.util.HashMap ; 39 import java.util.Iterator ; 40 import java.util.Locale ; 41 import java.util.Map ; 42 43 44 58 public class BeanContextSupport extends BeanContextChildSupport 59 implements BeanContext , 60 Serializable , 61 PropertyChangeListener , 62 VetoableChangeListener { 63 64 static final long serialVersionUID = -4879613978649577204L; 66 67 86 public BeanContextSupport(BeanContext peer, Locale lcle, boolean dTime, boolean visible) { 87 super(peer); 88 89 locale = lcle != null ? lcle : Locale.getDefault(); 90 designTime = dTime; 91 okToUseGui = visible; 92 93 initialize(); 94 } 95 96 111 public BeanContextSupport(BeanContext peer, Locale lcle, boolean dtime) { 112 this (peer, lcle, dtime, true); 113 } 114 115 131 public BeanContextSupport(BeanContext peer, Locale lcle) { 132 this (peer, lcle, false, true); 133 } 134 135 143 public BeanContextSupport(BeanContext peer) { 144 this (peer, null, false, true); 145 } 146 147 150 151 public BeanContextSupport() { 152 this (null, null, false, true); 153 } 154 155 160 public BeanContext getBeanContextPeer() { return (BeanContext )getBeanContextChildPeer(); } 161 162 179 public Object instantiateChild(String beanName) 180 throws IOException , ClassNotFoundException { 181 BeanContext bc = getBeanContextPeer(); 182 183 return Beans.instantiate(bc.getClass().getClassLoader(), beanName, bc); 184 } 185 186 192 public int size() { 193 synchronized(children) { 194 return children.size(); 195 } 196 } 197 198 206 public boolean isEmpty() { 207 synchronized(children) { 208 return children.isEmpty(); 209 } 210 } 211 212 218 public boolean contains(Object o) { 219 synchronized(children) { 220 return children.containsKey(o); 221 } 222 } 223 224 230 public boolean containsKey(Object o) { 231 synchronized(children) { 232 return children.containsKey(o); 233 } 234 } 235 236 241 public Iterator iterator() { 242 synchronized(children) { 243 return new BCSIterator(children.keySet().iterator()); 244 } 245 } 246 247 251 public Object [] toArray() { 252 synchronized(children) { 253 return children.keySet().toArray(); 254 } 255 } 256 257 265 public Object [] toArray(Object [] arry) { 266 synchronized(children) { 267 return children.keySet().toArray(arry); 268 } 269 } 270 271 272 273 274 278 279 protected static final class BCSIterator implements Iterator { 280 BCSIterator(Iterator i) { super(); src = i; } 281 282 public boolean hasNext() { return src.hasNext(); } 283 public Object next() { return src.next(); } 284 public void remove() { } 285 286 private Iterator src; 287 } 288 289 290 291 299 300 protected class BCSChild implements Serializable { 301 302 private static final long serialVersionUID = -5815286101609939109L; 303 304 BCSChild(Object bcc, Object peer) { 305 super(); 306 307 child = bcc; 308 proxyPeer = peer; 309 } 310 311 Object getChild() { return child; } 312 313 void setRemovePending(boolean v) { removePending = v; } 314 315 boolean isRemovePending() { return removePending; } 316 317 boolean isProxyPeer() { return proxyPeer != null; } 318 319 Object getProxyPeer() { return proxyPeer; } 320 323 324 325 private Object child; 326 private Object proxyPeer; 327 328 private transient boolean removePending; 329 } 330 331 341 342 protected BCSChild createBCSChild(Object targetChild, Object peer) { 343 return new BCSChild(targetChild, peer); 344 } 345 346 347 348 362 public boolean add(Object targetChild) { 363 364 if (targetChild == null) throw new IllegalArgumentException (); 365 366 369 if (children.containsKey(targetChild)) return false; 371 synchronized(BeanContext.globalHierarchyLock) { 372 if (children.containsKey(targetChild)) return false; 374 if (!validatePendingAdd(targetChild)) { 375 throw new IllegalStateException (); 376 } 377 378 379 382 BeanContextChild cbcc = getChildBeanContextChild(targetChild); 383 BeanContextChild bccp = null; 384 385 synchronized(targetChild) { 386 387 if (targetChild instanceof BeanContextProxy ) { 388 bccp = ((BeanContextProxy )targetChild).getBeanContextProxy(); 389 390 if (bccp == null) throw new NullPointerException ("BeanContextPeer.getBeanContextProxy()"); 391 } 392 393 BCSChild bcsc = createBCSChild(targetChild, bccp); 394 BCSChild pbcsc = null; 395 396 synchronized (children) { 397 children.put(targetChild, bcsc); 398 399 if (bccp != null) children.put(bccp, pbcsc = createBCSChild(bccp, targetChild)); 400 } 401 402 if (cbcc != null) synchronized(cbcc) { 403 try { 404 cbcc.setBeanContext(getBeanContextPeer()); 405 } catch (PropertyVetoException pve) { 406 407 synchronized (children) { 408 children.remove(targetChild); 409 410 if (bccp != null) children.remove(bccp); 411 } 412 413 throw new IllegalStateException (); 414 } 415 416 cbcc.addPropertyChangeListener("beanContext", childPCL); 417 cbcc.addVetoableChangeListener("beanContext", childVCL); 418 } 419 420 Visibility v = getChildVisibility(targetChild); 421 422 if (v != null) { 423 if (okToUseGui) 424 v.okToUseGui(); 425 else 426 v.dontUseGui(); 427 } 428 429 if (getChildSerializable(targetChild) != null) serializable++; 430 431 childJustAddedHook(targetChild, bcsc); 432 433 if (bccp != null) { 434 v = getChildVisibility(bccp); 435 436 if (v != null) { 437 if (okToUseGui) 438 v.okToUseGui(); 439 else 440 v.dontUseGui(); 441 } 442 443 if (getChildSerializable(bccp) != null) serializable++; 444 445 childJustAddedHook(bccp, pbcsc); 446 } 447 448 449 } 450 451 453 fireChildrenAdded(new BeanContextMembershipEvent (getBeanContextPeer(), bccp == null ? new Object [] { targetChild } : new Object [] { targetChild, bccp } )); 454 455 } 456 457 return true; 458 } 459 460 466 public boolean remove(Object targetChild) { 467 return remove(targetChild, true); 468 } 469 470 479 protected boolean remove(Object targetChild, boolean callChildSetBC) { 480 481 if (targetChild == null) throw new IllegalArgumentException (); 482 483 synchronized(BeanContext.globalHierarchyLock) { 484 if (!containsKey(targetChild)) return false; 485 486 if (!validatePendingRemove(targetChild)) { 487 throw new IllegalStateException (); 488 } 489 490 BCSChild bcsc = (BCSChild)children.get(targetChild); 491 BCSChild pbcsc = null; 492 Object peer = null; 493 494 497 synchronized(targetChild) { 498 if (callChildSetBC) { 499 BeanContextChild cbcc = getChildBeanContextChild(targetChild); 500 if (cbcc != null) synchronized(cbcc) { 501 cbcc.removePropertyChangeListener("beanContext", childPCL); 502 cbcc.removeVetoableChangeListener("beanContext", childVCL); 503 504 try { 505 cbcc.setBeanContext(null); 506 } catch (PropertyVetoException pve1) { 507 cbcc.addPropertyChangeListener("beanContext", childPCL); 508 cbcc.addVetoableChangeListener("beanContext", childVCL); 509 throw new IllegalStateException (); 510 } 511 512 } 513 } 514 515 synchronized (children) { 516 children.remove(targetChild); 517 518 if (bcsc.isProxyPeer()) { 519 pbcsc = (BCSChild)children.get(peer = bcsc.getProxyPeer()); 520 children.remove(peer); 521 } 522 } 523 524 if (getChildSerializable(targetChild) != null) serializable--; 525 526 childJustRemovedHook(targetChild, bcsc); 527 528 if (peer != null) { 529 if (getChildSerializable(peer) != null) serializable--; 530 531 childJustRemovedHook(peer, pbcsc); 532 } 533 } 534 535 fireChildrenRemoved(new BeanContextMembershipEvent (getBeanContextPeer(), peer == null ? new Object [] { targetChild } : new Object [] { targetChild, peer } )); 536 537 } 538 539 return true; 540 } 541 542 552 public boolean containsAll(Collection c) { 553 synchronized(children) { 554 Iterator i = c.iterator(); 555 while (i.hasNext()) 556 if(!contains(i.next())) 557 return false; 558 559 return true; 560 } 561 } 562 563 568 public boolean addAll(Collection c) { 569 throw new UnsupportedOperationException (); 570 } 571 572 577 public boolean removeAll(Collection c) { 578 throw new UnsupportedOperationException (); 579 } 580 581 582 587 public boolean retainAll(Collection c) { 588 throw new UnsupportedOperationException (); 589 } 590 591 596 public void clear() { 597 throw new UnsupportedOperationException (); 598 } 599 600 606 607 public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) { 608 if (bcml == null) throw new NullPointerException ("listener"); 609 610 synchronized(bcmListeners) { 611 if (bcmListeners.contains(bcml)) 612 return; 613 else 614 bcmListeners.add(bcml); 615 } 616 } 617 618 624 625 public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) { 626 if (bcml == null) throw new NullPointerException ("listener"); 627 628 synchronized(bcmListeners) { 629 if (!bcmListeners.contains(bcml)) 630 return; 631 else 632 bcmListeners.remove(bcml); 633 } 634 } 635 636 643 644 public InputStream getResourceAsStream(String name, BeanContextChild bcc) { 645 if (name == null) throw new NullPointerException ("name"); 646 if (bcc == null) throw new NullPointerException ("bcc"); 647 648 if (containsKey(bcc)) { 649 ClassLoader cl = bcc.getClass().getClassLoader(); 650 651 return cl != null ? cl.getResourceAsStream(name) 652 : ClassLoader.getSystemResourceAsStream(name); 653 } else throw new IllegalArgumentException ("Not a valid child"); 654 } 655 656 662 663 public URL getResource(String name, BeanContextChild bcc) { 664 if (name == null) throw new NullPointerException ("name"); 665 if (bcc == null) throw new NullPointerException ("bcc"); 666 667 if (containsKey(bcc)) { 668 ClassLoader cl = bcc.getClass().getClassLoader(); 669 670 return cl != null ? cl.getResource(name) 671 : ClassLoader.getSystemResource(name); 672 } else throw new IllegalArgumentException ("Not a valid child"); 673 } 674 675 679 public synchronized void setDesignTime(boolean dTime) { 680 if (designTime != dTime) { 681 designTime = dTime; 682 683 firePropertyChange("designMode", Boolean.valueOf(!dTime), Boolean.valueOf(dTime)); 684 } 685 } 686 687 688 694 public synchronized boolean isDesignTime() { return designTime; } 695 696 702 public synchronized void setLocale(Locale newLocale) throws PropertyVetoException { 703 704 if ((locale != null && !locale.equals(newLocale)) && newLocale != null) { 705 Locale old = locale; 706 707 fireVetoableChange("locale", old, newLocale); 709 locale = newLocale; 710 711 firePropertyChange("locale", old, newLocale); 712 } 713 } 714 715 720 public synchronized Locale getLocale() { return locale; } 721 722 734 public synchronized boolean needsGui() { 735 BeanContext bc = getBeanContextPeer(); 736 737 if (bc != this) { 738 if (bc instanceof Visibility ) return ((Visibility )bc).needsGui(); 739 740 if (bc instanceof Container || bc instanceof Component ) 741 return true; 742 } 743 744 synchronized(children) { 745 for (Iterator i = children.keySet().iterator(); i.hasNext();) { 746 Object c = i.next(); 747 748 try { 749 return ((Visibility )c).needsGui(); 750 } catch (ClassCastException cce) { 751 } 753 754 if (c instanceof Container || c instanceof Component ) 755 return true; 756 } 757 } 758 759 return false; 760 } 761 762 765 766 public synchronized void dontUseGui() { 767 if (okToUseGui) { 768 okToUseGui = false; 769 770 synchronized(children) { 772 for (Iterator i = children.keySet().iterator(); i.hasNext();) { 773 Visibility v = getChildVisibility(i.next()); 774 775 if (v != null) v.dontUseGui(); 776 } 777 } 778 } 779 } 780 781 784 785 public synchronized void okToUseGui() { 786 if (!okToUseGui) { 787 okToUseGui = true; 788 789 synchronized(children) { 791 for (Iterator i = children.keySet().iterator(); i.hasNext();) { 792 Visibility v = getChildVisibility(i.next()); 793 794 if (v != null) v.okToUseGui(); 795 } 796 } 797 } 798 } 799 800 806 public boolean avoidingGui() { 807 return !okToUseGui && needsGui(); 808 } 809 810 816 public boolean isSerializing() { return serializing; } 817 818 823 protected Iterator bcsChildren() { synchronized(children) { return children.values().iterator(); } } 824 825 836 837 protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException { 838 } 839 840 851 852 protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException , ClassNotFoundException { 853 } 854 855 860 protected void childDeserializedHook(Object child, BCSChild bcsc) { 861 synchronized(children) { 862 children.put(child, bcsc); 863 } 864 } 865 866 873 protected final void serialize(ObjectOutputStream oos, Collection coll) throws IOException { 874 int count = 0; 875 Object [] objects = coll.toArray(); 876 877 for (int i = 0; i < objects.length; i++) { 878 if (objects[i] instanceof Serializable ) 879 count++; 880 else 881 objects[i] = null; 882 } 883 884 oos.writeInt(count); 886 for (int i = 0; count > 0; i++) { 887 Object o = objects[i]; 888 889 if (o != null) { 890 oos.writeObject(o); 891 count--; 892 } 893 } 894 } 895 896 901 protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException , ClassNotFoundException { 902 int count = 0; 903 904 count = ois.readInt(); 905 906 while (count-- > 0) { 907 coll.add(ois.readObject()); 908 } 909 } 910 911 918 public final void writeChildren(ObjectOutputStream oos) throws IOException { 919 if (serializable <= 0) return; 920 921 boolean prev = serializing; 922 923 serializing = true; 924 925 int count = 0; 926 927 synchronized(children) { 928 Iterator i = children.entrySet().iterator(); 929 930 while (i.hasNext() && count < serializable) { 931 Map.Entry entry = (Map.Entry )i.next(); 932 933 if (entry.getKey() instanceof Serializable ) { 934 try { 935 oos.writeObject(entry.getKey()); oos.writeObject(entry.getValue()); } catch (IOException ioe) { 938 serializing = prev; 939 throw ioe; 940 } 941 count++; 942 } 943 } 944 } 945 946 serializing = prev; 947 948 if (count != serializable) { 949 throw new IOException ("wrote different number of children than expected"); 950 } 951 952 } 953 954 967 968 private synchronized void writeObject(ObjectOutputStream oos) throws IOException , ClassNotFoundException { 969 serializing = true; 970 971 synchronized (BeanContext.globalHierarchyLock) { 972 try { 973 oos.defaultWriteObject(); 975 bcsPreSerializationHook(oos); 976 977 if (serializable > 0 && this.equals(getBeanContextPeer())) 978 writeChildren(oos); 979 980 serialize(oos, (Collection )bcmListeners); 981 } finally { 982 serializing = false; 983 } 984 } 985 } 986 987 992 993 public final void readChildren(ObjectInputStream ois) throws IOException , ClassNotFoundException { 994 int count = serializable; 995 996 while (count-- > 0) { 997 Object child = null; 998 BeanContextSupport.BCSChild bscc = null; 999 1000 try { 1001 child = ois.readObject(); 1002 bscc = (BeanContextSupport.BCSChild )ois.readObject(); 1003 } catch (IOException ioe) { 1004 continue; 1005 } catch (ClassNotFoundException cnfe) { 1006 continue; 1007 } 1008 1009 1010 synchronized(child) { 1011 BeanContextChild bcc = null; 1012 1013 try { 1014 bcc = (BeanContextChild )child; 1015 } catch (ClassCastException cce) { 1016 } 1018 1019 if (bcc != null) { 1020 try { 1021 bcc.setBeanContext(getBeanContextPeer()); 1022 1023 bcc.addPropertyChangeListener("beanContext", childPCL); 1024 bcc.addVetoableChangeListener("beanContext", childVCL); 1025 1026 } catch (PropertyVetoException pve) { 1027 continue; 1028 } 1029 } 1030 1031 childDeserializedHook(child, bscc); 1032 } 1033 } 1034 } 1035 1036 1041 1042 private synchronized void readObject(ObjectInputStream ois) throws IOException , ClassNotFoundException { 1043 1044 synchronized(BeanContext.globalHierarchyLock) { 1045 ois.defaultReadObject(); 1046 1047 initialize(); 1048 1049 bcsPreDeserializationHook(ois); 1050 1051 if (serializable > 0 && this.equals(getBeanContextPeer())) 1052 readChildren(ois); 1053 1054 deserialize(ois, bcmListeners = new ArrayList (1)); 1055 } 1056 } 1057 1058 1061 1062 public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException { 1063 String propertyName = pce.getPropertyName(); 1064 Object source = pce.getSource(); 1065 1066 synchronized(children) { 1067 if ("beanContext".equals(propertyName) && 1068 containsKey(source) && 1069 !getBeanContextPeer().equals(pce.getNewValue()) 1070 ) { 1071 if (!validatePendingRemove(source)) { 1072 throw new PropertyVetoException ("current BeanContext vetoes setBeanContext()", pce); 1073 } else ((BCSChild)children.get(source)).setRemovePending(true); 1074 } 1075 } 1076 } 1077 1078 1081 1082 public void propertyChange(PropertyChangeEvent pce) { 1083 String propertyName = pce.getPropertyName(); 1084 Object source = pce.getSource(); 1085 1086 synchronized(children) { 1087 if ("beanContext".equals(propertyName) && 1088 containsKey(source) && 1089 ((BCSChild)children.get(source)).isRemovePending()) { 1090 BeanContext bc = getBeanContextPeer(); 1091 1092 if (bc.equals(pce.getOldValue()) && !bc.equals(pce.getNewValue())) { 1093 remove(source, false); 1094 } else { 1095 ((BCSChild)children.get(source)).setRemovePending(false); 1096 } 1097 } 1098 } 1099 } 1100 1101 1110 1111 protected boolean validatePendingAdd(Object targetChild) { 1112 return true; 1113 } 1114 1115 1124 1125 protected boolean validatePendingRemove(Object targetChild) { 1126 return true; 1127 } 1128 1129 1134 1135 protected void childJustAddedHook(Object child, BCSChild bcsc) { 1136 } 1137 1138 1143 1144 protected void childJustRemovedHook(Object child, BCSChild bcsc) { 1145 } 1146 1147 1152 protected static final Visibility getChildVisibility(Object child) { 1153 try { 1154 return (Visibility )child; 1155 } catch (ClassCastException cce) { 1156 return null; 1157 } 1158 } 1159 1160 1165 protected static final Serializable getChildSerializable(Object child) { 1166 try { 1167 return (Serializable )child; 1168 } catch (ClassCastException cce) { 1169 return null; 1170 } 1171 } 1172 1173 1179 protected static final PropertyChangeListener getChildPropertyChangeListener(Object child) { 1180 try { 1181 return (PropertyChangeListener )child; 1182 } catch (ClassCastException cce) { 1183 return null; 1184 } 1185 } 1186 1187 1193 protected static final VetoableChangeListener getChildVetoableChangeListener(Object child) { 1194 try { 1195 return (VetoableChangeListener )child; 1196 } catch (ClassCastException cce) { 1197 return null; 1198 } 1199 } 1200 1201 1207 protected static final BeanContextMembershipListener getChildBeanContextMembershipListener(Object child) { 1208 try { 1209 return (BeanContextMembershipListener )child; 1210 } catch (ClassCastException cce) { 1211 return null; 1212 } 1213 } 1214 1215 1221 protected static final BeanContextChild getChildBeanContextChild(Object child) { 1222 try { 1223 BeanContextChild bcc = (BeanContextChild )child; 1224 1225 if (child instanceof BeanContextChild && child instanceof BeanContextProxy ) 1226 throw new IllegalArgumentException ("child cannot implement both BeanContextChild and BeanContextProxy"); 1227 else 1228 return bcc; 1229 } catch (ClassCastException cce) { 1230 try { 1231 return ((BeanContextProxy )child).getBeanContextProxy(); 1232 } catch (ClassCastException cce1) { 1233 return null; 1234 } 1235 } 1236 } 1237 1238 1241 1242 protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) { 1243 Object [] copy; 1244 1245 synchronized(bcmListeners) { copy = bcmListeners.toArray(); } 1246 1247 for (int i = 0; i < copy.length; i++) 1248 ((BeanContextMembershipListener )copy[i]).childrenAdded(bcme); 1249 } 1250 1251 1254 1255 protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) { 1256 Object [] copy; 1257 1258 synchronized(bcmListeners) { copy = bcmListeners.toArray(); } 1259 1260 for (int i = 0; i < copy.length; i++) 1261 ((BeanContextMembershipListener )copy[i]).childrenRemoved(bcme); 1262 } 1263 1264 1274 1275 protected synchronized void initialize() { 1276 children = new HashMap (serializable + 1); 1277 bcmListeners = new ArrayList (1); 1278 1279 childPCL = new PropertyChangeListener () { 1280 1281 1287 1288 public void propertyChange(PropertyChangeEvent pce) { 1289 BeanContextSupport.this.propertyChange(pce); 1290 } 1291 }; 1292 1293 childVCL = new VetoableChangeListener () { 1294 1295 1301 1302 public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException { 1303 BeanContextSupport.this.vetoableChange(pce); 1304 } 1305 }; 1306 } 1307 1308 1312 protected final Object [] copyChildren() { 1313 synchronized(children) { return children.keySet().toArray(); } 1314 } 1315 1316 1323 protected static final boolean classEquals(Class first, Class second) { 1324 return first.equals(second) || first.getName().equals(second.getName()); 1325 } 1326 1327 1328 1331 1332 1333 1337 protected transient HashMap children; 1338 1339 private int serializable = 0; 1341 1345 protected transient ArrayList bcmListeners; 1346 1347 1349 1352 protected Locale locale; 1353 1354 1358 protected boolean okToUseGui; 1359 1360 1361 1365 protected boolean designTime; 1366 1367 1370 1371 private transient PropertyChangeListener childPCL; 1372 1373 private transient VetoableChangeListener childVCL; 1374 1375 private transient boolean serializing; 1376} 1377 | Popular Tags |