1 package org.apache.beehive.controls.runtime.bean; 2 19 20 import java.lang.annotation.Annotation ; 21 import java.lang.reflect.AnnotatedElement ; 22 import java.lang.reflect.Field ; 23 import java.lang.reflect.Method ; 24 import java.beans.PropertyChangeEvent ; 25 import java.beans.PropertyVetoException ; 26 import java.beans.beancontext.BeanContext ; 27 import java.beans.beancontext.BeanContextServiceRevokedEvent ; 28 import java.beans.beancontext.BeanContextServiceRevokedListener ; 29 import java.beans.beancontext.BeanContextServiceProvider ; 30 import java.beans.beancontext.BeanContextServices ; 31 import java.beans.beancontext.BeanContextServicesSupport ; 32 import java.util.*; 33 import java.io.InputStream ; 34 import java.io.InputStreamReader ; 35 import java.io.BufferedReader ; 36 import java.io.IOException ; 37 38 import org.apache.beehive.controls.api.ControlException; 39 import org.apache.beehive.controls.api.bean.ControlInterface; 40 import org.apache.beehive.controls.api.context.ControlHandle; 41 import org.apache.beehive.controls.api.properties.AnnotatedElementMap; 42 import org.apache.beehive.controls.api.properties.BeanPropertyMap; 43 import org.apache.beehive.controls.api.properties.PropertyMap; 44 import org.apache.beehive.controls.api.properties.PropertySet; 45 import org.apache.beehive.controls.api.properties.PropertySetProxy; 46 47 57 public class ControlBeanContext 58 extends BeanContextServicesSupport 59 implements BeanContextServiceRevokedListener , 60 org.apache.beehive.controls.api.context.ControlBeanContext, 61 java.beans.PropertyChangeListener , 62 java.beans.VetoableChangeListener 63 { 64 71 protected ControlBeanContext(ControlBean bean) 72 { 73 _bean = bean; 74 } 75 76 82 private static class ControlBeanContextProvider implements BeanContextServiceProvider 83 { 84 public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, 88 Object serviceSelector) 89 { 90 if (requestor instanceof ControlBean) 95 return ((ControlBean)requestor).getControlBeanContext(); 96 97 return null; 98 } 99 100 public void releaseService(BeanContextServices bcs, Object requestor, Object service) 104 { 105 } 107 108 public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) 112 { 113 return null; } 115 } 116 117 122 static private ControlBeanContextProvider theProvider = new ControlBeanContextProvider(); 123 124 128 public void initialize() 129 { 130 super.initialize(); 131 132 addService(org.apache.beehive.controls.api.context.ControlBeanContext.class, theProvider); 136 } 137 138 143 public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) 144 { 145 } 150 151 156 public synchronized void setBeanContext(BeanContext beanContext) throws PropertyVetoException 157 { 158 ControlBeanContext cbcs = null; 159 160 if (beanContext != null) 161 { 162 if (!(beanContext instanceof ControlBeanContext)) 167 { 168 PropertyChangeEvent pce = new PropertyChangeEvent (_bean, "beanContext", 169 getBeanContext(), beanContext); 170 throw new PropertyVetoException ("Context does not support nesting controls: " + 171 beanContext.getClass(), pce); 172 } 173 174 cbcs = (ControlBeanContext)beanContext; 175 } 176 177 178 super.setBeanContext(beanContext); 179 180 resetControlID(); 181 182 _hasSingleThreadedParent = cbcs != null ? cbcs.isSingleThreadedContainer() : false; 183 184 if (_bean != null) 188 _bean.setBeanContext(beanContext); 189 } 190 191 195 private static class NameGenerator implements java.io.Serializable 196 { 197 NameGenerator(String namePrefix) 198 { 199 _namePrefix = namePrefix; 200 } 201 202 205 public synchronized String next() 206 { 207 return _namePrefix + _nextIndex++; 208 } 209 210 int _nextIndex = 0; 211 String _namePrefix; 212 } 213 214 218 private NameGenerator getNameGenerator(String namePrefix) 219 { 220 synchronized(this) 221 { 222 if (_nameGenerators == null) 223 _nameGenerators = new HashMap<String ,NameGenerator>(); 224 225 NameGenerator nameGenerator = (NameGenerator)_nameGenerators.get(namePrefix); 226 if (nameGenerator == null) 227 { 228 nameGenerator = new NameGenerator(namePrefix); 229 _nameGenerators.put(namePrefix, nameGenerator); 230 } 231 return nameGenerator; 232 } 233 } 234 235 238 public String generateUniqueID(Class clazz) 239 { 240 String namePrefix = clazz.getName(); 241 int dotIndex = namePrefix.lastIndexOf('.'); 242 if (dotIndex > 0) 243 namePrefix = namePrefix.substring(dotIndex+1); 244 NameGenerator nameGenerator = getNameGenerator(namePrefix); 245 return nameGenerator.next(); 246 } 247 248 252 public boolean add(Object targetChild) 253 { 254 String beanID = null; 259 if (targetChild instanceof ControlBean) 260 { 261 ControlBean bean = (ControlBean)targetChild; 265 beanID = bean.getLocalID(); 266 267 if (beanID == null) 271 { 272 beanID = generateUniqueID(bean.getClass()); 273 bean.setLocalID(beanID); 274 } 275 276 ControlBean existingBean = (ControlBean)_childMap.get(beanID); 277 if (existingBean != null && existingBean != targetChild) 278 { 279 throw new IllegalArgumentException ("Attempting to add control with duplicate ID: " + 280 beanID); 281 } 282 } 283 boolean added = super.add(targetChild); 284 if (added && beanID != null) 285 _childMap.put(beanID, targetChild); 286 287 return added; 288 } 289 290 294 public boolean remove(Object targetChild) 295 { 296 assert targetChild instanceof ControlBean; boolean removed = super.remove(targetChild); 298 if (removed) 299 { 300 String localID = ((ControlBean)targetChild).getLocalID(); 304 Object removedChild = _childMap.remove(localID); 305 assert removedChild == targetChild; } 307 return removed; 308 } 309 310 315 public ControlBean getBean(String id) 316 { 317 int delim = id.indexOf(org.apache.beehive.controls.api.bean.ControlBean.IDSeparator); 319 if (delim < 0) return (ControlBean)_childMap.get(id); 321 322 ControlBean bean = (ControlBean)_childMap.get(id.substring(0, delim)); 324 if (bean == null) 325 return bean; 326 327 return ((ControlBeanContext)bean.getBeanContextProxy()).getBean(id.substring(delim+1)); 330 } 331 332 336 public ControlBean getControlBean() 337 { 338 return _bean; 339 } 340 341 public synchronized boolean hasSingleThreadedParent() 342 { 343 return _hasSingleThreadedParent; 344 } 345 346 353 public synchronized boolean isSingleThreadedContainer() 354 { 355 return ( hasSingleThreadedParent() || ( _bean != null && _bean.hasSingleThreadedImpl() )); 356 } 357 358 362 public void initializeControl() 363 { 364 if (_lifeCycleListeners != null) 368 { 369 Iterator iter = _lifeCycleListeners.iterator(); 370 while (iter.hasNext()) 371 { 372 LifeCycle listener = (LifeCycle)iter.next(); 373 listener.onCreate(); 374 } 375 } 376 } 377 378 385 public PropertyMap getAnnotationMap(AnnotatedElement annotElem) 386 { 387 ControlBeanContext beanContext = this; 388 while (beanContext != null) 389 { 390 if (beanContext instanceof ControlContainerContext) 393 return beanContext.getBeanAnnotationMap(_bean, annotElem); 394 beanContext = (ControlBeanContext)beanContext.getBeanContext(); 395 } 396 397 return getBeanAnnotationMap(_bean, annotElem); 399 } 400 401 405 protected PropertyMap getBeanAnnotationMap(ControlBean bean, AnnotatedElement annotElem) 406 { 407 PropertyMap map = new AnnotatedElementMap(annotElem); 408 409 if ( bean != null ) 411 setDelegateMap( map, bean, annotElem ); 412 413 return map; 414 } 415 416 static protected void setDelegateMap( PropertyMap map, ControlBean bean, AnnotatedElement annotElem ) 417 { 418 Class annotClass = null; 423 if (annotElem instanceof Field ) 424 { 425 annotClass = ((Field )annotElem).getType(); 426 } 427 else if (annotElem instanceof Method ) 428 { 429 annotClass = bean.getControlInterface(); 430 } 431 if (annotClass != null) 432 { 433 PropertyMap delegateMap = bean.getAnnotationMap(annotClass); 434 map.setDelegateMap(delegateMap); 435 } 436 } 437 438 441 static public String getDefaultControlBinding(Class controlIntf) 442 { 443 controlIntf = ControlBean.getMostDerivedInterface(controlIntf); 444 445 ControlInterface intfAnnot = 446 (ControlInterface)controlIntf.getAnnotation(ControlInterface.class); 447 String implBinding = intfAnnot.defaultBinding(); 448 implBinding = resolveDefaultBinding( implBinding, controlIntf.getName() ); 449 450 return implBinding; 451 } 452 453 461 public static String resolveDefaultBinding( String implBinding, String controlClass ) 462 { 463 int intfIndex = implBinding.indexOf(ControlInterface.INTERFACE_NAME); 464 if (intfIndex >= 0) 465 { 466 implBinding = implBinding.substring(0,intfIndex) + controlClass + 467 implBinding.substring(intfIndex + 468 ControlInterface.INTERFACE_NAME.length()); 469 } 470 return implBinding; 471 } 472 473 public Class getControlInterface() 477 { 478 return _bean.getControlInterface(); 479 } 480 481 public <T extends Annotation > T getControlPropertySet(Class <T> propertySet) 485 { 486 PropertyMap map = _bean.getPropertyMap(); 487 488 if (!map.containsPropertySet(propertySet)) 495 { 496 PropertySet psAnnot = propertySet.getAnnotation(PropertySet.class); 497 if (psAnnot.optional()) 498 return null; 499 } 500 501 return PropertySetProxy.getProxy(propertySet, map); 506 } 507 508 public <T extends Annotation > T getMethodPropertySet(Method m, Class <T> propertySet) 512 { 513 PropertyMap map = _bean.getAnnotationMap(m); 514 515 if (!map.containsPropertySet(propertySet)) 522 { 523 PropertySet psAnnot = propertySet.getAnnotation(PropertySet.class); 524 if (psAnnot.optional()) 525 return null; 526 } 527 528 return PropertySetProxy.getProxy(propertySet, _bean.getAnnotationMap(m)); 533 } 534 535 public <T extends Annotation > T getParameterPropertySet(Method m, int i, Class <T> propertySet) 539 throws IllegalArgumentException , IndexOutOfBoundsException 540 { 541 if (i >= m.getParameterTypes().length) 542 throw new IndexOutOfBoundsException ("Invalid parameter index for method:" + m); 543 544 Annotation [] paramAnnots = m.getParameterAnnotations()[i]; 548 for (int j = 0; j < paramAnnots.length; j++) 549 if (propertySet.isAssignableFrom(paramAnnots[j].getClass())) 550 return (T)paramAnnots[j]; 551 552 return null; 553 } 554 555 public String [] getParameterNames(Method m) throws IllegalArgumentException 559 { 560 return _bean.getParameterNames(m); 561 } 562 563 public Object getParameterValue(Method m, String parameterName, Object [] parameters) 567 throws IllegalArgumentException 568 { 569 String [] names = getParameterNames(m); 570 571 if (parameters.length != names.length) 573 throw new IllegalArgumentException ("Expected " + names.length + " parameters," + 574 "Found " + parameters.length); 575 576 int i = 0; 578 while (i < names.length) 579 { 580 if (names[i].equals(parameterName)) 581 break; 582 i++; 583 } 584 if (i == names.length) 585 throw new IllegalArgumentException ("No method parameter with name: " + parameterName); 586 587 return parameters[i]; 589 } 590 591 public PropertyMap getControlPropertyMap() 595 { 596 return new BeanPropertyMap(_bean.getPropertyMap()); 601 } 602 603 public <T> T getService(Class <T> serviceClass, Object selector) 607 { 608 if (serviceClass.equals(org.apache.beehive.controls.api.context.ControlBeanContext.class)) 613 return (T)this; 614 615 BeanContext bc = getBeanContext(); 620 if (bc == null || !(bc instanceof BeanContextServices )) 621 return null; 622 623 try 628 { 629 return (T)((BeanContextServices )bc).getService(this, _bean, serviceClass, selector, 630 this); 631 } 632 catch (TooManyListenersException tmle) 633 { 634 throw new ControlException("Unable to register for service events", tmle); 637 } 638 } 639 640 public ControlHandle getControlHandle() 644 { 645 ControlBeanContext beanContext = this; 650 while (beanContext != null && !(beanContext instanceof ControlContainerContext)) 651 beanContext = (ControlBeanContext)beanContext.getBeanContext(); 652 653 if (beanContext == null) 654 return null; 655 656 return ((ControlContainerContext)beanContext).getControlHandle(_bean); 660 } 661 662 public java.lang.ClassLoader getClassLoader() 666 { 667 return getControlInterface().getClassLoader(); 668 } 669 670 675 public static final String INTERCEPTOR_CONFIG_FILE = "controls-interceptors.config"; 676 677 684 public static String [] prioritizeInterceptors( String [] interceptors ) 685 { 686 if ( interceptors == null ) 687 return null; 688 689 if ( _interceptorPriorities == null ) 691 { 692 _interceptorPriorities = new ArrayList<String >(); 694 BufferedReader in = null; 695 try 696 { 697 InputStream configFileStream = 698 ControlBeanContext.class.getClassLoader().getResourceAsStream( INTERCEPTOR_CONFIG_FILE ); 699 700 if ( configFileStream != null ) 701 { 702 in = new BufferedReader (new InputStreamReader (configFileStream)); 703 String str; 704 while ((str = in.readLine()) != null) 705 _interceptorPriorities.add(str); 706 } 707 } 708 catch (IOException e) 709 { 710 } 711 finally 712 { 713 try 714 { 715 if (in != null) 716 in.close(); 717 } 718 catch ( IOException ie ) { } 719 } 720 } 721 722 Set<String > input = new HashSet<String >(); 724 for ( String ii : interceptors ) 725 input.add( ii ); 726 727 ArrayList<String > prioritized = new ArrayList<String >(interceptors.length); 729 for ( String p : _interceptorPriorities ) 730 { 731 if ( input.contains(p) ) 732 { 733 input.remove(p); 734 prioritized.add(p); 735 } 736 } 737 738 for ( String p : input ) 741 prioritized.add(p); 742 743 return prioritized.toArray(new String [prioritized.size()]); 744 } 745 746 synchronized public void addLifeCycleListener(LifeCycle listener) 750 { 751 if (_lifeCycleListeners == null) 752 { 753 _lifeCycleListeners = new Vector<LifeCycle>(); 754 755 _bean.getPropertyChangeSupport().addPropertyChangeListener(this); 761 _bean.getVetoableChangeSupport().addVetoableChangeListener(this); 762 } 763 _lifeCycleListeners.addElement(listener); 764 } 765 766 synchronized public void removeLifeCycleListener(LifeCycle listener) 770 { 771 if (_lifeCycleListeners != null) 772 _lifeCycleListeners.removeElement(listener); 773 } 774 775 public void propertyChange(PropertyChangeEvent pce) 779 { 780 if (_lifeCycleListeners != null) 781 { 782 Iterator iter = _lifeCycleListeners.iterator(); 783 while (iter.hasNext()) 784 { 785 LifeCycle listener = (LifeCycle)iter.next(); 786 listener.onPropertyChange(pce); 787 } 788 } 789 } 790 791 public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException 795 { 796 if (_lifeCycleListeners != null) 797 { 798 Iterator iter = _lifeCycleListeners.iterator(); 799 while (iter.hasNext()) 800 { 801 LifeCycle listener = (LifeCycle)iter.next(); 802 listener.onVetoableChange(pce); 803 } 804 } 805 } 806 807 String getControlID() 808 { 809 if (_controlID != null || _bean == null) 810 return _controlID; 811 812 String id = _bean.getLocalID(); 814 815 BeanContext bc = getBeanContext(); 817 if (bc != null && bc instanceof ControlBeanContext) 818 { 819 String parentID = ((ControlBeanContext)bc).getControlID(); 820 if (parentID != null) 821 { 822 id = parentID + 823 org.apache.beehive.controls.api.bean.ControlBean.IDSeparator + 824 id; 825 } 826 } 827 828 _controlID = id; 830 831 return id; 832 } 833 834 839 private void resetControlID() 840 { 841 _controlID = null; 842 Iterator childIter = this.iterator(); 843 while (childIter.hasNext()) 844 { 845 Object child = childIter.next(); 846 if (child instanceof ControlBeanContext) 847 ((ControlBeanContext)child).resetControlID(); 848 } 849 } 850 851 synchronized public Iterator getCurrentServiceClasses() 862 { 863 Set classSet = new HashSet(); 864 BeanContextServices bcs = this; 865 866 while (bcs != null) 867 { 868 if (bcs instanceof ControlBeanContext) 870 { 871 classSet.addAll(((ControlBeanContext)bcs).services.keySet()); 872 } 873 else 874 { 875 Iterator iter = bcs.getCurrentServiceClasses(); 876 while (iter.hasNext()) 877 classSet.add(iter.next()); 878 } 879 880 BeanContext bc = getBeanContext(); 882 if (bc instanceof BeanContextServices && bcs != bc) 883 bcs = (BeanContextServices )bc; 884 else 885 bcs = null; 886 } 887 return classSet.iterator(); 888 } 889 890 public Iterator getCurrentServiceSelectors(Class serviceClass) 895 { 896 if (hasService(serviceClass)) 897 return super.getCurrentServiceSelectors(serviceClass); 898 899 BeanContext bc = getBeanContext(); 900 if (bc instanceof BeanContextServices ) 901 return ((BeanContextServices )bc).getCurrentServiceSelectors(serviceClass); 902 903 return null; 904 } 905 906 910 private ControlBean _bean; 911 912 915 private boolean _hasSingleThreadedParent = false; 916 917 924 private Map<String ,Object > _childMap = 925 Collections.synchronizedMap(new HashMap<String ,Object >()); 926 927 932 private Map<String ,NameGenerator> _nameGenerators; 933 934 937 transient private Vector<LifeCycle> _lifeCycleListeners; 938 939 944 transient private String _controlID; 945 946 private static ArrayList<String > _interceptorPriorities; 947 } 948 | Popular Tags |