You can subscribe to this list here.
| 2003 |
Jan
|
Feb
(55) |
Mar
(100) |
Apr
(203) |
May
(330) |
Jun
(190) |
Jul
(302) |
Aug
(323) |
Sep
(197) |
Oct
(245) |
Nov
(490) |
Dec
(330) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(194) |
Feb
(400) |
Mar
(416) |
Apr
(415) |
May
(359) |
Jun
(381) |
Jul
(491) |
Aug
(311) |
Sep
(291) |
Oct
(273) |
Nov
(355) |
Dec
(266) |
| 2005 |
Jan
(306) |
Feb
(303) |
Mar
(520) |
Apr
(346) |
May
(255) |
Jun
(221) |
Jul
(171) |
Aug
(247) |
Sep
(147) |
Oct
(125) |
Nov
(165) |
Dec
(65) |
| 2006 |
Jan
(90) |
Feb
(53) |
Mar
(121) |
Apr
(103) |
May
(113) |
Jun
(103) |
Jul
(104) |
Aug
(67) |
Sep
(78) |
Oct
(82) |
Nov
(78) |
Dec
(70) |
| 2007 |
Jan
(77) |
Feb
(76) |
Mar
(63) |
Apr
(30) |
May
(47) |
Jun
(41) |
Jul
(44) |
Aug
(44) |
Sep
(49) |
Oct
(33) |
Nov
(25) |
Dec
(21) |
| 2008 |
Jan
(45) |
Feb
(13) |
Mar
(15) |
Apr
(12) |
May
(9) |
Jun
(33) |
Jul
(30) |
Aug
(7) |
Sep
(20) |
Oct
(17) |
Nov
(20) |
Dec
(10) |
| 2009 |
Jan
(8) |
Feb
(5) |
Mar
(12) |
Apr
(17) |
May
(19) |
Jun
(97) |
Jul
(77) |
Aug
(33) |
Sep
(24) |
Oct
(41) |
Nov
(16) |
Dec
(32) |
| 2010 |
Jan
(24) |
Feb
(14) |
Mar
(50) |
Apr
(71) |
May
(70) |
Jun
(64) |
Jul
(45) |
Aug
(62) |
Sep
(32) |
Oct
(4) |
Nov
(12) |
Dec
(2) |
| 2011 |
Jan
(1) |
Feb
(3) |
Mar
(4) |
Apr
(3) |
May
(6) |
Jun
(1) |
Jul
(4) |
Aug
(3) |
Sep
(4) |
Oct
(6) |
Nov
(3) |
Dec
(3) |
| 2012 |
Jan
(4) |
Feb
(8) |
Mar
(6) |
Apr
(10) |
May
(2) |
Jun
(3) |
Jul
(11) |
Aug
(10) |
Sep
(4) |
Oct
|
Nov
(1) |
Dec
(1) |
| 2013 |
Jan
(4) |
Feb
(1) |
Mar
(9) |
Apr
(1) |
May
(8) |
Jun
(2) |
Jul
(5) |
Aug
(2) |
Sep
|
Oct
(3) |
Nov
(10) |
Dec
(8) |
| 2014 |
Jan
(3) |
Feb
(12) |
Mar
(9) |
Apr
(12) |
May
(2) |
Jun
|
Jul
(3) |
Aug
(1) |
Sep
(1) |
Oct
(4) |
Nov
|
Dec
(2) |
| 2015 |
Jan
(1) |
Feb
(3) |
Mar
(4) |
Apr
(9) |
May
(2) |
Jun
(2) |
Jul
|
Aug
(2) |
Sep
(7) |
Oct
(9) |
Nov
(7) |
Dec
(9) |
| 2016 |
Jan
(7) |
Feb
(5) |
Mar
(5) |
Apr
(5) |
May
(8) |
Jun
(4) |
Jul
(5) |
Aug
(4) |
Sep
(6) |
Oct
(7) |
Nov
(2) |
Dec
(3) |
| 2017 |
Jan
(7) |
Feb
(8) |
Mar
(7) |
Apr
(3) |
May
(4) |
Jun
(3) |
Jul
(5) |
Aug
(8) |
Sep
(4) |
Oct
(2) |
Nov
(3) |
Dec
|
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2019 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2021 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2022 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
| 2024 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2025 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
(2) |
Aug
(5) |
Sep
(2) |
Oct
|
Nov
|
Dec
(1) |
| 2026 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <jue...@we...> - 2003-10-10 17:58:36
|
RGVhciBTcHJpbmcgYXNzb2NpYXRlcyBhbmQgZm9sbG93ZXJzLA0KIA0KV2UncmUgYXBwcm9hY2hp bmcgb3VyIHNlY29uZCAxLjAgbWlsZXN0b25lIHJlbGVhc2UsIHNjaGVkdWxlZCBmb3IgbWlkIE9j dG9iZXIuIEkgd291bGQgbGlrZSB0byByZWxlYXNlIGl0IG5leHQgd2Vla2VuZCwgYXJvdW5kIFN1 bmRheSB0aGUgMTl0aCwgaWYgdGhlcmUgYXJlbid0IGFueSBvYnN0YWNsZXMgb3Igb2JqZWN0aW9u cy4NCiANCldlJ3ZlIHF1aXRlIGEgbG90IG9mIG5ldyBmdW5jdGlvbmFsaXR5LCBmb3IgZXhhbXBs ZToNCiANCi0gbXVsdGlwYXJ0IGhhbmRsaW5nIGFrYSBmaWxlIHVwbG9hZCBzdXBwb3J0LCBib3Ro IGZvciBEaXNwYXRjaGVyU2VydmxldCBhbmQgZ2VuZXJhbCB1c2UsIHdpdGggQ29tbW9ucyBGaWxl VXBsb2FkIGFuZCBDT1MgaW1wbGVtZW50YXRpb25zOw0KIA0KLSBhIE1haWxTZW5kZXIgQVBJLCB3 aXRoIGFuIG9wdGlvbmFsIGV4dGVuZGVkIEphdmFNYWlsU2VuZGVyIGludGVyZmFjZSwgcGx1cyBK YXZhTWFpbCBhbmQgQ09TIGltcGxlbWVudGF0aW9uczsNCiANCi0gUHJvcGVydHlPdmVycmlkZUNv bmZpZ3VyZXIgYW5kIFByb3BlcnR5UGxhY2Vob2xkZXJDb25maWd1cmVyLCBhbGxvd2luZyBmb3Ig cHVzaCBhbmQgcHVsbCBzdHlsZSBtZXJnaW5nIG9mIHByb3BlcnRpZXMgZmlsZXMgaW50byBiZWFu IHByb3BlcnR5IHZhbHVlcyBvZiBhbiBhcHBsaWNhdGlvbiBjb250ZXh0Ow0KIA0KLSB0aGUgQmVh blBvc3RQcm9jZXNzb3IgaG9vaywgYW5kIHJld29ya2VkIGJlYW4gZmFjdG9yeS9hcHBsaWNhdGlv biBjb250ZXh0IGludGVncmF0aW9uOyANCiANCi0gUGljb0NvbnRhaW5lciBzdHlsZSBkZXBlbmRl bmN5IGNoZWNraW5nIGFuZCBhdXRvd2lyZSBvcHRpb25zIGZvciB0aGUgYmVhbiBmYWN0b3J5Ow0K IA0KLSByZXR1cm5pbmcgcmVzdWx0IHNldHMgZnJvbSBhIHN0b3JlZCBwcm9jZWR1cmU7DQogDQot IHJld29ya2VkIExhc3QtTW9kaWZpZWQgc3VwcG9ydCwgVmVsb2NpdHkgc3VwcG9ydCwgcmVtb3Rp bmcgcHJveGllcywgZXRjLg0KIA0KKERldGFpbHMgY2FuIGJlIGZvdW5kIGluIHRoZSBjdXJyZW50 IGNoYW5nZWxvZy50eHQgaW4gQ1ZTLCBhbmQgaW4gdGhlIEphdmFkb2NzLikNCiANCkknZCBsaWtl IHRvIGVuY291cmFnZSBldmVyeWJvZHkgdG8gZ2l2ZSB0aGUgbmV3IGZlYXR1cmVzIGEgdHJ5IHZp YSBhIENWUyBzbmFwc2hvdC4gRWFybHkgZmVlZGJhY2sgd2lsbCBoZWxwIHVzIHRvIHJlbGVhc2Ug TTIgYXMgc3RhYmxlIGFzIHBvc3NpYmxlLg0KIA0KLS0tLS0NCiANCkxvb2tpbmcgYmV5b25kIE0y LCB3ZSBkbyBub3QgaGF2ZSBtYW55IHBsYW5uZWQgMS4wIGZlYXR1cmVzIGxlZnQgLS0gYW5kIGFs bCBvZiB0aGVtIGFyZSBhbHJlYWR5IGluIHRoZSB3b3JrczoNCiANCi0gc291cmNlLWxldmVsIG1l dGFkYXRhLCBlc3BlY2lhbGx5IGZvciB0cmFuc2FjdGlvbiBhdHRyaWJ1dGVzOw0KIA0KLSBHbHVl IHN1cHBvcnQsIGJvdGggYWNjZXNzaW5nIFNPQVAgd2ViIHNlcnZpY2VzIGFuZCBleHBvc2luZyB0 aGVtICh0aGF0J3MgYWN0dWFsbHkgYW4gb3JpZ2luYWwgMS4xIGdvYWwgdGhhdCBtaWdodCBtYWtl IGl0IGludG8gMS4wOyAxLjEgd2lsbCBwcm9iYWJseSBzZWUgQXhpcyBzdXBwb3J0KTsNCiANCi0g YSBTcHJpbmcvSGliZXJuYXRlIHNhbXBsZSBhcHAgKGJ5IG15c2VsZik7DQogDQotIGRvY3MsIGRv Y3MsIGRvY3MhDQogDQpUaGUgbGFzdCBvbmVzIGFyZSBwcm9iYWJseSB0aGUgbW9zdCBpbXBvcnRh bnQ6IEkgY29uc2lkZXIgb3VyIEphdmFkb2NzIGFzIG1vc3RseSBleGVtcGxhcnksIHRoZXkgZG9j dW1lbnQgYWxtb3N0IGFsbCB0aGUgc3VidGxlIGZlYXR1cmVzIC0tIGJ1dCB3ZSBzdGlsbCBuZWVk IG1vcmUgdHV0b3JpYWxzIGFuZCBmZWF0dXJlIGd1aWRlcy4gVGhlcmUncyBzdWNoIGEgbG90IG9m IHVzZWZ1bCBzdHVmZiB0aGF0J3MgaGFyZCB0byBmaW5kIGN1cnJlbnRseS4uLg0KIA0KSWYgSSBo YXZlIGZvcmdvdHRlbiBhYm91dCBvbmUgb2Ygb3VyIDEuMCBnb2FscywgZmVlbCBmcmVlIHRvIGNv cnJlY3QgbWUuIEFsbCBvZiB0aGUgYWJvdmUgc2hvdWxkIGJlIHJlYWR5IGZvciAxLjAgTTMgaW4g ZWFybHkgdG8gbWlkIE5vdmVtYmVyIC0tIGF0IGxlYXN0IGluIHRoZWlyIGZpcnN0IGluY2FybmF0 aW9uLg0KIA0KVGhlIGZpbmFsIHdheSB0b3dhcmRzIDEuMCBzaG91bGQgYmUgYWJvdXQgZmluZS10 dW5pbmcgYW5kIHByb3BlciBkb2N1bWVudGF0aW9uLiBJJ20gbm90IGF3YXJlIG9mIGFueSBtb3Jl IHBsYW5uZWQgZmVhdHVyZXMgYmV5b25kIHRoZSBNMyBvbmVzOyBzbyB3ZSBzaG91bGQgbm90IG5l ZWQgYW5vdGhlciBtaWxlc3RvbmUgYnV0IGJlIHJlYWR5IHRvIHNjaGVkdWxlIDEuMCBmaW5hbCBm b3IgZWFybHkgRGVjZW1iZXIuDQogDQpGZWVkYmFjayBvZiBhbnkga2luZCBpcyB2ZXJ5IHdlbGNv bWUhDQogDQpSZWdhcmRzLA0KSnVlcmdlbg0K |
|
From: Colin S. <col...@ex...> - 2003-10-10 17:40:29
|
jürgen höller [werk3AT] wrote:
>Fortunately, this *is* available for XmlBeanFactory too, like as follows --
>with the very same API that XmlWebApplicationContext internally uses to load multiple files.
>
> XmlBeanFactory bf = new XmlBeanFactory();
> bf.loadBeanDefinitions("appCtx1.xml");
> bf.loadBeanDefinitions("appCtx1.xml");
> bf.preInstantiateSingletons();
>
>It's currently not available in FileSystemXmlApplicationContext though, mainly to not place any restrictions on file names in terms of spaces or commas. FileSystemXmlApplicationContext already has a constructor with a String array, for automatically setting up *nested* contexts. We could redefine that constructor to specify multiple files that make up a *single* context, and offer an overloaded version that takes a parent ApplicationContext reference. That way, both multiple files for a single context and nesting would be possible.
>
>
>
That sounds good. There are certain deployment scenarios where config
files references via filenames (as opposed to having to be on the
classpath) are a lot more convenient, and I think. I am trying to think
if there are any use cases where somebody would be feeding in a list of
contexts in the existing implementation, and would be worst off if they
were nested as opposed to flattened into one as you propose. I can't
really think of any. I think the nesting does make a lot of sense when
you are assembling together contexts from different layers which may
already exist (that is, the lower layer(s) may already exist), as per my
multi-webapp usecase, but in this case you are doing it dynamically
anyways, and can't do it as a list.
>-----
>
>What I'm most excited about is the BeanPostProcessor hook. I expect that to be very powerful, as already indicated by the respective test case in StaticApplicationContextSuite. Another example that I've prototyped is the following (not yet in CVS):
>public class AutoProxyCreator implements BeanPostProcessor {
> private List beanNames;
> private Interceptor[] interceptors;
>
> public void setBeanNames(String[] beanNames) {
> this.beanNames = Arrays.asList(beanNames);
> }
>
> public void setInterceptors(Interceptor[] interceptors) {
> this.interceptors = interceptors;
> }
>
> public Object postProcessBean(Object bean, String name, RootBeanDefinition definition) {
> if (this.beanNames != null && this.beanNames.contains(name)) {
> ProxyFactory proxyFactory = new ProxyFactory();
> for (int i = 0; i < this.interceptors.length; i++) {
> proxyFactory.addInterceptor(this.interceptors[i]);
> }
> proxyFactory.addInterceptor(new InvokerInterceptor(bean));
> return proxyFactory.getProxy();
> }
> else {
> return bean;
> }
> }
>}
>
>This is a BeanPostProcessor bean that can be set up as follows to proxy the beans with the given names with the given interceptors. Note that this is only one bean with proxy settings to define, although there might be dozens of target beans with the same proxy behavior.
>
><bean id="autoProxyCreator" class="org.springframework.aop.framework.support.AutoProxyCreator">
> <property name="beanNames"><value>myBean1,myBean2,myBean3</value></property>
> <property name="interceptors>
> <list>
> <ref bean="myInterceptor1"/>
> <ref bean="myInterceptor2"/>
> </list>
> </property>
></bean>
>
>So setting up 10 transactional beans would just involve 1 AutoProxyCreator and 1 transaction interceptor plus the 10 target beans (12 beans in total), instead of 10 TransactionProxyFactoryBeans plus the 10 target beans (20 beans in total). The transaction attributes would be centralized though, in contrast to TransactionProxyFactoryBean that keeps them local per individual proxy definition.
>
>
I really like this. It will reduce boilerplate proxy definitions for 80%
of the code that needs simple wrapping of everything...
|
|
From: <jue...@we...> - 2003-10-10 17:08:03
|
Rm9ydHVuYXRlbHksIHRoaXMgKmlzKiBhdmFpbGFibGUgZm9yIFhtbEJlYW5GYWN0b3J5IHRvbywg bGlrZSBhcyBmb2xsb3dzIC0tIA0Kd2l0aCB0aGUgdmVyeSBzYW1lIEFQSSB0aGF0IFhtbFdlYkFw cGxpY2F0aW9uQ29udGV4dCBpbnRlcm5hbGx5IHVzZXMgdG8gbG9hZCBtdWx0aXBsZSBmaWxlcy4N CiANCiAgWG1sQmVhbkZhY3RvcnkgYmYgPSBuZXcgWG1sQmVhbkZhY3RvcnkoKTsNCiAgYmYubG9h ZEJlYW5EZWZpbml0aW9ucygiYXBwQ3R4MS54bWwiKTsNCiAgYmYubG9hZEJlYW5EZWZpbml0aW9u cygiYXBwQ3R4MS54bWwiKTsNCiAgYmYucHJlSW5zdGFudGlhdGVTaW5nbGV0b25zKCk7DQogDQpJ dCdzIGN1cnJlbnRseSBub3QgYXZhaWxhYmxlIGluIEZpbGVTeXN0ZW1YbWxBcHBsaWNhdGlvbkNv bnRleHQgdGhvdWdoLCBtYWlubHkgdG8gbm90IHBsYWNlIGFueSByZXN0cmljdGlvbnMgb24gZmls ZSBuYW1lcyBpbiB0ZXJtcyBvZiBzcGFjZXMgb3IgY29tbWFzLiBGaWxlU3lzdGVtWG1sQXBwbGlj YXRpb25Db250ZXh0IGFscmVhZHkgaGFzIGEgY29uc3RydWN0b3Igd2l0aCBhIFN0cmluZyBhcnJh eSwgZm9yIGF1dG9tYXRpY2FsbHkgc2V0dGluZyB1cCAqbmVzdGVkKiBjb250ZXh0cy4gV2UgY291 bGQgcmVkZWZpbmUgdGhhdCBjb25zdHJ1Y3RvciB0byBzcGVjaWZ5IG11bHRpcGxlIGZpbGVzIHRo YXQgbWFrZSB1cCBhICpzaW5nbGUqIGNvbnRleHQsIGFuZCBvZmZlciBhbiBvdmVybG9hZGVkIHZl cnNpb24gdGhhdCB0YWtlcyBhIHBhcmVudCBBcHBsaWNhdGlvbkNvbnRleHQgcmVmZXJlbmNlLiBU aGF0IHdheSwgYm90aCBtdWx0aXBsZSBmaWxlcyBmb3IgYSBzaW5nbGUgY29udGV4dCBhbmQgbmVz dGluZyB3b3VsZCBiZSBwb3NzaWJsZS4NCiANCi0tLS0tDQogDQpXaGF0IEknbSBtb3N0IGV4Y2l0 ZWQgYWJvdXQgaXMgdGhlIEJlYW5Qb3N0UHJvY2Vzc29yIGhvb2suIEkgZXhwZWN0IHRoYXQgdG8g YmUgdmVyeSBwb3dlcmZ1bCwgYXMgYWxyZWFkeSBpbmRpY2F0ZWQgYnkgdGhlIHJlc3BlY3RpdmUg dGVzdCBjYXNlIGluIFN0YXRpY0FwcGxpY2F0aW9uQ29udGV4dFN1aXRlLiBBbm90aGVyIGV4YW1w bGUgdGhhdCBJJ3ZlIHByb3RvdHlwZWQgaXMgdGhlIGZvbGxvd2luZyAobm90IHlldCBpbiBDVlMp Og0KcHVibGljIGNsYXNzIEF1dG9Qcm94eUNyZWF0b3IgaW1wbGVtZW50cyBCZWFuUG9zdFByb2Nl c3NvciB7DQogIHByaXZhdGUgTGlzdCBiZWFuTmFtZXM7DQogIHByaXZhdGUgSW50ZXJjZXB0b3Jb XSBpbnRlcmNlcHRvcnM7DQoNCiAgcHVibGljIHZvaWQgc2V0QmVhbk5hbWVzKFN0cmluZ1tdIGJl YW5OYW1lcykgew0KICAgIHRoaXMuYmVhbk5hbWVzID0gQXJyYXlzLmFzTGlzdChiZWFuTmFtZXMp Ow0KICB9DQoNCiAgcHVibGljIHZvaWQgc2V0SW50ZXJjZXB0b3JzKEludGVyY2VwdG9yW10gaW50 ZXJjZXB0b3JzKSB7DQogICAgdGhpcy5pbnRlcmNlcHRvcnMgPSBpbnRlcmNlcHRvcnM7DQogIH0N Cg0KICBwdWJsaWMgT2JqZWN0IHBvc3RQcm9jZXNzQmVhbihPYmplY3QgYmVhbiwgU3RyaW5nIG5h bWUsIFJvb3RCZWFuRGVmaW5pdGlvbiBkZWZpbml0aW9uKSB7DQogICAgaWYgKHRoaXMuYmVhbk5h bWVzICE9IG51bGwgJiYgdGhpcy5iZWFuTmFtZXMuY29udGFpbnMobmFtZSkpIHsNCiAgICAgIFBy b3h5RmFjdG9yeSBwcm94eUZhY3RvcnkgPSBuZXcgUHJveHlGYWN0b3J5KCk7DQogICAgICBmb3Ig KGludCBpID0gMDsgaSA8IHRoaXMuaW50ZXJjZXB0b3JzLmxlbmd0aDsgaSsrKSB7DQogICAgICAg IHByb3h5RmFjdG9yeS5hZGRJbnRlcmNlcHRvcih0aGlzLmludGVyY2VwdG9yc1tpXSk7DQogICAg ICB9DQogICAgICBwcm94eUZhY3RvcnkuYWRkSW50ZXJjZXB0b3IobmV3IEludm9rZXJJbnRlcmNl cHRvcihiZWFuKSk7DQogICAgICByZXR1cm4gcHJveHlGYWN0b3J5LmdldFByb3h5KCk7DQogICAg fQ0KICAgIGVsc2Ugew0KICAgICAgcmV0dXJuIGJlYW47DQogICAgfQ0KICB9DQp9DQoNClRoaXMg aXMgYSBCZWFuUG9zdFByb2Nlc3NvciBiZWFuIHRoYXQgY2FuIGJlIHNldCB1cCBhcyBmb2xsb3dz IHRvIHByb3h5IHRoZSBiZWFucyB3aXRoIHRoZSBnaXZlbiBuYW1lcyB3aXRoIHRoZSBnaXZlbiBp bnRlcmNlcHRvcnMuIE5vdGUgdGhhdCB0aGlzIGlzIG9ubHkgb25lIGJlYW4gd2l0aCBwcm94eSBz ZXR0aW5ncyB0byBkZWZpbmUsIGFsdGhvdWdoIHRoZXJlIG1pZ2h0IGJlIGRvemVucyBvZiB0YXJn ZXQgYmVhbnMgd2l0aCB0aGUgc2FtZSBwcm94eSBiZWhhdmlvci4NCg0KPGJlYW4gaWQ9ImF1dG9Q cm94eUNyZWF0b3IiIGNsYXNzPSJvcmcuc3ByaW5nZnJhbWV3b3JrLmFvcC5mcmFtZXdvcmsuc3Vw cG9ydC5BdXRvUHJveHlDcmVhdG9yIj4NCiAgPHByb3BlcnR5IG5hbWU9ImJlYW5OYW1lcyI+PHZh bHVlPm15QmVhbjEsbXlCZWFuMixteUJlYW4zPC92YWx1ZT48L3Byb3BlcnR5Pg0KICA8cHJvcGVy dHkgbmFtZT0iaW50ZXJjZXB0b3JzPg0KICAgIDxsaXN0Pg0KICAgICAgPHJlZiBiZWFuPSJteUlu dGVyY2VwdG9yMSIvPg0KICAgICAgPHJlZiBiZWFuPSJteUludGVyY2VwdG9yMiIvPg0KICAgIDwv bGlzdD4NCiAgPC9wcm9wZXJ0eT4NCjwvYmVhbj4NCg0KU28gc2V0dGluZyB1cCAxMCB0cmFuc2Fj dGlvbmFsIGJlYW5zIHdvdWxkIGp1c3QgaW52b2x2ZSAxIEF1dG9Qcm94eUNyZWF0b3IgYW5kIDEg dHJhbnNhY3Rpb24gaW50ZXJjZXB0b3IgcGx1cyB0aGUgMTAgdGFyZ2V0IGJlYW5zICgxMiBiZWFu cyBpbiB0b3RhbCksIGluc3RlYWQgb2YgMTAgVHJhbnNhY3Rpb25Qcm94eUZhY3RvcnlCZWFucyBw bHVzIHRoZSAxMCB0YXJnZXQgYmVhbnMgKDIwIGJlYW5zIGluIHRvdGFsKS4gVGhlIHRyYW5zYWN0 aW9uIGF0dHJpYnV0ZXMgd291bGQgYmUgY2VudHJhbGl6ZWQgdGhvdWdoLCBpbiBjb250cmFzdCB0 byBUcmFuc2FjdGlvblByb3h5RmFjdG9yeUJlYW4gdGhhdCBrZWVwcyB0aGVtIGxvY2FsIHBlciBp bmRpdmlkdWFsIHByb3h5IGRlZmluaXRpb24uDQogDQpPZiBjb3Vyc2UsIHNvdXJjZS1sZXZlbCBt ZXRhZGF0YSB3b3VsZCBhbGxvdyBmb3IganVzdCAxIEJlYW5Qb3N0UHJvY2Vzc29yIHBsdXMgdGhl IDEwIHRhcmdldCBiZWFucyAoMTEgYmVhbnMgaW4gdG90YWwpLCB3aXRoIHRoZSB0cmFuc2FjdGlv biBhdHRyaWJ1dGVzIGJlaW5nIGtlcHQgd2l0aCB0aGUgcmVzcGVjdGl2ZSBtZXRob2RzIGluIHRo ZSBzb3VyY2UgY29kZS4gVGhpcyB3b3VsZCBqdXN0IGdldCByaWQgb2YgMSBiZWFuIGJ1dCBvZiBh IHByZXR0eSBibG9hdGVkIG9uZTogdGhlIFRyYW5zYWN0aW9uSW50ZXJjZXB0b3IgZGVmaW5pdGlv biB3aXRoIGl0cyBjZW50cmFsaXplZCB0cmFuc2FjdGlvbiBhdHRyaWJ1dGVzIGZvciB0aGUgd2hv bGUgYXBwLg0KIA0KSnVlcmdlbg0KIA0KIA0KDQoJLS0tLS1VcnNwcsO8bmdsaWNoZSBOYWNocmlj aHQtLS0tLSANCglWb246IFJvZCBKb2huc29uIFttYWlsdG86cm9kLmpvaG5zb25AaW50ZXJmYWNl MjEuY29tXSANCglHZXNlbmRldDogRnIgMTAuMTAuMjAwMyAxNjo0MSANCglBbjogc3ByaW5nZnJh bWV3b3JrLWRldmVsb3BlckBsaXN0cy5zb3VyY2Vmb3JnZS5uZXQgDQoJQ2M6IA0KCUJldHJlZmY6 IFJlOiBbU3ByaW5nZnJhbWV3b3JrLWRldmVsb3Blcl0gbmV3IGJlYW4gZmFjdG9yeSBhbmQgYXBw bGljYXRpb24gY29udGV4dCBmZWF0dXJlcw0KCQ0KCQ0KDQoJSSB0aGluayB0aGlzIGlzIHZlcnkg dXNlZnVsLg0KCQ0KCUl0IHdvdWxkIGJlIGdvb2QgdG8gaGF2ZSB0aGlzIGF2YWlsYWJsZSBmb3Ig dGhlIFhtbEJlYW5GYWN0b3J5IGFzIHdlbGwuDQoJT2Z0ZW4sIGVzcGVjaWFsbHkgZm9yIGludGVn cmF0aW9uIHRlc3RpbmcsIEkgdGVuZCB0byB1c2UgYSBCZWFuRmFjdG9yeQ0KCXVubGVzcyBteSBj b2RlIGhhcyBzcGVjaWZpYyBkZXBlbmRlbmNpZXMgb24gYW4gYXBwbGljYXRpb24gY29udGV4dCBm b3INCglzb3VyY2luZyBtZXNzYWdlcyBldGMuDQoJDQoJUmVnYXJkcywNCglSb2QNCgkNCgktLS0t LSBPcmlnaW5hbCBNZXNzYWdlIC0tLS0tDQoJRnJvbTogImrDvHJnZW4gaMO2bGxlciBbd2VyazNB VF0iIDxqdWVyZ2VuLmhvZWxsZXJAd2VyazNhdC5jb20+DQoJVG86IDxzcHJpbmdmcmFtZXdvcmst ZGV2ZWxvcGVyQGxpc3RzLnNvdXJjZWZvcmdlLm5ldD4NCglTZW50OiBGcmlkYXksIE9jdG9iZXIg MTAsIDIwMDMgMzozMCBQTQ0KCVN1YmplY3Q6IFtTcHJpbmdmcmFtZXdvcmstZGV2ZWxvcGVyXSBu ZXcgYmVhbiBmYWN0b3J5IGFuZCBhcHBsaWNhdGlvbg0KCWNvbnRleHQgZmVhdHVyZXMNCgkNCgkN CglFdmVyeWJvZHksDQoJDQoJUmVsYXRlZCB0byB0aGUgZGlzY3Vzc2lvbiBhYm91dCBoaWVyYXJj aGljYWwgbG9hZGluZywgSSd2ZSBqdXN0IGNvbW1pdHRlZA0KCXN1cHBvcnQgZm9yIGFzc2VtYmxp bmcgYW4gYXBwbGljYXRpb24gY29udGV4dCBmcm9tIG1vcmUgdGhhbiBvbmUgWE1MIGZpbGUsDQoJ anVzdCBhdmFpbGFibGUgdmlhIFhtbFdlYkFwcGxpY2F0aW9uQ29udGV4dCBmb3IgdGhlIG1vbWVu dC4gSXQgYWxsb3dzIHRvDQoJc3BlY2lmeSBjb25maWcgbG9jYXRpb25zIHdpdGggbXVsdGlwbGUg cGF0aHMgaW4gaXQsIGxpa2UgaW4gdGhlIHdlYiBjYXNlOg0KCQ0KCSAgPGNvbnRleHQtcGFyYW0+ DQoJICAgIDxwYXJhbS1uYW1lPmNvbnRleHRDb25maWdMb2NhdGlvbjwvcGFyYW0tbmFtZT4NCgkg ICAgICA8cGFyYW0tdmFsdWU+DQoJICAgICAgICBXRUItSU5GL2FwcGxpY2F0aW9uQ29udGV4dDEu eG1sDQoJICAgICAgICBXRUItSU5GL2FwcGxpY2F0aW9uQ29udGV4dDIueG1sDQoJICAgICAgPC9w YXJhbS12YWx1ZT4NCgkgIDwvY29udGV4dC1wYXJhbT4NCgkNCglBbnkgbnVtYmVyIG9mIHRoZSBj aGFyYWN0ZXJzICI7LCAiIGJldHdlZW4gcGF0aHMgYXJlIGlnbm9yZWQsIHRvIGFsbG93IGZvcg0K CWxlbmllbnQgcGFyc2luZy4gVGhlIHJlc3VsdCBpcyBhICpzaW5nbGUqIHJvb3Qgd2ViIGFwcGxp Y2F0aW9uIGNvbnRleHQgdGhhdA0KCWhhcyBiZWVuIGxvYWRlZCBmcm9tIG11bHRpcGxlIFhNTCBm aWxlcywgZWFjaCBjb25mb3JtaW5nIHRvIHRoZSBzcHJpbmctYmVhbnMNCglEVEQuIEJlYW4gcmVm ZXJlbmNlcyBiZXR3ZWVuIHRoZSBpbmRpdmlkdWFsIGZpbGVzIG5lZWQgdG8gYmUgPHJlZg0KCWV4 dGVybmFsPSIuLi4iPiBpbnN0ZWFkIG9mIDxyZWYgYmVhbj0iLi4uIj4gdGhhdCByZWZlcmVuY2Vz IFhNTCBlbnRpdGllcyBpbg0KCXRoZSBzYW1lIGZpbGUuDQoJDQoJVGhpcyBhbGxvd3MgdG8gc3Bs aXQgYSBsYXJnZSBkZWZpbml0aW9uIG9mIGEgbWlkZGxlIHRpZXIgYXBwbGljYXRpb24gY29udGV4 dA0KCWludG8gbXVsdGlwbGUgWE1MIGZpbGVzLCBlaXRoZXIgc2VwYXJhdGluZyBieSBzeXN0ZW0g bW9kdWxlcyBvciBieSBzdWINCglsYXllcnMuIE9idmlvdXNseSB0aGlzIGRvZXNuJ3QgYWRkcmVz cyB0aGUgRUpCL211bHRpcGxlIHdlYiBhcHAgY2FzZSwgYnV0IGl0DQoJc2hvdWxkIGJlIHdlbGwg c3VpdGVkIGZvciB0eXBpY2FsIGxhcmdlIHdlYiBhcHBsaWNhdGlvbnMuDQoJDQoJQlRXLCBJJ3Zl IGFsc28gYWRkZWQgc3VwcG9ydCBmb3IgbXVsdGlwbGUgcmVzb3VyY2UgYnVuZGxlIGJhc2VuYW1l cyBpbg0KCVJlc291cmNlQnVuZGxlTWVzc2FnZVNvdXJjZSwgdmlhIHRoZSAiYmFzZW5hbWVzIiBw cm9wZXJ0eSAoaW4gYWRkaXRpb24gdG8NCgl0aGUgZXhpc3RpbmcgImJhc2VuYW1lIiBvbmUpLiBU aG9zZSByZXNvdXJjZSBidW5kbGVzIGdldCBjaGVja2VkDQoJc2VxdWVudGlhbGx5IHdpdGhpbiBh ICpzaW5nbGUqIE1lc3NhZ2VTb3VyY2UsIGFsbG93aW5nIHRvIHNwbGl0IGxhcmdlDQoJbWVzc2Fn ZSBidW5kbGVzIGludG8gbXVsdGlwbGUgZmlsZXMuDQoJDQoJRnVydGhlcm1vcmUsIEkndmUgcmV2 aXNlZCB0aGUgbm90YXRpb24gb2YgbmFtZSBhbGlhc2VzIGxpa2UgPGJlYW4gLi4uDQoJbmFtZT0i bXlhbGlhczEsbXlhbGlhczIiPiB0byBtYXRjaCB0aGUgcnVsZXMgYWJvdmU6IEFueSBudW1iZXIg b2YgdGhlDQoJY2hhcmFjdGVycyAiOywgIiBiZXR3ZWVuIGJlYW4gbmFtZXMgYXJlIGlnbm9yZWQu IFRoaXMgcGFydGljdWxhcmx5IGFsbG93cw0KCUJlYW5OYW1lVXJsSGFuZGxlck1hcHBpbmcgdG8g aW50ZXJwcmV0IG11bHRpcGxlIGFsaWFzZXMgYXMgbXVsdGlwbGUgbWFwcGluZ3MNCgl3aXRob3V0 IGN1c3RvbSBwYXJzaW5nLCBubyBtYXR0ZXIgaWYgc2VwYXJhdGVkIGJ5IGEgY29tbWEgb3Igc3Bh Y2UgKHRoZQ0KCWxhdHRlciBsb29rcyBjbGVhbmVyIHdpdGggVVJMcykuDQoJDQoJVGhlIGRyYXdi YWNrIG9mIHRoZSBsYXR0ZXIgaXMgdGhhdCBYTUwgYmVhbiBhbGlhc2VzIGFyZSBub3QgYWxsb3dl ZCB0bw0KCWNvbnRhaW5zIHNwYWNlcyBvciBjb21tYXMgYW55bW9yZSAtLSBmb3IgdGhlIGJlbmVm aXQgb2YgYmVpbmcgYWJsZSB0bw0KCXNwZWNpZnkgbXVsdGlwbGUgYWxpYXNlcy4gRG9lcyBhbnlv bmUgb2JqZWN0IHRvIHRoYXQgdHJhZGVvZmY/DQoJDQoJLS0tLS0NCgkNCglJJ3ZlIGFsc28gYWRk ZWQgYSBuZXcgcG9zdCBwcm9jZXNzb3IgdHlwZTogQmVhblBvc3RQcm9jZXNzb3IsIGluIGFkZGl0 aW9uIHRvDQoJdGhlIGV4aXN0aW5nIEJlYW5GYWN0b3J5UG9zdFByb2Nlc3Nvci4gTm90ZSB0aGF0 IHRoZSBmb3JtZXIgaXMgaW4gdGhlDQoJYmVhbnMuZmFjdG9yeS5zdXBwb3J0IHBhY2thZ2UsIHdp dGggQWJzdHJhY3RCZWFuRmFjdG9yeSBvZmZlcmluZyBzdXBwb3J0IGZvcg0KCWl0IC0tIHdoaWxl IHRoZSBsYXR0ZXIgaXMgaW4gY29udGV4dC5jb25maWcsIGFzIGl0IGFsbG93cyBhcHBsaWNhdGlv bg0KCWNvbnRleHRzIHRvIG92ZXJyaWRlIHByb3BlcnR5IHZhbHVlcyAqYWZ0ZXIqIHRoZWlyIGJl YW4gZmFjdG9yeSAoYQ0KCUxpc3RhYmxlQmVhbkZhY3RvcnlJbXBsLCB0byBiZSBleGFjdCkgaGFz IGxvYWRlZC4NCgkNCglBIEJlYW5GYWN0b3J5UG9zdFByb2Nlc3NvciBnZXRzIGludm9rZWQgb25j ZSBwZXIgYmVhbiBmYWN0b3J5IGxvYWRpbmc7DQoJQmVhblBvc3RQcm9jZXNzb3Igb25jZSBwZXIg YmVhbiBjcmVhdGlvbi4gQm90aCB0eXBlcyBvZiBwb3N0IHByb2Nlc3NvciBjYW4NCgliZSBkZWZp bmVkIGFzIG5vcm1hbCBiZWFucyBpbiBhbiBhcHBsaWNhdGlvbiBjb250ZXh0LCBnZXR0aW5nIGF1 dG9tYXRpY2FsbHkNCglkZXRlY3RlZCBhdCBzdGFydHVwLCBhbmQgYXBwbGllZCBiZWZvcmUgdGhl IHJlc3Qgb2YgdGhlIGJlYW5zIGdldHMgY3JlYXRlZC4NCglXaXRoIGEgcGxhaW4gYmVhbiBmYWN0 b3J5LCBvbmx5IEJlYW5Qb3N0UHJvY2Vzc29yIGlzIGFwcGxpY2FibGUsIGJ1dCBub3QNCglkZWZp bmVkIGFzIGEgbm9ybWFsIGJlYW4gYnV0IHJhdGhlciBzZXQgdmlhIEFic3RyYWN0QmVhbkZhY3Rv cnkncw0KCXNldEJlYW5Qb3N0UHJvY2Vzc29ycyBtZXRob2QuDQoJDQoJSSd2ZSBhcHBsaWVkIHRo ZSBwcmluY2lwbGUgdGhhdCBiZWFuIGZhY3RvcmllcyBhcmUgbm90IHN1cHBvc2VkIHRvDQoJdW5k ZXJzdGFuZCBzcGVjaWFsIGJlYW5zIGluIHRoZSBiZWFuIGRlZmluaXRpb25zIHRoYXQgaW5mbHVl bmNlIHRoZSBiZWhhdmlvcg0KCW9mIHRoZSBmYWN0b3J5IGl0c2VsZiAtLSBqdXN0IGFwcGxpY2F0 aW9uIGNvbnRleHRzIGFyZSwgbGlrZSB3aXRoIHRoZQ0KCW1lc3NhZ2Ugc291cmNlLCBvcHRpb25z IGJlYW5zLCBhbmQgcG9zdCBwcm9jZXNzb3JzLiBCZWFuIGZhY3RvcmllcyBjYW4gYmUNCgljdXN0 b21pemVkIHRocm91Z2ggdGhlaXIgaW1wbGVtZW50YXRpb24gY2xhc3MsIHRob3VnaCAtIGUuZy4N CglzZXRFbnRpdHlSZXNvbHZlciwgc2V0VmFsaWRhdGluZywgYW5kIHNldEJlYW5Qb3N0UHJvY2Vz c29ycyBvbg0KCVhtbEJlYW5GYWN0b3J5Lg0KCQ0KCUEgc3BlY2lhbCBpbXBsZW1lbnRhdGlvbiBv ZiBCZWFuUG9zdFByb2Nlc3NvciBpcyBhcHBsaWVkIHVuZGVyIHRoZSBob29kIGJ5DQoJQWJzdHJh Y3RBcHBsaWNhdGlvbkNvbnRleHQ6IEFwcGxpY2F0aW9uQ29udGV4dEF3YXJlUHJvY2Vzc29yIGlz IGltcGxpY3RseQ0KCXJlZ2lzdGVyZWQgd2l0aCB0aGUgdW5kZXJseWluZyBiZWFuIGZhY3Rvcnkg dG8gYXV0b21hdGljYWxseSBwYXNzIHRoZQ0KCWFwcGxpY2F0aW9uIGNvbnRleHQgdG8gQXBwbGlj YXRpb25Db250ZXh0QXdhcmUgYmVhbnMuIFRoaXMgYWxsb3dlZCBtZSB0byBnZXQNCglyaWQgb2Yg dGhlIHJhdGhlciB1Z2x5IG1hbnVhbCBjaGVjayBmb3IgQXBwbGljYXRpb25Db250ZXh0QXdhcmUg d2l0aCBhIGNhY2hlDQoJb2YgYWxyZWFkeSBtYW5hZ2VkIGluc3RhbmNlcyB0byBhdm9pZCBkb3Vi bGUgc2V0dGluZyBvZiB0aGUgYXBwbGljYXRpb24NCgljb250ZXh0IC0tIHRoZSBjdXJyZW50IHNv bHV0aW9uIGlzIG11Y2ggY2xlYW5lci4NCgkNCglOb3RlIHRoYXQgYSBjdXN0b20gQmVhblBvc3RQ cm9jZXNzb3IgZGVmaW5pdGlvbiBpbiBhbiBhcHBsaWNhdGlvbiBjb250ZXh0DQoJY2FuIG5vdCBv bmx5IGJlIHVzZWQgdG8gY2hlY2sgZm9yIG1hcmtlciBpbnRlcmZhY2VzIGJ1dCBhbHNvIHRvIHdy YXAgY2VydGFpbg0KCWJlYW4gaW5zdGFuY2VzIHdpdGggcHJveGllcywgYXMgaXQgY2FuIHJldHVy biBhIGRpZmZlcmVudCBiZWFuIGluc3RhbmNlIHRoYW4NCgl0aGUgb25lIHRoYXQgY2FtZSBpbi4g TG9vayBhdCB0aGUgcmVzcGVjdGl2ZSB0ZXN0IGNhc2UgaW4NCglTdGF0aWNBcHBsaWNhdGlvbkNv bnRleHRUZXN0U3VpdGUgdGhhdCBpbXBsaWNpdGx5IHdyYXBzIGVhY2ggYmVhbiBpbnN0YW5jZQ0K CXdpdGggYSBDR0xJQiBwcm94eS4NCgkNCglOb3cgaW1hZ2luZSBhIEJlYW5Qb3N0UHJvY2Vzc29y IGltcGxlbWVudGF0aW9uIHRoYXQgY2hlY2tzIGZvciBjZXJ0YWluDQoJYXR0cmlidXRlcyBpbiB0 aGUgYmVhbiBjbGFzcyBmaWxlIGFuZCBhcHBsaWVzIHJlc3BlY3RpdmUgaW50ZXJjZXB0b3JzIC0t DQoJbGlrZSB0cmFuc2FjdGlvbiBhdHRyaWJ1dGVzIHRoYXQgdHJpZ2dlciBhIENHTElCIHByb3h5 IGFuZCBhbiBpbXBsaWNpdA0KCVRyYW5zYWN0aW9uSW50ZXJjZXB0b3IhIEkgY29uc2lkZXIgdGhp cyBhcyB0aGUgcGVyZmVjdCBob29rIGZvciBzdWNoDQoJaW1wbGljaXQgd3JhcHBpbmcgYXQgYmVh biBjcmVhdGlvbiB0aW1lLg0KCQ0KCUp1ZXJnZW4NCgkNCgkNCgktLS0tLU9yaWdpbmFsIE1lc3Nh Z2UtLS0tLQ0KCUZyb206IENvbGluIFNhbXBhbGVhbnUgW21haWx0bzpjb2xpbm1sMUBleGlzLmNv bV0NCglTZW50OiBUaHVyc2RheSwgU2VwdGVtYmVyIDE4LCAyMDAzIDU6MTUgUE0NCglUbzogc3By aW5nZnJhbWV3b3JrLXVzZXJAbGlzdHMuc291cmNlZm9yZ2UubmV0DQoJU3ViamVjdDogW1Nwcmlu Z2ZyYW1ld29yay11c2VyXSBIaWVyYXJjaGljYWwgbG9hZGluZyBvZiBBcHBsaWNhdGlvbg0KCUNv bnRleHRzDQoJDQoJDQoJSSB3YW50ZWQgdG8gc3B1ciBzb21lIGRpc2N1c3Npb24gb2YgYmVzdCBw cmFjdGljZXMgZm9yIGhpZXJhY2hpY2FsDQoJbG9hZGluZyBvZiBBcHBsaWNhdGlvbkNvbnRleHRz LiBBcHBsaWNhdGlvbkNvbnRleHQgaW1wbGVtZW50YXRpb25zIGNhbg0KCW9mIGNvdXJzZSBiZSBj cmVhdGVkIHdpdGggYSBwYXJlbnQgY29udGV4dCBzcGVjaWZpZWQuIEN1cnJlbnRseSwgdGhlcmUN CglpcyBzb21lIGNvZGUgc3VwcG9ydCBmb3IgYWN0dWFsbHkgbWFuYWdpbmcgdGhpcyBsb2FkaW5n IGluIHRoZSB3ZWIgdWkNCglsYXllciAod2hlcmUgaXQncyBlYXN5IHRvIGhhdmUgYSBzZXR1cCB3 aXRoIGEgcm9vdA0KCVdlYkFwcGxpY2F0aW9uQ29udGV4dCwgYW5kIG11bHRpcGxlIGNoaWxkIGNv bnRleHRzLCBwZXIgc2VydmxldC4NCgkNCglNb3N0IFNwcmluZyB1c2FnZSBleGFtcGxlcyBhc3N1 bWUgKHVubGVzcyBJJ20gbWlzc2luZyBzb21ldGhpbmcpIHRoYXQNCgl0aGUgcm9vdCBXZWJBcHBs aWNhdGlvbkNvbnRleHQgd2lsbCBjb250YWluIHRoZSBlbnRpcmUgbGF5ZXIgc3RhY2ssIHRoYXQN CglpcywgZGF0YS1hY2Nlc3MgYmVhbnMgYW5kIHNlcnZpY2UgbGF5ZXIgYmVhbnMgd2lsbCBiZSBk ZWZpbmVkIGluIHRoZXJlLg0KCVRoaXMgZG9lcyB3b3JrIGdyZWF0IHdoZW4gdGhlcmUgdGhlcmUg aXMgb25seSBvbmUgd2ViLWFwcC4NCgkNCglOb3cgaW4gbXkgY2FzZSwgSSBuZWVkIHNvbWV0aGlu ZyBhIGxpdHRsZSBiaXQgZGlmZmVyZW50LiBJIGhhdmUgYSBKMkVFDQoJYXBwbGljYXRpb24gYXMg YW4gRUFSIGZpbGUsIHdoaWNoIGNvbnRhaW5zIDMgd2ViLWFwcHMgKGFzIFdBUnMpIGF0IHRoZQ0K CXRvcCBsYXllci4gQW1vbmcgb3RoZXIgbGF5ZXJzLCBiZWxvdyB0aGUgd2ViIHVpIGxheWVyIHRo ZXJlIGlzIGENCglzZXJ2aWNlcyBsYXllciwgYW5kIGEgZGF0YS1hY2Nlc3MgbGF5ZXIuICBOb3cg SSBjb3VsZCBnZXQgYnkgd2l0aCB0aHJlZQ0KCWRpZmZlcmVudCwgcGFyYWxsZWwsIGFwcGxpY2F0 aW9uIGNvbnRleHRzIGRlZmluZWQsIG9uZSBmb3IgZWFjaCBvZiB0aGUNCgl3ZWItYXBwcywgd2hl cmUgYWxsIHRoZSBiZWFuIGRlZmluaXRpb25zIGZvciB0aGUgZGF0YS1hY2Nlc3MgYW5kDQoJc2Vy dmljZXMgbGF5ZXIgd2FzIGR1cGxpY2F0ZWQgaW4gZWFjaCBhcHBsaWNhdGlvbiBjb250ZXh0LiBJ IGRvIG5vdCB3YW50DQoJdG8gZG8gdGhpcyBob3dldmVyLCBzaW5jZSBJIGFtIHVzaW5nIEhpYmVy bmF0ZSwgYW5kIGRvIG5vdCB3YW50IHRvIGZvcmNlDQoJdGhlIEhpYmVybmF0ZSBtZXRhLWRhdGEg dG8gYmUgcmVhZCBpbiAzIHRpbWVzIChpdCdzIGEgc2xvdyBwcm9jZXNzKS4gSQ0KCW11Y2ggcHJl ZmVyIHRvIGhhdmUgYSBoaWVyYWNoaWNhbCBzZXR1cCBmb3IgdGhlIHdob2xlIGoyZWUgYXBwLCB3 aGVyZSAgSQ0KCWhhdmUgYW4gYXBwbGljYXRpb24gY29udGV4dCBkZWZpbml0aW9uIGZvciB0aGUg ZGF0YS1hY2Nlc3MgbGF5ZXIsIHdoaWNoDQoJbmVlZHMgdG8gYmUgdGhlIHBhcmVudCBvZiBhbiBh cHBsaWNhdGlvbiBjb250ZXh0IGRlZmluaXRpb24gZm9yIHRoZQ0KCXNlcnZpY2VzIGxheWVyLCB3 aGljaCBuZWVkcyB0byBiZSB0aGUgcGFyZW50IG9mIHRocmVlIHNlcGFyYXRlIHdlYg0KCWFwcGxp Y2F0aW9uIGNvbnRleHQgZGVmaW5pdGlvbnMsIG9uZSBpbiBlYWNoIHdlYi1hcHAuDQoJDQoJSSBo YXZlIGJlZW4gYWJsZSB0byBhY2hpZXZlIHRoaXMgYXMgZm9sbG93cyAoYW5kIHdhbnQgdG8gZ2V0 IGZlZWRiYWNrIGlmDQoJc29tZWJvZHkgY2FuIHRoaW5rIG9mIGEgYmV0dGVyIHdheSk6IEkgaGF2 ZSBhbiBhcHBsaWNhdGlvbiBjb250ZXh0DQoJZGVmaW50aW9uIGZvciBteSBkYXRhIGFjY2VzcyBs YXllcg0KCSAgZGF0YS1hY2Nlc3MtYXBwbGljYXRpb25Db250ZXh0LnhtbA0KCUkgaGF2ZSBhbiBh cHBsaWNhdGlvbiBjb250ZXh0IGRlZmluaXRpb24gZm9yIG15IHNlcnZpY2VzIGxheWVyLCB3aGlj aCBpcw0KCWEgY2hpbGQgb2YgdGhlIGRhdGEtYWNjZXNzIGNvbnRleHQsIGFuZCByZWZlcnMgdG8g YmVhbnMgaW4gaXQuOg0KCSAgY29yZS1zZXJ2aWVzLWFwcGxpY2F0aW9uQ29udGV4dC54bWwNCglJ IHRoZW4gaGF2ZSB0aGUgdGhyZWUgYXBwbGljYXRpb24gY29udGV4dHMgZm9yIHRoZSB3ZWIgYXBw cywgd2hpY2ggYXJlDQoJY2hpbGRyZW4gb2YgdGhlIHNlcnZpY2VzIGNvbnRleHQsIGFuZCByZWZl ciB0byBiZWFucyB3aXRoaW4gaXQuDQoJDQoJTm93IHdoYXQgSSBkbywgaXMgKGluIGEgc29tZXdo YXQgbGF6eSBmYXNoaW9uKSB0cmlnZ2VyIGxvYWRpbmcgKG9uY2UpIG9mDQoJdGhlIHNlcnZpY2Vz IGFuZCBkYXRhLWFjY2VzcyBjb250ZXh0cywgd2hlbiBJIGxvYWQgdGhlIGZpcnN0IHdlYg0KCWFw cGxpY2F0aW9uIGNvbnRleHQuIFRoZSAybmQgYW5kIDNyZCB3ZWIgYXBwbGljYXRpb24gY29udGV4 dCBlbmQgdXANCgl1c2luZyB0aGUgcHJldmlvdXNseSBsb2FkZWQgc2VydmljZSBjb250ZXh0IGlu c3RhbmNlLiBJIGhhdmUgYW4NCglpbnRlcmZhY2UsIENvbnRleHRGYWN0b3J5LCBhcyBmb2xsb3dz Og0KCQ0KCS8qKg0KCSAqIERlZmluZXMgaW50ZXJmYWNlIGZvciBhbiBBcHBsaWNhdGlvbkNvbnRl eHQgZmFjdG9yeS4NCgkgKg0KCSAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS40MCAkDQoJICogQGF1 dGhvciAgY29saW4NCgkgKi8NCglwdWJsaWMgaW50ZXJmYWNlIENvbnRleHRGYWN0b3J5IHsNCgkN CgkgIC8qKg0KCSAgICogVXNlIHRoZSBBcHBsaWNhdGlvbkNvbnRleHQgc3BlY2lmaWVkIGJ5IHRo ZSBrZXkgcGFyYW1ldGVyLiBUaGUNCgljb250ZXh0IGlzIHBvc3NpYmx5DQoJICAgKiBsb2FkZWQv Y3JlYXRlZCBhcyBuZWVkZWQuDQoJICAgKg0KCSAgICogQHBhcmFtIGtleSBhIHZhbHVlIHNwZWNp Znlpbmcgd2hpY2ggY29udGV4dCB0byB1c2UNCgkgICAqIEByZXR1cm4gdGhlIEFwcGxpY2F0aW9u Q29udGV4dCBpbnN0YW5jZQ0KCSAgICogQHRocm93cyBBcHBsaWNhdGlvbkNvbnRleHRFeGNlcHRp b24gaWYgdGhlcmUgaXMgYW4gZXJyb3IgbG9hZGluZw0KCW9uZSBvciBtb3JlIGNvbnRleHRzDQoJ ICAgKi8NCgkgIEFwcGxpY2F0aW9uQ29udGV4dCB1c2VDb250ZXh0KFN0cmluZyBrZXkpIHRocm93 cw0KCUFwcGxpY2F0aW9uQ29udGV4dEV4Y2VwdGlvbjsNCgkNCgkgIC8qKg0KCSAgICogSW5kaWNh dGUgdGhhdCB0aGUgc3BlY2lmaWVkIEFwcGxpY2F0aW9uQ29udGV4dCBpbnN0YW5jZSBpcyBub3QN CgluZWVkZWQgYnkgYSB1c2VyIG9mIGl0LA0KCSAgICogd2hvIGhhcyBwcmV2aXNvdWx5IG9idGFp bmVkIGl0IHZpYSB7QGxpbmsgdXNlQ29udGV4dH0uIEl0IGlzIGFuDQoJZXJyb3IgZm9yIHJlbGVh c2VDb250ZXh0DQoJICAgKiB0byBiZSBjYWxsZWQgYSBncmVhdGVyIG51bWJlciBvZiB0aW1lcyB0 aGFuIHVzZUNvbnRleHQuIENhbGxpbmcNCgl0aGlzIHJlbGVhc2UgbWV0aG9kIG1heQ0KCSAgICog Y2F1c2UgY2xvc2UoKSB0byBiZSBjYWxsZWQgb24gdGhlIHNwZWNpZmllZCBjb250ZXh0LCBpZiB0 aGlzIGlzIHRoZQ0KCWxhc3QgdXNlciBvZiBpdC4NCgkgICAqDQoJICAgKiBAcGFyYW0gYWMgdGhl IEFwcGxpY2F0aW9uQ29udGV4dCBpbnN0YW5jZQ0KCSAgICogQHRocm93cyBBcHBsaWNhdGlvbkNv bnRleHRFeGNlcHRpb24NCgkgICAqLw0KCSAgdm9pZCByZWxlYXNlQ29udGV4dChBcHBsaWNhdGlv bkNvbnRleHQgYWMpIHRocm93cw0KCUFwcGxpY2F0aW9uQ29udGV4dEV4Y2VwdGlvbjsNCgkNCgl9 DQoJDQoJTm93IEkgaGF2ZSBhbiBhY3R1YWwgaW1wbGVtZW50YXRpb24sIHdoaWNoIGNhbiBiZSB1 c2VkIHRvIGdldCBhY2Nlc3MgdG8NCglhIHJlZmVyZW5jZSBjb3VudGVkIGNvbnRleHQsIHRyaWdn ZXJpbmcgbG9hZGluZyBhcyBuZWVkZWQsIGFuZCBsb2FkaW5nDQoJcGFyZW50cyBvZiB0aGF0IGNv bnRleHQsIGlmIG5lZWRlZDoNCgkNCgkvKioNCgkgKiBJbXBsZW1lbnRhdGlvbiBvZiBDb250ZXh0 RmFjdG9yeS48YnIgLz4NCgkgKiBJbiB0aGlzIGltcGxlbWVudGF0aW9uLCB0aGUga2V5IGlzIGFj dHVhbGx5IHRoZSBuYW1lIG9mIGEgcHJvcGVydGllcw0KCWZpbGUgYWNjZXNzZWQgYXMNCgkgKiBh IHJlc291cmNlLCBlYWNoIGxpbmUgb2Ygd2hpY2ggc3BlY2lmaWVzIGFuIEFwcGxpY2F0aW9uQ29u dGV4dCB0bw0KCWxvYWQuIEVhY2ggbGluZSBpbg0KCSAqIHRoZSBmaWxlIGlzIHRoZSBwYXJlbnQg b2YgdGhlIHN1YnNlcXVlbnQgbGluZS4gVGhlIGxhc3QgY29udGV4dCBpcw0KCXRoZSBvbmUgcmV0 dXJuZWQuDQoJICoNCgkgKiBAdmVyc2lvbiAkUmV2aXNpb246ICQNCgkgKiBAYXV0aG9yICBjb2xp bg0KCSovDQoJcHVibGljIGNsYXNzIENvbnRleHRGYWN0b3J5SW1wbCBpbXBsZW1lbnRzIENvbnRl eHRGYWN0b3J5IHsNCgkNCgkgIC8vIC0tLSBzdGF0aWNzDQoJDQoJICBwdWJsaWMgc3RhdGljIGZp bmFsIExvZ2dlciBfbG9nID0NCglMb2dnZXIuZ2V0TG9nZ2VyKENvbnRleHRGYWN0b3J5SW1wbC5j bGFzcyk7DQoJDQoJICAvLyB3ZSBtYXAgQ29udGV4dEluZm8gb2JqZWN0cyBieSBTdHJpbmcga2V5 cywgYW5kIGJ5IENvbnRleHRzDQoJICBwcml2YXRlIHN0YXRpYyBIYXNoTWFwIGluc3RhbmNlc0J5 S2V5ID0gbmV3IEhhc2hNYXAoKTsNCgkgIHByaXZhdGUgc3RhdGljIEhhc2hNYXAgaW5zdGFuY2Vz QnlPYmogPSBuZXcgSGFzaE1hcCgpOw0KCQ0KCSAgLy8gLS0tIG1ldGhvZHMNCgkNCgkgIC8qIChu b24tSmF2YWRvYykNCgkgICAqIEBzZWUNCgljb20udGlyYS5jb3Jlc2Vydi53ZWJ1dGlsLkNvbnRl eHRGYWN0b3J5I3VzZUNvbnRleHQoamF2YS5sYW5nLlN0cmluZykNCgkgICAqLw0KCSAgcHVibGlj IEFwcGxpY2F0aW9uQ29udGV4dCB1c2VDb250ZXh0KFN0cmluZyBrZXkpIHRocm93cw0KCUFwcGxp Y2F0aW9uQ29udGV4dEV4Y2VwdGlvbiB7DQoJDQoJICAgIHN5bmNocm9uaXplZChpbnN0YW5jZXNC eUtleSkgew0KCSAgICAgIENvbnRleHRJbmZvIGNpID0gKENvbnRleHRJbmZvKSBpbnN0YW5jZXNC eUtleS5nZXQoa2V5KTsNCgkgICAgICBpZiAoY2kgIT0gbnVsbCkgew0KCSAgICAgICAgX2xvZy5k ZWJ1ZygiQ29udGV4dCB3aXRoIGtleSAnIiArIGtleSArICInIHJlcXVlc3RlZC4gUmV0dXJuaW5n DQoJZXhpc3RpbmcgaW5zdGFuY2VzIik7DQoJICAgICAgICBjaS5yZWZjb3VudCsrOw0KCSAgICAg ICAgcmV0dXJuIGNpLmNvbnRleHQ7DQoJICAgICAgfQ0KCQ0KCSAgICAgIF9sb2cuZGVidWcoIkNv bnRleHQgd2l0aCBrZXkgJyIgKyBrZXkgKyAiJyByZXF1ZXN0ZWQuIENyZWF0aW5nIG5ldw0KCWlu c3RhbmNlIik7DQoJDQoJICAgICAgLy8gdGhpcyBjb250ZXh0IGRvZXNuJ3QgZXhpc3QsIHdlIG5l ZWQgdG8gdHJ5IHRvIGxvYWQgaXQNCgkgICAgICBJbnB1dFN0cmVhbSBpcyA9IGdldENsYXNzKCku Z2V0UmVzb3VyY2VBc1N0cmVhbShrZXkpOw0KCSAgICAgIGlmIChpcyA9PSBudWxsKQ0KCSAgICAg ICAgdGhyb3cgbmV3IEFwcGxpY2F0aW9uQ29udGV4dEV4Y2VwdGlvbigiVW5hYmxlIHRvIGxvYWQN Cgljb250ZXh0KHMpLiBLZXkgZG9lcyBub3QgcG9pbnQgdG8gYSB2YWxpZCByZXNvdXJjZTogIiAr IGtleSk7DQoJDQoJICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7DQoJ ICAgICAgdHJ5IHsNCgkgICAgICAgIHByb3BzLmxvYWQoaXMpOw0KCSAgICAgICAgaXMuY2xvc2Uo KTsNCgkgICAgICB9DQoJICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsNCgkgICAgICAgIHRo cm93IG5ldyBBcHBsaWNhdGlvbkNvbnRleHRFeGNlcHRpb24oIkVycm9yIHJlYWRpbmcgYXBwbGlj YXRpb24NCgljb250ZXh0IHBvaW50ZXIgZGVmaW5pdGlvbi4iLCBlKTsNCgkgICAgICB9DQoJDQoJ ICAgICAgQXJyYXlMaXN0IGNvbnRleHRzID0gbmV3IEFycmF5TGlzdCgpOw0KCSAgICAgIGZvciAo aW50IGkgPSAwOyA7ICsraSkgew0KCSAgICAgICAgU3RyaW5nIGNvbnRleHQgPSBwcm9wcy5nZXRQ cm9wZXJ0eShJbnRlZ2VyLnRvU3RyaW5nKGkpKTsNCgkgICAgICAgIGlmIChjb250ZXh0ID09IG51 bGwpDQoJICAgICAgICAgIGJyZWFrOw0KCSAgICAgICAgY29udGV4dHMuYWRkKGNvbnRleHQpOw0K CSAgICAgIH0NCgkNCgkgICAgICBpZiAoY29udGV4dHMuc2l6ZSgpID09IDApDQoJICAgICAgICB0 aHJvdyBuZXcgQXBwbGljYXRpb25Db250ZXh0RXhjZXB0aW9uKCJObyBhcHBsaWNhdGlvbiBjb250 ZXh0DQoJZGVmaW5pdGlvbnMgc3BlY2lmaWVkIGluIGRlZmluaXRpb24gZmlsZTogIiArIGtleSk7 DQoJDQoJICAgICAgQ2xhc3NQYXRoWG1sQXBwbGljYXRpb25Db250ZXh0IGFjOw0KCSAgICAgIHRy eSB7DQoJICAgICAgICBhYyA9IG5ldw0KCUNsYXNzUGF0aFhtbEFwcGxpY2F0aW9uQ29udGV4dCgo U3RyaW5nW10pY29udGV4dHMudG9BcnJheShuZXcgU3RyaW5nWzBdKSk7DQoJICAgICAgfQ0KCSAg ICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7DQoJICAgICAgICB0aHJvdyBuZXcgQXBwbGljYXRp b25Db250ZXh0RXhjZXB0aW9uKCJFcnJvciByZWFkaW5nIGFwcGxpY2F0aW9uDQoJY29udGV4dCBk ZWZpbml0aW9uIiwgZSk7DQoJICAgICAgfQ0KCQ0KCSAgICAgIGNpID0gbmV3IENvbnRleHRJbmZv KCk7DQoJICAgICAgY2kuY29udGV4dCA9IGFjOw0KCSAgICAgIGNpLmtleSA9IGtleTsNCgkgICAg ICBjaS5yZWZjb3VudCA9IDE7DQoJICAgICAgaW5zdGFuY2VzQnlLZXkucHV0KGtleSwgY2kpOw0K CSAgICAgIGluc3RhbmNlc0J5T2JqLnB1dChhYywgY2kpOw0KCQ0KCSAgICAgIHJldHVybiBhYzsN CgkgICAgfQ0KCSAgfQ0KCQ0KCSAgLyoqDQoJICAgKiBSZWxlYXNlcyB0aGUgc3BlY2lmaWVkIEFw cGxpY2F0aW9uQ29udGV4dCBpbnN0YW5jZS4gSWYgdGhlcmUgYXJlIG5vDQoJbW9yZSB1c2VycyBv ZiB0aGlzDQoJICAgKiBjb250ZXh0LCBjbG9zZSgpIHdpbGwgYmUgY2FsbGVkIG9uIGl0LiBOb3Rl IHRoYXQgY2xvc2Ugd2lsbCBiZQ0KCWNhbGxlZCBvbiBpdHMgcGFyZW50cyBhcw0KCSAgICogd2Vs bCwgcmVjdXJzaXZlbHkuDQoJICAgKiBAc2VlDQoJY29tLnRpcmEuY29yZXNlcnYud2VidXRpbC5D b250ZXh0RmFjdG9yeSNSZWxlYXNlQ29udGV4dChvcmcuc3ByaW5nZnJhbWV3b3JrLg0KCWNvbnRl eHQuQXBwbGljYXRpb25Db250ZXh0KQ0KCSAgICovDQoJICBwdWJsaWMgdm9pZCByZWxlYXNlQ29u dGV4dChBcHBsaWNhdGlvbkNvbnRleHQgYWMpIHRocm93cw0KCUFwcGxpY2F0aW9uQ29udGV4dEV4 Y2VwdGlvbiB7DQoJDQoJICAgIHN5bmNocm9uaXplZChpbnN0YW5jZXNCeUtleSkgew0KCSAgICAg IENvbnRleHRJbmZvIGNpID0gKENvbnRleHRJbmZvKSBpbnN0YW5jZXNCeU9iai5nZXQoYWMpOw0K CSAgICAgIGlmIChjaSAhPSBudWxsKSB7DQoJICAgICAgICBjaS5yZWZjb3VudC0tOw0KCSAgICAg ICAgaWYgKGNpLnJlZmNvdW50IDwgMCkNCgkgICAgICAgICAgdGhyb3cgbmV3IEFwcGxpY2F0aW9u Q29udGV4dEV4Y2VwdGlvbigiSWxsZWdhbCBzdGF0ZTogY29udGV4dA0KCXJlbGVhc2VkIG1vcmUg dGltZXMgdGhhbiBhY3F1aXJlZCIpOw0KCQ0KCSAgICAgICAgaWYgKGNpLnJlZmNvdW50ID09IDAp IHsNCgkgICAgICAgICAgX2xvZy5kZWJ1ZygiUmVsZWFzZSByZXF1ZXN0ZWQgb24gQ29udGV4dCB3 aXRoIGtleSAnIiArIGNpLmtleQ0KCSsgIicuIExhc3QgcmVmZXJlbmNlLCBzbyBjbG9zaW5nIGFs b25nIHdpdGggcGFyZW50cyIpOw0KCSAgICAgICAgICBpbnN0YW5jZXNCeU9iai5yZW1vdmUoYWMp Ow0KCSAgICAgICAgICBpbnN0YW5jZXNCeUtleS5yZW1vdmUoY2kua2V5KTsNCgkgICAgICAgICAg QXBwbGljYXRpb25Db250ZXh0IGNoaWxkID0gY2kuY29udGV4dDsNCgkgICAgICAgICAgQXBwbGlj YXRpb25Db250ZXh0IHBhcmVudDsNCgkgICAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsN CgkgICAgICAgICAgICBwYXJlbnQgPSBjaGlsZC5nZXRQYXJlbnQoKTsNCgkgICAgICAgICAgICBj aGlsZC5jbG9zZSgpOw0KCSAgICAgICAgICAgIGNoaWxkID0gcGFyZW50Ow0KCSAgICAgICAgICB9 DQoJICAgICAgICB9DQoJICAgICAgICBlbHNlDQoJICAgICAgICAgIF9sb2cuZGVidWcoIlJlbGVh c2UgcmVxdWVzdGVkIG9uIENvbnRleHQgd2l0aCBrZXkgJyIgKyBjaS5rZXkNCgkrICInLiBSZWZl cmVuY2VzIHJlbWFpbiwgc28gbm90IGNsb3NpbmcuIik7DQoJICAgICAgfQ0KCSAgICAgIGVsc2UN CgkgICAgICAgIHRocm93IG5ldyBBcHBsaWNhdGlvbkNvbnRleHRFeGNlcHRpb24oIkF0dGVtcHRl ZCB0byByZWxlYXNlDQoJY29udGV4dCByZWZlcmVuY2UgZm9yIGNvbnRleHQgbm90IGtub3duIHRv IHRoaXMgZmFjdG9yeSIpOw0KCSAgICB9DQoJICB9DQoJDQoJICAvLyB3ZSB0cmFjayBjb250ZXh0 cyB3aXRoIHRoaXMgY2xhc3MNCgkgIHByaXZhdGUgY2xhc3MgQ29udGV4dEluZm8gew0KCSAgICBw dWJsaWMgQXBwbGljYXRpb25Db250ZXh0IGNvbnRleHQ7DQoJICAgIHB1YmxpYyBTdHJpbmcga2V5 Ow0KCSAgICBwdWJsaWMgaW50IHJlZmNvdW50ID0gMDsNCgkgIH0NCgkNCgl9DQoJDQoJU28gbXkg Q29udGV4dEZhY3RvcnkgaW1wbCBjYW4gbG9hZCB0aGUgc2VydmljZXMgYXBwbGljYXRpb24gY29u dGV4dCwgYW5kDQoJZmlyc3QgaXRzIHBhcmVudCwgdGhlIGRhdGEtYWNjZXNzIGNvbnRleHQsIG9u IGRlbWFuZCwgYW5kIHN1YnNlcXVlbnQNCglyZXF1ZXN0IHdpbGwganVzdCByZXR1cm4gYSByZWZl cmVuY2UgdG8gdGhlIHNhbWUgY29udGV4dC4gVGhlICdrZXknDQoJc3BlY2lmaWVkIHRvIHRoZSBj b250ZXh0IGZhY3RvcnkgaXMganVzdCB0aGUgbmFtZSBvZiBhIGZpbGUgc3BlY2lmeWluZw0KCXdo aWNoIGNvbnRleHRzIHRvIGxvYWQ6DQoJDQoJRmlsZSBjb3JlLXNlcnZpY2VzLWFwcGxpY2F0aW9u Q29udGV4dHMucHJvcGVydGllczoNCgkjIGRlZmluZXMgb25lIG9yIG1vcmUgaGllcmFyY2hpY2Fs IHhtbCBBcHBsaWNhdGlvbkNvbnRleHQgaW5zdGFuY2VzDQoJd2hpY2ggYXJlIGNvbnNpZGVyZWQN CgkjIHRvIG1ha2UgdXAgdGhlIGFwcGxpY2F0aW9uIGNvbnRleHQgc3RhY2sgZm9yIGNvcmUtc2Vy dmljZXMuIEVhY2ggbGluZQ0KCWlzIGEgcGFyZW50IG9mIHRoZQ0KCSMgc3Vic2VxdWVudCBsaW5l Lg0KCTA9L2RhdGEtYWNjZXNzLWFwcGxpY2F0aW9uQ29udGV4dC54bWwNCgkxPS9jb3JlLXNlcnZp Y2VzLWFwcGxpY2F0aW9uQ29udGV4dC54bWwNCgkNCglOb3cgSSBqdXN0IG5lZWQgdG8gaGF2ZSBh IG1vZGlmaWVkIHZlcnNpb24gb2YgQ29udGV4dExvYWRlciBmcm9tIFNwcmluZw0KCXdoaWNoIGFs b25nIHdpdGggbG9hZGluZyBhIHNwZWNpZmllZCBXZWJBcHBsaWNhdGlvbkNvbnRleHQgaW5zdGFu Y2UsDQoJd2lsbCBvcHRpb2luYWxseSB1c2UgdGhlIENvbnRleHRGYWN0b3J5IHRvIGxvYWQgYSBw YXJlbnQgY29udGV4dCBmaXJzdC4NCglIZXJlJ3MgdGhlIGNvZGU6DQoJDQoJLyoqDQoJICogQ2xh c3MgdXNlZCB0byBsb2FkIGEgd2ViIGFwcGxpY2F0aW9uIGNvbnRleHQsIGluY2x1ZGluZyBwb3Nz aWJseQ0KCXRyaWdnZXJpbmcgbG9hZGluZyBvZiBhIHBhcmVudA0KCSAqIGNvbnRleHQgdGhyb3Vn aCBhIENvbnRleHRGYWN0b3J5IGluc3RhbmNlDQoJICoNCgkgKiBAdmVyc2lvbiAkUmV2aXNpb246 ICAkDQoJKi8NCglwdWJsaWMgY2xhc3MgQ29udGV4dExvYWRlciB7DQoJDQoJICAvLyAtLS0gc3Rh dGljcw0KCQ0KCSAgLyoqPw0KCSAgICogQ29uZmlnIHBhcmFtIGZvciB0aGUgcm9vdCBXZWJBcHBs aWNhdGlvbkNvbnRleHQgaW1wbGVtZW50YXRpb24NCgljbGFzcyB0byB1c2UuDQoJICAgKi8NCgkg IHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENPTlRFWFRfQ0xBU1NfUEFSQU0gPSAiY29udGV4 dENsYXNzIjsNCgkNCgkgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgREVGQVVMVF9DT05URVhU X0NMQVNTID0NCglYbWxXZWJBcHBsaWNhdGlvbkNvbnRleHQuY2xhc3M7DQoJDQoJICBwdWJsaWMg c3RhdGljIGZpbmFsIFN0cmluZyBQQVJFTlRfQ09OVEVYVF9GQUNUT1JZX0NMQVNTX1BBUkFNID0N CgkicGFyZW50Q29udGV4dEZhY3RvcnlDbGFzcyI7DQoJDQoJICBwdWJsaWMgc3RhdGljIGZpbmFs IFN0cmluZyBQQVJFTlRfQ09OVEVYVF9GQUNUT1JZX1BBUkFNMV9QQVJBTSA9DQoJInBhcmVudENv bnRleHRGYWN0b3J5UGFyYW0iOw0KCQ0KCSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFS RU5UX0NPTlRFWFRfS0VZX1BBUkFNID0gInBhcmVudENvbnRleHRLZXkiOw0KCQ0KCSAgcHVibGlj IHN0YXRpYyBmaW5hbCBMb2dnZXIgX2xvZyA9IExvZ2dlci5nZXRMb2dnZXIoQ29udGV4dExvYWRl ci5jbGFzcyk7DQoJDQoJICAvKioNCgkgICAqIEluaXRpYWxpemUgU3ByaW5nJ3Mgd2ViIGFwcGxp Y2F0aW9uIGNvbnRleHQgZm9yIHRoZSBnaXZlbiBzZXJ2bGV0DQoJY29udGV4dCwNCgkgICAqIHJl Z2FyZGluZyB0aGUgImNvbnRleHRDbGFzcyIgc2VydmxldCBjb250ZXh0IGluaXQgcGFyYW1ldGVy Lg0KCSAgICogQHBhcmFtIHNlcnZsZXRDb250ZXh0IGN1cnJlbnQgc2VydmxldCBjb250ZXh0DQoJ ICAgKiBAcmV0dXJuIHRoZSBuZXcgV2ViQXBwbGljYXRpb25Db250ZXh0DQoJICAgKi8NCgkgIHB1 YmxpYyBzdGF0aWMgV2ViQXBwbGljYXRpb25Db250ZXh0IGluaXRDb250ZXh0KFNlcnZsZXRDb250 ZXh0DQoJc2VydmxldENvbnRleHQpDQoJICAgIHRocm93cyBBcHBsaWNhdGlvbkNvbnRleHRFeGNl cHRpb24gew0KCQ0KCSAgICBzZXJ2bGV0Q29udGV4dC5sb2coIkxvYWRpbmcgcm9vdCBXZWJBcHBs aWNhdGlvbkNvbnRleHQiKTsNCgkgICAgU3RyaW5nIGNvbnRleHRDbGFzcyA9DQoJc2VydmxldENv bnRleHQuZ2V0SW5pdFBhcmFtZXRlcihDT05URVhUX0NMQVNTX1BBUkFNKTsNCgkNCgkgICAgU3Ry aW5nIGNsYXNzTmFtZSA9IG51bGw7DQoJICAgIHRyeSB7DQoJICAgICAgY2xhc3NOYW1lID0NCglz ZXJ2bGV0Q29udGV4dC5nZXRJbml0UGFyYW1ldGVyKFBBUkVOVF9DT05URVhUX0ZBQ1RPUllfQ0xB U1NfUEFSQU0pOw0KCSAgICAgIENvbnRleHRGYWN0b3J5IHBhcmVudENvbnRleHRGYWN0b3J5ID0N CglnZXRQYXJlbnRDb250ZXh0RmFjdG9yeShzZXJ2bGV0Q29udGV4dCk7DQoJDQoJICAgICAgQXBw bGljYXRpb25Db250ZXh0IHBhcmVudENvbnRleHQgPSBudWxsOw0KCSAgICAgIGlmIChwYXJlbnRD b250ZXh0RmFjdG9yeSAhPSBudWxsKSB7DQoJICAgICAgICBTdHJpbmcgcGFyZW50Q29udGV4dEtl eSA9DQoJc2VydmxldENvbnRleHQuZ2V0SW5pdFBhcmFtZXRlcihQQVJFTlRfQ09OVEVYVF9LRVlf UEFSQU0pOw0KCSAgICAgICAgX2xvZy5pbmZvKA0KCSAgICAgICAgICAiR2V0dGluZyBwYXJlbnQg Y29udGV4dDogdXNpbmcgY29udGV4dCBmYWN0b3J5IGNsYXNzICciICsNCgljbGFzc05hbWUgKyAi Jywga2V5ICciICsNCgkgICAgICAgICAgICAgICAgICBwYXJlbnRDb250ZXh0S2V5ICsgIiciKTsN CgkgICAgICAgIHBhcmVudENvbnRleHQgPSBwYXJlbnRDb250ZXh0RmFjdG9yeS51c2VDb250ZXh0 KHBhcmVudENvbnRleHRLZXkpOw0KCSAgICAgIH0NCgkNCgkgICAgICAvLyBOb3cgd2UgbXVzdCBs b2FkIHRoZSBXZWJBcHBsaWNhdGlvbkNvbnRleHQuDQoJICAgICAgLy8gSXQgY29uZmlndXJlcyBp dHNlbGY6IGFsbCB3ZSBuZWVkIHRvIGRvIGlzIGNvbnN0cnVjdCB0aGUgY2xhc3MNCgl3aXRoIHRo ZSBwcm9wZXINCgkgICAgICAvLyBjb25zdHJ1Y3RvciwgYW5kIGludm9rZSBzZXRTZXJ2bGV0Q29u dGV4dC4NCgkgICAgICBDbGFzcyBjbGF6eiA9IChjb250ZXh0Q2xhc3MgIT0gbnVsbCA/IENsYXNz LmZvck5hbWUoY29udGV4dENsYXNzKQ0KCTogREVGQVVMVF9DT05URVhUX0NMQVNTKTsNCgkgICAg ICBfbG9nLmluZm8oDQoJICAgICAgICAiTG9hZGluZyByb290IFdlYkFwcGxpY2F0aW9uQ29udGV4 dDogdXNpbmcgY29udGV4dCBjbGFzcyAnIiArDQoJY2xhenouZ2V0TmFtZSgpICsgIiciKTsNCgkg ICAgICBpZiAoIVdlYkFwcGxpY2F0aW9uQ29udGV4dC5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGNs YXp6KSkgew0KCSAgICAgICAgdGhyb3cgbmV3IEFwcGxpY2F0aW9uQ29udGV4dEV4Y2VwdGlvbigN CgkgICAgICAgICAgIkNvbnRleHQgY2xhc3MgaXMgbm8gV2ViQXBwbGljYXRpb25Db250ZXh0OiAi ICsgY29udGV4dENsYXNzKTsNCgkgICAgICB9DQoJDQoJICAgICAgQ2xhc3NbXSBwYXJhbWV0ZXJU eXBlczsNCgkgICAgICBPYmplY3RbXSBwYXJhbXM7DQoJICAgICAgaWYgKHBhcmVudENvbnRleHQg PT0gbnVsbCkgew0KCSAgICAgICAgcGFyYW1ldGVyVHlwZXMgPSBuZXcgQ2xhc3NbMF07DQoJICAg ICAgICBwYXJhbXMgPSBuZXcgT2JqZWN0WzBdOw0KCSAgICAgIH0NCgkgICAgICBlbHNlIHsNCgkg ICAgICAgIHBhcmFtZXRlclR5cGVzID0gbmV3IENsYXNzW10ge0FwcGxpY2F0aW9uQ29udGV4dC5j bGFzcywNCglTdHJpbmcuY2xhc3N9Ow0KCSAgICAgICAgcGFyYW1zID0gbmV3IE9iamVjdFtdIHtw YXJlbnRDb250ZXh0LCBudWxsfTsNCgkgICAgICB9DQoJDQoJICAgICAgQ29uc3RydWN0b3IgY29u c3RydWN0b3IgPSBjbGF6ei5nZXRDb25zdHJ1Y3RvcihwYXJhbWV0ZXJUeXBlcyk7DQoJICAgICAg V2ViQXBwbGljYXRpb25Db250ZXh0IHdlYkFwcGxpY2F0aW9uQ29udGV4dCA9DQoJKFdlYkFwcGxp Y2F0aW9uQ29udGV4dCkgY29uc3RydWN0b3IubmV3SW5zdGFuY2UocGFyYW1zKTsNCgkgICAgICB3 ZWJBcHBsaWNhdGlvbkNvbnRleHQuc2V0U2VydmxldENvbnRleHQoc2VydmxldENvbnRleHQpOw0K CSAgICAgIHJldHVybiB3ZWJBcHBsaWNhdGlvbkNvbnRleHQ7DQoJICAgIH0NCgkgICAgY2F0Y2gg KEFwcGxpY2F0aW9uQ29udGV4dEV4Y2VwdGlvbiBleCkgew0KCSAgICAgIGhhbmRsZUV4Y2VwdGlv bigiRmFpbGVkIHRvIGluaXRpYWxpemUgYXBwbGljYXRpb24gY29udGV4dCIsIGV4KTsNCgkgICAg fQ0KCSAgICBjYXRjaCAoQmVhbnNFeGNlcHRpb24gZXgpIHsNCgkgICAgICBoYW5kbGVFeGNlcHRp b24oIkZhaWxlZCB0byBpbml0aWFsaXplIGJlYW5zIGluIGFwcGxpY2F0aW9uDQoJY29udGV4dCIs IGV4KTsNCgkgICAgfQ0KCSAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBleCkgew0K CSAgICAgIGhhbmRsZUV4Y2VwdGlvbigiRmFpbGVkIHRvIGxvYWQgY29uZmlnIGNsYXNzICciICsg Y2xhc3NOYW1lICsgIiciLA0KCWV4KTsNCgkgICAgfQ0KCSAgICBjYXRjaCAoSW5zdGFudGlhdGlv bkV4Y2VwdGlvbiBleCkgew0KCSAgICAgIGhhbmRsZUV4Y2VwdGlvbigNCgkgICAgICAgICJGYWls ZWQgdG8gaW5zdGFudGlhdGUgY29uZmlnIGNsYXNzICciDQoJICAgICAgICAgICsgY2xhc3NOYW1l DQoJICAgICAgICAgICsgIic6IGRvZXMgaXQgaGF2ZSB0aGUgcHJvcGVyIGNvbnN0cnVjdG9yPyIs DQoJICAgICAgICBleCk7DQoJICAgIH0NCgkgICAgY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRp b24gZXgpIHsNCgkgICAgICBoYW5kbGVFeGNlcHRpb24oDQoJICAgICAgICAiSWxsZWdhbCBhY2Nl c3Mgd2hpbGUgZmluZGluZyBvciBpbnN0YW50aWF0aW5nIGNvbmZpZyBjbGFzcyAnIg0KCSAgICAg ICAgICArIGNsYXNzTmFtZQ0KCSAgICAgICAgICArICInOiBkb2VzIGl0IGhhdmUgdGhlIHByb3Bl ciBjb25zdHJ1Y3Rvcj8iLA0KCSAgICAgICAgZXgpOw0KCSAgICB9DQoJICAgIGNhdGNoIChUaHJv d2FibGUgZXgpIHsNCgkgICAgICBoYW5kbGVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXJyb3IgbG9h ZGluZyBjb250ZXh0IGNvbmZpZ3VyYXRpb24iLCBleCk7DQoJICAgIH0NCgkNCgkgICAgcmV0dXJu IG51bGw7DQoJICB9DQoJDQoJICAvKioNCgkgICAqIExvZyBhbmQgdGhyb3cgYW4gYXBwcm9wcmlh dGUgZXhjZXB0aW9uLg0KCSAgICovDQoJICBwcml2YXRlIHN0YXRpYyB2b2lkIGhhbmRsZUV4Y2Vw dGlvbihTdHJpbmcgbXNnLCBUaHJvd2FibGUgZXgpDQoJICAgIHRocm93cyBBcHBsaWNhdGlvbkNv bnRleHRFeGNlcHRpb24gew0KCSAgICBTdHJpbmcgdGhyb3duTXNnID0gbXNnICsgIjogIiArIGV4 LmdldE1lc3NhZ2UoKTsNCgkgICAgX2xvZy5lcnJvcih0aHJvd25Nc2csIGV4KTsNCgkgICAgaWYg KGV4IGluc3RhbmNlb2YgRXJyb3IpIHsNCgkgICAgICB0aHJvdyAoRXJyb3IpIGV4Ow0KCSAgICB9 DQoJICAgIGVsc2UgaWYgKGV4IGluc3RhbmNlb2YgQXBwbGljYXRpb25Db250ZXh0RXhjZXB0aW9u KSB7DQoJICAgICAgdGhyb3cgKEFwcGxpY2F0aW9uQ29udGV4dEV4Y2VwdGlvbikgZXg7DQoJICAg IH0NCgkgICAgZWxzZSB7DQoJICAgICAgdGhyb3cgbmV3IEFwcGxpY2F0aW9uQ29udGV4dEV4Y2Vw dGlvbih0aHJvd25Nc2csIGV4KTsNCgkgICAgfQ0KCSAgfQ0KCQ0KCSAgLyoqDQoJICAgKiBDbG9z ZSBTcHJpbmcncyB3ZWIgYXBwbGljYXRpb24gY29udGV4dCBmb3IgdGhlIGdpdmVuIHNlcnZsZXQg Y29udGV4dC4NCgkgICAqIEBwYXJhbSBzZXJ2bGV0Q29udGV4dCBjdXJyZW50IHNlcnZsZXQgY29u dGV4dA0KCSAgICovDQoJICBwdWJsaWMgc3RhdGljIHZvaWQgY2xvc2VDb250ZXh0KFNlcnZsZXRD b250ZXh0IHNlcnZsZXRDb250ZXh0KSB7DQoJICAgIHNlcnZsZXRDb250ZXh0LmxvZygiQ2xvc2lu ZyByb290IFdlYkFwcGxpY2F0aW9uQ29udGV4dCIpOw0KCSAgICBBcHBsaWNhdGlvbkNvbnRleHQg YWMgPQ0KCVdlYkFwcGxpY2F0aW9uQ29udGV4dFV0aWxzLmdldFdlYkFwcGxpY2F0aW9uQ29udGV4 dChzZXJ2bGV0Q29udGV4dCk7DQoJICAgIEFwcGxpY2F0aW9uQ29udGV4dCBwYXJlbnQgPSBhYy5n ZXRQYXJlbnQoKTsNCgkgICAgdHJ5IHsNCgkgICAgICBhYy5jbG9zZSgpOw0KCSAgICB9DQoJICAg IGZpbmFsbHkgew0KCSAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgew0KCSAgICAgICAgQ29udGV4 dEZhY3RvcnkgY2YgPSBudWxsOw0KCSAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9DQoJc2Vydmxl dENvbnRleHQuZ2V0SW5pdFBhcmFtZXRlcihQQVJFTlRfQ09OVEVYVF9GQUNUT1JZX0NMQVNTX1BB UkFNKTsNCgkgICAgICAgIC8vIHNob3VsZCB3ZSBjaGVjayB0aGlzIGZvciBudWxsLiBmb3Igbm93 LCBsZXQncyBub3QsIGFzIGl0IGhhcw0KCXRvIGJlIHRoZXJlIGlmIHRoZXJlIGlzIGEgcGFyZW50 DQoJICAgICAgICB0cnkgew0KCSAgICAgICAgICBjZiA9IGdldFBhcmVudENvbnRleHRGYWN0b3J5 KHNlcnZsZXRDb250ZXh0KTsNCgkgICAgICAgIH0NCgkgICAgICAgIGNhdGNoIChFeGNlcHRpb24g ZXgpIHsNCgkgICAgICAgICAgaGFuZGxlRXhjZXB0aW9uKCJVbmFibGUgdG8gb2J0YWluIGNvbnRl eHQgZmFjdG9yeSB0byByZWxlYXNlDQoJcGFyZW50IGNvbnRleHQuIENvbnRleHQgZmFjdG9yeSBj bGFzc05hbWUgJyIgKyBjbGFzc05hbWUgKyAiJyIsIGV4KTsNCgkgICAgICAgIH0NCgkgICAgICAg IGNmLnJlbGVhc2VDb250ZXh0KHBhcmVudCk7DQoJICAgICAgfQ0KCSAgICB9DQoJICB9DQoJDQoJ ICAvKioNCgkgICAqIFJldHVybnMgYSBDb250ZXh0RmFjdG9yeSwgaWYgYW55LCB0byBiZSB1c2Vk IHRvIG9idGFpbiBhbmQgcmVsZWFzZQ0KCWEgcGFyZW50IGNvbnRleHQNCgkgICAqLw0KCSAgcHJp dmF0ZSBzdGF0aWMgQ29udGV4dEZhY3RvcnkgZ2V0UGFyZW50Q29udGV4dEZhY3RvcnkoU2Vydmxl dENvbnRleHQNCglzZXJ2bGV0Q29udGV4dCkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24s IFNlY3VyaXR5RXhjZXB0aW9uLA0KCU5vU3VjaE1ldGhvZEV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3Vt ZW50RXhjZXB0aW9uLCBJbnN0YW50aWF0aW9uRXhjZXB0aW9uLA0KCUlsbGVnYWxBY2Nlc3NFeGNl cHRpb24sIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gew0KCQ0KCSAgICBTdHJpbmcgcGFyZW50 Q29udGV4dEZhY3RvcnlDbGFzc05hbWUgPQ0KCXNlcnZsZXRDb250ZXh0LmdldEluaXRQYXJhbWV0 ZXIoUEFSRU5UX0NPTlRFWFRfRkFDVE9SWV9DTEFTU19QQVJBTSk7DQoJICAgIFN0cmluZyBwYXJl bnRDb250ZXh0RmFjdG9yeVBhcmFtMSA9DQoJc2VydmxldENvbnRleHQuZ2V0SW5pdFBhcmFtZXRl cihQQVJFTlRfQ09OVEVYVF9GQUNUT1JZX1BBUkFNMV9QQVJBTSk7DQoJDQoJICAgIFN0cmluZyBj bGFzc05hbWUgPSBudWxsOw0KCSAgICBDbGFzc1tdIHBhcmFtZXRlclR5cGVzOw0KCSAgICBPYmpl Y3RbXSBwYXJhbXM7DQoJDQoJICAgIENvbnRleHRGYWN0b3J5IHBhcmVudENvbnRleHRGYWN0b3J5 ID0gbnVsbDsNCgkgICAgaWYgKHBhcmVudENvbnRleHRGYWN0b3J5Q2xhc3NOYW1lICE9IG51bGwp IHsNCgkgICAgICBjbGFzc05hbWUgPSBwYXJlbnRDb250ZXh0RmFjdG9yeUNsYXNzTmFtZTsNCgkg ICAgICBDbGFzcyBjbGF6eiA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsNCgkgICAgICBwYXJh bWV0ZXJUeXBlcyA9IG5ldyBDbGFzc1swXTsNCgkgICAgICBwYXJhbXMgPSBuZXcgT2JqZWN0WzBd Ow0KCSAgICAgIGlmIChwYXJlbnRDb250ZXh0RmFjdG9yeVBhcmFtMSAhPSBudWxsKSB7DQoJICAg ICAgICBwYXJhbWV0ZXJUeXBlcyA9IG5ldyBDbGFzc1tdIHtTdHJpbmcuY2xhc3N9Ow0KCSAgICAg ICAgcGFyYW1zID0gbmV3IE9iamVjdFtdIHtwYXJlbnRDb250ZXh0RmFjdG9yeVBhcmFtMX07DQoJ ICAgICAgfQ0KCSAgICAgIENvbnN0cnVjdG9yIGNvbnN0cnVjdG9yID0gY2xhenouZ2V0Q29uc3Ry dWN0b3IocGFyYW1ldGVyVHlwZXMpOw0KCSAgICAgIHBhcmVudENvbnRleHRGYWN0b3J5ID0gKENv bnRleHRGYWN0b3J5KQ0KCWNvbnN0cnVjdG9yLm5ld0luc3RhbmNlKHBhcmFtcyk7DQoJICAgIH0N CgkNCgkgICAgcmV0dXJuIHBhcmVudENvbnRleHRGYWN0b3J5Ow0KCSAgfQ0KCX0NCgkNCgkNCglT byB0aGlzIG1lY2hhbmlzbSB3b3JrcyBmaW5lLiBJdCBhbGxvd3MgbWUgdG8gbGF5ZXIgYXBwbGlj YXRpb24gY29udGV4dHMNCglhbGwgdGhlIHdheSBkb3duIHRoZSBsYXllciBzdGFjaywgbm90IGp1 c3QgaW4gdGhlIHdlYi11aSBsYXllci4gQ2FuDQoJYW55Ym9keSB0aGluayBvZiBhIGJldHRlciBv ciBzaW1wbGVyIHdheSB0byBoYW5kbGUgdGhpcyBuZWVkPw0KCQ0KCUlzIGl0IHdvcnRoIGFkZGlu ZyBzb21lIG9mIHRoaXMgY29kZSBpbnRvIFNwcmluZyBpdHNlbGY/IEkgZG9uJ3QgdGhpbmsNCglJ J20gdGhlIG9ubHkgcGVyc29uIHdobyB3aWxsIG5lZWQgdG8gZG8gc29tZXRoaW5nIGxpa2UgdGhp cy4gQWRtaXR0ZWRseSwNCglpbiB0aGUgYWJzZW5jZSBvZiB0aGUgbGFyZ2Ugc3RhcnQtdXAgdGlt ZSBmb3IgSGliZXJuYXRlLCBpdCB3b3VsZCBoYXZlDQoJYmVlbiBhY2NlcHRpYmxlIHRvIGhhbmRs ZSB0aGlzIHZpYSBqdXN0IHRocmVlIGFwcGxpY2F0aW9uIGNvbnRleHRzIGF0DQoJdGhlIHdlYiBs ZXZlbCwgd2l0aCBkdXBsaWNhdGUgZGVmaW5pdGlvbnMgZm9yIHRoZSBjb250ZW50IGZyb20gdGhl DQoJZGF0YS1hY2Nlc3MgYW5kIHNlcnZpY2VzIGxheWVyIGJyb3VnaHQgaW4gdmlhIHhtbCBpbmNs dWRlcy4NCgkNCglSZWdhcmRzLA0KCUNvbGluDQoJDQoJDQoJDQoJDQoJLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KCVRoaXMgc2YubmV0IGVt YWlsIGlzIHNwb25zb3JlZCBieTpUaGlua0dlZWsNCglXZWxjb21lIHRvIGdlZWsgaGVhdmVuLg0K CWh0dHA6Ly90aGlua2dlZWsuY29tL3NmDQoJX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX18NCglTcHJpbmdmcmFtZXdvcmstdXNlciBtYWlsaW5nIGxpc3QNCglT cHJpbmdmcmFtZXdvcmstdXNlckBsaXN0cy5zb3VyY2Vmb3JnZS5uZXQNCglodHRwczovL2xpc3Rz LnNvdXJjZWZvcmdlLm5ldC9saXN0cy9saXN0aW5mby9zcHJpbmdmcmFtZXdvcmstdXNlcg0KCQ0K CQ0KCS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0NCglUaGlzIFNGLm5ldCBlbWFpbCBpcyBzcG9uc29yZWQgYnk6IFNGLm5ldCBHaXZlYmFjayBQ cm9ncmFtLg0KCVNvdXJjZUZvcmdlLm5ldCBob3N0cyBvdmVyIDcwLDAwMCBPcGVuIFNvdXJjZSBQ cm9qZWN0cy4NCglTZWUgdGhlIHBlb3BsZSB3aG8gaGF2ZSBIRUxQRUQgVVMgcHJvdmlkZSBiZXR0 ZXIgc2VydmljZXM6DQoJQ2xpY2sgaGVyZTogaHR0cDovL3NvdXJjZWZvcmdlLm5ldC9zdXBwb3J0 ZXJzLnBocA0KCV9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f DQoJU3ByaW5nZnJhbWV3b3JrLWRldmVsb3BlciBtYWlsaW5nIGxpc3QNCglTcHJpbmdmcmFtZXdv cmstZGV2ZWxvcGVyQGxpc3RzLnNvdXJjZWZvcmdlLm5ldA0KCWh0dHBzOi8vbGlzdHMuc291cmNl Zm9yZ2UubmV0L2xpc3RzL2xpc3RpbmZvL3NwcmluZ2ZyYW1ld29yay1kZXZlbG9wZXINCgkNCgkN CgkNCgkNCgktLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tDQoJVGhpcyBTRi5uZXQgZW1haWwgaXMgc3BvbnNvcmVkIGJ5OiBTRi5uZXQgR2l2ZWJh Y2sgUHJvZ3JhbS4NCglTb3VyY2VGb3JnZS5uZXQgaG9zdHMgb3ZlciA3MCwwMDAgT3BlbiBTb3Vy Y2UgUHJvamVjdHMuDQoJU2VlIHRoZSBwZW9wbGUgd2hvIGhhdmUgSEVMUEVEIFVTIHByb3ZpZGUg YmV0dGVyIHNlcnZpY2VzOg0KCUNsaWNrIGhlcmU6IGh0dHA6Ly9zb3VyY2Vmb3JnZS5uZXQvc3Vw cG9ydGVycy5waHANCglfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fXw0KCVNwcmluZ2ZyYW1ld29yay1kZXZlbG9wZXIgbWFpbGluZyBsaXN0DQoJU3ByaW5nZnJh bWV3b3JrLWRldmVsb3BlckBsaXN0cy5zb3VyY2Vmb3JnZS5uZXQNCglodHRwczovL2xpc3RzLnNv dXJjZWZvcmdlLm5ldC9saXN0cy9saXN0aW5mby9zcHJpbmdmcmFtZXdvcmstZGV2ZWxvcGVyDQoJ DQoNCg== |
|
From: Rod J. <rod...@in...> - 2003-10-10 15:32:30
|
I think this is very useful.
It would be good to have this available for the XmlBeanFactory as well.
Often, especially for integration testing, I tend to use a BeanFactory
unless my code has specific dependencies on an application context for
sourcing messages etc.
Regards,
Rod
----- Original Message -----
From: "jürgen höller [werk3AT]" <jue...@we...>
To: <spr...@li...>
Sent: Friday, October 10, 2003 3:30 PM
Subject: [Springframework-developer] new bean factory and application
context features
Everybody,
Related to the discussion about hierarchical loading, I've just committed
support for assembling an application context from more than one XML file,
just available via XmlWebApplicationContext for the moment. It allows to
specify config locations with multiple paths in it, like in the web case:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/applicationContext1.xml
WEB-INF/applicationContext2.xml
</param-value>
</context-param>
Any number of the characters ";, " between paths are ignored, to allow for
lenient parsing. The result is a *single* root web application context that
has been loaded from multiple XML files, each conforming to the spring-beans
DTD. Bean references between the individual files need to be <ref
external="..."> instead of <ref bean="..."> that references XML entities in
the same file.
This allows to split a large definition of a middle tier application context
into multiple XML files, either separating by system modules or by sub
layers. Obviously this doesn't address the EJB/multiple web app case, but it
should be well suited for typical large web applications.
BTW, I've also added support for multiple resource bundle basenames in
ResourceBundleMessageSource, via the "basenames" property (in addition to
the existing "basename" one). Those resource bundles get checked
sequentially within a *single* MessageSource, allowing to split large
message bundles into multiple files.
Furthermore, I've revised the notation of name aliases like <bean ...
name="myalias1,myalias2"> to match the rules above: Any number of the
characters ";, " between bean names are ignored. This particularly allows
BeanNameUrlHandlerMapping to interpret multiple aliases as multiple mappings
without custom parsing, no matter if separated by a comma or space (the
latter looks cleaner with URLs).
The drawback of the latter is that XML bean aliases are not allowed to
contains spaces or commas anymore -- for the benefit of being able to
specify multiple aliases. Does anyone object to that tradeoff?
-----
I've also added a new post processor type: BeanPostProcessor, in addition to
the existing BeanFactoryPostProcessor. Note that the former is in the
beans.factory.support package, with AbstractBeanFactory offering support for
it -- while the latter is in context.config, as it allows application
contexts to override property values *after* their bean factory (a
ListableBeanFactoryImpl, to be exact) has loaded.
A BeanFactoryPostProcessor gets invoked once per bean factory loading;
BeanPostProcessor once per bean creation. Both types of post processor can
be defined as normal beans in an application context, getting automatically
detected at startup, and applied before the rest of the beans gets created.
With a plain bean factory, only BeanPostProcessor is applicable, but not
defined as a normal bean but rather set via AbstractBeanFactory's
setBeanPostProcessors method.
I've applied the principle that bean factories are not supposed to
understand special beans in the bean definitions that influence the behavior
of the factory itself -- just application contexts are, like with the
message source, options beans, and post processors. Bean factories can be
customized through their implementation class, though - e.g.
setEntityResolver, setValidating, and setBeanPostProcessors on
XmlBeanFactory.
A special implementation of BeanPostProcessor is applied under the hood by
AbstractApplicationContext: ApplicationContextAwareProcessor is implictly
registered with the underlying bean factory to automatically pass the
application context to ApplicationContextAware beans. This allowed me to get
rid of the rather ugly manual check for ApplicationContextAware with a cache
of already managed instances to avoid double setting of the application
context -- the current solution is much cleaner.
Note that a custom BeanPostProcessor definition in an application context
can not only be used to check for marker interfaces but also to wrap certain
bean instances with proxies, as it can return a different bean instance than
the one that came in. Look at the respective test case in
StaticApplicationContextTestSuite that implicitly wraps each bean instance
with a CGLIB proxy.
Now imagine a BeanPostProcessor implementation that checks for certain
attributes in the bean class file and applies respective interceptors --
like transaction attributes that trigger a CGLIB proxy and an implicit
TransactionInterceptor! I consider this as the perfect hook for such
implicit wrapping at bean creation time.
Juergen
-----Original Message-----
From: Colin Sampaleanu [mailto:col...@ex...]
Sent: Thursday, September 18, 2003 5:15 PM
To: spr...@li...
Subject: [Springframework-user] Hierarchical loading of Application
Contexts
I wanted to spur some discussion of best practices for hierachical
loading of ApplicationContexts. ApplicationContext implementations can
of course be created with a parent context specified. Currently, there
is some code support for actually managing this loading in the web ui
layer (where it's easy to have a setup with a root
WebApplicationContext, and multiple child contexts, per servlet.
Most Spring usage examples assume (unless I'm missing something) that
the root WebApplicationContext will contain the entire layer stack, that
is, data-access beans and service layer beans will be defined in there.
This does work great when there there is only one web-app.
Now in my case, I need something a little bit different. I have a J2EE
application as an EAR file, which contains 3 web-apps (as WARs) at the
top layer. Among other layers, below the web ui layer there is a
services layer, and a data-access layer. Now I could get by with three
different, parallel, application contexts defined, one for each of the
web-apps, where all the bean definitions for the data-access and
services layer was duplicated in each application context. I do not want
to do this however, since I am using Hibernate, and do not want to force
the Hibernate meta-data to be read in 3 times (it's a slow process). I
much prefer to have a hierachical setup for the whole j2ee app, where I
have an application context definition for the data-access layer, which
needs to be the parent of an application context definition for the
services layer, which needs to be the parent of three separate web
application context definitions, one in each web-app.
I have been able to achieve this as follows (and want to get feedback if
somebody can think of a better way): I have an application context
defintion for my data access layer
data-access-applicationContext.xml
I have an application context definition for my services layer, which is
a child of the data-access context, and refers to beans in it.:
core-servies-applicationContext.xml
I then have the three application contexts for the web apps, which are
children of the services context, and refer to beans within it.
Now what I do, is (in a somewhat lazy fashion) trigger loading (once) of
the services and data-access contexts, when I load the first web
application context. The 2nd and 3rd web application context end up
using the previously loaded service context instance. I have an
interface, ContextFactory, as follows:
/**
* Defines interface for an ApplicationContext factory.
*
* @version $Revision: 1.40 $
* @author colin
*/
public interface ContextFactory {
/**
* Use the ApplicationContext specified by the key parameter. The
context is possibly
* loaded/created as needed.
*
* @param key a value specifying which context to use
* @return the ApplicationContext instance
* @throws ApplicationContextException if there is an error loading
one or more contexts
*/
ApplicationContext useContext(String key) throws
ApplicationContextException;
/**
* Indicate that the specified ApplicationContext instance is not
needed by a user of it,
* who has previsouly obtained it via {@link useContext}. It is an
error for releaseContext
* to be called a greater number of times than useContext. Calling
this release method may
* cause close() to be called on the specified context, if this is the
last user of it.
*
* @param ac the ApplicationContext instance
* @throws ApplicationContextException
*/
void releaseContext(ApplicationContext ac) throws
ApplicationContextException;
}
Now I have an actual implementation, which can be used to get access to
a reference counted context, triggering loading as needed, and loading
parents of that context, if needed:
/**
* Implementation of ContextFactory.<br />
* In this implementation, the key is actually the name of a properties
file accessed as
* a resource, each line of which specifies an ApplicationContext to
load. Each line in
* the file is the parent of the subsequent line. The last context is
the one returned.
*
* @version $Revision: $
* @author colin
*/
public class ContextFactoryImpl implements ContextFactory {
// --- statics
public static final Logger _log =
Logger.getLogger(ContextFactoryImpl.class);
// we map ContextInfo objects by String keys, and by Contexts
private static HashMap instancesByKey = new HashMap();
private static HashMap instancesByObj = new HashMap();
// --- methods
/* (non-Javadoc)
* @see
com.tira.coreserv.webutil.ContextFactory#useContext(java.lang.String)
*/
public ApplicationContext useContext(String key) throws
ApplicationContextException {
synchronized(instancesByKey) {
ContextInfo ci = (ContextInfo) instancesByKey.get(key);
if (ci != null) {
_log.debug("Context with key '" + key + "' requested. Returning
existing instances");
ci.refcount++;
return ci.context;
}
_log.debug("Context with key '" + key + "' requested. Creating new
instance");
// this context doesn't exist, we need to try to load it
InputStream is = getClass().getResourceAsStream(key);
if (is == null)
throw new ApplicationContextException("Unable to load
context(s). Key does not point to a valid resource: " + key);
Properties props = new Properties();
try {
props.load(is);
is.close();
}
catch (IOException e) {
throw new ApplicationContextException("Error reading application
context pointer definition.", e);
}
ArrayList contexts = new ArrayList();
for (int i = 0; ; ++i) {
String context = props.getProperty(Integer.toString(i));
if (context == null)
break;
contexts.add(context);
}
if (contexts.size() == 0)
throw new ApplicationContextException("No application context
definitions specified in definition file: " + key);
ClassPathXmlApplicationContext ac;
try {
ac = new
ClassPathXmlApplicationContext((String[])contexts.toArray(new String[0]));
}
catch (IOException e) {
throw new ApplicationContextException("Error reading application
context definition", e);
}
ci = new ContextInfo();
ci.context = ac;
ci.key = key;
ci.refcount = 1;
instancesByKey.put(key, ci);
instancesByObj.put(ac, ci);
return ac;
}
}
/**
* Releases the specified ApplicationContext instance. If there are no
more users of this
* context, close() will be called on it. Note that close will be
called on its parents as
* well, recursively.
* @see
com.tira.coreserv.webutil.ContextFactory#ReleaseContext(org.springframework.
context.ApplicationContext)
*/
public void releaseContext(ApplicationContext ac) throws
ApplicationContextException {
synchronized(instancesByKey) {
ContextInfo ci = (ContextInfo) instancesByObj.get(ac);
if (ci != null) {
ci.refcount--;
if (ci.refcount < 0)
throw new ApplicationContextException("Illegal state: context
released more times than acquired");
if (ci.refcount == 0) {
_log.debug("Release requested on Context with key '" + ci.key
+ "'. Last reference, so closing along with parents");
instancesByObj.remove(ac);
instancesByKey.remove(ci.key);
ApplicationContext child = ci.context;
ApplicationContext parent;
while (child != null) {
parent = child.getParent();
child.close();
child = parent;
}
}
else
_log.debug("Release requested on Context with key '" + ci.key
+ "'. References remain, so not closing.");
}
else
throw new ApplicationContextException("Attempted to release
context reference for context not known to this factory");
}
}
// we track contexts with this class
private class ContextInfo {
public ApplicationContext context;
public String key;
public int refcount = 0;
}
}
So my ContextFactory impl can load the services application context, and
first its parent, the data-access context, on demand, and subsequent
request will just return a reference to the same context. The 'key'
specified to the context factory is just the name of a file specifying
which contexts to load:
File core-services-applicationContexts.properties:
# defines one or more hierarchical xml ApplicationContext instances
which are considered
# to make up the application context stack for core-services. Each line
is a parent of the
# subsequent line.
0=/data-access-applicationContext.xml
1=/core-services-applicationContext.xml
Now I just need to have a modified version of ContextLoader from Spring
which along with loading a specified WebApplicationContext instance,
will optioinally use the ContextFactory to load a parent context first.
Here's the code:
/**
* Class used to load a web application context, including possibly
triggering loading of a parent
* context through a ContextFactory instance
*
* @version $Revision: $
*/
public class ContextLoader {
// --- statics
/**?
* Config param for the root WebApplicationContext implementation
class to use.
*/
public static final String CONTEXT_CLASS_PARAM = "contextClass";
public static final Class DEFAULT_CONTEXT_CLASS =
XmlWebApplicationContext.class;
public static final String PARENT_CONTEXT_FACTORY_CLASS_PARAM =
"parentContextFactoryClass";
public static final String PARENT_CONTEXT_FACTORY_PARAM1_PARAM =
"parentContextFactoryParam";
public static final String PARENT_CONTEXT_KEY_PARAM = "parentContextKey";
public static final Logger _log = Logger.getLogger(ContextLoader.class);
/**
* Initialize Spring's web application context for the given servlet
context,
* regarding the "contextClass" servlet context init parameter.
* @param servletContext current servlet context
* @return the new WebApplicationContext
*/
public static WebApplicationContext initContext(ServletContext
servletContext)
throws ApplicationContextException {
servletContext.log("Loading root WebApplicationContext");
String contextClass =
servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
String className = null;
try {
className =
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
ContextFactory parentContextFactory =
getParentContextFactory(servletContext);
ApplicationContext parentContext = null;
if (parentContextFactory != null) {
String parentContextKey =
servletContext.getInitParameter(PARENT_CONTEXT_KEY_PARAM);
_log.info(
"Getting parent context: using context factory class '" +
className + "', key '" +
parentContextKey + "'");
parentContext = parentContextFactory.useContext(parentContextKey);
}
// Now we must load the WebApplicationContext.
// It configures itself: all we need to do is construct the class
with the proper
// constructor, and invoke setServletContext.
Class clazz = (contextClass != null ? Class.forName(contextClass)
: DEFAULT_CONTEXT_CLASS);
_log.info(
"Loading root WebApplicationContext: using context class '" +
clazz.getName() + "'");
if (!WebApplicationContext.class.isAssignableFrom(clazz)) {
throw new ApplicationContextException(
"Context class is no WebApplicationContext: " + contextClass);
}
Class[] parameterTypes;
Object[] params;
if (parentContext == null) {
parameterTypes = new Class[0];
params = new Object[0];
}
else {
parameterTypes = new Class[] {ApplicationContext.class,
String.class};
params = new Object[] {parentContext, null};
}
Constructor constructor = clazz.getConstructor(parameterTypes);
WebApplicationContext webApplicationContext =
(WebApplicationContext) constructor.newInstance(params);
webApplicationContext.setServletContext(servletContext);
return webApplicationContext;
}
catch (ApplicationContextException ex) {
handleException("Failed to initialize application context", ex);
}
catch (BeansException ex) {
handleException("Failed to initialize beans in application
context", ex);
}
catch (ClassNotFoundException ex) {
handleException("Failed to load config class '" + className + "'",
ex);
}
catch (InstantiationException ex) {
handleException(
"Failed to instantiate config class '"
+ className
+ "': does it have the proper constructor?",
ex);
}
catch (IllegalAccessException ex) {
handleException(
"Illegal access while finding or instantiating config class '"
+ className
+ "': does it have the proper constructor?",
ex);
}
catch (Throwable ex) {
handleException("Unexpected error loading context configuration", ex);
}
return null;
}
/**
* Log and throw an appropriate exception.
*/
private static void handleException(String msg, Throwable ex)
throws ApplicationContextException {
String thrownMsg = msg + ": " + ex.getMessage();
_log.error(thrownMsg, ex);
if (ex instanceof Error) {
throw (Error) ex;
}
else if (ex instanceof ApplicationContextException) {
throw (ApplicationContextException) ex;
}
else {
throw new ApplicationContextException(thrownMsg, ex);
}
}
/**
* Close Spring's web application context for the given servlet context.
* @param servletContext current servlet context
*/
public static void closeContext(ServletContext servletContext) {
servletContext.log("Closing root WebApplicationContext");
ApplicationContext ac =
WebApplicationContextUtils.getWebApplicationContext(servletContext);
ApplicationContext parent = ac.getParent();
try {
ac.close();
}
finally {
if (parent != null) {
ContextFactory cf = null;
String className =
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
// should we check this for null. for now, let's not, as it has
to be there if there is a parent
try {
cf = getParentContextFactory(servletContext);
}
catch (Exception ex) {
handleException("Unable to obtain context factory to release
parent context. Context factory className '" + className + "'", ex);
}
cf.releaseContext(parent);
}
}
}
/**
* Returns a ContextFactory, if any, to be used to obtain and release
a parent context
*/
private static ContextFactory getParentContextFactory(ServletContext
servletContext) throws ClassNotFoundException, SecurityException,
NoSuchMethodException, IllegalArgumentException, InstantiationException,
IllegalAccessException, InvocationTargetException {
String parentContextFactoryClassName =
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
String parentContextFactoryParam1 =
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_PARAM1_PARAM);
String className = null;
Class[] parameterTypes;
Object[] params;
ContextFactory parentContextFactory = null;
if (parentContextFactoryClassName != null) {
className = parentContextFactoryClassName;
Class clazz = Class.forName(className);
parameterTypes = new Class[0];
params = new Object[0];
if (parentContextFactoryParam1 != null) {
parameterTypes = new Class[] {String.class};
params = new Object[] {parentContextFactoryParam1};
}
Constructor constructor = clazz.getConstructor(parameterTypes);
parentContextFactory = (ContextFactory)
constructor.newInstance(params);
}
return parentContextFactory;
}
}
So this mechanism works fine. It allows me to layer application contexts
all the way down the layer stack, not just in the web-ui layer. Can
anybody think of a better or simpler way to handle this need?
Is it worth adding some of this code into Spring itself? I don't think
I'm the only person who will need to do something like this. Admittedly,
in the absence of the large start-up time for Hibernate, it would have
been acceptible to handle this via just three application contexts at
the web level, with duplicate definitions for the content from the
data-access and services layer brought in via xml includes.
Regards,
Colin
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Springframework-user mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-user
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: Colin S. <col...@ex...> - 2003-10-10 14:51:54
|
Hi Jürgen,
This is good stuff.
W/regards to the multiple-webapp case and hierarchical loading, I do
think it's worth having a built-in solution which addresses it. My
solution below doesn't feel quite clean or generic enough, so I'm going
to keep on thinking about possible implementations, as I get time...
Regards,
Colin
jürgen höller [werk3AT] wrote:
>Everybody,
>
>Related to the discussion about hierarchical loading, I've just committed support for assembling an application context from more than one XML file, just available via XmlWebApplicationContext for the moment. It allows to specify config locations with multiple paths in it, like in the web case:
>
> <context-param>
> <param-name>contextConfigLocation</param-name>
> <param-value>
> WEB-INF/applicationContext1.xml
> WEB-INF/applicationContext2.xml
> </param-value>
> </context-param>
>
>Any number of the characters ";, " between paths are ignored, to allow for lenient parsing. The result is a *single* root web application context that has been loaded from multiple XML files, each conforming to the spring-beans DTD. Bean references between the individual files need to be <ref external="..."> instead of <ref bean="..."> that references XML entities in the same file.
>
>This allows to split a large definition of a middle tier application context into multiple XML files, either separating by system modules or by sub layers. Obviously this doesn't address the EJB/multiple web app case, but it should be well suited for typical large web applications.
>
>BTW, I've also added support for multiple resource bundle basenames in ResourceBundleMessageSource, via the "basenames" property (in addition to the existing "basename" one). Those resource bundles get checked sequentially within a *single* MessageSource, allowing to split large message bundles into multiple files.
>
>Furthermore, I've revised the notation of name aliases like <bean ... name="myalias1,myalias2"> to match the rules above: Any number of the characters ";, " between bean names are ignored. This particularly allows BeanNameUrlHandlerMapping to interpret multiple aliases as multiple mappings without custom parsing, no matter if separated by a comma or space (the latter looks cleaner with URLs).
>
>The drawback of the latter is that XML bean aliases are not allowed to contains spaces or commas anymore -- for the benefit of being able to specify multiple aliases. Does anyone object to that tradeoff?
>
>-----
>
>I've also added a new post processor type: BeanPostProcessor, in addition to the existing BeanFactoryPostProcessor. Note that the former is in the beans.factory.support package, with AbstractBeanFactory offering support for it -- while the latter is in context.config, as it allows application contexts to override property values *after* their bean factory (a ListableBeanFactoryImpl, to be exact) has loaded.
>
>A BeanFactoryPostProcessor gets invoked once per bean factory loading; BeanPostProcessor once per bean creation. Both types of post processor can be defined as normal beans in an application context, getting automatically detected at startup, and applied before the rest of the beans gets created. With a plain bean factory, only BeanPostProcessor is applicable, but not defined as a normal bean but rather set via AbstractBeanFactory's setBeanPostProcessors method.
>
>I've applied the principle that bean factories are not supposed to understand special beans in the bean definitions that influence the behavior of the factory itself -- just application contexts are, like with the message source, options beans, and post processors. Bean factories can be customized through their implementation class, though - e.g. setEntityResolver, setValidating, and setBeanPostProcessors on XmlBeanFactory.
>
>A special implementation of BeanPostProcessor is applied under the hood by AbstractApplicationContext: ApplicationContextAwareProcessor is implictly registered with the underlying bean factory to automatically pass the application context to ApplicationContextAware beans. This allowed me to get rid of the rather ugly manual check for ApplicationContextAware with a cache of already managed instances to avoid double setting of the application context -- the current solution is much cleaner.
>
>Note that a custom BeanPostProcessor definition in an application context can not only be used to check for marker interfaces but also to wrap certain bean instances with proxies, as it can return a different bean instance than the one that came in. Look at the respective test case in StaticApplicationContextTestSuite that implicitly wraps each bean instance with a CGLIB proxy.
>
>Now imagine a BeanPostProcessor implementation that checks for certain attributes in the bean class file and applies respective interceptors -- like transaction attributes that trigger a CGLIB proxy and an implicit TransactionInterceptor! I consider this as the perfect hook for such implicit wrapping at bean creation time.
>
>Juergen
>
>
>-----Original Message-----
>From: Colin Sampaleanu [mailto:col...@ex...]
>Sent: Thursday, September 18, 2003 5:15 PM
>To: spr...@li...
>Subject: [Springframework-user] Hierarchical loading of Application
>Contexts
>
>
>I wanted to spur some discussion of best practices for hierachical
>loading of ApplicationContexts. ApplicationContext implementations can
>of course be created with a parent context specified. Currently, there
>is some code support for actually managing this loading in the web ui
>layer (where it's easy to have a setup with a root
>WebApplicationContext, and multiple child contexts, per servlet.
>
>Most Spring usage examples assume (unless I'm missing something) that
>the root WebApplicationContext will contain the entire layer stack, that
>is, data-access beans and service layer beans will be defined in there.
>This does work great when there there is only one web-app.
>
>Now in my case, I need something a little bit different. I have a J2EE
>application as an EAR file, which contains 3 web-apps (as WARs) at the
>top layer. Among other layers, below the web ui layer there is a
>services layer, and a data-access layer. Now I could get by with three
>different, parallel, application contexts defined, one for each of the
>web-apps, where all the bean definitions for the data-access and
>services layer was duplicated in each application context. I do not want
>to do this however, since I am using Hibernate, and do not want to force
>the Hibernate meta-data to be read in 3 times (it's a slow process). I
>much prefer to have a hierachical setup for the whole j2ee app, where I
>have an application context definition for the data-access layer, which
>needs to be the parent of an application context definition for the
>services layer, which needs to be the parent of three separate web
>application context definitions, one in each web-app.
>
>I have been able to achieve this as follows (and want to get feedback if
>somebody can think of a better way): I have an application context
>defintion for my data access layer
> data-access-applicationContext.xml
>I have an application context definition for my services layer, which is
>a child of the data-access context, and refers to beans in it.:
> core-servies-applicationContext.xml
>I then have the three application contexts for the web apps, which are
>children of the services context, and refer to beans within it.
>
>Now what I do, is (in a somewhat lazy fashion) trigger loading (once) of
>the services and data-access contexts, when I load the first web
>application context. The 2nd and 3rd web application context end up
>using the previously loaded service context instance. I have an
>interface, ContextFactory, as follows:
>
>/**
> * Defines interface for an ApplicationContext factory.
> *
> * @version $Revision: 1.40 $
> * @author colin
> */
>public interface ContextFactory {
>
> /**
> * Use the ApplicationContext specified by the key parameter. The
>context is possibly
> * loaded/created as needed.
> *
> * @param key a value specifying which context to use
> * @return the ApplicationContext instance
> * @throws ApplicationContextException if there is an error loading
>one or more contexts
> */
> ApplicationContext useContext(String key) throws
>ApplicationContextException;
>
> /**
> * Indicate that the specified ApplicationContext instance is not
>needed by a user of it,
> * who has previsouly obtained it via {@link useContext}. It is an
>error for releaseContext
> * to be called a greater number of times than useContext. Calling
>this release method may
> * cause close() to be called on the specified context, if this is the
>last user of it.
> *
> * @param ac the ApplicationContext instance
> * @throws ApplicationContextException
> */
> void releaseContext(ApplicationContext ac) throws
>ApplicationContextException;
>
>}
>
>Now I have an actual implementation, which can be used to get access to
>a reference counted context, triggering loading as needed, and loading
>parents of that context, if needed:
>
>/**
> * Implementation of ContextFactory.<br />
> * In this implementation, the key is actually the name of a properties
>file accessed as
> * a resource, each line of which specifies an ApplicationContext to
>load. Each line in
> * the file is the parent of the subsequent line. The last context is
>the one returned.
> *
> * @version $Revision: $
> * @author colin
>*/
>public class ContextFactoryImpl implements ContextFactory {
>
> // --- statics
>
> public static final Logger _log =
>Logger.getLogger(ContextFactoryImpl.class);
>
> // we map ContextInfo objects by String keys, and by Contexts
> private static HashMap instancesByKey = new HashMap();
> private static HashMap instancesByObj = new HashMap();
>
> // --- methods
>
> /* (non-Javadoc)
> * @see
>com.tira.coreserv.webutil.ContextFactory#useContext(java.lang.String)
> */
> public ApplicationContext useContext(String key) throws
>ApplicationContextException {
>
> synchronized(instancesByKey) {
> ContextInfo ci = (ContextInfo) instancesByKey.get(key);
> if (ci != null) {
> _log.debug("Context with key '" + key + "' requested. Returning
>existing instances");
> ci.refcount++;
> return ci.context;
> }
>
> _log.debug("Context with key '" + key + "' requested. Creating new
>instance");
>
> // this context doesn't exist, we need to try to load it
> InputStream is = getClass().getResourceAsStream(key);
> if (is == null)
> throw new ApplicationContextException("Unable to load
>context(s). Key does not point to a valid resource: " + key);
>
> Properties props = new Properties();
> try {
> props.load(is);
> is.close();
> }
> catch (IOException e) {
> throw new ApplicationContextException("Error reading application
>context pointer definition.", e);
> }
>
> ArrayList contexts = new ArrayList();
> for (int i = 0; ; ++i) {
> String context = props.getProperty(Integer.toString(i));
> if (context == null)
> break;
> contexts.add(context);
> }
>
> if (contexts.size() == 0)
> throw new ApplicationContextException("No application context
>definitions specified in definition file: " + key);
>
> ClassPathXmlApplicationContext ac;
> try {
> ac = new
>ClassPathXmlApplicationContext((String[])contexts.toArray(new String[0]));
> }
> catch (IOException e) {
> throw new ApplicationContextException("Error reading application
>context definition", e);
> }
>
> ci = new ContextInfo();
> ci.context = ac;
> ci.key = key;
> ci.refcount = 1;
> instancesByKey.put(key, ci);
> instancesByObj.put(ac, ci);
>
> return ac;
> }
> }
>
> /**
> * Releases the specified ApplicationContext instance. If there are no
>more users of this
> * context, close() will be called on it. Note that close will be
>called on its parents as
> * well, recursively.
> * @see
>com.tira.coreserv.webutil.ContextFactory#ReleaseContext(org.springframework.context.ApplicationContext)
> */
> public void releaseContext(ApplicationContext ac) throws
>ApplicationContextException {
>
> synchronized(instancesByKey) {
> ContextInfo ci = (ContextInfo) instancesByObj.get(ac);
> if (ci != null) {
> ci.refcount--;
> if (ci.refcount < 0)
> throw new ApplicationContextException("Illegal state: context
>released more times than acquired");
>
> if (ci.refcount == 0) {
> _log.debug("Release requested on Context with key '" + ci.key
>+ "'. Last reference, so closing along with parents");
> instancesByObj.remove(ac);
> instancesByKey.remove(ci.key);
> ApplicationContext child = ci.context;
> ApplicationContext parent;
> while (child != null) {
> parent = child.getParent();
> child.close();
> child = parent;
> }
> }
> else
> _log.debug("Release requested on Context with key '" + ci.key
>+ "'. References remain, so not closing.");
> }
> else
> throw new ApplicationContextException("Attempted to release
>context reference for context not known to this factory");
> }
> }
>
> // we track contexts with this class
> private class ContextInfo {
> public ApplicationContext context;
> public String key;
> public int refcount = 0;
> }
>
>}
>
>So my ContextFactory impl can load the services application context, and
>first its parent, the data-access context, on demand, and subsequent
>request will just return a reference to the same context. The 'key'
>specified to the context factory is just the name of a file specifying
>which contexts to load:
>
>File core-services-applicationContexts.properties:
># defines one or more hierarchical xml ApplicationContext instances
>which are considered
># to make up the application context stack for core-services. Each line
>is a parent of the
># subsequent line.
>0=/data-access-applicationContext.xml
>1=/core-services-applicationContext.xml
>
>Now I just need to have a modified version of ContextLoader from Spring
>which along with loading a specified WebApplicationContext instance,
>will optioinally use the ContextFactory to load a parent context first.
>Here's the code:
>
>/**
> * Class used to load a web application context, including possibly
>triggering loading of a parent
> * context through a ContextFactory instance
> *
> * @version $Revision: $
>*/
>public class ContextLoader {
>
> // --- statics
>
> /**?
> * Config param for the root WebApplicationContext implementation
>class to use.
> */
> public static final String CONTEXT_CLASS_PARAM = "contextClass";
>
> public static final Class DEFAULT_CONTEXT_CLASS =
>XmlWebApplicationContext.class;
>
> public static final String PARENT_CONTEXT_FACTORY_CLASS_PARAM =
>"parentContextFactoryClass";
>
> public static final String PARENT_CONTEXT_FACTORY_PARAM1_PARAM =
>"parentContextFactoryParam";
>
> public static final String PARENT_CONTEXT_KEY_PARAM = "parentContextKey";
>
> public static final Logger _log = Logger.getLogger(ContextLoader.class);
>
> /**
> * Initialize Spring's web application context for the given servlet
>context,
> * regarding the "contextClass" servlet context init parameter.
> * @param servletContext current servlet context
> * @return the new WebApplicationContext
> */
> public static WebApplicationContext initContext(ServletContext
>servletContext)
> throws ApplicationContextException {
>
> servletContext.log("Loading root WebApplicationContext");
> String contextClass =
>servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
>
> String className = null;
> try {
> className =
>servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
> ContextFactory parentContextFactory =
>getParentContextFactory(servletContext);
>
> ApplicationContext parentContext = null;
> if (parentContextFactory != null) {
> String parentContextKey =
>servletContext.getInitParameter(PARENT_CONTEXT_KEY_PARAM);
> _log.info(
> "Getting parent context: using context factory class '" +
>className + "', key '" +
> parentContextKey + "'");
> parentContext = parentContextFactory.useContext(parentContextKey);
> }
>
> // Now we must load the WebApplicationContext.
> // It configures itself: all we need to do is construct the class
>with the proper
> // constructor, and invoke setServletContext.
> Class clazz = (contextClass != null ? Class.forName(contextClass)
>: DEFAULT_CONTEXT_CLASS);
> _log.info(
> "Loading root WebApplicationContext: using context class '" +
>clazz.getName() + "'");
> if (!WebApplicationContext.class.isAssignableFrom(clazz)) {
> throw new ApplicationContextException(
> "Context class is no WebApplicationContext: " + contextClass);
> }
>
> Class[] parameterTypes;
> Object[] params;
> if (parentContext == null) {
> parameterTypes = new Class[0];
> params = new Object[0];
> }
> else {
> parameterTypes = new Class[] {ApplicationContext.class,
>String.class};
> params = new Object[] {parentContext, null};
> }
>
> Constructor constructor = clazz.getConstructor(parameterTypes);
> WebApplicationContext webApplicationContext =
>(WebApplicationContext) constructor.newInstance(params);
> webApplicationContext.setServletContext(servletContext);
> return webApplicationContext;
> }
> catch (ApplicationContextException ex) {
> handleException("Failed to initialize application context", ex);
> }
> catch (BeansException ex) {
> handleException("Failed to initialize beans in application
>context", ex);
> }
> catch (ClassNotFoundException ex) {
> handleException("Failed to load config class '" + className + "'",
>ex);
> }
> catch (InstantiationException ex) {
> handleException(
> "Failed to instantiate config class '"
> + className
> + "': does it have the proper constructor?",
> ex);
> }
> catch (IllegalAccessException ex) {
> handleException(
> "Illegal access while finding or instantiating config class '"
> + className
> + "': does it have the proper constructor?",
> ex);
> }
> catch (Throwable ex) {
> handleException("Unexpected error loading context configuration", ex);
> }
>
> return null;
> }
>
> /**
> * Log and throw an appropriate exception.
> */
> private static void handleException(String msg, Throwable ex)
> throws ApplicationContextException {
> String thrownMsg = msg + ": " + ex.getMessage();
> _log.error(thrownMsg, ex);
> if (ex instanceof Error) {
> throw (Error) ex;
> }
> else if (ex instanceof ApplicationContextException) {
> throw (ApplicationContextException) ex;
> }
> else {
> throw new ApplicationContextException(thrownMsg, ex);
> }
> }
>
> /**
> * Close Spring's web application context for the given servlet context.
> * @param servletContext current servlet context
> */
> public static void closeContext(ServletContext servletContext) {
> servletContext.log("Closing root WebApplicationContext");
> ApplicationContext ac =
>WebApplicationContextUtils.getWebApplicationContext(servletContext);
> ApplicationContext parent = ac.getParent();
> try {
> ac.close();
> }
> finally {
> if (parent != null) {
> ContextFactory cf = null;
> String className =
>servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
> // should we check this for null. for now, let's not, as it has
>to be there if there is a parent
> try {
> cf = getParentContextFactory(servletContext);
> }
> catch (Exception ex) {
> handleException("Unable to obtain context factory to release
>parent context. Context factory className '" + className + "'", ex);
> }
> cf.releaseContext(parent);
> }
> }
> }
>
> /**
> * Returns a ContextFactory, if any, to be used to obtain and release
>a parent context
> */
> private static ContextFactory getParentContextFactory(ServletContext
>servletContext) throws ClassNotFoundException, SecurityException,
>NoSuchMethodException, IllegalArgumentException, InstantiationException,
>IllegalAccessException, InvocationTargetException {
>
> String parentContextFactoryClassName =
>servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
> String parentContextFactoryParam1 =
>servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_PARAM1_PARAM);
>
> String className = null;
> Class[] parameterTypes;
> Object[] params;
>
> ContextFactory parentContextFactory = null;
> if (parentContextFactoryClassName != null) {
> className = parentContextFactoryClassName;
> Class clazz = Class.forName(className);
> parameterTypes = new Class[0];
> params = new Object[0];
> if (parentContextFactoryParam1 != null) {
> parameterTypes = new Class[] {String.class};
> params = new Object[] {parentContextFactoryParam1};
> }
> Constructor constructor = clazz.getConstructor(parameterTypes);
> parentContextFactory = (ContextFactory)
>constructor.newInstance(params);
> }
>
> return parentContextFactory;
> }
>}
>
>
>So this mechanism works fine. It allows me to layer application contexts
>all the way down the layer stack, not just in the web-ui layer. Can
>anybody think of a better or simpler way to handle this need?
>
>Is it worth adding some of this code into Spring itself? I don't think
>I'm the only person who will need to do something like this. Admittedly,
>in the absence of the large start-up time for Hibernate, it would have
>been acceptible to handle this via just three application contexts at
>the web level, with duplicate definitions for the content from the
>data-access and services layer brought in via xml includes.
>
>Regards,
>Colin
>
>
|
|
From: <jue...@we...> - 2003-10-10 14:32:34
|
Everybody,
Related to the discussion about hierarchical loading, I've just =
committed support for assembling an application context from more than =
one XML file, just available via XmlWebApplicationContext for the =
moment. It allows to specify config locations with multiple paths in it, =
like in the web case:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/applicationContext1.xml
WEB-INF/applicationContext2.xml
</param-value>
</context-param>
Any number of the characters ";, " between paths are ignored, to allow =
for lenient parsing. The result is a *single* root web application =
context that has been loaded from multiple XML files, each conforming to =
the spring-beans DTD. Bean references between the individual files need =
to be <ref external=3D"..."> instead of <ref bean=3D"..."> that =
references XML entities in the same file.
This allows to split a large definition of a middle tier application =
context into multiple XML files, either separating by system modules or =
by sub layers. Obviously this doesn't address the EJB/multiple web app =
case, but it should be well suited for typical large web applications.
BTW, I've also added support for multiple resource bundle basenames in =
ResourceBundleMessageSource, via the "basenames" property (in addition =
to the existing "basename" one). Those resource bundles get checked =
sequentially within a *single* MessageSource, allowing to split large =
message bundles into multiple files.
Furthermore, I've revised the notation of name aliases like <bean ... =
name=3D"myalias1,myalias2"> to match the rules above: Any number of the =
characters ";, " between bean names are ignored. This particularly =
allows BeanNameUrlHandlerMapping to interpret multiple aliases as =
multiple mappings without custom parsing, no matter if separated by a =
comma or space (the latter looks cleaner with URLs).
The drawback of the latter is that XML bean aliases are not allowed to =
contains spaces or commas anymore -- for the benefit of being able to =
specify multiple aliases. Does anyone object to that tradeoff?
-----
I've also added a new post processor type: BeanPostProcessor, in =
addition to the existing BeanFactoryPostProcessor. Note that the former =
is in the beans.factory.support package, with AbstractBeanFactory =
offering support for it -- while the latter is in context.config, as it =
allows application contexts to override property values *after* their =
bean factory (a ListableBeanFactoryImpl, to be exact) has loaded.
A BeanFactoryPostProcessor gets invoked once per bean factory loading; =
BeanPostProcessor once per bean creation. Both types of post processor =
can be defined as normal beans in an application context, getting =
automatically detected at startup, and applied before the rest of the =
beans gets created. With a plain bean factory, only BeanPostProcessor is =
applicable, but not defined as a normal bean but rather set via =
AbstractBeanFactory's setBeanPostProcessors method.
I've applied the principle that bean factories are not supposed to =
understand special beans in the bean definitions that influence the =
behavior of the factory itself -- just application contexts are, like =
with the message source, options beans, and post processors. Bean =
factories can be customized through their implementation class, though - =
e.g. setEntityResolver, setValidating, and setBeanPostProcessors on =
XmlBeanFactory.
A special implementation of BeanPostProcessor is applied under the hood =
by AbstractApplicationContext: ApplicationContextAwareProcessor is =
implictly registered with the underlying bean factory to automatically =
pass the application context to ApplicationContextAware beans. This =
allowed me to get rid of the rather ugly manual check for =
ApplicationContextAware with a cache of already managed instances to =
avoid double setting of the application context -- the current solution =
is much cleaner.
Note that a custom BeanPostProcessor definition in an application =
context can not only be used to check for marker interfaces but also to =
wrap certain bean instances with proxies, as it can return a different =
bean instance than the one that came in. Look at the respective test =
case in StaticApplicationContextTestSuite that implicitly wraps each =
bean instance with a CGLIB proxy.
Now imagine a BeanPostProcessor implementation that checks for certain =
attributes in the bean class file and applies respective interceptors -- =
like transaction attributes that trigger a CGLIB proxy and an implicit =
TransactionInterceptor! I consider this as the perfect hook for such =
implicit wrapping at bean creation time.
Juergen
-----Original Message-----
From: Colin Sampaleanu [mailto:col...@ex...]
Sent: Thursday, September 18, 2003 5:15 PM
To: spr...@li...
Subject: [Springframework-user] Hierarchical loading of Application
Contexts
I wanted to spur some discussion of best practices for hierachical=20
loading of ApplicationContexts. ApplicationContext implementations can=20
of course be created with a parent context specified. Currently, there=20
is some code support for actually managing this loading in the web ui=20
layer (where it's easy to have a setup with a root=20
WebApplicationContext, and multiple child contexts, per servlet.
Most Spring usage examples assume (unless I'm missing something) that=20
the root WebApplicationContext will contain the entire layer stack, that =
is, data-access beans and service layer beans will be defined in there.=20
This does work great when there there is only one web-app.
Now in my case, I need something a little bit different. I have a J2EE=20
application as an EAR file, which contains 3 web-apps (as WARs) at the=20
top layer. Among other layers, below the web ui layer there is a=20
services layer, and a data-access layer. Now I could get by with three=20
different, parallel, application contexts defined, one for each of the=20
web-apps, where all the bean definitions for the data-access and=20
services layer was duplicated in each application context. I do not want =
to do this however, since I am using Hibernate, and do not want to force =
the Hibernate meta-data to be read in 3 times (it's a slow process). I=20
much prefer to have a hierachical setup for the whole j2ee app, where I =
have an application context definition for the data-access layer, which=20
needs to be the parent of an application context definition for the=20
services layer, which needs to be the parent of three separate web=20
application context definitions, one in each web-app.
I have been able to achieve this as follows (and want to get feedback if =
somebody can think of a better way): I have an application context=20
defintion for my data access layer
data-access-applicationContext.xml
I have an application context definition for my services layer, which is =
a child of the data-access context, and refers to beans in it.:
core-servies-applicationContext.xml
I then have the three application contexts for the web apps, which are=20
children of the services context, and refer to beans within it.
Now what I do, is (in a somewhat lazy fashion) trigger loading (once) of =
the services and data-access contexts, when I load the first web=20
application context. The 2nd and 3rd web application context end up=20
using the previously loaded service context instance. I have an=20
interface, ContextFactory, as follows:
/**
* Defines interface for an ApplicationContext factory.
*
* @version $Revision: 1.40 $
* @author colin
*/
public interface ContextFactory {
=20
/**
* Use the ApplicationContext specified by the key parameter. The=20
context is possibly
* loaded/created as needed.
*
* @param key a value specifying which context to use
* @return the ApplicationContext instance
* @throws ApplicationContextException if there is an error loading=20
one or more contexts
*/
ApplicationContext useContext(String key) throws=20
ApplicationContextException;
=20
/**
* Indicate that the specified ApplicationContext instance is not=20
needed by a user of it,
* who has previsouly obtained it via {@link useContext}. It is an=20
error for releaseContext
* to be called a greater number of times than useContext. Calling=20
this release method may
* cause close() to be called on the specified context, if this is the =
last user of it.
*=20
* @param ac the ApplicationContext instance
* @throws ApplicationContextException
*/
void releaseContext(ApplicationContext ac) throws=20
ApplicationContextException;
}
Now I have an actual implementation, which can be used to get access to=20
a reference counted context, triggering loading as needed, and loading=20
parents of that context, if needed:
/**
* Implementation of ContextFactory.<br />
* In this implementation, the key is actually the name of a properties=20
file accessed as
* a resource, each line of which specifies an ApplicationContext to=20
load. Each line in
* the file is the parent of the subsequent line. The last context is=20
the one returned.
*=20
* @version $Revision: $
* @author colin
*/
public class ContextFactoryImpl implements ContextFactory {
=20
// --- statics
public static final Logger _log =3D=20
Logger.getLogger(ContextFactoryImpl.class);
// we map ContextInfo objects by String keys, and by Contexts
private static HashMap instancesByKey =3D new HashMap();
private static HashMap instancesByObj =3D new HashMap();
// --- methods
=20
/* (non-Javadoc)
* @see=20
com.tira.coreserv.webutil.ContextFactory#useContext(java.lang.String)
*/
public ApplicationContext useContext(String key) throws=20
ApplicationContextException {
synchronized(instancesByKey) {
ContextInfo ci =3D (ContextInfo) instancesByKey.get(key);
if (ci !=3D null) {
_log.debug("Context with key '" + key + "' requested. Returning=20
existing instances");
ci.refcount++;
return ci.context;
}
_log.debug("Context with key '" + key + "' requested. Creating new =
instance");
// this context doesn't exist, we need to try to load it
InputStream is =3D getClass().getResourceAsStream(key);
if (is =3D=3D null)
throw new ApplicationContextException("Unable to load=20
context(s). Key does not point to a valid resource: " + key);
Properties props =3D new Properties();
try {
props.load(is);
is.close();
}
catch (IOException e) {
throw new ApplicationContextException("Error reading application =
context pointer definition.", e);
}
=20
ArrayList contexts =3D new ArrayList();
for (int i =3D 0; ; ++i) {
String context =3D props.getProperty(Integer.toString(i));
if (context =3D=3D null)
break;
contexts.add(context);
}
=20
if (contexts.size() =3D=3D 0)
throw new ApplicationContextException("No application context=20
definitions specified in definition file: " + key);
ClassPathXmlApplicationContext ac;
try {
ac =3D new=20
ClassPathXmlApplicationContext((String[])contexts.toArray(new =
String[0]));
}
catch (IOException e) {
throw new ApplicationContextException("Error reading application =
context definition", e);
}
=20
ci =3D new ContextInfo();
ci.context =3D ac;
ci.key =3D key;
ci.refcount =3D 1;
instancesByKey.put(key, ci);
instancesByObj.put(ac, ci);
=20
return ac;
}
}
/**
* Releases the specified ApplicationContext instance. If there are no =
more users of this
* context, close() will be called on it. Note that close will be=20
called on its parents as
* well, recursively.
* @see=20
com.tira.coreserv.webutil.ContextFactory#ReleaseContext(org.springframewo=
rk.context.ApplicationContext)
*/
public void releaseContext(ApplicationContext ac) throws=20
ApplicationContextException {
synchronized(instancesByKey) {
ContextInfo ci =3D (ContextInfo) instancesByObj.get(ac);
if (ci !=3D null) {
ci.refcount--;
if (ci.refcount < 0)
throw new ApplicationContextException("Illegal state: context=20
released more times than acquired");
if (ci.refcount =3D=3D 0) {
_log.debug("Release requested on Context with key '" + ci.key=20
+ "'. Last reference, so closing along with parents");
instancesByObj.remove(ac);
instancesByKey.remove(ci.key);
ApplicationContext child =3D ci.context;
ApplicationContext parent;
while (child !=3D null) {
parent =3D child.getParent();
child.close();
child =3D parent;
}
}
else
_log.debug("Release requested on Context with key '" + ci.key=20
+ "'. References remain, so not closing.");
}
else
throw new ApplicationContextException("Attempted to release=20
context reference for context not known to this factory");
}
}
// we track contexts with this class
private class ContextInfo {
public ApplicationContext context;
public String key;
public int refcount =3D 0;
}
}
So my ContextFactory impl can load the services application context, and =
first its parent, the data-access context, on demand, and subsequent=20
request will just return a reference to the same context. The 'key'=20
specified to the context factory is just the name of a file specifying=20
which contexts to load:
File core-services-applicationContexts.properties:
# defines one or more hierarchical xml ApplicationContext instances=20
which are considered
# to make up the application context stack for core-services. Each line=20
is a parent of the
# subsequent line.
0=3D/data-access-applicationContext.xml
1=3D/core-services-applicationContext.xml
Now I just need to have a modified version of ContextLoader from Spring=20
which along with loading a specified WebApplicationContext instance,=20
will optioinally use the ContextFactory to load a parent context first.=20
Here's the code:
/**
* Class used to load a web application context, including possibly=20
triggering loading of a parent
* context through a ContextFactory instance
*
* @version $Revision: $
*/
public class ContextLoader {
// --- statics
/**?
* Config param for the root WebApplicationContext implementation=20
class to use.
*/
public static final String CONTEXT_CLASS_PARAM =3D "contextClass";
public static final Class DEFAULT_CONTEXT_CLASS =3D=20
XmlWebApplicationContext.class;
public static final String PARENT_CONTEXT_FACTORY_CLASS_PARAM =3D=20
"parentContextFactoryClass";
public static final String PARENT_CONTEXT_FACTORY_PARAM1_PARAM =3D=20
"parentContextFactoryParam";
=20
public static final String PARENT_CONTEXT_KEY_PARAM =3D =
"parentContextKey";
public static final Logger _log =3D =
Logger.getLogger(ContextLoader.class);
/**
* Initialize Spring's web application context for the given servlet=20
context,
* regarding the "contextClass" servlet context init parameter.
* @param servletContext current servlet context
* @return the new WebApplicationContext
*/
public static WebApplicationContext initContext(ServletContext=20
servletContext)
throws ApplicationContextException {
servletContext.log("Loading root WebApplicationContext");
String contextClass =3D=20
servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
=20
String className =3D null;
try {
className =3D=20
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
ContextFactory parentContextFactory =3D=20
getParentContextFactory(servletContext);
ApplicationContext parentContext =3D null;
if (parentContextFactory !=3D null) {
String parentContextKey =3D=20
servletContext.getInitParameter(PARENT_CONTEXT_KEY_PARAM);
_log.info(
"Getting parent context: using context factory class '" +=20
className + "', key '" +
parentContextKey + "'");
parentContext =3D =
parentContextFactory.useContext(parentContextKey);
}
// Now we must load the WebApplicationContext.
// It configures itself: all we need to do is construct the class=20
with the proper
// constructor, and invoke setServletContext.
Class clazz =3D (contextClass !=3D null ? =
Class.forName(contextClass)=20
: DEFAULT_CONTEXT_CLASS);
_log.info(
"Loading root WebApplicationContext: using context class '" +=20
clazz.getName() + "'");
if (!WebApplicationContext.class.isAssignableFrom(clazz)) {
throw new ApplicationContextException(
"Context class is no WebApplicationContext: " + contextClass);
}
Class[] parameterTypes;
Object[] params;
if (parentContext =3D=3D null) {
parameterTypes =3D new Class[0];
params =3D new Object[0];
}
else {
parameterTypes =3D new Class[] {ApplicationContext.class,=20
String.class};
params =3D new Object[] {parentContext, null};
}
Constructor constructor =3D clazz.getConstructor(parameterTypes);
WebApplicationContext webApplicationContext =3D=20
(WebApplicationContext) constructor.newInstance(params);
webApplicationContext.setServletContext(servletContext);
return webApplicationContext;
}
catch (ApplicationContextException ex) {
handleException("Failed to initialize application context", ex);
}
catch (BeansException ex) {
handleException("Failed to initialize beans in application=20
context", ex);
}
catch (ClassNotFoundException ex) {
handleException("Failed to load config class '" + className + "'", =
ex);
}
catch (InstantiationException ex) {
handleException(
"Failed to instantiate config class '"
+ className
+ "': does it have the proper constructor?",
ex);
}
catch (IllegalAccessException ex) {
handleException(
"Illegal access while finding or instantiating config class '"
+ className
+ "': does it have the proper constructor?",
ex);
}
catch (Throwable ex) {
handleException("Unexpected error loading context configuration", =
ex);
}
return null;
}
/**
* Log and throw an appropriate exception.
*/
private static void handleException(String msg, Throwable ex)
throws ApplicationContextException {
String thrownMsg =3D msg + ": " + ex.getMessage();
_log.error(thrownMsg, ex);
if (ex instanceof Error) {
throw (Error) ex;
}
else if (ex instanceof ApplicationContextException) {
throw (ApplicationContextException) ex;
}
else {
throw new ApplicationContextException(thrownMsg, ex);
}
}
/**
* Close Spring's web application context for the given servlet =
context.
* @param servletContext current servlet context
*/
public static void closeContext(ServletContext servletContext) {
servletContext.log("Closing root WebApplicationContext");
ApplicationContext ac =3D=20
WebApplicationContextUtils.getWebApplicationContext(servletContext);
ApplicationContext parent =3D ac.getParent();
try {
ac.close();
}
finally {
if (parent !=3D null) {
ContextFactory cf =3D null;
String className =3D=20
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
// should we check this for null. for now, let's not, as it has=20
to be there if there is a parent
try {
cf =3D getParentContextFactory(servletContext);
}
catch (Exception ex) {
handleException("Unable to obtain context factory to release=20
parent context. Context factory className '" + className + "'", ex);
}
cf.releaseContext(parent);
}
}
}
/**
* Returns a ContextFactory, if any, to be used to obtain and release=20
a parent context
*/
private static ContextFactory getParentContextFactory(ServletContext=20
servletContext) throws ClassNotFoundException, SecurityException,=20
NoSuchMethodException, IllegalArgumentException, InstantiationException, =
IllegalAccessException, InvocationTargetException {
String parentContextFactoryClassName =3D=20
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_CLASS_PARAM);
String parentContextFactoryParam1 =3D=20
servletContext.getInitParameter(PARENT_CONTEXT_FACTORY_PARAM1_PARAM);
=20
String className =3D null;
Class[] parameterTypes;
Object[] params;
ContextFactory parentContextFactory =3D null;
if (parentContextFactoryClassName !=3D null) {
className =3D parentContextFactoryClassName;
Class clazz =3D Class.forName(className);
parameterTypes =3D new Class[0];
params =3D new Object[0];
if (parentContextFactoryParam1 !=3D null) {
parameterTypes =3D new Class[] {String.class};
params =3D new Object[] {parentContextFactoryParam1};
}
Constructor constructor =3D clazz.getConstructor(parameterTypes);
parentContextFactory =3D (ContextFactory)=20
constructor.newInstance(params);
}
=20
return parentContextFactory;
}
}
So this mechanism works fine. It allows me to layer application contexts =
all the way down the layer stack, not just in the web-ui layer. Can=20
anybody think of a better or simpler way to handle this need?
Is it worth adding some of this code into Spring itself? I don't think=20
I'm the only person who will need to do something like this. Admittedly, =
in the absence of the large start-up time for Hibernate, it would have=20
been acceptible to handle this via just three application contexts at=20
the web level, with duplicate definitions for the content from the=20
data-access and services layer brought in via xml includes.
Regards,
Colin
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Springframework-user mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-user
|
|
From: Ivan R. <iv...@we...> - 2003-10-10 09:20:53
|
Mike Cannon-Brookes wrote: > Personally I'd like to see (or would be happy to create) a Quartz bean. And I would be happy to work with you so that schedulers coexist :) > Rewriting your own scheduler seems like a waste of effort to me? Quartz is > extremely flexible, Open Source and has been debugged for a long time! > Writing a scheduler is no easy task. I am sure it seems that way from your point of view. It is different from my point of view: it doesn't give me what I want, it forces me to think about things I don't care and it simply doesn't "feel" right. For the record, after getting suggestions from this list, I did attempt to wrap Quartz and use it from Spring. For a while I thought I'll do that but I gave up after learning more about it. In the end, I do believe that it is an overkill for most uses. It is an eternal question you are asking, to "buy or build". I am not against "buying" - I happily chose to use Spring over my own XML-based configuration mechanism because I believed it is better than anything I would be able to build. I don't think that way about Quartz. > Why not configure them all in the context file? Simply put there are often > hundreds of scheduled jobs and they more belong in their own custom file > IMHO. Both approaches have their merits. People will probably chose on or the other depending on the type of project they have. -- ModSecurity (http://www.modsecurity.org) [ Open source IDS for Web applications ] |
|
From: Rod J. <rod...@in...> - 2003-10-10 07:38:22
|
Or implement BeanFactoryAware, so it could work in a BeanFactory, not just
an ApplicationContext (which is a subinterface of BeanFactory).
----- Original Message -----
From: "Kopylenko, Dmitry" <dko...@su...>
To: "'Mike Cannon-Brookes '" <mi...@at...>; "'Spring Developer '"
<spr...@li...>
Sent: Friday, October 10, 2003 2:57 AM
Subject: RE: [Springframework-developer] Scheduler update
> > On a side note - is there a way for a bean to receive a reference to
> > it's
> > context? This would be useful for a scheduler as it could then pas that
> > context on to each of the jobs it has configured.
>
> A bean just needs to implement the ApplicationContextAware interface.
>
> Dmitriy.
>
> -----Original Message-----
> From: Mike Cannon-Brookes
> To: Spring Developer
> Sent: 10/9/2003 7:58 PM
> Subject: Re: [Springframework-developer] Scheduler update
>
> Personally I'd like to see (or would be happy to create) a Quartz bean.
> Rewriting your own scheduler seems like a waste of effort to me? Quartz
> is
> extremely flexible, Open Source and has been debugged for a long time!
> Writing a scheduler is no easy task.
>
> We have a simple XML format in house for configuring Quartz with
> volatile
> jobs and triggers, and which currently uses a ServletListener to start
> it.
>
> On a side note - is there a way for a bean to receive a reference to
> it's
> context? This would be useful for a scheduler as it could then pas that
> context on to each of the jobs it has configured.
>
> Why not configure them all in the context file? Simply put there are
> often
> hundreds of scheduled jobs and they more belong in their own custom file
> IMHO.
>
> M
>
> On 10/10/03 9:26 AM, "Ivan Ristic" (iv...@we...) penned the
> words:
>
> > Kopylenko, Dmitry wrote:
> >> Ivan,
> >>
> >> would it make sense to make SpringExecWrapper a bean, that is, expose
> its
> >> properties (i.e bean, event, methodName, args) so they could be
> configured
> >> through an application context and also make it implement
> >> ApplicationContextAware interface, so the ApplicationContext would be
> >> provided to it by the BeanFactory ?
> >
> > Interesting idea. I always thought about creating a class such as
> > SpringAwareCronScheduler and then configuring it via parameters.
> >
> > Your approach may be better, but I'd rather create a new class
> > for that then use the wrapper itself.
> >
> > How would this class know which scheduler to use? Look it up by
> > name ('scheduler') or have a setter method accepting a scheduler
> > instance? I would go with the setter method: you first create your
> > beans, then the schedule, and then create as many tasks as needed.
> >
> > Besides, it would also work with the auto-wire feature ;)
> >
> > BTW, the biggest problem I had when I was trying to create an
> > interface for various scheduling implementations was the way
> > schedules are specified. At best we will have to accept that
> > a schedule is specified with a single string.
> >
> > I could refactor RecurringSchedule to accept something like
> > this on input:
> >
> > "rate=5000ms, repeatCount=10"
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: SF.net Giveback Program.
> SourceForge.net hosts over 70,000 Open Source Projects.
> See the people who have HELPED US provide better services:
> Click here: http://sourceforge.net/supporters.php
> _______________________________________________
> Springframework-developer mailing list
> Spr...@li...
> https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: SF.net Giveback Program.
> SourceForge.net hosts over 70,000 Open Source Projects.
> See the people who have HELPED US provide better services:
> Click here: http://sourceforge.net/supporters.php
> _______________________________________________
> Springframework-developer mailing list
> Spr...@li...
> https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
|
|
From: Kopylenko, D. <dko...@ac...> - 2003-10-10 01:57:34
|
> On a side note - is there a way for a bean to receive a reference to
> it's
> context? This would be useful for a scheduler as it could then pas that
> context on to each of the jobs it has configured.
A bean just needs to implement the ApplicationContextAware interface.
Dmitriy.
-----Original Message-----
From: Mike Cannon-Brookes
To: Spring Developer
Sent: 10/9/2003 7:58 PM
Subject: Re: [Springframework-developer] Scheduler update
Personally I'd like to see (or would be happy to create) a Quartz bean.
Rewriting your own scheduler seems like a waste of effort to me? Quartz
is
extremely flexible, Open Source and has been debugged for a long time!
Writing a scheduler is no easy task.
We have a simple XML format in house for configuring Quartz with
volatile
jobs and triggers, and which currently uses a ServletListener to start
it.
On a side note - is there a way for a bean to receive a reference to
it's
context? This would be useful for a scheduler as it could then pas that
context on to each of the jobs it has configured.
Why not configure them all in the context file? Simply put there are
often
hundreds of scheduled jobs and they more belong in their own custom file
IMHO.
M
On 10/10/03 9:26 AM, "Ivan Ristic" (iv...@we...) penned the
words:
> Kopylenko, Dmitry wrote:
>> Ivan,
>>
>> would it make sense to make SpringExecWrapper a bean, that is, expose
its
>> properties (i.e bean, event, methodName, args) so they could be
configured
>> through an application context and also make it implement
>> ApplicationContextAware interface, so the ApplicationContext would be
>> provided to it by the BeanFactory ?
>
> Interesting idea. I always thought about creating a class such as
> SpringAwareCronScheduler and then configuring it via parameters.
>
> Your approach may be better, but I'd rather create a new class
> for that then use the wrapper itself.
>
> How would this class know which scheduler to use? Look it up by
> name ('scheduler') or have a setter method accepting a scheduler
> instance? I would go with the setter method: you first create your
> beans, then the schedule, and then create as many tasks as needed.
>
> Besides, it would also work with the auto-wire feature ;)
>
> BTW, the biggest problem I had when I was trying to create an
> interface for various scheduling implementations was the way
> schedules are specified. At best we will have to accept that
> a schedule is specified with a single string.
>
> I could refactor RecurringSchedule to accept something like
> this on input:
>
> "rate=5000ms, repeatCount=10"
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: Mike Cannon-B. <mi...@at...> - 2003-10-10 00:00:07
|
Personally I'd like to see (or would be happy to create) a Quartz bean.
Rewriting your own scheduler seems like a waste of effort to me? Quartz is
extremely flexible, Open Source and has been debugged for a long time!
Writing a scheduler is no easy task.
We have a simple XML format in house for configuring Quartz with volatile
jobs and triggers, and which currently uses a ServletListener to start it.
On a side note - is there a way for a bean to receive a reference to it's
context? This would be useful for a scheduler as it could then pas that
context on to each of the jobs it has configured.
Why not configure them all in the context file? Simply put there are often
hundreds of scheduled jobs and they more belong in their own custom file
IMHO.
M
On 10/10/03 9:26 AM, "Ivan Ristic" (iv...@we...) penned the words:
> Kopylenko, Dmitry wrote:
>> Ivan,
>>
>> would it make sense to make SpringExecWrapper a bean, that is, expose its
>> properties (i.e bean, event, methodName, args) so they could be configured
>> through an application context and also make it implement
>> ApplicationContextAware interface, so the ApplicationContext would be
>> provided to it by the BeanFactory ?
>
> Interesting idea. I always thought about creating a class such as
> SpringAwareCronScheduler and then configuring it via parameters.
>
> Your approach may be better, but I'd rather create a new class
> for that then use the wrapper itself.
>
> How would this class know which scheduler to use? Look it up by
> name ('scheduler') or have a setter method accepting a scheduler
> instance? I would go with the setter method: you first create your
> beans, then the schedule, and then create as many tasks as needed.
>
> Besides, it would also work with the auto-wire feature ;)
>
> BTW, the biggest problem I had when I was trying to create an
> interface for various scheduling implementations was the way
> schedules are specified. At best we will have to accept that
> a schedule is specified with a single string.
>
> I could refactor RecurringSchedule to accept something like
> this on input:
>
> "rate=5000ms, repeatCount=10"
|
|
From: Ivan R. <iv...@we...> - 2003-10-09 23:25:30
|
Kopylenko, Dmitry wrote:
> Ivan,
>
> would it make sense to make SpringExecWrapper a bean, that is, expose its
> properties (i.e bean, event, methodName, args) so they could be configured
> through an application context and also make it implement
> ApplicationContextAware interface, so the ApplicationContext would be
> provided to it by the BeanFactory ?
Interesting idea. I always thought about creating a class such as
SpringAwareCronScheduler and then configuring it via parameters.
Your approach may be better, but I'd rather create a new class
for that then use the wrapper itself.
How would this class know which scheduler to use? Look it up by
name ('scheduler') or have a setter method accepting a scheduler
instance? I would go with the setter method: you first create your
beans, then the schedule, and then create as many tasks as needed.
Besides, it would also work with the auto-wire feature ;)
BTW, the biggest problem I had when I was trying to create an
interface for various scheduling implementations was the way
schedules are specified. At best we will have to accept that
a schedule is specified with a single string.
I could refactor RecurringSchedule to accept something like
this on input:
"rate=5000ms, repeatCount=10"
--
ModSecurity (http://www.modsecurity.org)
[ Open source IDS for Web applications ]
|
|
From: Kopylenko, D. <dko...@ac...> - 2003-10-09 22:36:15
|
Ivan, would it make sense to make SpringExecWrapper a bean, that is, expose its properties (i.e bean, event, methodName, args) so they could be configured through an application context and also make it implement ApplicationContextAware interface, so the ApplicationContext would be provided to it by the BeanFactory ? Regards, Dmitriy. -----Original Message----- From: Ivan Ristic To: spr...@li... Sent: 10/9/2003 4:39 PM Subject: [Springframework-developer] Scheduler update After spending some time trying to create a light interface to Quartz I gave up and wrote a new scheduler package, as I had originally planned. That was several weeks ago. The project I am working on at the moment finishes in two weeks, and I expect to finish this package immediately after that. I would appreciate if anyone would care to look and comment: http://www.ivanristic.com/chronos/ It is very light and supports most of the requirements I sent in an email earlier. It contains two scheduler implementations: DefaultScheduler - non-persistent tasks executed at a regular rate (+ start date, end date, repeat count) CronScheduler - persistent cronlike tasks (but since it inherits from the DefaultScheduler it supports non-persistent tasks too). Schedulers accept Runnable instances and execute them. Wrappers are used to achieve other execution methods such as object method call, class method call, Spring event fired, Spring bean method call, etc. A typical usage would look like this: CronScheduler scheduler = new CronScheduler(); scheduler.start(); scheduler.createTask("*/2 * * * * bsh.Interpreter.source test.bsh"); Schedule schedule = new RecurringSchedule(); schedule.setRate(10000); schedule.setRepeatCount(7); scheduler.createTask(new SomeJob(), schedule); Comments related to Spring integration are especially welcome. I've done most of the work. What remains to be done is: final debugging, tests, and implementation of several helper classes in a subpackage to use other means of execution (native, HTTP, probably only ones that can be done without introducing library dependencies). I am also considering creating a MBean (more likely as my app will be JMX based) and an EJB interface (less likely). -- ModSecurity (http://www.modsecurity.org) [ Open source IDS for Web applications ] ------------------------------------------------------- This SF.net email is sponsored by: SF.net Giveback Program. SourceForge.net hosts over 70,000 Open Source Projects. See the people who have HELPED US provide better services: Click here: http://sourceforge.net/supporters.php _______________________________________________ Springframework-developer mailing list Spr...@li... https://lists.sourceforge.net/lists/listinfo/springframework-developer |
|
From: Ivan R. <iv...@we...> - 2003-10-09 20:40:18
|
After spending some time trying to create a light interface to Quartz I gave up and wrote a new scheduler package, as I had originally planned. That was several weeks ago. The project I am working on at the moment finishes in two weeks, and I expect to finish this package immediately after that. I would appreciate if anyone would care to look and comment: http://www.ivanristic.com/chronos/ It is very light and supports most of the requirements I sent in an email earlier. It contains two scheduler implementations: DefaultScheduler - non-persistent tasks executed at a regular rate (+ start date, end date, repeat count) CronScheduler - persistent cronlike tasks (but since it inherits from the DefaultScheduler it supports non-persistent tasks too). Schedulers accept Runnable instances and execute them. Wrappers are used to achieve other execution methods such as object method call, class method call, Spring event fired, Spring bean method call, etc. A typical usage would look like this: CronScheduler scheduler = new CronScheduler(); scheduler.start(); scheduler.createTask("*/2 * * * * bsh.Interpreter.source test.bsh"); Schedule schedule = new RecurringSchedule(); schedule.setRate(10000); schedule.setRepeatCount(7); scheduler.createTask(new SomeJob(), schedule); Comments related to Spring integration are especially welcome. I've done most of the work. What remains to be done is: final debugging, tests, and implementation of several helper classes in a subpackage to use other means of execution (native, HTTP, probably only ones that can be done without introducing library dependencies). I am also considering creating a MBean (more likely as my app will be JMX based) and an EJB interface (less likely). -- ModSecurity (http://www.modsecurity.org) [ Open source IDS for Web applications ] |
|
From: Colin S. <col...@ex...> - 2003-10-09 20:35:55
|
SF anon servers have been hosed to various degress for the last 2-3 months, pending a hardware upgrade. As per my message below, try using the alternate server they have, which should be fine (I just verified this morning) >>>>> It's a little known fact that Sourceforge has an alternate CVS server setup for people to access when they are behind a firewall, as described here: http://sourceforge.net/docman/display_doc.php?docid=14033&group_id=1#firewall Try hitting that address instead. While they say it redirects to cvs.sourceforge.net, it seems to redirect to the committer's cvs server, not the 24 hour delayed anon cvs server. Anon access via this address is t anon access is _way_ faster, and there is no time delay. In any case, according to the last SF update, they are almost done their switchover to new hardware... Regards, Colin >>>>> Justinus Menzel wrote: > Hi, > is it just me or is there something wrong with anonymous CVS access to > sourceforge.net? > following the instructions on http://sourceforge.net/cvs/?group_id=73357: > > cvs -d:pserver:ano...@cv...:/cvsroot/springframework > login > > I get: > Logging in to > :pserver:ano...@cv...:2401/cvsroot/springframework > CVS password: <enter> > cvs [login aborted]: unrecognized auth response from > cvs.sourceforge.net: M PserverBackend::PserverBackend() Connect > (Connection refused) > > cvs update in a directory that I checked out earlier, maybe four weeks > ago leads to the same error. > > Any ideas? > > Thanks > > Justinus > > > > ------------------------------------------------------- > This SF.net email is sponsored by: SF.net Giveback Program. > SourceForge.net hosts over 70,000 Open Source Projects. > See the people who have HELPED US provide better services: > Click here: http://sourceforge.net/supporters.php > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer |
|
From: Justinus M. <jus...@lb...> - 2003-10-09 20:10:04
|
Hi, is it just me or is there something wrong with anonymous CVS access to sourceforge.net? following the instructions on http://sourceforge.net/cvs/?group_id=73357: cvs -d:pserver:ano...@cv...:/cvsroot/springframework login I get: Logging in to :pserver:ano...@cv...:2401/cvsroot/springframework CVS password: <enter> cvs [login aborted]: unrecognized auth response from cvs.sourceforge.net: M PserverBackend::PserverBackend() Connect (Connection refused) cvs update in a directory that I checked out earlier, maybe four weeks ago leads to the same error. Any ideas? Thanks Justinus |
|
From: Colin S. <col...@ex...> - 2003-10-09 17:53:58
|
I would like to change the Eclipse project's target output directories to match the ant build script (.classes and .testclasses). Right now all compiled classes output go to the default Eclipse value of /bin. I can't think of any good reason to leave it that way, but I thought I'd ask before making the change. Additionally, I think it would be more standard (closer to how the majority of ant projects do it (of course there are a lot of variations) and closer to how Maven does it), to put all artifacts produced by the build in directories starting under a common target dir, named something like 'target' or 'build'. I don't know how other people feel about this (at the end of the day it's a trivial item compared to the contents of the library itself), but I always like consistency, all things being equal... Regards, Colin |
|
From: <jue...@we...> - 2003-10-09 17:18:26
|
Matthew, Mike,
Hmmm, I'm not always too keen in terms of perception... anyway: Hi =
Matthew, I don't think I can to tell you anything about Conductor that =
you wouldn't already know ;-)
In terms of effort, I expect my XWork proposal to be pretty =
straightforward to implement: It's basically just about introducing the =
"external-ref" tag and an "ExternalReferenceResolver" interface that the =
tag delegates to. A Spring implementation of that interface should be =
easy to do too: Load the application context in some init method, and =
resolve the references as bean names in the context.
The only issue is where to load the application context from: If this =
should be possible from the WEB-INF directory, we would need a reference =
to the ServletContext in the SpringReferenceResolver implementation. =
Else, we could use ClassPathXmlApplicationContext to load the XML file =
from the class path: This would not involve anything special at all.
So in fact, the interface would need an init method:
public interface ExternalReferenceResolver {
void init();
Object resolveReference(String name);
}
A Spring implementation could look as follows:
public class SpringReferenceResolver implements =
ExternalReferenceResolver {
private ApplicationContext applicationContext;
public void init() {
applicationContext =3D new =
ClassPathXmlApplicationContext("/spring-context.xml");
}
public Object resolveReference(String name) {
return applicationContext.getBean(name);
}
}
It doesn't need to be more complicated than this. We would just need to =
introduce such external reference hooks in XWork. I do not consider an =
"external-ref" tag as much extra XML; and it's easy to specify =
references to specific bean instances with it. What do you think?
Juergen
-----Original Message-----
From: j=FCrgen h=F6ller [werk3AT]=20
Sent: Thursday, October 09, 2003 6:33 PM
To: Matthew E. Porter
Cc: spr...@li...;
spr...@li...
Subject: [Springframework-developer] RE: [Springframework-user]
Introduction and Hibernate-Spring queries
Not yet. Maybe Mike can comment on a timeframe, although Jason might be =
the one that actually works on it. Note that this plan is not fixed at =
all; currently, XWork has its own enable-interface-centric simple IoC =
support. I'm just "consulting" on this issue; Mike, Jason, and the other =
XWork guys will have to decide on what to adopt in the end.
Juergen
-----Original Message-----
From: Matthew E. Porter [mailto:ma...@me...]
Sent: Thursday, October 09, 2003 6:31 PM
To: j=FCrgen h=F6ller [werk3AT]
Cc: spr...@li...;
spr...@li...
Subject: Re: [Springframework-user] Introduction and Hibernate-Spring
queries
Has any work (i.e. code) been done on this?
Cheers,
matthew
On Thursday, October 9, 2003, at 11:15 AM, j=FCrgen h=F6ller [werk3AT]=20
wrote:
> Matthew, everybody,
>
> My XWork/Spring integration proposal is no secret -- here it is, cut=20
> from a recent mail to Jason and Mike. We've been discussing IoC=20
> options for XWork/Conductor for quite a while, mainly in terms of=20
> PicoContainer vs Spring.
>
> <quote>
>
> As far as I see, the XWork config file supports setting bean=20
> properties as parameters on actions like this:
>
> <action name=3D"Bar" class=3D"com.opensymphony.xwork.SimpleAction">
> <param name=3D"foo">17</param>
> <param name=3D"bar">23</param>
> </action>
>
> This is obviously pretty similar to a Spring bean definition, just=20
> specific for a WebWork action. A significant difference is that the=20
> Spring property tag can tag either a value tag or a ref tag within,=20
> i.e. either specify a parameter value or a=B4dependency on another =
bean.
>
> Currently, I see the easiest way of accessing a Spring context from=20
> XWork via a tag that resolves an external component reference, a la:
>
> <action name=3D"Bar" class=3D"com.opensymphony.xwork.SimpleAction">
> <param name=3D"foo">17</param>
> <external-ref name=3D"bar">myDataSource</external-ref>
> </action>
>
> XWork could fetch the Spring context then, look up the bean named=20
> "myDataSource", and set the reference into the "bar" bean property of=20
> the "Bar" action. This would be intuitive, as it works analogously to=20
> setting a parameter value, and flexible, as it allows to reference any =
> specific instance. Effectively, you would be accessing beans in a=20
> Spring middle tier context rather than letting Spring touch your=20
> action instances - but that's not a disadvantage, rather a clean=20
> separation of responsibilities.
>
> Of course, the Spring support for such external references can be=20
> pluggable in XWork, potentially replacing the current ComponentManager =
> mechanism with its enabler interfaces. Any such resolver for external=20
> references would simply need to return an object for the given=20
> symbolic name. The interface could look like this:
>
> public interface ExternalReferenceResolver {
> Object resolveReference(String name);
> }
>
> A Spring implementation would grab a reference to the Spring=20
> application context and call getBean with the given name. The=20
> application context itself could get initialized on XWork startup,=20
> initializing its singletons upfront. I consider such an XWork/Spring=20
> integration as pretty simple but very powerful: no enabler interfaces, =
> just bean properties with component types, and an external-ref tag in=20
> addition to the param tag.
>
> </quote>
>
> Juergen
>
>
> -----Original Message-----
> From: Matthew E. Porter [mailto:ma...@me...]
> Sent: Thursday, October 09, 2003 4:16 PM
> To: j=FCrgen h=F6ller [werk3AT]
> Subject: Re: [Springframework-user] Introduction and Hibernate-Spring
> queries
>
>
>>
>> Throwing in Spring as middle tier glue is a good idea, of course :-)
>> Have you already thought about my proposal regarding XWork/Spring
>> integration from some days ago? Finally, we're of course open for any
>> suggestions and enhancement requests on the Spring side of things!
>>
>
> I this proposal in the public space. I would also like to see
> XW/WW2-Spring integration in the near term future.
>
>
> Cheers,
> matthew
>
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: <jue...@we...> - 2003-10-09 16:35:24
|
Not yet. Maybe Mike can comment on a timeframe, although Jason might be =
the one that actually works on it. Note that this plan is not fixed at =
all; currently, XWork has its own enable-interface-centric simple IoC =
support. I'm just "consulting" on this issue; Mike, Jason, and the other =
XWork guys will have to decide on what to adopt in the end.
Juergen
-----Original Message-----
From: Matthew E. Porter [mailto:ma...@me...]
Sent: Thursday, October 09, 2003 6:31 PM
To: j=FCrgen h=F6ller [werk3AT]
Cc: spr...@li...;
spr...@li...
Subject: Re: [Springframework-user] Introduction and Hibernate-Spring
queries
Has any work (i.e. code) been done on this?
Cheers,
matthew
On Thursday, October 9, 2003, at 11:15 AM, j=FCrgen h=F6ller [werk3AT]=20
wrote:
> Matthew, everybody,
>
> My XWork/Spring integration proposal is no secret -- here it is, cut=20
> from a recent mail to Jason and Mike. We've been discussing IoC=20
> options for XWork/Conductor for quite a while, mainly in terms of=20
> PicoContainer vs Spring.
>
> <quote>
>
> As far as I see, the XWork config file supports setting bean=20
> properties as parameters on actions like this:
>
> <action name=3D"Bar" class=3D"com.opensymphony.xwork.SimpleAction">
> <param name=3D"foo">17</param>
> <param name=3D"bar">23</param>
> </action>
>
> This is obviously pretty similar to a Spring bean definition, just=20
> specific for a WebWork action. A significant difference is that the=20
> Spring property tag can tag either a value tag or a ref tag within,=20
> i.e. either specify a parameter value or a=B4dependency on another =
bean.
>
> Currently, I see the easiest way of accessing a Spring context from=20
> XWork via a tag that resolves an external component reference, a la:
>
> <action name=3D"Bar" class=3D"com.opensymphony.xwork.SimpleAction">
> <param name=3D"foo">17</param>
> <external-ref name=3D"bar">myDataSource</external-ref>
> </action>
>
> XWork could fetch the Spring context then, look up the bean named=20
> "myDataSource", and set the reference into the "bar" bean property of=20
> the "Bar" action. This would be intuitive, as it works analogously to=20
> setting a parameter value, and flexible, as it allows to reference any =
> specific instance. Effectively, you would be accessing beans in a=20
> Spring middle tier context rather than letting Spring touch your=20
> action instances - but that's not a disadvantage, rather a clean=20
> separation of responsibilities.
>
> Of course, the Spring support for such external references can be=20
> pluggable in XWork, potentially replacing the current ComponentManager =
> mechanism with its enabler interfaces. Any such resolver for external=20
> references would simply need to return an object for the given=20
> symbolic name. The interface could look like this:
>
> public interface ExternalReferenceResolver {
> Object resolveReference(String name);
> }
>
> A Spring implementation would grab a reference to the Spring=20
> application context and call getBean with the given name. The=20
> application context itself could get initialized on XWork startup,=20
> initializing its singletons upfront. I consider such an XWork/Spring=20
> integration as pretty simple but very powerful: no enabler interfaces, =
> just bean properties with component types, and an external-ref tag in=20
> addition to the param tag.
>
> </quote>
>
> Juergen
>
>
> -----Original Message-----
> From: Matthew E. Porter [mailto:ma...@me...]
> Sent: Thursday, October 09, 2003 4:16 PM
> To: j=FCrgen h=F6ller [werk3AT]
> Subject: Re: [Springframework-user] Introduction and Hibernate-Spring
> queries
>
>
>>
>> Throwing in Spring as middle tier glue is a good idea, of course :-)
>> Have you already thought about my proposal regarding XWork/Spring
>> integration from some days ago? Finally, we're of course open for any
>> suggestions and enhancement requests on the Spring side of things!
>>
>
> I this proposal in the public space. I would also like to see
> XW/WW2-Spring integration in the near term future.
>
>
> Cheers,
> matthew
>
|
|
From: <jue...@we...> - 2003-10-09 16:17:19
|
Matthew, everybody,
My XWork/Spring integration proposal is no secret -- here it is, cut =
from a recent mail to Jason and Mike. We've been discussing IoC options =
for XWork/Conductor for quite a while, mainly in terms of PicoContainer =
vs Spring.
<quote>
As far as I see, the XWork config file supports setting bean properties =
as parameters on actions like this:
<action name=3D"Bar" class=3D"com.opensymphony.xwork.SimpleAction">
<param name=3D"foo">17</param>
<param name=3D"bar">23</param>
</action>
This is obviously pretty similar to a Spring bean definition, just =
specific for a WebWork action. A significant difference is that the =
Spring property tag can tag either a value tag or a ref tag within, i.e. =
either specify a parameter value or a=B4dependency on another bean.
Currently, I see the easiest way of accessing a Spring context from =
XWork via a tag that resolves an external component reference, a la:
<action name=3D"Bar" class=3D"com.opensymphony.xwork.SimpleAction">
<param name=3D"foo">17</param>
<external-ref name=3D"bar">myDataSource</external-ref>
</action>
XWork could fetch the Spring context then, look up the bean named =
"myDataSource", and set the reference into the "bar" bean property of =
the "Bar" action. This would be intuitive, as it works analogously to =
setting a parameter value, and flexible, as it allows to reference any =
specific instance. Effectively, you would be accessing beans in a Spring =
middle tier context rather than letting Spring touch your action =
instances - but that's not a disadvantage, rather a clean separation of =
responsibilities.
Of course, the Spring support for such external references can be =
pluggable in XWork, potentially replacing the current ComponentManager =
mechanism with its enabler interfaces. Any such resolver for external =
references would simply need to return an object for the given symbolic =
name. The interface could look like this:
public interface ExternalReferenceResolver {
Object resolveReference(String name);
}
A Spring implementation would grab a reference to the Spring application =
context and call getBean with the given name. The application context =
itself could get initialized on XWork startup, initializing its =
singletons upfront. I consider such an XWork/Spring integration as =
pretty simple but very powerful: no enabler interfaces, just bean =
properties with component types, and an external-ref tag in addition to =
the param tag.
</quote>
Juergen
-----Original Message-----
From: Matthew E. Porter [mailto:ma...@me...]
Sent: Thursday, October 09, 2003 4:16 PM
To: j=FCrgen h=F6ller [werk3AT]
Subject: Re: [Springframework-user] Introduction and Hibernate-Spring
queries
>
> Throwing in Spring as middle tier glue is a good idea, of course :-)=20
> Have you already thought about my proposal regarding XWork/Spring=20
> integration from some days ago? Finally, we're of course open for any=20
> suggestions and enhancement requests on the Spring side of things!
>
I this proposal in the public space. I would also like to see=20
XW/WW2-Spring integration in the near term future.
Cheers,
matthew
|
|
From: Darren D. <da...@da...> - 2003-10-08 18:51:45
|
On Wednesday 08 October 2003 18:10, Kopylenko, Dmitry wrote: > Darren, > > AbstractBeanFactory.managedListToArray() tries to convert a List into > Object[]. I would guess, since "types" property is int[], that's where it's > getting ClassCastException. Am I correct? Anyone? I'm pretty sure that's why the exception occurs. As noted in the xml comment in the original post, the list of parameters (in my example, there's only one) needs somehow to be handled as an int[] since that's what the setTypes() method takes in the bean's interface. The question really was, is it therefore not possible because of the API for RdbmsOperation, or can it be acheived some other way? (Apart from creating them in code of course which is what I'm doing now, but which is inconsistent since I can declare them in an app context if they don't take bind parameters). Would a setTypes(Integer[]) method in RdbmsOperation work that simply unwraps the values and delegates to setTypes(int[]) ? Sorry for not being clearer originally! Cheers, -- Darren Davison Public Key: http://www.davison.uk.net/key.jsp |
|
From: <jue...@we...> - 2003-10-08 17:31:58
|
SGkgVHJldm9yLCBldmVyeWJvZHksDQoNCkkndmUgY29tbWl0dGVkIGEgc2VyaW91cyByZXZpc2lv biBvZiBvdXIgbXVsdGlwYXJ0IHN1cHBvcnQgdG9kYXksIGJvdGggaW4gdGVybXMgb2YgQVBJIGFu ZCBpbXBsZW1lbnRhdGlvbi4gSXQgbm93IHJlc2lkZXMgaW4gb3JnLnNwcmluZ2ZyYW1ld29yay53 ZWIubXVsdGlwYXJ0IGluc3RlYWQgb2Ygd2ViLnNlcnZsZXQubXVsdGlwYXJ0LCB0byByZWZsZWN0 IGl0cyBtb3JlIGdlbmVyaWMgbmF0dXJlOiBJdCdzIG5vdCBib3VuZCB0byBEaXNwYXRjaGVyU2Vy dmxldCBpdCBhbnkgd2F5OyB0aGUgbGF0dGVyIGp1c3QgaGFzIHN1cHBvcnQgdG8gZGV0ZWN0IGEg Im11bHRpcGFydFJlc29sdmVyIiBiZWFuIGFuZCBhdXRvbWF0aWNhbGx5IGFwcGx5IGl0Lg0KDQpP dXIgbXVsdGlwYXJ0IGluZnJhc3RydWN0dXJlIGNhbiBhbHNvIGJlIHVzZWQgcHJvZ3JhbW1hdGlj YWxseSwgYnkgZGlyZWN0IE11bHRpcGFydFJlc29sdmVyIGNhbGxzLCBvciB2aWEgdGhlIG5ldyBN dWx0aXBhcnRGaWx0ZXI6IFRoZSBmaWx0ZXIgZGV0ZWN0cyB0aGUgcmVzb2x2ZXIgaW4gYSByb290 IHdlYiBhcHBsaWNhdGlvbiBjb250ZXh0IGFuZCBhcHBsaWVzIGl0OyBpdCBjYW4gYWxzbyBiZSBv dmVycmlkZGVuIHRvIHVzZSBhIGN1c3RvbSBNdWx0aXBhcnRSZXNvbHZlciBpbnN0YW5jZSBjb21w bGV0ZWx5IHdpdGhvdXQgYSBTcHJpbmcgYXBwbGljYXRpb24gY29udGV4dC4gVGhlIGZpbHRlciBp cyBtYWlubHkgaW50ZW5kZWQgZm9yIGFwcGxpY2F0aW9ucyB0aGF0IGRvIG5vdCB1c2UgU3ByaW5n J3Mgd2ViIE1WQywgZS5nLiBpbiB0aGUgY2FzZSBvZiBjdXN0b20gd2ViIHZpZXdzIG9yIFN0cnV0 cyBhY3Rpb25zLg0KDQpJJ3ZlIGFsc28gaW50cm9kdWNlZCBhIENPUyBpbXBsZW1lbnRhdGlvbiBv ZiBNdWx0aXBhcnRSZXNvbHZlciwgYW5kIGFkZGVkIGEgZnVsbC1ibG93biB0ZXN0IHN1aXRlIGZv ciBDb21tb25zTXVsdGlwYXJ0UmVzb2x2ZXIuIFVuZm9ydHVuYXRlbHksIENPUyBpcyBoYXJkIHRv IG1vY2s7IHRoZXJlZm9yZSwgdGhlIENvc011bHRpcGFydFJlc29sdmVyIHRlc3Qgc3VpdGUgaXMg c3RpbGwgcmF0aGVyIGxpbWl0ZWQuDQoNCkZ1cnRoZXJtb3JlLCBJJ3ZlIGRyb3BwZWQgdGhlIHBy ZXZpb3VzIFByb3BlcnR5RWRpdG9ycyBzdXBwb3J0LCBhbmQgdGhlIGFzc29jaWF0ZWQgcmVxdWly ZW1lbnQgZm9yIGZpbGUgcGFyYW1ldGVycyBoYXZpbmcgdG8gYmUgYXZhaWxhYmxlIGFzIG5vcm1h bCBwYXJhbWV0ZXJzIHdpdGggdGhlIGZpZWxkIG5hbWUgYXMgdmFsdWUuIFRoYXQgc2VlbWVkIGxp a2UgYSB3b3JrYXJvdW5kOyBpbnN0ZWFkLCBJJ3ZlIGFkZGVkIGV4cGxpY2l0IGRldGVjdGlvbiB0 byBTZXJ2bGV0UmVxdWVzdERhdGFCaW5kZXIsIHdoaWNoIGlzIG5vdyBhYmxlIHRvIGJpbmQgZmls ZSBwYXJhbWV0ZXJzIGFzIE11bHRpcGFydEZpbGUgb3IgYnl0ZVtdLCBkZXBlbmRpbmcgb24gdGhl IHR5cGUgb2YgdGhlIHRhcmdldCBiZWFuIHByb3BlcnR5LiBJJ3ZlIG5vdCByZWludHJvZHVjZWQg YmluZGluZyB0aGUgb3JpZ2luYWwgZmlsZSBuYW1lIHRvIGEgU3RyaW5nIHByb3BlcnR5LCBhcyBJ IGNhbid0IHNlZSB0aGUgdmFsdWUgb2YgdGhhdCBmZWF0dXJlLg0KDQpJIGhvcGUgZXZlcnlib2R5 J3MgaGFwcHkgd2l0aCB0aGUgY3VycmVudCBzdGF0ZS4gUGxlYXNlIGdpdmUgaXQgYSB0cnk6IEl0 J3MgcHJldHR5IHNpbXBsZSB0byBzZXR1cCwganVzdCBwdXQNCg0KICA8YmVhbiBpZD0ibXVsdGlw YXJ0UmVzb2x2ZXIiIGNsYXNzPSJvcmcuc3ByaW5nZnJhbWV3b3JrLndlYi5tdWx0aXBhcnQuY29t bW9ucy5Db21tb25zTXVsdGlwYXJ0UmVzb2x2ZXIiLz4NCg0Kb3INCg0KICA8YmVhbiBpZD0ibXVs dGlwYXJ0UmVzb2x2ZXIiIGNsYXNzPSJvcmcuc3ByaW5nZnJhbWV3b3JrLndlYi5tdWx0aXBhcnQu Y29zLkNvc011bHRpcGFydFJlc29sdmVyIi8+DQoNCmluIHlvdXIgRGlzcGF0Y2hlclNlcnZsZXQg YXBwbGljYXRpb24gY29udGV4dHMsIGFuZCBkcm9wIHRoZSBDb21tb25zIEZpbGVVcGxvYWQgb3Ig Q09TIGphcnMgaW4geW91ciBXRUItSU5GL2xpYi4gVGhlbiBjYXN0IHRoZSByZXF1ZXN0IHRvIE11 bHRpcGFydEh0dHBTZXJ2bGV0UmVxdWVzdCBpbiB5b3VyIGNvbnRyb2xsZXIocyksIGNoZWNraW5n IGZvciB1cGxvYWRlZCBmaWxlcy4gQW4gdXBsb2FkIGNvbnRyb2xsZXIgY2FuIGJlIGRyaXZlbiB3 aXRoIGFuIEhUTUwgZm9ybSBhcyBzaW1wbGUgYXM6DQoNCiAgPGZvcm0gYWN0aW9uPSIvdGVzdC91 cGxvYWQiIG1ldGhvZD0icG9zdCIgZW5jdHlwZT0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSI+DQogICAg PGlucHV0IG5hbWU9Im15ZmlsZSIgdHlwZT0iZmlsZSI+DQogICAgPGlucHV0IHR5cGU9InN1Ym1p dCI+DQogIDwvZm9ybT4NCg0KUmVnYXJkcywNCkp1ZXJnZW4NCg0KDQoNCi0tLS0tT3JpZ2luYWwg TWVzc2FnZS0tLS0tDQpGcm9tOiBUcmV2b3IgQ29vayBbbWFpbHRvOnByaXNlMDNAc2VudGV4Lm5l dF0NClNlbnQ6IFN1bmRheSwgU2VwdGVtYmVyIDI4LCAyMDAzIDQ6NDAgUE0NClRvOiBqw7xyZ2Vu IGjDtmxsZXIgW3dlcmszQVRdOyBTcHJpbmcgRGV2ZWxvcGVycw0KU3ViamVjdDogUkU6IFtTcHJp bmdmcmFtZXdvcmstZGV2ZWxvcGVyXSBNdWx0aXBhcnQgRmlsZSBIYW5kbGluZw0KDQoNCkp1ZXJn ZW4gLSBHbGFkIHRoYXQgeW91J2xsIGxvb2sgYXQgaXQuICBCYXNlZCBvbiB0aGUgcHJldmlvdXMg ZW1haWxzIHlvdSBzZWVtIHRvIGhhdmUgYSBwcmV0dHkgZ29vZCBoYW5kbGUgb24gdGhpcywgYW5k IG15IGlkZWFzIGFyZSBmYWlybHkgY2xvc2UgdG8geW91cnMuICBBcmUgeW91IGJhY2sgZnJvbSB2 YWNhdGlvbiBub3csIG9yIHN0aWxsIGNoZWNraW5nIHJlbW90ZWx5Pw0KDQpBcyBmYXIgYXMgdGhl IGZpbHRlciBnb2VzLCB0aGF0IGlzIGRlZmluYXRlbHkgYSBwb3NzaWJsaXR5IHRvIGFkZCBsYXRl ciAocG9zc2libHkgZXZlbiBmb3IgMS4wKSBidXQgbm90IHNvbWV0aGluZyBJJ2xsIGJlIGFibGUg dG8gbG9vayBhdCByaWdodCBhd2F5LiAgSG93ZXZlciwgaXQgY291bGQgdXNlIHRoZSBzYW1lIGNv ZGUsIHNvIGl0IHNob3VsZG4ndCBiZSB0b28gZGlmZmljdWx0Lg0KDQpUcmV2b3INCg0KDQotLS0t LU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KRnJvbTogasO8cmdlbiBow7ZsbGVyIFt3ZXJrM0FUXSBb bWFpbHRvOmp1ZXJnZW4uaG9lbGxlckB3ZXJrM2F0LmNvbV0NClNlbnQ6IFNlcHRlbWJlciAyOCwg MjAwMyA2OjMzIEFNDQpUbzogVHJldm9yIENvb2s7IFNwcmluZyBEZXZlbG9wZXJzDQpTdWJqZWN0 OiBSZTogW1NwcmluZ2ZyYW1ld29yay1kZXZlbG9wZXJdIE11bHRpcGFydCBGaWxlIEhhbmRsaW5n DQoNCg0KSGkgVHJldm9yLA0KIA0KQSBNdWx0aXBhcnRSZXNvbHZlciBpbnRlcmZhY2Ugd2l0aCBp bXBsZW1lbnRhdGlvbnMgZm9yIENvbW1vbnMgRmlsZVVwbG9hZCBhbmQgQ09TIGlzIGZpbmUgd2l0 aCBtZSAtIGl0IGp1c3QgaGFkbid0IGhpZ2ggcHJpb3JpdHkgc2luY2UgSSBwcm9wb3NlZCBpdCBo YWxmIGEgeWVhciBhZ28uIEFzIEkgc3RpbGwgaGF2ZSBhIHByZXR0eSBjbGVhciBwaWN0dXJlIG9m IHRoZSBpc3N1ZXMsIEknbGwgYmUgaGFwcHkgdG8gcmV2aWV3IHlvdXIgY29kZSBvbmNlIHlvdSd2 ZSBjaGVja2VkIGl0IGluLiBBcyB0aGlzIHNob3VsZCBiZSBwcmV0dHkgc3RyYWlnaHRmb3J3YXJk LCBsZXQncyB0cnkgdG8gaW5jbHVkZSB0aGlzIGFscmVhZHkgaW4gMS4wIE0yIC0gYXQgbGVhc3Qg d2l0aCBhIENvbW1vbnMgRmlsZVVwbG9hZCBpbXBsZW1lbnRhdGlvbi4NCiANCkJUVywgaW4gY29u dHJhc3QgdG8gQ09TLCBDb21tb25zIEZpbGVVcGxvYWQgZG9lc24ndCBwcm92aWRlIGEgU2Vydmxl dCAyLjMgZmlsdGVyIGFueXdheS4gVGhpcyBtZWFucyB0aGF0IHRoZXJlIHdvdWxkIGJlIHNvbWUg aW5mcmFzdHJ1Y3R1cmUgY29kZSB0byB3cml0ZSBmb3IgdGhhdCB1c2UgY2FzZSB0b28sIGV2ZW4g d2hlbiB1c2luZyBzdGFuZGFyZCBmaWx0ZXJzLiBBIHNpbXBsZSBidXQgY29udmVuaWVudCBTcHJp bmcgc29sdXRpb24gd291bGQgZGVmaW5pdGVseSBiZSBhIGdvb2QgdGhpbmcuDQogDQpKdWVyZ2Vu DQogDQogDQogDQoNCgktLS0tLVVyc3BybmdsaWNoZSBOYWNocmljaHQtLS0tLSANCglWb246IFRy ZXZvciBDb29rIFttYWlsdG86cHJpc2UwM0BzZW50ZXgubmV0XSANCglHZXNlbmRldDogU2EgMjcu MDkuMjAwMyAxOTozNSANCglBbjogU3ByaW5nIERldmVsb3BlcnMgDQoJQ2M6IA0KCUJldHJlZmY6 IFtbVzMtU1BBTV1dIC0gW1NwcmluZ2ZyYW1ld29yay1kZXZlbG9wZXJdIE11bHRpcGFydCBGaWxl IEhhbmRsaW5nIC0gRW1haWwgZm91bmQgaW4gc3ViamVjdA0KCQ0KCQ0KDQoJRmlyc3Qgc29tZSBo aXN0b3J5Og0KCWh0dHA6Ly9zb3VyY2Vmb3JnZS5uZXQvbWFpbGFyY2hpdmUvbWVzc2FnZS5waHA/ bXNnX2lkPTM4OTEyNzkNCglodHRwOi8vc291cmNlZm9yZ2UubmV0L21haWxhcmNoaXZlL21lc3Nh Z2UucGhwP21zZ19pZD01MTc1Mjc2DQoJaHR0cDovL3NvdXJjZWZvcmdlLm5ldC9tYWlsYXJjaGl2 ZS9mb3J1bS5waHA/dGhyZWFkX2lkPTMxMjU1NjEmZm9ydW1faWQ9MzAyOA0KCTcNCglodHRwOi8v c291cmNlZm9yZ2UubmV0L21haWxhcmNoaXZlL21lc3NhZ2UucGhwP21zZ19pZD02MDYyMjg4DQoJ DQoJVG8gYWRkcmVzcyBhIGZldyB0aGluZ3MgSnVlcmdlbiBtZW50aW9uZWQgcHJldmlvdXNseS4N CgkNCgk+PiBhIGxlc3MgaW50cnVzaXZlIHdheSB3b3VsZCBiZSB0byB3cmFwIHRoZSBIdHRwU2Vy dmxldFJlcXVlc3QgdmlhIGEgZmlsdGVyDQoJSSBwZXJzb25hbGx5IGRvbid0IGxpa2UgdGhlIGZp bHRlciBhcHByb2FjaCwgYXQgbGVhc3QgZm9yIHRoZSBmcmFtZXdvcmsuICBJdA0KCXJlcXVpcmVz IGFkZGl0aW9uYWwgc2V0dXAgZm9yIHRoZSB1c2VyIChpbiB0aGUgd2ViLnhtbCBmaWxlKSBhbmQg bWlnaHQgYmUNCglsZXNzIHVuZGVyc3RhbmRhYmxlIHNpbmNlIG91ciBub3JtYWwgc3RyYXRlZ3kg c28gZmFyIGhhcyBiZWVuIHdpdGggcmVzb2x2ZXJzDQoJaW5zaWRlIHRoZSBzZXJ2bGV0Lg0KCQ0K CT4+d2Ugd291bGQgbmVlZCB0byBmaW5kIGNvbmNyZXRlIHJlcXVpcmVtZW50cyBmb3IgdGhpcw0K CVdlIGhhdmUgbnVtZXJvdXMgdXNlcyBmb3IgZmlsZSB1cGxvYWQgaGFuZGxpbmcuICBXZSBoYXZl IGEgcHVibGljIHBob3RvDQoJY29udGVzdCB3aGVyZSB1c2VycyBjYW4gdXBsb2FkIGZvdG9zLiAg V2UgaGF2ZSBzcGVjaWFsIGFjY2VzcyBmb3Igc3VwcGxpZXJzDQoJdG8gdXBsb2FkIHByb2R1Y3Qg ZmlsZXMgKGNzdikgd2hpY2ggd2UgdGhlbiBhZGQgaW4gdG8gb3VyIG9yZGVyaW5nIHN5c3RlbS4N CglGaW5hbGx5LCB3ZSBoYXZlIGEgd2ViIGFkbWluaXN0cmF0aW9uIGludGVyZmFjZSB3aGljaCBh bGxvd3Mgb3VyIGNsaWVudCB0bw0KCXVwbG9hZCBmaWxlcyB0byB0aGUgd2Vic2l0ZSBzbyB0aGV5 IGNhbiBiZSBkb3dubG9hZGVkLiAgSSB0aGluayB0aGF0DQoJaW5jbHVkaW5nIHRoaXMgc3VwcG9y dCAobXVsdGlwYXJ0IGhhbmRsaW5nKSBpcyBhIG5vLWJyYWluZXIuDQoJDQoJQmFzaWNhbGx5LCBJ IGhhdmUgdXNlZCBDT1MgZXhjbHVzaXZlbHkgaW4gb3VyIHByb2plY3RzLCBidXQgSSBkb24ndCB0 aGluaw0KCXRoYXQncyBlYXN5IGZvciBTcHJpbmcgdG8gdXNlIChkdWUgdG8gdGhlIGxpY2Vuc2lu ZykuICBJIHdvdWxkIHNpbXBseSBjb2RlDQoJdGhpcyBhY2NvcmRpbmcgdG8gU3ByaW5nIG5vcm1z IHVzaW5nIGFuIGludGVyZmFjZSBhbmQgYSBkZWZhdWx0IHZlcnNpb24NCgl1c2luZyBDb21tb25z IEZpbGVVcGxvYWQuICBMYXRlciwgaWYgc29tZWJvZHkgd2FudHMgdG8gY3JlYXRlIGEgY29zIHZl cnNpb24NCgl3ZSBjYW4gKGJ1dCB0byBiZSBob25lc3QsIGlmIHdlIGhhdmUgYSB3b3JraW5nLCBp bnRlZ3JhdGVkIHNvbHV0aW9uIEknbSBub3QNCglzdXJlIHRoYXQgaXMgbmVjZXNzYXJ5IC0gYXQg bGVhc3Qgbm90IGluIHRoZSBTcHJpbmcgZnJhbWV3b3JrKS4gIEJhc2ljYWxseSwNCglwcm92aWRl IGhvb2tzIGFuZCBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb24sIGFuZCBhbGxvdyB1c2VycyB0byBh ZG9wdCBhcw0KCW5lY2Vzc2FyeS4NCgkNCglJbiBvdXIgcHJvamVjdCB3ZSBoYWQgbW9kaWZpZWQg dGhlIEFic3RyYWN0Q29udHJvbGxlciBhbmQgcHV0IHRoZSBjb2RlIGludG8NCglpdCB0byBoYW5k bGUgdGhlIG11bHRpcGFydCBwcm9jZXNzaW5nLCByZXR1cm5pbmcgYSB3cmFwcGVkDQoJSHR0cFNl cnZsZXRSZXF1ZXN0IHRocm91Z2ggdGhlIGhhbmRsZXJzLiAgVGhpcyBpcyB2ZXJ5IHNpbWlsaWFy IHRvIEp1ZXJnZW4ncw0KCW91dGxpbmUgKGh0dHA6Ly9zb3VyY2Vmb3JnZS5uZXQvbWFpbGFyY2hp dmUvbWVzc2FnZS5waHA/bXNnX2lkPTM4OTEyNzkpLg0KCQ0KCVNpbmNlIHdlIGFyZSBtaWdyYXRp bmcgdG8gdGhlIGN1cnJlbnQgU3ByaW5nIGNvZGViYXNlLCBJIG5lZWQgdG8gbW92ZSBvdXINCglt dWx0aXBhcnQgaGFuZGxpbmcgY29kZS4gIFRoZSBtYWluIHF1ZXN0aW9uIGlzIHdoZXRoZXIgd2Ug a2VlcCBpdA0KCWludGVybmFsbHksIG9yIHBsYWNlIGl0IGludG8gU3ByaW5nLiAgSSBwcm9wb3Nl IG1vZGlmeWluZw0KCW9yZy5zcHJpbmdmcmFtZXdvcmsud2ViLnNlcnZsZXQuRGlzcGF0Y2hlclNl cnZsZXQgdG8gaGF2ZSBhDQoJIk11bHRpcGFydFJlc29sdmVyIi4gIEluIHRoZSBEaXNwYXRjaGVy U2VydmxldCwgdGhlIHJlc29sdmVyIHdvdWxkIGJlIGNhbGxlZA0KCXRvIHdyYXAgdGhlIHJlcXVl c3QgaW4gZG9TZXJ2aWNlIGltbWVkaWF0ZWx5IGJlZm9yZSBnZXRIYW5kbGVyKHJlcXVlc3QpIC0N CgljdXJyZW50bHkgbGluZSAzNTEsIGFuZCB0aGVuIGNhbGxlZCB0byBkbyBhbnkgY2xlYW51cCBp bW1lZGlhdGVseSBiZWZvcmUNCglleGl0aW5nIHRoZSBkb1NlcnZpY2UgbWV0aG9kLg0KCQ0KCUkg aGF2ZSBhYm91dCAyLzMgb2YgdGhlIGNvZGUgYWxyZWFkeSB3cml0dGVuLCBhbmQgSSB3aWxsIGJl IHdyaXRpbmcgdGhlIHJlc3QNCgliZXR3ZWVuIG5vdyBhbmQgTW9uZGF5LiAgRG9lcyB0aGlzIHN0 cmF0ZWd5IHNvdW5kIGFwcHJvcHJpYXRlIGZvciBTcHJpbmcNCgkobWVhbmluZyBzaG91bGQgSSBj b21taXQgaXQgdG8gdGhlIFNwcmluZyBjb2RlYmFzZSkgd2hlbiBpdCdzIGZpbmlzaGVkPw0KCQ0K CVRyZXZvciBELiBDb29rDQoJSW50ZXJwcmlzZSBTb2Z0d2FyZQ0KCQ0KCQ0KCQ0KCS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCglUaGlzIHNm Lm5ldCBlbWFpbCBpcyBzcG9uc29yZWQgYnk6VGhpbmtHZWVrDQoJV2VsY29tZSB0byBnZWVrIGhl YXZlbi4NCglodHRwOi8vdGhpbmtnZWVrLmNvbS9zZg0KCV9fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fDQoJU3ByaW5nZnJhbWV3b3JrLWRldmVsb3BlciBtYWls aW5nIGxpc3QNCglTcHJpbmdmcmFtZXdvcmstZGV2ZWxvcGVyQGxpc3RzLnNvdXJjZWZvcmdlLm5l dA0KCWh0dHBzOi8vbGlzdHMuc291cmNlZm9yZ2UubmV0L2xpc3RzL2xpc3RpbmZvL3NwcmluZ2Zy YW1ld29yay1kZXZlbG9wZXINCgkNCg0KDQo= |
|
From: Kopylenko, D. <dko...@ac...> - 2003-10-08 17:10:58
|
Darren,
AbstractBeanFactory.managedListToArray() tries to convert a List into
Object[]. I would guess, since "types" property is int[], that's where it's
getting ClassCastException. Am I correct? Anyone?
Regards,
Dmitriy.
-----Original Message-----
From: dar...@hs... [mailto:dar...@hs...]
Sent: Wednesday, October 08, 2003 11:27 AM
To: spr...@li...
Subject: [Springframework-developer] MappingSqlQuery - setTypes in
application context?
hi,
is it possible to declare a bean in an application context whose class is a
subclass of MappingSqlQuery and declare bind params? Something like this:
<bean
id="myMapper"
class="some.subclass.of.MappingSqlQuery">
<property name="sql"><value>SELECT * FROM table WHERE field=?
</value></property>
<!-- 12 is the typecode for VARCHAR and somehow needs to be handled as
an int[] -->
<property name="types"><list><value>12</value></list></property>
<property name="dataSource"><ref bean="myDS"/></property> </bean>
I seem to be having a lot of troube getting the beans instantiated due to
the 'types' property, with the following trace:
java.lang.ClassCastException: java.lang.Object
at
org.springframework.beans.factory.support.AbstractBeanFactory.managedListToA
rray(AbstractBeanFactory.java:452)
at
org.springframework.beans.factory.support.AbstractBeanFactory.resolveValueIf
Necessary(AbstractBeanFactory.java:393)
at
org.springframework.beans.factory.support.AbstractBeanFactory.applyPropertyV
alues(AbstractBeanFactory.java:327)
at
org.springframework.beans.factory.support.AbstractBeanFactory.createBean(Abs
tractBeanFactory.java:303)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getSharedInsta
nce(AbstractBeanFactory.java:232)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBeanInterna
l(AbstractBeanFactory.java:161)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(Abstra
ctBeanFactory.java:139)
...
Am I going about this the wrong way completely?
Cheers,
Darren.
_____________________________________________________
This transmission has been issued by a member of the HSBC Group
"HSBC" for the information of the addressee only and should not be
reproduced and / or distributed to any other person. Each page attached
hereto must be read in conjunction with any disclaimer which forms part
of it. Unless otherwise stated, this transmission is neither an offer nor
the
solicitation of an offer to sell or purchase any investment. Its contents
are
based on information obtained from sources believed to be reliable but HSBC
makes no representation and accepts no responsibility or liability as
to its completeness or accuracy.
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program. SourceForge.net
hosts over 70,000 Open Source Projects. See the people who have HELPED US
provide better services: Click here: http://sourceforge.net/supporters.php
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: <dar...@hs...> - 2003-10-08 15:27:23
|
hi,
is it possible to declare a bean in an application context whose class is a
subclass of MappingSqlQuery and declare bind params? Something like this:
<bean
id="myMapper"
class="some.subclass.of.MappingSqlQuery">
<property name="sql"><value>SELECT * FROM table WHERE field=?
</value></property>
<!-- 12 is the typecode for VARCHAR and somehow needs to be handled as
an int[] -->
<property name="types"><list><value>12</value></list></property>
<property name="dataSource"><ref bean="myDS"/></property>
</bean>
I seem to be having a lot of troube getting the beans instantiated due to
the 'types' property, with the following trace:
java.lang.ClassCastException: java.lang.Object
at
org.springframework.beans.factory.support.AbstractBeanFactory.managedListToArray(AbstractBeanFactory.java:452)
at
org.springframework.beans.factory.support.AbstractBeanFactory.resolveValueIfNecessary(AbstractBeanFactory.java:393)
at
org.springframework.beans.factory.support.AbstractBeanFactory.applyPropertyValues(AbstractBeanFactory.java:327)
at
org.springframework.beans.factory.support.AbstractBeanFactory.createBean(AbstractBeanFactory.java:303)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getSharedInstance(AbstractBeanFactory.java:232)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBeanInternal(AbstractBeanFactory.java:161)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:139)
...
Am I going about this the wrong way completely?
Cheers,
Darren.
_____________________________________________________
This transmission has been issued by a member of the HSBC Group
"HSBC" for the information of the addressee only and should not be
reproduced and / or distributed to any other person. Each page attached
hereto must be read in conjunction with any disclaimer which forms part
of it. Unless otherwise stated, this transmission is neither an offer nor the
solicitation of an offer to sell or purchase any investment. Its contents are
based on information obtained from sources believed to be reliable but
HSBC makes no representation and accepts no responsibility or liability as
to its completeness or accuracy.
|
|
From: <jue...@we...> - 2003-10-07 23:46:30
|
SSd2ZSBqdXN0IGNvbW1pdHRlZCB0aGUgcmV2aXNlZCB2ZXJzaW9uLiBJJ3ZlIHN0aWxsIHJlZmlu ZWQgdGhlIHByb3Bvc2FsIGEgYml0OyBmb3IgZXhhbXBsZSwgdGhlcmUncyBhIEphdmFNYWlsU2Vu ZGVyIGludGVyZmFjZSBub3cgKGV4dGVuZHMgTWFpbFNlbmRlcikgcGx1cyBhIEphdmFNYWlsU2Vu ZGVySW1wbCBpbXBsZW1lbnRhdGlvbi4NCiANCkZ1cnRoZXJtb3JlLCBJJ3ZlIHR1cm5lZCBNYWls RXhjZXB0aW9uIGludG8gYSBjaGVja2VkIGV4Y2VwdGlvbiwgYXMgZmFpbGVkIHNlbmRpbmcgY2Fu IHR5cGljYWxseSBiZSBoYW5kbGVkIGJ5IGFwcGxpY2F0aW9ucywgZS5nLiBhcyAic2VuZCBmYWls ZWQgLSBkbyB5b3Ugd2FudCB0byByZXRyeT8iIG1lc3NhZ2VzLiBUaGlzIG1pZ2h0IGJlIGNvbnRy b3ZlcnNpYWw7IGFueSBzdHJvbmcgb2JqZWN0aW9ucyBhZ2FpbnN0IHRoaXM/DQogDQpJJ3ZlIGFs c28gcmV2aXNlZCB0aGUgdGVzdCBzdWl0ZS4gV2l0aCB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlv biBzdHJhdGVneSwgaXQncyBiZWVuIGVhc3kgdG8gdGVzdCBKYXZhTWFpbFNlbmRlckltcGwgd2l0 aCBhIFRyYW5zcG9ydCBtb2NrIChhcHBsaWVkIGJ5IG92ZXJyaWRpbmcgYSBwcm90ZWN0ZWQgZ2V0 VHJhbnNwb3J0IG1ldGhvZCkuIEkgZ3Vlc3Mgd2Ugd29uJ3QgbmVlZCBmdXJ0aGVyIHRlc3RzIHdp dGggYW4gU01UUCBzZXJ2ZXI7IGFmdGVyIGFsbCwgdGhhdCB3b3VsZCB0ZXN0IEphdmFNYWlsIHJh dGhlciB0aGFuIG91ciB3cmFwcGVyLg0KIA0KSnVlcmdlbg0KIA0KIA0KDQoJLS0tLS1VcnNwcsO8 bmdsaWNoZSBOYWNocmljaHQtLS0tLSANCglWb246IEtvcHlsZW5rbywgRG1pdHJ5IFttYWlsdG86 ZGtvcHlsZW5rb0BhY3MucnV0Z2Vycy5lZHVdIA0KCUdlc2VuZGV0OiBNbyAwNi4xMC4yMDAzIDEz OjUxIA0KCUFuOiBqw7xyZ2VuIGjDtmxsZXIgW3dlcmszQVRdOyAnUm9kIEpvaG5zb24nIA0KCUNj OiAnc3ByaW5nZnJhbWV3b3JrLWRldmVsb3BlckBsaXN0cy5zb3VyY2Vmb3JnZS5uZXQnIA0KCUJl dHJlZmY6IFJFOiBbU3ByaW5nZnJhbWV3b3JrLWRldmVsb3Blcl0gTWFpbCBzdXBwb3J0DQoJDQoJ DQoNCglKdWVyZ2VuLA0KCQ0KCVRoZSBwcm9wb3NlZCBBUEkgbG9va3MgZ29vZCB0byBtZS4NCgkN CglSZWdhcmRzLA0KCURtaXRyaXkuDQoJDQoJLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCglG cm9tOiBqw7xyZ2VuIGjDtmxsZXIgW3dlcmszQVRdIFttYWlsdG86anVlcmdlbi5ob2VsbGVyQHdl cmszYXQuY29tXQ0KCVNlbnQ6IE1vbmRheSwgT2N0b2JlciAwNiwgMjAwMyAyOjQ4IEFNDQoJVG86 IFJvZCBKb2huc29uOyBLb3B5bGVua28sIERtaXRyeQ0KCUNjOiBzcHJpbmdmcmFtZXdvcmstZGV2 ZWxvcGVyQGxpc3RzLnNvdXJjZWZvcmdlLm5ldA0KCVN1YmplY3Q6IFJlOiBbU3ByaW5nZnJhbWV3 b3JrLWRldmVsb3Blcl0gTWFpbCBzdXBwb3J0DQoJDQoJDQoJUm9kLCBEbWl0cml5LA0KCQ0KCUkg YWdyZWUgaW4gdGVybXMgb2YgU3RvcmUgc3VwcG9ydCAtIGxldCdzIGNvbmNlbnRyYXRlIG9uIG1h aWwgc2VuZGluZyBmb3INCglub3cuIEkgYWxzbyB0ZW5kIHRvIGFncmVlIGluIHRlcm1zIG9mIGFi c3RyYWN0aW5nIEphdmFNYWlsIGZvciBzaW1wbGUgZW5vdWdoDQoJbWFpbCBzZW5kaW5nIHJlcXVp cmVtZW50cy4gSSBmb3Jnb3QgdGhhdCBTZXNzaW9uIGlzIGZpbmFsLCBCVFcuIEphdmFNYWlsIGlz DQoJcmVhbGx5IG1lc3N5IC0gQVBJIGRlc2lnbiBzZWVtcyB0byBiZSBhbiBhcnQuLi4gOy0pDQoJ DQoJU28gbGV0IG1lIHN1Z2dlc3QgYSBtZWV0LWluLXRoZS1taWRkbGUgc29sdXRpb246IEFzIEkn dmUgaW5pdGlhbGx5IGludGVuZGVkLA0KCWxldCdzIHNlcGFyYXRlIHRyYW5zcG9ydC1yZWxhdGVk IChob3N0LCB1c2VybmFtZSwgcGFzc3dvcmQpIGFuZA0KCW1lc3NhZ2UtcmVsYXRlZCBwcm9wZXJ0 aWVzLCBpLmUuIGRyb3AgTWFpbFNldHRpbmdzIGluIGl0cyBjdXJyZW50IGZvcm0sIG1vdmUNCgl0 cmFuc3BvcnQgc2V0dGluZ3MgdG8gdGhlIE1haWxTZW5kZXIgaW1wbGVtZW50YXRpb24sIGFuZCBp bnRyb2R1Y2UgYQ0KCVNpbXBsZU1lc3NhZ2UgY2xhc3MuDQoJDQoJQXMgdGhlIGVmZmVjdCBvZiB0 aGUgY3VycmVudCBNYWlsVGVtcGxhdGUvTWFpbENhbGxiYWNrIGNvbWJvIChvdmVycmlkaW5nDQoJ Y2VydGFpbiBwcmUtZGVmaW5lZCBtYWlsIHNldHRpbmdzKSBjYW4gYmUgYWNoaWV2ZWQgd2l0aCB1 c2luZyBhDQoJU2ltcGxlTWVzc2FnZSBjb3B5IGNvbnN0cnVjdG9yLCBJIHN1Z2dlc3QgdG8gZHJv cCBNYWlsVGVtcGxhdGUgYW5kDQoJTWFpbENhbGxiYWNrLiBUaGlzIGxlYXZlcyBTaW1wbGVNZXNz YWdlLCBNYWlsU2VuZGVyLCBhbmQgYSBKYXZhTWFpbFNlbmRlcg0KCWltcGxlbWVudGF0aW9uLg0K CQ0KCVRvIG9mZmVyIG1vcmUgcG93ZXIgZm9yIHRob3NlIHdobyBuZWVkIGl0LCBJIHN1Z2dlc3Qg dG8gb2ZmZXIgYWRkaXRpb25hbA0KCW1ldGhvZHMgaW4gSmF2YU1haWxTZW5kZXIuIFdob2V2ZXIg d2FudHMgdG8gdXNlIHRob3NlIHNob3VsZCBjYXN0IHRvDQoJSmF2YU1haWxTZW5kZXIsIHJlc3Bl Y3RpdmVseSBvZmZlciBhIGJlYW4gcHJvcGVydHkgb2YgdHlwZSBKYXZhTWFpbFNlbmRlciB0bw0K CWJlIHBvcHVsYXRlZCBieSBhIGJlYW4gcmVmZXJlbmNlLiBBbGwgb3RoZXIgYXBwbGljYXRpb24g Y2xhc3NlcyBjYW4gd29yaw0KCXdpdGggdGhlIE1haWxTZW5kZXIgaW50ZXJmYWNlLg0KCQ0KCU1h aWxTZW5kZXIgaW50ZXJmYWNlIHVzZXJzIGFyZSBlYXNpbHkgdGVzdGFibGUgd2l0aCBhIG1vY2sg TWFpbFNlbmRlcg0KCWltcGxlbWVudGF0aW9uLiBJdCB3aWxsIGJlIGEgYml0IGhhcmRlciB3aXRo IEphdmFNYWlsU2VuZGVyIHVzZXJzLCBidXQgc3RpbGwNCglwb3NzaWJsZTogQSBtb2NrIEphdmFN YWlsU2VuZGVyIHN1YmNsYXNzIHRoYXQgb3ZlcnJpZGVzIHNlbmQoTWltZU1lc3NhZ2UpDQoJYW5k IHNlbmQoTWltZU1lc3NhZ2VbXSkgc2hvdWxkIGFsbG93IGZvciBlYXN5IHRlc3RpbmcgdG9vLiBO b3RlIHRoYXQgYQ0KCWNvbm5lY3Rpb24gdG8gdGhlIG1haWwgc2VydmVyIGlzIG9ubHkgcmVxdWly ZWQgZm9yIGFjdHVhbCBtYWlsIHNlbmRpbmcsIG5vdA0KCWZvciBTZXNzaW9uIHNldHVwLg0KCQ0K CXB1YmxpYyBjbGFzcyBTaW1wbGVNZXNzYWdlew0KCSAgcHJpdmF0ZSBTdHJpbmcgZnJvbTsNCgkg IHByaXZhdGUgU3RyaW5nIHRvOw0KCSAgcHJpdmF0ZSBTdHJpbmdbXSBjYzsNCgkgIHByaXZhdGUg U3RyaW5nIHN1YmplY3Q7DQoJICBwcml2YXRlIFN0cmluZyB0ZXh0Ow0KCSANCgkgIHB1YmxpYyBT aW1wbGVNZXNzYWdlKFNpbXBsZU1lc3NhZ2Ugb3JpZ2luYWwpIHsNCgkgICAgLy8gY29weSBjb25z dHJ1Y3Rvcg0KCSAgfQ0KCQ0KCSAgKGdldHRlcnMgYW5kIHNldHRlcnMpDQoJfQ0KCQ0KCXB1Ymxp YyBpbnRlcmZhY2UgTWFpbFNlbmRlciB7DQoJICB2b2lkIHNlbmQoU2ltcGxlTWVzc2FnZSBtZXNz YWdlKTsNCgl9DQoJDQoJcHVibGljIGNsYXNzIEphdmFNYWlsU2VuZGVyIGltcGxlbWVudHMgTWFp bFNlbmRlciwgSW5pdGlhbGl6aW5nQmVhbiB7DQoJICBwcml2YXRlIFN0cmluZyBob3N0Ow0KCSAg cHJpdmF0ZSBTdHJpbmcgdXNlcm5hbWU7DQoJICBwcml2YXRlIFN0cmluZyBwYXNzd29yZDsNCgkN CgkgIChnZXR0ZXJzIGFuZCBzZXR0ZXJzKQ0KCQ0KCSAgcHVibGljIHZvaWQgYWZ0ZXJQcm9wZXJ0 aWVzU2V0KCkgew0KCSAgICAvLyBjcmVhdGUgYW5kIGtlZXAgU2Vzc2lvbiBpbnN0YW5jZQ0KCSAg fQ0KCQ0KCSAgcHVibGljIHZvaWQgc2VuZChTaW1wbGVNZXNzYWdlIG1lc3NhZ2UpIHsNCgkgICAg Ly8gc2VuZCBTaW1wbGVNZXNzYWdlIHZpYSBKYXZhTWFpbA0KCSAgICAvLyBjcmVhdGluZyBhIE1p bWVNZXNzYWdlIGludGVybmFsbHkgYW5kIGRlbGVnYXRpbmcgdG8gc2VuZChNaW1lTWVzc2FnZSkN Cgl9DQoJDQoJICBwdWJsaWMgdm9pZCBzZW5kKE1pbWVNZXNzYWdlIG1lc3NhZ2UpIHsNCgkgICAg Ly8gc2VuZCBKYXZhTWFpbCBNaW1lTWVzc2FnZQ0KCSAgICAvLyB1c2luZyBhIFRyYW5zcG9ydCBp bnN0YW5jZTogY29ubmVjdCwgc2VuZE1lc3NhZ2UsIGRpc2Nvbm5lY3QNCgkgIH0NCgkNCgkgIHB1 YmxpYyB2b2lkIHNlbmQoTWltZU1lc3NhZ2VbXSBtZXNzYWdlcykgew0KCSAgICAvLyBzZW5kIG11 bHRpcGxlIEphdmFNYWlsIE1pbWVNZXNzYWdlcyBpbiBvbmUgYmF0Y2gNCgkgICAgLy8gdXNpbmcg YSBUcmFuc3BvcnQgaW5zdGFuY2U6IGNvbm5lY3QsIG11bHRpcGxlIHNlbmRNZXNzYWdlLCBkaXNj b25uZWN0DQoJICB9DQoJDQoJICBwdWJsaWMgTWltZU1lc3NhZ2UgY3JlYXRlTWltZU1lc3NhZ2Uo KSB7DQoJICAgIC8vIGNyZWF0ZSBKYXZhTWFpbCBNaW1lTWVzc2FnZSBmb3IgdGhlIFNlc3Npb24g b2YgdGhpcyBzZW5kZXINCgkgICAgLy8gbmVjZXNzYXJ5IGJlY2F1c2Ugb2YgTWltZU1lc3NhZ2Uo U2Vzc2lvbikgY29uc3RydWN0b3INCgkgIH0NCgl9DQoJDQoJSSBjb25zaWRlciB0aGlzIHRoZSBi ZXN0IG9mIGJvdGggd29ybGRzLiBBcHBsaWNhdGlvbnMgY2FuIGNob29zZSB0byB1c2UgdGhlDQoJ ZnVsbCBhYnN0cmFjdGlvbiAoTWFpbFNlbmRlcikgZm9yIHNpbXBsZSBwdXJwb3Nlcywgb3IgdXNl IEphdmFNYWlsU2VuZGVyIGZvcg0KCW1vcmUgc29waGlzdGljYXRlZCByZXF1aXJlbWVudHMuIEFz IHRlc3Rpbmcgc3VjaCBhcHBzIGRvZXMgbm90IHJlcXVpcmUNCgltb2NraW5nIEphdmFNYWlsIGl0 c2VsZiBpbiBhbnkgY2FzZSwgd2Ugc2hvdWxkIGhhdmUgcmVhY2hlZCBhbGwgb3VyIGdvYWxzLg0K CQ0KCVdoYXQgZG8geW91IHRoaW5rPyBJZiB3ZSBhZ3JlZSBvbiB0aGUgQVBJIGRlc2lnbiwgSSds bCBiZSBoYXBweSB0byByZXdvcmsNCglvdXIgbWFpbCBzdXBwb3J0IHRoYXQgd2F5IGZvciAxLjAg TTIuDQoJDQoJUmVnYXJkcywNCglKdWVyZ2VuDQoJDQoJDQoJDQoJICAgICAgICAtLS0tLVVyc3By w7xuZ2xpY2hlIE5hY2hyaWNodC0tLS0tDQoJICAgICAgICBWb246IFJvZCBKb2huc29uIFttYWls dG86cm9kLmpvaG5zb25AaW50ZXJmYWNlMjEuY29tXQ0KCSAgICAgICAgR2VzZW5kZXQ6IFNvIDA1 LjEwLjIwMDMgMTE6MzgNCgkgICAgICAgIEFuOiBqw7xyZ2VuIGjDtmxsZXIgW3dlcmszQVRdOyBL b3B5bGVua28sIERtaXRyeQ0KCSAgICAgICAgQ2M6DQoJICAgICAgICBCZXRyZWZmOiBSZTogW1Nw cmluZ2ZyYW1ld29yay1kZXZlbG9wZXJdIE1haWwgc3VwcG9ydA0KCSAgICAgICANCgkgICAgICAg DQoJDQoJICAgICAgICA+IEFmdGVyIGluLWRlcHRoIGNvbnNpZGVyYXRpb24gb2YgdGhlIG1haWwg c2VuZGluZyByZXF1aXJlbWVudHMgaW4NCgl3ZXJrM0FUDQoJICAgICAgICBwcm9kdWN0cyBhbmQg c3R1ZHkgb2YgdGhlIEphdmFNYWlsIHNwZWMsIEknbSBpbmNsaW5lZCB0byBzdWdnZXN0IGENCgkg ICAgICAgIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGtpbmQgb2YgbWFpbCBzdXBwb3J0IHRoYW4g dGhlIGN1cnJlbnQgb25lLg0KCVRoZSBtYWluDQoJICAgICAgICByZWFzb25zIGFyZSBjZXJ0YWlu IGxpbWl0YXRpb25zIG9mIHRoZSBjdXJyZW50IFNwcmluZyBtYWlsIHNlbmRlciwNCglub3QNCgkg ICAgICAgIGFsbG93aW5nIGZvciBxdWl0ZSBhIGxvdCBvZiBKYXZhTWFpbCBmdW5jdGlvbmFsaXR5 Og0KCSAgICAgICAgPg0KCSAgICAgICAgPiAxLiBIb3cgdG8gc2VuZCBibGluZCBjb3BpZXMgKGJj Yyk/DQoJICAgICAgICA+IDIuIEhvdyB0byBzcGVjaWZ5IGEgbmFtZSBmb3Igc2VuZGVyIG9yIHJl Y2lwaWVudCBhZGRyZXNzZXMgKHRvDQoJbWFrZSBtYWlsDQoJICAgICAgICBjbGllbnRzIHNob3cg c29tZXRoaW5nIGxpa2UgIkp1ZXJnZW4gSG9lbGxlciA8amhvQHdlcmszYXQuY29tPiIpPw0KCSAg ICAgICAgPiAzLiBIb3cgdG8gc2V0IGEgY2hhcnNldCBmb3Igc3ViamVjdCBhbmQgdGV4dCAodmVy eSBpbXBvcnRhbnQgZm9yDQoJbG9jYWxpemVkDQoJICAgICAgICBtYWlscyk/DQoJICAgICAgICA+ IDQuIEhvdyB0byBhdXRoZW50aWNhdGUgYWdhaW5zdCB0aGUgU01UUCBzZXJ2ZXIgaWYgbmVjZXNz YXJ5DQoJKHVzZXJuYW1lLA0KCSAgICAgICAgcGFzc3dvcmQpPw0KCSAgICAgICAgPiA1LiBIb3cg dG8gc2VuZCBtdWx0aXBsZSBtZXNzYWdlcyBpbiBiYXRjaCwgd2l0aGluIGEgc2luZ2xlIG1haWwN CglzZXJ2ZXINCgkgICAgICAgIGNvbm5lY3Rpb24/DQoJICAgICAgICA+IDYuIEhvdyB0byBhY2Nl c3MgYSBtYWlsIHN0b3JlLCBpLmUuIGFuIGluYm94IGZvciByZWFkaW5nIG1haWxzPw0KCSAgICAg ICAgPg0KCSAgICAgICAgPiBUaGUgZmlyc3QgdGhyZWUgcmVxdWlyZSB0aGUgb3B0aW9uIHRvIGNv bmZpZ3VyZSBhIE1pbWVNZXNzYWdlDQoJZGlyZWN0bHksDQoJICAgICAgICBpbnN0ZWFkIG9mIGp1 c3QgY3JlYXRpbmcgb25lIGludGVybmFsbHkgZnJvbSBzaW1wbGlmaWVkIGFyZ3VtZW50cy4NCglU aGVyZSdzIGENCgkgICAgICAgIGxvdCBvZiB1c2VmdWwgZnVuY3Rpb25hbGl0eSBpbiB0aGVyZSwg d2Ugc2hvdWxkIG5vdCB0cnkgdG8gYWJzdHJhY3QNCgl0aGF0IC0NCgkgICAgICAgIGp1c3Qgb2Zm ZXIgc2ltcGxlIGNvbnZlbmllbmNlIG1ldGhvZHMgYXMgc2hvcnRjdXRzLg0KCSAgICAgICAgPg0K CSAgICAgICAgPiBOci4gNCBjYW4gYmUgb3ZlcmNvbWUgYnkgdHdvIG1lY2hhbmlzbXMsIGVpdGhl ciBwYXNzaW5nIGFuDQoJQXV0aGVudGljYXRvcg0KCSAgICAgICAgaW1wbGVtZW50YXRpb24gb24g U2Vzc2lvbi5nZXRJbnN0YW5jZSwgb3IgdXNpbmcgYSBUcmFuc3BvcnQgaW5zdGFuY2UNCgkgICAg ICAgIGV4cGxpY2l0bHksIHBhc3NpbmcgaG9zdCwgdXNlcm5hbWUsIGFuZCBwYXNzd29yZCBvbiB0 aGUgY29ubmVjdA0KCWNhbGwuDQoJICAgICAgICBGdXJ0aGVybW9yZSwgYW4gZXhwbGljaXQgVHJh bnNwb3J0IGluc3RhbmNlIGFsbG93cyB0byBzZW5kIG11bHRpcGxlDQoJbWVzc2FnZXMNCgkgICAg ICAgIHdpdGhpbiBvbmUgY29ubmVjdGlvbiAtIE5yLiA1Lg0KCSAgICAgICAgPg0KCSAgICAgICAg PiBOci4gNiBuZWVkcyB0aGUgb3B0aW9uIHRvIHdvcmsgd2l0aGluIGEgU3RvcmUsIGFzIG9wcG9z ZWQgdG8gYQ0KCVRyYW5zcG9ydA0KCSAgICAgICAgZm9yIHNlbmRpbmcuDQoJICAgICAgIA0KCSAg ICAgICAgSSdtIG5vdCBzdXJlIHdlIG5lZWQgdG8gd29ycnkgYWJvdXQgNiBub3csIHNvIGxvbmcg YXMgd2UgY2FuIHN1cHBvcnQNCglpdA0KCSAgICAgICAgZXZlbnR1YWxseS4gSSB0aGluayBtb3N0 IHBlb3BsZSBhcmUgaW50ZXJlc3RlZCBwcmltYXJpbHkgaW4gc2VuZGluZw0KCW1haWwuDQoJICAg ICAgIA0KCSAgICAgICAgPiBTbyB0aGUgbW9zdCBhcHByb3ByaWF0ZSBtYWlsIHN1cHBvcnQgc2Vl bXMgdG8gbWUgYSBNYWlsVGVtcGxhdGUNCgljbGFzcw0KCSAgICAgICAgdGhhdCdzIGZvY3VzZWQg b24gbWFraW5nIEphdmFNYWlsIHVzYWdlIGVhc2llciByYXRoZXIgdGhhbiBnZW5lcmFsDQoJICAg ICAgICBhYnN0cmFjdGlvbi4gSSBlbnZpc2FnZSB0aGUgZm9sbG93aW5nIGJlYW4gcHJvcGVydGll czoNCgkgICAgICAgID4NCgkgICAgICAgID4gLSB0cmFuc3BvcnRQcm90b2NvbCAoZGVmYXVsdCAi c210cCIpOw0KCSAgICAgICAgPiAtIHN0b3JlUHJvdG9jb2wgKGRlZmF1bHQgInBvcDMiKTsNCgkg ICAgICAgID4gLSB0cmFuc3BvcnRIb3N0IChha2EgIm1haWwuc210cC5ob3N0Iik7DQoJICAgICAg ICA+IC0gc3RvcmVIb3N0IChha2EgIm1haWwucG9wMy5ob3N0Iik7DQoJICAgICAgICA+IC0gdXNl cm5hbWUgKGRlZmF1bHQgZW1wdHkpOw0KCSAgICAgICAgPiAtIHBhc3N3b3JkIChkZWZhdWx0IGVt cHR5KS4NCgkgICAgICAgID4NCgkgICAgICAgID4gVGhlIGZvbGxvd2luZyBtZXRob2RzIGFsbG93 IHRvIHdvcmsgd2l0aGluIGEgcHJvcGVybHkgbWFuYWdlZA0KCVRyYW5zcG9ydCBvcg0KCSAgICAg ICAgU3RvcmUgcmVzb3VyY2UsIGFuYWxvZ291cyB0byBIaWJlcm5hdGVUZW1wbGF0ZSB3aXRoIGEg SGliZXJuYXRlDQoJU2Vzc2lvbjoNCgkgICAgICAgID4NCgkgICAgICAgID4gLSBleGVjdXRlSW5U cmFuc3BvcnQoTWFpbFRyYW5zcG9ydENhbGxiYWNrKTsNCgkgICAgICAgID4gLSBleGVjdXRlSW5T dG9yZShNYWlsU3RvcmVDYWxsYmFjayk7DQoJICAgICAgICA+DQoJICAgICAgICA+IHdpdGggdGhl IGZvbGxvd2luZyBjYWxsYmFjayBpbnRlcmZhY2VzOg0KCSAgICAgICAgPg0KCSAgICAgICAgPiAg IHB1YmxpYyBpbnRlcmZhY2UgTWFpbFRyYW5zcG9ydENhbGxiYWNrKCkgew0KCSAgICAgICAgPiAg ICAgZG9JblRyYW5zcG9ydChTZXNzaW9uIHNlc3Npb24sIFRyYW5zcG9ydCB0cmFuc3BvcnQpOw0K CSAgICAgICAgPiAgIH0NCgkgICAgICAgID4NCgkgICAgICAgID4gICBwdWJsaWMgaW50ZXJmYWNl IE1haWxTdG9yZUNhbGxiYWNrKCkgew0KCSAgICAgICAgPiAgICAgZG9JblN0b3JlKFNlc3Npb24g c2Vzc2lvbiwgU3RvcmUgc3RvcmUpOw0KCSAgICAgICAgPiAgIH0NCgkgICAgICAgID4NCgkgICAg ICAgID4gT2YgY291cnNlLCBsaWtlIHdpdGggSGliZXJuYXRlVGVtcGxhdGUsIHRoZXJlJ3MgYSBs b3Qgb2YNCglvcHBvcnR1bml0eSBmb3INCgkgICAgICAgIGNvbnZlbmllbmNlIG1ldGhvZHMgb24g TWFpbFRlbXBsYXRlLCB0byBhdm9pZCBoYXZpbmcgdG8gaW1wbGVtZW50IGENCgkgICAgICAgIGNh bGxiYWNrOiBqdXN0IGZvciB0cmFuc3BvcnQgdGhvdWdoLCBhcyBzdG9yZS1yZWxhdGVkIHdvcmsg d2lsbA0KCWFsd2F5cyBiZQ0KCSAgICAgICAgY3VzdG9tLg0KCSAgICAgICAgPg0KCSAgICAgICAg PiAtIHNlbmRNZXNzYWdlKE1pbWVNZXNzYWdlKTsNCgkgICAgICAgID4gLSBzZW5kTWVzc2FnZXMo TWltZU1lc3NhZ2VbXSk7DQoJICAgICAgICA+IC0gc2VuZE1lc3NhZ2UoU2ltcGxlTWVzc2FnZSBt ZXNzYWdlKTsNCgkgICAgICAgID4gLSBzZW5kTWVzc2FnZShTdHJpbmcgZnJvbSwgU3RyaW5nIHRv LCBTdHJpbmcgc3ViamVjdCwgU3RyaW5nDQoJdGV4dCk7DQoJICAgICAgICA+IC0gc2VuZE1lc3Nh Z2UoU3RyaW5nIGZyb20sIFN0cmluZyB0bywgU3RyaW5nW10gY2MsIFN0cmluZyBzdWJqZWN0LA0K CVN0cmluZw0KCSAgICAgICAgdGV4dCk7DQoJICAgICAgICA+IC0gZXRjLg0KCSAgICAgICAgPg0K CSAgICAgICAgPiBTbyBzZW5kaW5nIGEgcGxhaW4gbWVzc2FnZSBpcyBzdHJhaWdodGZvcndhcmQ6 IFBvcHVsYXRlIGENCglNYWlsVGVtcGxhdGUNCgkgICAgICAgIHdpdGggdHJhbnNwb3J0SG9zdCwg dXNlcm5hbWUsIGFuZCBwYXNzd29yZCAoZS5nLiBpbiB0aGUgYXBwbGljYXRpb24NCgkgICAgICAg IGNvbnRleHQpLCBwYXNzIGl0IHRvIHlvdXIgYXBwbGljYXRpb24gb2JqZWN0OyBpbnZva2Ugb25l IG9mIHRoZQ0KCXNlbmRNZXNzYWdlDQoJICAgICAgICBtZXRob2RzLiBCdXQgaWYgeW91IG5lZWQg aXQsIHRoZSBmdWxsIHBvd2VyIG9mIEphdmFNYWlsIGlzIGF0IHlvdXINCgkgICAgICAgIGZpbmdl cnRpcHMgaW4gYSBjdXN0b20gY2FsbGJhY2sgaW1wbGVtZW50YXRpb24hDQoJICAgICAgICA+DQoJ ICAgICAgICA+IFByZWNvbmZpZ3VyaW5nIG1haWwgc2V0dGluZ3MgaXMgc3RpbGwgcG9zc2libGU6 IHRoZQ0KCSJ0cmFuc3BvcnRIb3N0IiBpbiB0aGUNCgkgICAgICAgIE1haWxUZW1wbGF0ZSBpbnN0 YW5jZSwgdGhlIG1haWwgYWRkcmVzc2VzIGFuZCBjb250ZW50cyB2aWENCglTaW1wbGVNZXNzYWdl Lg0KCSAgICAgICAgVGhlIGxhdHRlciB3aXRoICJmcm9tIiwgInRvIiwgInN1YmplY3QiLCAidGV4 dCIsIGFuZCBhIGNvcHkNCgljb25zdHJ1Y3RvciBjYW4NCgkgICAgICAgIHNlcnZlIHRoZSByb2xl IG9mIHRoZSBjdXJyZW50IE1haWxTZXR0aW5ncywganVzdCB3aXRob3V0ICJob3N0IjogYQ0KCSAg ICAgICAgc2ltcGxpZmllZCBvYmplY3QgcmVwcmVzZW50YXRpb24gb2YgYSBwbGFpbiBtZXNzYWdl Lg0KCSAgICAgICAgPg0KCSAgICAgICAgPiAgIFNpbXBsZU1lc3NhZ2UgbXNnID0gbmV3IFNpbXBs ZU1lc3NhZ2UocHJlY29uZmlndXJlZE1lc3NhZ2UpOw0KCSAgICAgICAgPiAgIG1zZy5zZXRYWFgo Li4uKTsNCgkgICAgICAgID4gICBtYWlsVGVtcGxhdGUuc2VuZE1lc3NhZ2UobXNnKTsNCgkgICAg ICAgID4NCgkgICAgICAgID4gLS0tLS0NCgkgICAgICAgDQoJICAgICAgICBJIGFncmVlIHJlZ2Fy ZGluZyB1dGlsaXR5IG1ldGhvZHMuIEkgbGlrZSB0aGUgcHJvcG9zZWQgQVBJIG1vZGVsDQoJKGNh bGxiYWNrcw0KCSAgICAgICAgb25seSBmb3IgY3VzdG9tIHN0dWZmKS4NCgkgICAgICAgDQoJICAg ICAgICA+IEkga25vdyB0aGF0IHRoaXMgaXMgY29tcGxldGVseSBkaWZmZXJlbnQgdGhhbiB0aGUg Y3VycmVudCBtYWlsDQoJc3VwcG9ydA0KCSAgICAgICAgbW9kZWwuIFRoZSBtYWluIGRpZmZlcmVu Y2UgaXMgdGhhdCB0aGVyZSBpcyBubyBhdHRlbXB0IHRvIGFic3RyYWN0DQoJSmF2YU1haWwNCgkg ICAgICAgIGNvbXBsZXRlbHksIHJhdGhlciBhIGhlbHBlciBmb3Igc2ltcGxpZmllZCB1c2FnZSBs aWtlDQoJSGliZXJuYXRlVGVtcGxhdGUuIEkNCgkgICAgICAgIGRvbid0IHNlZSBtdWNoIHZhbHVl IGluIGNvbXBsZXRlIGFic3RyYWN0aW9uIGFueXdheTogV2hhdA0KCWFsdGVybmF0aXZlDQoJICAg ICAgICBpbXBsZW1lbnRhdGlvbnMgbWlnaHQgdGhlcmUgYmU/DQoJICAgICAgIA0KCSAgICAgICAg SmF2YU1haWwgaXMgYSBtZXNzeSBBUEkuIFRoZXJlIGFyZSBhbHRlcm5hdGl2ZXMgc3VjaCBhcyB0 aGUgb2xkIFN1bg0KCW1haWwNCgkgICAgICAgIHBhY2thZ2VzLCB3aGljaCBJJ3ZlIHVzZWQgc3Vj Y2Vzc2Z1bGx5LCB3aGljaCBhcmUgdXN1YWxseSBlYXNpZXIgdG8NCgkgICAgICAgIGNvbmZpZ3Vy ZS4gSSBkb24ndCB0aGluayBKYXZhTWFpbCBpcyBhIGdyZWF0IGFic3RyYWN0aW9uLg0KCSAgICAg ICANCgkgICAgICAgID4gUmVnYXJkaW5nIHRlc3RpbmcsIHRoYXQgc2hvdWxkIGJlIGVhc2llciB3 aXRoIHRoZSBhYm92ZSBtb2RlbDoNCglCZXNpZGVzDQoJICAgICAgICBTZXNzaW9uLmdldEluc3Rh bmNlLCBubyBzdGF0aWMgSmF2YU1haWwgbWV0aG9kcyBhcmUgaW52b2x2ZWQsIGFzDQoJVHJhbnNw b3J0DQoJICAgICAgICBhbmQgU3RvcmUgYW5kIGhhbmRsZWQgYXMgaW5zdGFuY2VzLiBUaHVzLCBp ZiB3ZSBpc29sYXRlIHRoZQ0KCSAgICAgICAgU2Vzc2lvbi5nZXRJbnN0YW5jZSBjYWxsIGluIGEg cHJvdGVjdGVkIG1ldGhvZCwgd2Ugc2hvdWxkIGJlIGFibGUgdG8NCgl0ZXN0DQoJICAgICAgICBv dXIgbWFpbCBzdXBwb3J0IHdpdGggbW9jayBvYmplY3RzLCBpLmUuIG1vY2sgc3ViY2xhc3NlcyBv ZiBTZXNzaW9uLA0KCSAgICAgICAgVHJhbnNwb3J0LCBhbmQgU3RvcmUuDQoJICAgICAgIA0KCSAg ICAgICAgU2Vzc2lvbiBpcyBmaW5hbC4gVHJhbnNwb3J0IGlzIG5vdCBhIHJlYWwgb2JqZWN0LS1p ZSB0aGUgbW9zdA0KCWltcG9ydGFudA0KCSAgICAgICAgbWV0aG9kcyBhcmUgc3RhdGljLiBKYXZh TWFpbCBzdWNrcyBmcm9tIGEgdGVzdGFiaWxpdHkgcGVyc3BlY3RpdmUsDQoJc28gSSdtDQoJICAg ICAgICBub3Qgc3VyZSB3ZSBjYW4gYXZvaWQgdGhvc2UgbGltaXRhdGlvbnMgd2l0aG91dCBncmVh dGVyIGFic3RyYWN0aW9uLg0KCSAgICAgICANCgkgICAgICAgID4gVGhlIG1haW4gcmVhc29uIHdo eSBJJ20gdmVyeSBrZWVuIG9uIGltcGxlbWVudGluZyB0aGUgYWJvdmUNCglzdXBwb3J0IGlzDQoJ ICAgICAgICB0aGF0IHRoZSBjdXJyZW50IGFic3RyYWN0aW9uIGlzIHRvbyBzaW1wbGU6IEl0IGxv c2VzIG11Y2ggb2YNCglKYXZhTWFpbCdzDQoJICAgICAgICBwb3dlci4gSU1PLCB0aGUgYmV0dGVy IHRyYWRlb2ZmIGlzIHRvIHdvcmsgd2l0aCBKYXZhTWFpbCBleGNsdXNpdmVseQ0KCWFuZA0KCSAg ICAgICAgbWFrZSBpdHMgdXNhZ2Ugc2ltcGxlci4NCgkgICAgICAgDQoJICAgICAgICBJIHRoaW5r IG1vcmUgcG93ZXIgaXMgbmVlZGVkLiBJJ20gc3RpbGwgbm90IGNvbnZpbmNlZCB0aGF0IHdlIG5l ZWQNCgl0byBiZQ0KCSAgICAgICAgSmF2YU1haWwgb25seSB0byBkZWxpdmVyIHRoYXQuDQoJICAg ICAgIA0KCSAgICAgICAgUmVnYXJkcywNCgkgICAgICAgIFJvZA0KCSAgICAgICANCgkgICAgICAg DQoJICAgICAgIA0KCQ0KCQ0KDQo= |
|
From: <tri...@tr...> - 2003-10-07 23:06:46
|
Mark, Absolutely, I'd be happy to take a look at your code. Just send it as an attachement. Thomas > i'd like to submit a Sybase MaxValueIncrementer for review. > > is this appropriate for this list ? > > > > ============================================================================== > This message is for the named person's use only. It may contain sensitive > and > private proprietary or legally privileged information. No confidentiality or > privilege is waived or lost by any mistransmission. If you are not the > intended recipient, please immediately delete it and all copies of it from > your system, destroy any hard copies of it and notify the sender. You must > not, directly or indirectly, use, disclose, distribute, print, or copy any > part of this message if you are not the intended recipient. CREDIT SUISSE > GROUP and each legal entity in the CREDIT SUISSE FIRST BOSTON or CREDIT > SUISSE > ASSET MANAGEMENT business units of CREDIT SUISSE FIRST BOSTON reserve the > right to monitor all e-mail communications through its networks. Any views > expressed in this message are those of the individual sender, except where > the > message states otherwise and the sender is authorized to state them to be > the > views of any such entity. > Unless otherwise stated, any pricing information given in this message is > indicative only, is subject to change and does not constitute an offer to > deal at any price quoted. Any reference to the terms of executed > transactions > should be treated as preliminary only and subject to our formal written > confirmation. > ============================================================================== > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer > |