1 8 14 package jfun.yan; 15 16 import java.beans.IntrospectionException ; 17 import java.lang.reflect.Array ; 18 import java.lang.reflect.Field ; 19 import java.lang.reflect.Method ; 20 import java.util.ArrayList ; 21 import java.util.HashSet ; 22 import java.util.LinkedHashMap ; 23 import java.util.List ; 24 import java.util.Set ; 25 26 27 import jfun.util.Misc; 28 import jfun.util.StringUtils; 29 import jfun.util.beans.Bean; 30 import jfun.util.beans.BeanType; 31 import jfun.util.beans.NoSuchPropertyException; 32 import jfun.yan.element.ElementStore; 33 import jfun.yan.element.ListStore; 34 import jfun.yan.element.MapStore; 35 import jfun.yan.element.SetStore; 36 import jfun.yan.factory.Factory; 37 import jfun.yan.factory.Pool; 38 import jfun.yan.function.Function; 39 import jfun.yan.function.Property2Signature; 40 import jfun.yan.function.Signature; 41 import jfun.yan.util.Predicate; 42 import jfun.yan.util.ReflectionUtil; 43 44 57 public final class Components { 58 64 public static <T> Component<T> adapt(Creator<T> c){ 65 if(c instanceof Component){ 66 return (Component<T>)c; 67 } 68 else return new Creator2Component<T>(c); 69 } 70 75 public static <T> Component<T> fun(Function<T> fun){ 76 return new FunctionComponent<T>(fun).guard(); 79 } 80 94 public static <T> Component<T> ctor(Class <T> c) 95 throws IllegalArgumentException { 96 return fun(Functions.ctor(c)); 97 } 98 113 public static <T> Component<T> ctor(Class <T> c, Class [] param_types) 114 throws IllegalArgumentException { 115 return fun(Functions.ctor(c, param_types)); 116 } 117 130 public static Component static_method(Class c, String name) 131 throws IllegalArgumentException { 132 return fun(Functions.static_method(c, name)); 133 } 134 149 public static Component static_method( 150 Class c, String name, Class [] param_types){ 151 return fun( 152 Functions.static_method(c, name, param_types)); 153 } 154 168 public static Component method(Object obj, String name){ 169 return fun(Functions.method(obj, name)); 170 } 171 189 public static Component method(Class type, Object obj, String name){ 190 return fun(Functions.method(type, obj, name)); 191 } 192 208 public static Component method( 209 Object obj, String name, Class [] param_types){ 210 return fun( 211 Functions.method(obj, name, param_types)); 212 } 213 232 public static Component method(Class type, 233 Object obj, String name, Class [] param_types){ 234 return fun( 235 Functions.method(type, obj, name, param_types)); 236 } 237 247 public static Component static_field(Class c, String name) 248 throws IllegalArgumentException { 249 return fun(Functions.static_field(c, name)); 250 } 251 265 public static Component field(Class type, Object obj, String name){ 266 return fun(Functions.field(type, obj, name)); 267 } 268 278 public static Component field(Object obj, String name){ 279 return fun(Functions.field(obj, name)); 280 } 281 291 public static Component getter(Class type, Object obj, String prop) 292 throws IntrospectionException , NoSuchPropertyException, 293 NonReadablePropertyException{ 294 final BeanType btype = BeanType.instance(type); 295 final Method m = btype.getReader(prop); 296 if(m==null) 297 throw new NonReadablePropertyException(type, prop); 298 return fun(Functions.getter(Bean.instance(type, obj), prop)); 299 } 300 311 public static <T> Component<T> setter(Class type, T obj, String prop) 312 throws IntrospectionException , NoSuchPropertyException, 313 NonWritablePropertyException{ 314 final BeanType btype = BeanType.instance(type); 315 if(btype.getWriter(prop)==null && btype.getIndexedWriter(prop)==null) 316 throw new NonWritablePropertyException(type, prop); 317 return fun(Functions.setter(Bean.instance(type, obj), prop)); 318 } 319 331 public static Component indexed_getter(Class type, Object obj, String prop, int ind) 332 throws IntrospectionException , NoSuchPropertyException, 333 NonReadablePropertyException{ 334 final BeanType btype = BeanType.instance(type); 335 final Method m = btype.getIndexedReader(prop); 336 if(m==null) 337 throw new NonReadablePropertyException(type, prop); 338 return fun(Functions.indexed_getter(Bean.instance(type, obj), prop, ind)); 339 } 340 353 public static <T> Component<T> indexed_setter(Class type, T obj, String prop, int ind) 354 throws IntrospectionException , NoSuchPropertyException, 355 NonWritablePropertyException{ 356 final BeanType btype = BeanType.instance(type); 357 final Method m = btype.getIndexedWriter(prop); 358 if(m==null) 359 throw new NonWritablePropertyException(type, prop); 360 return fun(Functions.indexed_setter(Bean.instance(type, obj), prop, ind)); 361 } 362 363 372 public static Component getter(Object obj, String prop) 373 throws IntrospectionException , NoSuchPropertyException, 374 NonReadablePropertyException{ 375 return getter(obj.getClass(), obj, prop); 376 } 377 387 public static <T> Component<T> setter(T obj, String prop) 388 throws IntrospectionException , NoSuchPropertyException, 389 NonWritablePropertyException{ 390 return setter(obj.getClass(), obj, prop); 391 } 392 403 public static Component indexed_getter(Object obj, String prop, int ind) 404 throws IntrospectionException , NoSuchPropertyException, 405 NonReadablePropertyException{ 406 return indexed_getter(obj.getClass(), obj, prop, ind); 407 } 408 420 public static <T> Component<T> indexed_setter(T obj, String prop, int ind) 421 throws IntrospectionException , NoSuchPropertyException, 422 NonWritablePropertyException{ 423 return indexed_setter(obj.getClass(), obj, prop, ind); 424 } 425 426 434 public static <T> Component<T> value(final T val){ 435 if(val==null) return NilComponent.instance; 436 return new ValueComponent<T>(val); 437 } 438 444 public static Component<Double > value(final double val){ 445 return value(new Double (val)).cast(double.class); 446 } 447 453 public static Component<Float > value(final float val){ 454 return value(new Float (val)).cast(float.class); 455 } 456 462 public static Component<Long > value(final long val){ 463 return value(new Long (val)).cast(long.class); 464 } 465 471 public static Component<Integer > value(final int val){ 472 return value(new Integer (val)).cast(int.class); 473 } 474 480 public static Component<Short > value(final short val){ 481 return value(new Short (val)).cast(short.class); 482 } 483 489 public static Component<Byte > value(final byte val){ 490 return value(new Byte (val)).cast(byte.class); 491 } 492 498 public static Component<Character > value(final char val){ 499 return value(new Character (val)).cast(char.class); 500 } 501 507 public static Component<Boolean > value(final boolean val){ 508 return val?true_component:false_component; 509 } 510 511 private static Component<Boolean > return_bool(boolean b){ 512 return value(Boolean.valueOf(b)).cast(boolean.class); 513 } 514 private static final Component<Boolean > true_component = return_bool(true); 515 private static final Component<Boolean > false_component = return_bool(false); 516 548 public static <T> Component<T> bean(final Component<T> cc, java.util.Set props) 549 throws IntrospectionException , 550 IllegalPropertyNameException, NonWritablePropertyException{ 551 final PropertiesInjector pi = 552 DefaultPropertiesInjector.instance(cc.getType(), props); 553 return makeBean(cc, pi); 554 558 } 559 566 public static <T> Component<T> makeBean(Component<T> cc, PropertiesInjector injector){ 567 return makeBean(injector.toString(), cc, injector); 568 } 569 577 public static <T> Component<T> makeBean(String name, 578 Component<T> cc, PropertiesInjector injector){ 579 return Monad.followedBy(cc, new BeanBinder<T>(name, injector)).label(name); 580 } 581 607 public static <T> Component<T> bean(final Component<T> cc) 608 throws IntrospectionException { 609 final PropertiesInjector pi = DefaultPropertiesInjector.instance(cc.getType()); 610 return makeBean(cc, pi); 611 } 613 630 public static <T> Component<T> bean(final Class <T> type) 631 throws IntrospectionException , IllegalArgumentException { 632 return bean(ctor(type, null)); 633 } 634 652 public static <T> Component<T> bean(final Class <T> type, java.util.Set props) 653 throws IntrospectionException , IllegalPropertyNameException, 654 NonWritablePropertyException{ 655 return Components.bean(ctor(type, null), props); 656 } 657 690 public static <T> Component<T> bean(final Component<T> cc, String ... props) 691 throws IntrospectionException , IllegalPropertyNameException, 692 NonWritablePropertyException, IllegalArgumentException { 693 return Components.bean(cc, jfun.yan.util.Utils.toSet(props, "property name")); 694 } 695 714 public static <T> Component<T> bean(final Class <T> type, String [] props) 715 throws IntrospectionException , IllegalPropertyNameException, 716 NonWritablePropertyException, IllegalArgumentException { 717 return bean(ctor(type, null), props); 718 } 719 720 729 public static Component bindMethod(final Component cc, final Method mtd){ 730 return Monad.bind(autowired(cc), new MethodBinder(mtd)).label(""+cc+".<"+mtd+">") 731 .guard(); 732 } 733 749 public static Component bindMethod(final Component cc, final String name, 750 boolean suppress_security) 751 throws IllegalArgumentException { 752 final String lbl = ""+cc+"."+name + "( ... )"; 753 final Class type = cc.getType(); 754 return Monad.bind(autowired(cc), invokingMethod(type, name, suppress_security)) 755 .label(lbl).guard(); 756 } 757 774 public static Component bindMethod(final Component cc, 775 final String name, final int param_count, 776 boolean suppress_security) 777 throws IllegalArgumentException { 778 final String lbl = ReflectionUtil.toMethodString(name, param_count); 779 final Class type = cc.getType(); 780 return Monad.bind(autowired(cc), invokingMethod(type, name, param_count, suppress_security)) 781 .label(lbl).guard(); 782 } 783 792 public static Component bindField(final Component cc, final Field fld){ 793 return Monad.bind(autowired(cc), new FieldBinder(fld)).label(""+cc+".<"+fld+">") 794 .guard(); 795 } 796 797 809 public static Component bindField(final Component cc, final String name, 810 boolean suppress_security) 811 throws IllegalArgumentException { 812 final String lbl = ""+cc+"."+name; 813 final Class type = cc.getType(); 814 return Monad.bind(autowired(cc), readingField(type, name, suppress_security)) 815 .label(lbl).guard(); 816 } 817 818 827 public static ComponentBinder invokingMethod(Class type, String name, 828 final boolean suppress_security){ 829 if(type==null) 830 return new MethodNameBinder(name,suppress_security); 831 else 832 return new MethodBinder(ReflectionUtil.getMethod(type, name, suppress_security)); 833 } 834 844 public static ComponentBinder invokingMethod(Class type, String name, 845 int param_count, final boolean suppress_security){ 846 if(type==null) 847 return new MethodNameParamCountBinder(name,param_count,suppress_security); 848 else 849 return new MethodBinder(ReflectionUtil.getMethod(type, name, 850 param_count, suppress_security)); 851 } 852 853 862 public static ComponentBinder readingField(Class type, String name, 863 boolean suppress_security){ 864 if(type==null) 865 return new FieldNameBinder(name, suppress_security); 866 else 867 return new FieldBinder(ReflectionUtil.getField(type, name, suppress_security)); 868 } 869 886 public static Component bindMethod(final Component cc, 887 final String name, final Class [] param_types, boolean suppress_security) 888 throws IllegalArgumentException { 889 final String lbl = 890 ""+cc+"."+name + jfun.util.StringUtils.listString("(",",",")",param_types); 891 final Class type = cc.getType(); 892 return Monad.bind(autowired(cc), 893 invokingMethod(type, name, param_types, suppress_security)) 894 .label(lbl).guard(); 895 } 896 906 public static ComponentBinder invokingMethod(Class type, String name, 907 Class [] param_types, boolean suppress_security){ 908 if(type==null){ 909 return new DynamicMethodBinder(name, param_types, suppress_security); 910 } 911 else 912 return new MethodBinder(ReflectionUtil.getMethod(type, name, param_types, 913 suppress_security)); 914 } 915 923 public static Component bindGetter(final Component cc, 924 final String name)throws IntrospectionException { 925 final String lbl = ""+cc+"."+name; 926 final Class type = cc.getType(); 927 return Monad.bind(autowired(cc), invokingGetter(type, name)) 928 .label(lbl).guard(); 929 } 930 939 public static ComponentBinder invokingGetter(Class type, String name) 940 throws IntrospectionException { 941 if(type==null){ 942 return new DynamicPropertyReadingBinder(name); 943 } 944 else 945 return new PropertyReadingBinder(BeanType.instance(type), name); 946 } 947 957 public static Component bindSetter(final Component cc, 958 final String name) 959 throws IntrospectionException { 960 final String lbl = ""+cc+"."+name+"="; 961 final Class type = cc.getType(); 962 return Monad.bind(autowired(cc), invokingSetter(type,name)) 963 .label(lbl).guard(); 964 } 965 974 public static <T> ComponentBinder<T,T> invokingSetter(Class <T> type, String name) 975 throws IntrospectionException { 976 if(type==null){ 977 return new DynamicPropertyWritingBinder<T>(name); 978 } 979 else 980 return new PropertyWritingBinder(BeanType.instance(type), name); 981 } 982 991 public static Component bindGetter(final Component cc, 992 final String name, final int ind)throws IntrospectionException { 993 final String lbl = ""+cc+"."+name+"["+ind+"]"; 994 final Class type = cc.getType(); 995 return Monad.bind(autowired(cc), getterBinder(type, name, ind)) 996 .label(lbl).guard(); 997 } 998 private static ComponentBinder getterBinder(Class type, 999 final String name, final int ind) 1000 throws IntrospectionException { 1001 if(type==null){ 1002 return new DynamicIndexedPropertyReadingBinder(name, ind); 1003 } 1004 else 1005 return new IndexedPropertyReadingBinder(BeanType.instance(type), name, ind); 1006 } 1007 1018 public static <T> Component<T> bindSetter(final Component<T> cc, 1019 final String name, final int ind)throws IntrospectionException { 1020 final String lbl = ""+cc+"."+name+"["+ind+"]="; 1021 final Class type = cc.getType(); 1022 return Monad.bind(autowired(cc), setterBinder(type, name, ind)) 1023 .label(lbl).guard(); 1024 } 1025 private static <T> ComponentBinder<T,T> setterBinder(Class <T> type, 1026 String name, int ind) 1027 throws IntrospectionException { 1028 if(type==null){ 1029 return new DynamicIndexedPropertyWritingBinder<T>(name, ind); 1030 } 1031 else 1032 return new IndexedPropertyWritingBinder(BeanType.instance(type), name, ind); 1033 } 1034 1041 public static <T> Component<T> singleton(Component<T> cc){ 1042 if(cc.isSingleton()) return cc; 1043 return new SingletonComponent(cc); 1044 } 1045 1054 public static <T> Component<T> singleton(Component<T> cc, Pool<T> scope){ 1055 return new PooledComponent(cc, scope); 1056 } 1057 1067 public static <F> Component<F> factory(Creator cc, Class <F> factory_class, 1068 ClassLoader loader, String toString){ 1069 final Component<F> r = 1070 new FactoryComponent<F>(cc, factory_class, loader, toString).label(toString); 1071 if(cc.isSingleton()){ 1072 return r.singleton(); 1073 } 1074 else return r; 1075 } 1076 1085 public static <F> Component<F> factory(Creator cc, Class <F> factory_class, 1086 String toString){ 1087 if(Factory.class.equals(factory_class)){ 1088 return factory(cc, toString); 1089 } 1090 return factory(cc, factory_class, factory_class.getClassLoader(), 1091 toString); 1092 } 1093 1101 public static <T> Component<Factory<T>> factory(Creator<T> cc, String toString){ 1102 return new TheFactoryComponent<T>(cc, toString).label(toString); 1103 } 1104 static <T> Component<T> ensureComponent(Component<T> cc, Object key){ 1105 if(cc==null) 1106 throw new UnresolvedComponentException(key); 1107 return cc; 1108 } 1109 1116 public static <T> Component<T> fromLazy(final LazyComponent<T> lcc, final Object key){ 1117 return new LazyComponent2Component<T>(lcc, key).guard(); 1118 } 1119 1132 public static Component useKey( 1133 final ComponentMap cmap, final Object key){ 1134 return fromLazy(new LazyComponent(){ 1135 public Component eval(){ 1136 return cmap.getComponent(key); 1137 } 1138 public Class getType(){return null;} 1139 public String toString(){return "useKey <"+key+">";} 1140 }, key).label(); 1141 } 1142 1143 1155 public static <T> Component<T> useProperty( 1156 final Class component_type, final Object key, final Class <T> type){ 1157 return new UsePropertyComponent<T>(component_type, key, type).guard().label(); 1158 } 1159 1171 public static <T> Component<T> useArgument( 1172 final Signature src, final int pos, final Class <T> type){ 1173 return new UseArgumentComponent<T>(src, pos, type).guard().label(); 1174 } 1175 1181 public static Part useContainer(final ComponentMap cmap){ 1182 return new Part(){ 1183 public Object create(Class type, Dependency dependency){ 1184 return ensureComponent(cmap.getComponentOfType(type), type) 1185 .create(cmap.getDependencyOfType(type, cmap)); 1186 } 1187 public Class verify(Class type, Dependency dependency){ 1188 return ensureComponent(cmap.getComponentOfType(type), type) 1189 .verify(cmap.getDependencyOfType(type, cmap)); 1190 } 1191 }; 1192 } 1193 1196 public static Component<ComponentMap> thisContainer(){ 1197 return ThisContainerComponent.instance(); 1198 } 1199 1212 public static <T> Component<T> useType( 1213 final ComponentMap cmap, final Class <T> type){ 1214 return fromLazy(new LazyComponent<T>(){ 1215 public Component<T> eval(){ 1216 return cmap.getComponentOfType(type); 1217 } 1218 public Class <T> getType(){return null;} 1219 public String toString(){ 1220 return "useType <"+Misc.getTypeName(type) +">"; 1221 } 1222 }, type).guard().label(); 1223 } 1224 1238 public static <T> Component<ArrayList <T>> useAll( 1239 final ComponentMap cmap, final Class <T> type){ 1240 return fromLazy(new LazyComponent<ArrayList <T>>(){ 1241 public Component<ArrayList <T>> eval(){ 1242 return list(cmap.getComponentsOfType(type)); 1243 } 1244 public Class getType(){ 1245 return java.util.ArrayList .class; 1246 } 1247 public String toString(){ 1248 return "useAll <"+Misc.getTypeName(type)+">"; 1249 } 1250 }, type).label(); 1251 } 1252 1263 public static Component useState( 1264 final ComponentMap cmap, final Predicate pred){ 1265 return fromLazy(new LazyComponent(){ 1266 public Component eval(){ 1267 return list(findComponents(cmap, pred)); 1268 } 1269 public Class getType(){ 1270 return java.util.ArrayList .class; 1271 } 1272 public String toString(){ 1273 return "useState <"+pred+">"; 1274 } 1275 }, pred).guard().label(); 1276 } 1277 1284 public static <T> Component<T> label(final Component<T> cc, final Object lbl){ 1285 return new ClosureableComponent(cc){ 1286 public Class verify(Dependency dp){ 1287 try{ 1288 return cc.verify(dp); 1289 } 1290 catch(YanException e){ 1291 e.push(lbl); 1292 throw e; 1293 } 1294 } 1295 public Object create(Dependency dp){ 1296 try{ 1297 return cc.create(dp); 1298 } 1299 catch(YanException e){ 1300 e.push(lbl); 1301 throw e; 1302 } 1303 } 1304 public Component label(Object lbl){ 1306 return cc.label(lbl); } 1308 protected Component decorate(Component c){ 1309 return Components.label(c, lbl); 1310 } 1311 public String toString(){ 1312 return ""+lbl; 1313 } 1314 }; 1315 } 1316 1328 1329 public static Component useKey(final Object key){ 1330 return new UseKeyComponent(key).guard().label(); 1331 } 1332 1345 public static <T> Component<T> useType(final Class <T> type){ 1346 return new UseTypeComponent<T>(type).guard().label(); 1347 } 1348 1367 public static <T> Component<T> autodetect(final Class <T> type, final Object [] alternative_keys){ 1368 return new AutoDetectingComponent<T>(type, alternative_keys).guard().label(); 1369 } 1370 1383 public static <T> Component<List <T>> useAll(final Class <T> type){ 1384 return new Component<List <T>>(){ 1385 public Class verify(Dependency dependency){ 1386 return list(findComponents(dependency.getComponentMap(), type)) 1387 .verify(dependency); 1388 } 1389 public List <T> create(Dependency dependency){ 1390 return list(findComponents(dependency.getComponentMap(), type)) 1391 .create(dependency); 1392 } 1393 private java.util.List <Component<T>> findComponents(ComponentMap cmap, 1394 final Class <T> type){ 1395 return cmap.getComponentsOfType(type); 1396 } 1397 public Class getType(){ 1398 return java.util.ArrayList .class; 1399 } 1400 public boolean isConcrete(){ 1401 return true; 1402 } 1403 public String toString(){ 1404 return "useAll <" + Misc.getTypeName(type)+">"; 1405 } 1406 public boolean isSingleton(){ 1407 return false; 1408 } 1409 }.guard().label(); 1410 } 1411 private static java.util.List <Component> findComponents(ComponentMap cmap, 1412 final Predicate pred){ 1413 final java.util.Collection all = cmap.getComponents(); 1414 final java.util.ArrayList <Component> ret = new java.util.ArrayList <Component>(); 1415 for(java.util.Iterator it=all.iterator();it.hasNext();){ 1416 final Component c = (Component)it.next(); 1417 if(pred.isObject(c.getState())){ 1418 ret.add(c); 1419 } 1420 } 1421 return ret; 1422 } 1423 1433 public static Component useDefault(){ 1434 return UseDefaultComponent.instance(); 1435 } 1436 1446 public static Component useState(final Predicate pred){ 1447 return new Component(){ 1448 public Class verify(Dependency dependency){ 1449 final ComponentMap cmap = dependency.getComponentMap(); 1450 return list(findComponents(cmap, pred)).verify(dependency); 1451 } 1452 public Object create(Dependency dependency){ 1453 final ComponentMap cmap = dependency.getComponentMap(); 1454 return list(findComponents(cmap, pred)).create(dependency); 1455 } 1456 public Class getType(){ 1457 return java.util.ArrayList .class; 1458 } 1459 public boolean isConcrete(){ 1460 return true; 1461 } 1462 public String toString(){ 1463 return "useState <" + pred +">"; 1464 } 1465 public boolean isSingleton(){ 1466 return false; 1467 } 1468 }.guard().label(); 1469 } 1470 1476 public static Component returnState(final Stateful st){ 1477 return new ReturnStateComponent(st).label(); 1478 } 1479 1485 public static Component returnType(final Typeful t){ 1486 return new ReturnTypeComponent(t).guard().label(); 1487 } 1488 1494 public static Component returnVerification(final Verifiable veri){ 1495 return new ReturnVerificationComponent(veri).guard() 1496 .label(); 1497 } 1498 1567 private static Dependency setArguments( 1568 final Dependency dependency, 1569 final Part part){ 1570 return new DelegatingDependency(dependency){ 1571 public Object getArgument(Signature src, int i, Class type){ 1572 final Object r = part.create(type, dependency); 1573 Utils.checkArg(src, getComponentKey(), i, type, r); 1574 return r; 1575 } 1576 public Class verifyArgument(Signature src, int i, Class type){ 1577 final Class r = part.verify(type, dependency); 1578 Utils.checkType(src, getComponentKey(), i, type, r); 1579 return r; 1580 } 1581 public Dependency seal(){ 1582 return setArguments(dependency.seal(), part); 1583 } 1584 }; 1585 } 1586 private static Dependency setProperties( 1587 final Dependency dependency, final Part part){ 1588 return new DelegatingDependency(dependency){ 1589 public Object getProperty(Class component_type, Object k, Class type){ 1590 final Object r = part.create(type, dependency); 1591 Utils.checkArg(component_type, getComponentKey(), k, type, r); 1592 return r; 1593 } 1594 public Class verifyProperty(Class component_type, Object k, Class type){ 1595 final Class r = part.verify(type, dependency); 1596 Utils.checkType(component_type, getComponentKey(), k, type, r); 1597 return r; 1598 } 1599 public Dependency seal(){ 1600 return setProperties(dependency.seal(), part); 1601 } 1602 }; 1603 } 1604 1610 static ParameterBinder getParameterBinder(final Creator[] args){ 1611 return new ParameterBinder(){ 1612 public Creator bind(final Signature src, int k, Class type){ 1613 if(k>=0 && k < args.length){ 1614 return args[k]; 1615 } 1616 else return useArgument(src, k, type); 1617 } 1618 }; 1619 } 1620 1627 static PropertyBinder getPropertyBinder(final java.util.Map props){ 1628 return new PropertyBinder(){ 1629 public Creator bind(Class component_type, Object k, Class type){ 1630 final Creator r = (Creator)props.get(k); 1631 if(r==null) return useProperty(component_type, k, type); 1632 else return r; 1633 } 1634 }; 1635 } 1636 1645 public static Component withArguments( 1646 final Component cc, final Creator... creators){ 1647 return bindArguments(cc, getParameterBinder(creators)); 1648 1662 } 1663 1674 public static Component seal(final Component cc){ 1675 return new ClosureableComponent(cc){ 1676 public Object create(Dependency dependency){ 1677 return cc.create(dependency.seal()); 1678 } 1679 public Class verify(Dependency dependency){ 1680 return cc.verify(dependency.seal()); 1681 } 1682 public String toString(){ 1683 return "seal <" + cc + ">"; 1684 } 1685 protected Component decorate(Component cc){ 1686 return Components.seal(cc); 1687 } 1688 public Component seal(){ 1689 return this; 1690 } 1691 }.label(); 1692 } 1693 1694 1700 public static Component autowired(final Component c){ 1701 return new ClosureableComponent(c){ 1702 public Object create(Dependency dependency){ 1703 return c.create(dependency.getOriginal()); 1704 } 1705 public Class verify(Dependency dependency){ 1706 return c.verify(dependency.getOriginal()); 1707 } 1708 public String toString(){ 1709 return "autowired <" + c + ">"; 1710 } 1711 protected Component decorate(Component cc){ 1712 return Components.autowired(cc); 1713 } 1714 }.label(); 1715 } 1716 1723 public static Component bindArguments( 1724 final Component cc, final ParameterBinder binder){ 1725 return new DecoratingComponent(cc){ 1726 public Object create(Dependency dependency){ 1727 return cc.create(Components.bindArguments(dependency, binder)); 1728 } 1729 public Class verify(Dependency dependency){ 1730 return cc.verify(Components.bindArguments(dependency, binder)); 1731 } 1732 public Component singleton(){ 1734 return new SingletonComponent(super.singleton()); 1735 } 1736 public Component singleton(Pool scope){ 1738 return new PooledComponent(super.singleton(scope), scope); 1739 } 1740 protected Component decorate(Component cc){ 1741 return cc.bindArguments(binder); 1742 } 1743 }; 1744 } 1745 1753 public static Component bindArgument( 1754 final Component cc, final int k, final ParameterBinder binder){ 1755 return bindArguments(cc, new ParameterBinder(){ 1756 public Creator bind(final Signature src, int i, Class type){ 1757 if(i==k){ 1758 return binder.bind(src, i, type); 1759 } 1760 else return useArgument(src, i, type); 1761 } 1762 }); 1763 } 1764 1779 public static Component withProperties( 1780 final Component cc, final java.util.Map props){ 1781 return bindProperties(cc, getPropertyBinder(props)); 1782 1794 1795 } 1796 1803 public static Component bindProperties( 1804 final Component cc, final PropertyBinder binder){ 1805 return new ClosureableComponent(cc){ 1806 public Object create(Dependency dependency){ 1807 return cc.create(Components.bindProperties(dependency, binder)); 1808 } 1809 public Class verify(Dependency dependency){ 1810 return cc.verify(Components.bindProperties(dependency, binder)); 1811 } 1812 public Component singleton(){ 1814 return new SingletonComponent(super.singleton()); 1815 } 1816 public Component singleton(Pool scope){ 1818 return new PooledComponent(super.singleton(scope), scope); 1819 } 1820 public Component decorate(Component c){ 1821 return c.bindProperties(binder); 1822 } 1823 }; 1824 } 1825 1833 public static Component bindProperty(final Component cc, 1834 final Object k, final PropertyBinder binder){ 1835 return bindProperties(cc, new PropertyBinder(){ 1836 public Creator bind(Class component_type, Object i, Class type){ 1837 if(i.equals(k)){ 1838 return binder.bind(component_type, i,type); 1839 } 1840 else return useProperty(component_type, i, type); 1841 } 1842 }); 1843 } 1844 1845 1855 public static Component withProperties( 1856 final Component cc, final String [] names, final Creator[] creators){ 1857 return withProperties(cc, Utils.hashmap(names, creators)); 1858 } 1859 1860 1874 public static Component fromArguments( 1875 final Component cc, final Object ... keys){ 1876 return bindProperties(cc, new PropertyBinder(){ 1877 public Creator bind(Class component_type, Object key, Class type){ 1878 final int ind = findKey(key); 1879 if(ind < 0) return useProperty(component_type, key, type); 1880 else{ 1881 final Signature sig = new Property2Signature(component_type, key, type); 1882 return useArgument(sig, ind, type); 1883 } 1884 } 1885 private int findKey(Object k){ 1886 for(int i=0; i<keys.length;i++){ 1887 if(Utils.eq(k, keys[i])) return i; 1888 } 1889 return -1; 1890 } 1891 }); 1892 } 1893 1906 public static Component fromProperties( 1907 final Component cc, final Object ... keys){ 1908 return bindArguments(cc, new ParameterBinder(){ 1909 public Creator bind(final Signature src, int k, Class type){ 1910 if(k<0 || k>=keys.length){ 1911 return useArgument(src, k, type); 1912 } 1913 else return useProperty(src.getReturnType(), keys[k], type); 1914 } 1915 }); 1916 } 1917 1923 public static Component withArguments( 1924 final Component cc, final Part part){ 1925 return new ClosureableComponent(cc){ 1926 public Object create(Dependency dependency){ 1927 return cc.create(Components.setArguments(dependency, part)); 1928 } 1929 public Class verify(Dependency dependency){ 1930 return cc.verify(Components.setArguments(dependency, part)); 1931 } 1932 protected Component decorate(Component cc){ 1933 return Components.withArguments(cc, part); 1934 } 1935 }; 1936 } 1937 1943 public static Component withProperties( 1944 final Component cc, final Part part){ 1945 return new ClosureableComponent(cc){ 1946 public Object create(Dependency dependency){ 1947 return cc.create(Components.setProperties(dependency, part)); 1948 } 1949 public Class verify(Dependency dependency){ 1950 return cc.verify(Components.setProperties(dependency, part)); 1951 } 1952 public Component decorate(Component c){ 1953 return Components.withProperties(c, part); 1954 } 1955 }; 1956 } 1957 1975 private static Dependency setParent(final Dependency dep, 1976 final Dependency parent){ 1977 return new DelegatingDependency(dep){; 1978 public Dependency getParent(){ 1979 return parent; 1980 } 1981 public Dependency seal(){ 1982 return setParent(dep.seal(), parent); 1983 } 1984 }; 1985 } 1986 private static Dependency ofPart(final Dependency dep, Class type){ 1987 final ComponentMap cmap = dep.getComponentMap(); 1988 final Dependency newdep = cmap.getDependencyOfType(type, cmap); 1989 return setParent(newdep, dep); 1990 } 1991 private static Dependency ofProperty(final Dependency dep, Object key, Class type){ 1992 return ofPart(dep, type); 1993 } 1994 private static Dependency ofParameter(Dependency dep, int ind, Class type){ 1995 return ofPart(dep, type); 1996 } 1997 1998 2004 public static Dependency bindArguments( 2005 final Dependency dependency, 2006 final ParameterBinder binder){ 2007 return new DelegatingDependency(dependency){ 2008 public Object getArgument(Signature src, int i, Class type){ 2009 final Object r = binder.bind(src, i, type) 2010 .create(ofParameter(dependency, i, type)); 2011 Utils.checkArg(src, getComponentKey(), i, type, r); 2012 return r; 2013 } 2014 public Class verifyArgument(Signature src, int i, Class type){ 2015 final Class r = binder.bind(src, i,type) 2016 .verify(ofParameter(dependency, i, type)); 2017 Utils.checkType(src, getComponentKey(), i, type, r); 2018 return r; 2019 } 2020 public Dependency seal(){ 2021 return bindArguments(dependency.seal(), binder); 2022 } 2023 }; 2024 } 2025 2031 public static Dependency bindProperties( 2032 final Dependency dependency, 2033 final PropertyBinder binder){ 2034 return new DelegatingDependency(dependency){ 2035 public Object getProperty(Class component_type, Object i, Class type){ 2036 final Object r = binder.bind(component_type, i,type) 2037 .create(ofProperty(dependency, i, type)); 2038 Utils.checkArg(component_type, getComponentKey(), i, type, r); 2039 return r; 2040 } 2041 public Class verifyProperty(Class component_type, Object i, Class type){ 2042 final Class r = binder.bind(component_type, i, type) 2043 .verify(ofProperty(dependency, i, type)); 2044 Utils.checkType(component_type, getComponentKey(), i, type, r); 2045 return r; 2046 } 2047 public Dependency seal(){ 2048 return bindProperties(dependency.seal(), binder); 2049 } 2050 }; 2051 } 2052 2246 2247 private static Dependency setArgument( 2248 final Dependency dependency, 2249 final int k, final Part part){ 2250 return new DelegatingDependency(dependency){ 2251 public Object getArgument(Signature src, int i, Class type){ 2252 if(i==k){ 2253 final Object r = part.create(type, dependency); 2254 Utils.checkArg(src, getComponentKey(), i, type, r); 2255 return r; 2256 } 2257 else return dependency.getArgument(src, i, type); 2258 } 2259 public Class verifyArgument(Signature src, int i, Class type){ 2260 if(i==k){ 2261 final Class r = part.verify(type, dependency); 2262 Utils.checkType(src, getComponentKey(), i, type, r); 2263 return r; 2264 } 2265 else return dependency.verifyArgument(src, i, type); 2266 } 2267 public Dependency seal(){ 2268 return setArgument(dependency.seal(), k, part); 2269 } 2270 }; 2271 } 2272 private static Dependency setProperty( 2273 final Dependency dependency, 2274 final Object k, final Part part){ 2275 return new DelegatingDependency(dependency){ 2276 public Object getProperty(Class component_type, Object i, Class type){ 2277 if(i.equals(k)){ 2278 final Object r = part.create(type, dependency); 2279 Utils.checkArg(component_type, getComponentKey(), i, type, r); 2280 return r; 2281 } 2282 else return dependency.getProperty(component_type, i, type); 2283 } 2284 public Class verifyProperty(Class component_type, Object i, Class type){ 2285 if(i.equals(k)){ 2286 final Class r = part.verify(type, dependency); 2287 Utils.checkType(component_type, getComponentKey(), i, type, r); 2288 return r; 2289 } 2290 else return dependency.verifyProperty(component_type, i, type); 2291 } 2292 public Dependency seal(){ 2293 return setProperty(dependency.seal(), k, part); 2294 } 2295 }; 2296 } 2297 2298 2306 public static Component withArgument( 2307 final Component cc, 2308 final int k, final Creator factory){ 2309 return bindArgument(cc, k, constParamBinder(factory)); 2310 2322 } 2323 private static ParameterBinder constParamBinder(final Creator c){ 2324 return new ParameterBinder(){ 2325 public Creator bind(Signature src, int k, Class type){ 2326 return c; 2327 } 2328 }; 2329 } 2330 private static PropertyBinder constPropertyBinder(final Creator c){ 2331 return new PropertyBinder(){ 2332 public Creator bind(Class component_type, Object k, Class type){ 2333 return c; 2334 } 2335 }; 2336 } 2337 2345 public static <T> Component<T> withProperty( 2346 final Component<T> cc, 2347 final Object k, final Creator factory){ 2348 return bindProperty(cc, k, constPropertyBinder(factory)); 2349 2361 } 2362 2369 public static <T> Component<T> withArgument( 2370 final Component<T> cc, 2371 final int k, final Part part){ 2372 return new ClosureableComponent(cc){ 2373 public Object create(Dependency dependency){ 2374 return cc.create(Components.setArgument(dependency, k, part)); 2375 } 2376 public Class verify(Dependency dependency){ 2377 return cc.verify(Components.setArgument(dependency, k, part)); 2378 } 2379 public Component decorate(Component c){ 2380 return Components.withArgument(c, k, part); 2381 } 2382 }; 2383 } 2384 2392 public static <T> Component<T> withProperty( 2393 final Component<T> cc, 2394 final Object k, final Part part){ 2395 return new ClosureableComponent(cc){ 2396 public Object create(Dependency dependency){ 2397 return cc.create(Components.setProperty(dependency, k, part)); 2398 } 2399 public Class verify(Dependency dependency){ 2400 return cc.verify(Components.setProperty(dependency, k, part)); 2401 } 2402 public Component decorate(Component c){ 2403 return Components.withProperty(c, k, part); 2404 } 2405 }; 2406 } 2407 2408 2425 public static <T> Component<T> optionalProperty( 2426 final Component<T> cc, final Object k){ 2427 return bindProperty(cc, k, _optional_prop); 2428 2440 } 2441 2446 public static <T> Component<T> optionalProperties(final Component<T> cc){ 2447 return bindProperties(cc, _optional_prop); 2448 2461 } 2462 private static final ParameterBinder _optional_param = new ParameterBinder(){ 2463 public Creator bind(Signature src, int i, Class type){ 2464 return useArgument(src, i, type).optional(); 2465 } 2466 }; 2467 private static final PropertyBinder _optional_prop = new PropertyBinder(){ 2468 public Creator bind(Class component_type, Object k, Class type){ 2469 return useProperty(component_type, k, type).optional(); 2470 } 2471 }; 2472 2477 public static <T> Component<T> optionalParameters(final Component<T> cc){ 2478 return bindArguments(cc, _optional_param); 2479 2492 } 2493 2507 public static <T> Component<T> optionalParameter( 2508 final Component<T> cc, final int k){ 2509 return bindArgument(cc, k, _optional_param); 2510 2522 } 2523 2532 public static <T> Component<T> withDefaultProperty(final Component<T> cc, 2533 final Object k, final Creator v){ 2534 final Recovery def = 2535 Monad.onException(DefaultingException.class, v); 2536 return bindProperty(cc, k, new PropertyBinder(){ 2537 public Creator bind(Class component_type, Object i, Class type){ 2538 return 2539 Monad.recover( 2540 Monad.mplus(useProperty(component_type, i, type), v), 2541 def 2542 ); 2543 } 2544 }); 2557 } 2558 2568 public static <T> Component<T> withDefaultArgument(final Component<T> cc, 2569 final int k, final Creator v){ 2570 return bindArgument(cc, k, new ParameterBinder(){ 2571 final Recovery def = Monad.onException(DefaultingException.class, v); 2572 public Creator bind(Signature src, int i, Class type){ 2573 return Monad.recover( 2574 Monad.mplus(useArgument(src, i, type), v), 2575 def 2576 ); 2577 } 2578 }); 2579 2591 } 2592 2599 static <T> Component<T> withDependency( 2600 final Component<T> cc, final Dependency dep){ 2601 return new ClosureableComponent(cc){ 2602 public Object create(Dependency d){ 2603 return cc.create(dep); 2604 } 2605 public Class verify(Dependency d){ 2606 return cc.verify(dep); 2607 } 2608 public Component decorate(Component c){ 2609 return Components.withDependency(c, dep); 2610 } 2611 }; 2612 } 2613 2614 2621 public static Component subscript(final Component c, final int ind){ 2622 final Component result = c.map(new Map(){ 2623 public Object map(Object a){ 2624 if(a==null) 2625 throw new IllegalArgumentException ("subscript on null pointer"); 2626 else if(a.getClass().isArray()){ 2627 return Array.get(a, ind); 2628 } 2629 else if(a instanceof List ){ 2630 return ((List )a).get(ind); 2631 } 2632 else 2633 throw new IllegalArgumentException ("cannot apply subscript against " 2634 + Misc.getTypeName(a.getClass())); 2635 } 2636 }); 2637 return result; 2638 } 2639 2640 2647 public static Component get(Component c, final Object key){ 2648 return c.map(new Map(){ 2649 public Object map(Object o){ 2650 if(o==null) 2651 throw new IllegalArgumentException ("cannot apply get against null"); 2652 if(o instanceof java.util.Map ){ 2653 return ((java.util.Map )o).get(key); 2654 } 2655 else 2656 throw new IllegalArgumentException ("cannot apply get against " 2657 + Misc.getTypeName(o.getClass())); 2658 } 2659 }); 2660 } 2661 2666 public static <T> Component<T> guard(Component<T> cc){ 2667 if(cc.isSingleton()){ 2668 return cc; 2670 } 2671 return new GuardedComponent<T>(cc); 2672 } 2673 2679 public static <T> Component<T> withState(Component<T> cc, Object obj){ 2680 return new StatefulComponent(cc, obj); 2681 } 2682 2690 public static <Super, T extends Super> Component<Super> subsume(final Component<T> cc, final Class <Super> type){ 2691 final Class subtype = cc.getType(); 2692 if(subtype!=null){ 2693 checkType(type, subtype); 2694 if(type.equals(subtype)){ 2695 return (Component<Super>)cc; 2696 } 2697 } 2698 return new TypedComponent(cc, type){ 2699 protected Component decorate(Component c){ 2700 return Components.subsume(c, type); 2701 } 2702 public String toString(){ 2703 return "subsume <" + cc + "> as " + Misc.getTypeName(type); 2704 } 2705 }.label(); 2706 } 2707 2714 private static <T> Factory<T> castFactory(final Class <T> type, final Factory<?> f){ 2715 return new Factory<T>(){ 2716 public T create(){ 2717 final Object obj = f.create(); 2718 checkInstanceType(type, obj); 2719 return (T)obj; 2720 } 2721 public String toString(){ 2722 return f.toString(); 2723 } 2724 }; 2725 } 2726 private static abstract class TypedComponent extends DecoratingComponent{ 2727 public Class getType(){ 2728 return type; 2729 } 2730 public boolean isConcrete(){ 2731 return false; 2732 } 2733 public Component factory(String toString){ 2735 return getDelegateTarget().factory(toString); 2736 } 2737 public Object create(Dependency dependency){ 2738 return checkInstanceType(this.type, super 2739 .create(dependency)); 2740 } 2741 public Class verify(Dependency dependency){ 2742 super.verify(dependency); 2743 return getType(); 2744 } 2745 private final Class type; 2746 TypedComponent(Component cc, Class type) { 2747 super(cc); 2748 this.type = type; 2749 } 2750 2751 } 2752 2767 2768 public static <T> Component<T> cast(final Component<?> cc, final Class <T> type){ 2769 final Class suptype = cc.getType(); 2770 if(type == suptype) return (Component<T>)cc; 2771 if(type!=null && cc.isConcrete()) 2772 return subsume((Component)cc, type); 2773 if(type != null && suptype != null && type.equals(suptype)){ 2774 return (Component<T>)cc; 2775 } 2776 2777 return new TypedComponent(cc, type){ 2778 protected Component decorate(Component c){ 2779 return Components.cast(c,getType()); 2780 } 2781 public String toString(){ 2782 return "cast <" + cc +"> as " + Misc.getTypeName(getType()); 2783 } 2784 }.label(); 2785 } 2786 2793 public static Component proxy(final Component cc, final Class ... itfs){ 2794 if(itfs.length==0) return cc; 2796 return proxy(cc, itfs, itfs[0].getClassLoader()); 2797 } 2798 2806 public static Component proxy(final Component cc, 2807 final Class [] itfs, final ClassLoader loader){ 2808 if(itfs.length==0) return cc; 2810 final Class type = cc.getType(); 2811 if(type!=null) 2812 checkTypes(itfs, type); 2813 return new ProxyComponent(cc, itfs, loader).label(); 2815 } 2816 2823 public static <I> Component<I> proxy(final Component<?> cc, Class <I> itf){ 2824 return proxy(cc, toInterfaces(itf)); 2825 } 2826 2834 public static Component proxy(final Component cc){ 2835 final Class ctype = cc.getType(); 2836 if(ctype == null) return cc; 2837 return proxy(cc, ctype); 2838 } 2839 2850 public static <T> Component<T[]> array(final Component<T>[] ccs, 2851 final Class <T> etype) 2852 throws IllegalArgumentException { 2853 final Class target_type = Misc.getArrayType(etype); 2854 final Component<T[]> step1 = new SimpleComponent<T[]>(target_type){ 2855 public T[] create(){ 2856 return (T[])Array.newInstance(etype, ccs.length); 2857 } 2858 public String toString(){ 2859 return "array "+StringUtils.listArray("[",",","]",ccs) 2860 + ":"+Misc.getTypeName(target_type); 2861 } 2862 }; 2863 return storeArray(step1, ccs); 2864 2877 } 2878 public static <T> Component<T[]> storeArray(Component<T[]> component_returning_array, 2879 Creator<T>... creators){ 2880 final Class type = component_returning_array.getType(); 2881 final Class etype = type==null?null:type.getComponentType(); 2882 return component_returning_array 2883 .followedBy(new ArrayStoreBinder<T>(creators, etype)) 2884 .label(); 2885 } 2886 2905 public static <T> Component<T[]> array(final Component<T>... ccs){ 2906 return array(ccs, Utils.getCommonRootType(ccs)); 2907 2911 } 2912 2913 2922 public static <T> Component<ArrayList <T>> list(final Creator<T>... ccs){ 2923 final Component<ArrayList <T>> step1 = new SimpleComponent<ArrayList <T>>(ArrayList .class){ 2925 public ArrayList <T> create(){ 2926 return new ArrayList <T>(ccs.length); 2927 } 2928 public String toString(){ 2929 return "list "+StringUtils.listArray("[",",","]",ccs); 2930 } 2931 }; 2932 return storeList(step1, ccs); 2933 } 2934 2941 public static <T,L extends List <T>> Component<L> storeList(final Component<L> component_returning_list, 2942 final Creator<T>... creators){ 2943 return component_returning_list.followedBy(new StoreBinder<T,L>(creators){ 2944 public ElementStore<T> toStore(L v){ 2945 if(v instanceof List ){ 2946 return new ListStore<T>(v); 2947 } 2948 throw new ClassCastException ("java.util.List expected, " 2949 +Utils.getObjTypeName(v)+" encountered"); 2950 } 2951 }).label(); 2952 2953 } 2954 2963 public static <T> Component<HashSet <T>> hashset(final Creator<T>... ccs){ 2964 final Component<HashSet <T>> step1 = new SimpleComponent<HashSet <T>>(HashSet .class){ 2966 public HashSet <T> create(){ 2967 return new HashSet <T>(ccs.length); 2968 } 2969 public String toString(){ 2970 return "hashset "+StringUtils.listArray("[",",","]",ccs); 2971 } 2972 }; 2973 return storeSet(step1, ccs); 2974 } 2975 2982 public static <T, S extends Set <T>> Component<S> storeSet(final Component<S> component_returning_set, 2983 final Creator<T>... creators){ 2984 return component_returning_set.followedBy(new StoreBinder<T,S>(creators){ 2985 public ElementStore<T> toStore(S v){ 2986 if(v instanceof Set ){ 2987 return new SetStore<T>(v); 2988 } 2989 throw new ClassCastException ("java.util.Set expected, " 2990 +Utils.getObjTypeName(v)+" encountered"); 2991 } 2992 }).label(); 2993 } 2994 3003 public static <T, C extends Creator<T>> Component<ArrayList <T>> list(final java.util.List <C> ccs){ 3004 final Creator<T>[] crs = new Creator[ccs.size()]; 3005 ccs.toArray(crs); 3006 return list(crs); 3007 } 3008 3009 3029 public static <K,T> Component<java.util.LinkedHashMap <K, T>> hashmap(final K[] keys, final Creator<T>[] creators) 3030 throws IllegalArgumentException { 3031 if(keys.length != creators.length){ 3033 throw new IllegalArgumentException ("keys.length=="+keys.length 3034 + ", vals.length=="+creators.length); 3035 } 3036 final Component<LinkedHashMap <K,T>> step1 = new SimpleComponent<LinkedHashMap <K,T>>(LinkedHashMap .class){ 3037 public LinkedHashMap <K,T> create(){ 3038 return new LinkedHashMap <K,T>(keys.length); 3039 } 3040 }; 3041 return storeMap(step1, keys, creators); 3042 } 3043 3044 3052 public static <K,T,M extends java.util.Map <K,T>> Component<M> storeMap(final Component<M> component_return_map, 3053 final K[] keys, Creator<T>[] vals){ 3054 return component_return_map.followedBy(new StoreBinder<T,M>(vals){ 3055 public ElementStore<T> toStore(M v){ 3056 if(v instanceof java.util.Map ){ 3057 return new MapStore<K,T>(keys, v); 3058 } 3059 else{ 3060 throw new ClassCastException ("java.util.Map expected, "+ 3061 Utils.getObjTypeName(v)+" encountered."); 3062 } 3063 } 3064 }).label(); 3065 3066 } 3067 3082 public static <T> Component<T> incomplete(final Component<T> cc) 3083 throws UnknownComponentTypeException{ 3084 final Class ctype = cc.getType(); 3085 if(ctype ==null){ 3086 throw new UnknownComponentTypeException("immature component " + cc + 3087 " cannot be made incomplete"); 3088 } 3089 return new ClosureableComponent(cc){ 3090 public Class verify(Dependency dependency){ 3091 return ctype; 3092 } 3093 protected Component decorate(Component c){ 3094 return Components.incomplete(c); 3095 } 3096 public String toString(){ 3097 return "incomplete <" + cc + ">"; 3098 } 3099 }.label(); 3100 } 3101 3102 3103 3110 public static <T> Component<T> mutate(final Component<T> cc, final Mutation<T> m){ 3111 return cc.followedBy(new Mutation2Binder<T>(m)); 3113 } 3114 3115 3122 public static <T> Component<T> repeat(final Creator<T> cc, final int times){ 3123 if(times<0) 3124 throw new IllegalArgumentException ("negative repeat times: "+times); 3125 if(times==0) 3126 return value(null); 3127 if(times==1) 3128 return adapt(cc); 3129 return new RepeatComponent<T>(cc, times).label(); 3130 } 3131 3132 3138 public static <T> Component<T> synchronizedComponent(final Component<T> cc){ 3139 return new SynchronizedComponent(cc); 3140 } 3141 static Class [] toInterfaces(Class type){ 3142 if(type.isInterface()){ 3143 return new Class []{type}; 3144 } 3145 else return type.getInterfaces(); 3146 } 3147 private static void checkType(final Class itf, final Class type){ 3148 if(!ReflectionUtil.isAssignableFrom(itf, type)){ 3149 throw new IllegalArgumentException ( 3150 Misc.getTypeName(type) + " is not a subtype of " 3151 + Misc.getTypeName(itf)); 3152 } 3153 } 3154 private static void checkTypes(final Class [] itfs, final Class type){ 3155 for(int i=0; i<itfs.length; i++){ 3156 final Class itf = itfs[i]; 3157 checkType(itf, type); 3158 } 3159 } 3160 3168 private static Object checkInstanceType(final Class type, final Object r) { 3169 if(type != null && !ReflectionUtil.isInstance(type, r)){ 3170 throw new TypeMismatchException(type, r==null?null:r.getClass(), 3171 Misc.getTypeName(type) 3172 +" expected, while " + Misc.getTypeName(Utils.getObjType(r)) 3173 +" encountered."); 3174 } 3175 return r; 3176 } 3177} 3178 | Popular Tags |