Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 91253 invoked from network); 28 Dec 2001 02:28:35 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 28 Dec 2001 02:28:35 -0000 Received: (qmail 3738 invoked by uid 97); 28 Dec 2001 02:28:42 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@jakarta.apache.org Received: (qmail 3722 invoked by uid 97); 28 Dec 2001 02:28:41 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 3711 invoked from network); 28 Dec 2001 02:28:41 -0000 Reply-To: From: "Paulo Gaspar" To: "Jakarta Commons Developers List" , "Craig R. McClanahan" Subject: RE: [Design Discussion] DynaBeans - Round 2 Date: Fri, 28 Dec 2001 03:44:08 +0100 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) In-Reply-To: <20011227154328.F93245-100000@localhost> X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 Importance: Normal X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Hi Craig, Answer inline as usual: > -----Original Message----- > From: Craig R. McClanahan > > Snipping to deal with a few questinos and thoughts ... > > On Thu, 27 Dec 2001, Paulo Gaspar wrote: > > > > > In my experience the data type should be already in the most basic > > implementation or you have not much than a Map with an indexed (int) > > access. > > > > I'm thinking that there will be two common use cases -- one where you > don't want to bother predefining the datatypes, just grab whatever's there > and put a facade around it (HTTP request parameters), and another case > where you want to have type safety but still dynamically define the set of > supported properties. Ah! Partially understood. I wrap the HTTP request with another interface I call INameMapper. IRecord descends from that one. Most of my "move named values around" utility methods just copy things between INameMappers (which includes IRecords). The INameMapper is something like (meaning this is the stable part) this: public interface INameMapper { public Object get(String i_name); public boolean containsName(String i_name); public void set(String i_name, Object i_value); } But what do you mean by "dynamically define the set of supported properties"? Do you mean doing things like defining a DynaClass from a configuration file (I do that kind of thing) but keeping it immutable or do you mean changing the DynaClass all the time? I keep avoiding mutable DynaClasses (and I keep saying this). I am scared of complexity generated by side effects. I am playing with a DynaBean wrapper implementation with a private DynaClass but having several DynaBeans for a mutable DynaClass looks hard to control. > But the important benefit is a common *access* API for applications using > the DynaBeans without caring which "kind" they are -- the same benefit > you've created by putting IRecord wrappers around standard JavaBeans. Yes, of course. > ... > > > I often must make a DynaBean read-only and sometimes I have to declare > > it read-only straight from the DynaClass level. But field by field > > restriction does not happen often and always having it there weights on > > performance. > > > > Read-only-ness of the bean is really more useful at the DynaBean instance > level, right? Once you've populated all the properties themselves, you > just flip the switch to avoid inadvertent changes later. Exactly. I still didn't miss property by property access restrictions, but I do use both: - Temporary read-only switch (the usual read-only bit); - Permanent read-only switch (the bean becomes permanently immutable). I only have read-only defined on the DynaClass level for wrappers. > > What I am missing is to add extra "untyped" properties to a specific > > DynaBean, but that is a specialization for which I use a descendent > > class. > > > > Or define a mapped property (see below for more). Well, I am playing with this idea in order to add calculated values to a wrapped ResultSet. Since the ResultSet IRecord wrapper does not share type information, it is not problematic to change its structure. I never considered the mapped property approach. However, it does not look very natural in terms of syntax (such objects will usually end up passed to a Velocity template). > > > ... > > > > Quite often it is better to associate the converter to the DynaBean. > > > > I already covered this case quite a bit in my answer to Francois. > > > > As discussed, it's not mentioned in the interfaces now ... Converters are > an implementation level featuer. Sorry, I started this answer before all the others. I tried to disguise that a bit but it still shows. =;o) > > ... > > > > I could contribute my Converter. > > > > We agree on this interface, you could use a base implementation and I > > could use some improvements to it. > > =;o) > > > > That would be quite useful. Ok, I must make it self contained. I will post it in the next couple of days. > > > > > (2) Implement convenient base classes for DynaBean and DynaClass to > > > provide starting points for custom implementations. These classes > > > should be sufficient for basic DynaBean use. > > > > I have something, but my interfaces are quite different. > > > > > > > (3) Integrate transparent support for DynaBeans into the existing > > > PropertyUtils class. This will insulate developers > > > using the existing APIs from having to worry about the new > > > functionality provided by DynaBeans. > > > > You can also do a lot just in terms of DynaBeans if you use wrappers. > > That's undoubtedly true. However, *one* of the use cases for me is to let > applications already using BeanUtils and friends (which means, among > others, all Struts-based apps) to be able to transparently leverage > DynaBeans underneath the BeanUtils APIs. > > At the same time, I think DynaBean API wrappers around standard beans give > you a similar benefit if you're starting from DynaBeans. You probably > wouldn't deliberately choose to use both, but now you'll be able to go in > either direction. Of course: the innovative bit and the backwards compatibility. > > > > > (4) Implement "proxy" DynaClass and DynaBean wrappers around standard > > > JavaBeans. (This sounds sort of backwards, but allows an > application > > > to be written *totally* in terms of DynaBeans if desired.) > > > > And helps on applying conversion. > > > > > > > (5) Implement a convenient way to convert a > java.sql.ResultSet (or RowSet) > > > into a series of DynaBeans, where the corresponding DynaClass is > > > synthesized based on the metadata of the result set. > > > > See my DynaBean wrappers + DynaIntrospector remarks on my answer to > > Francois. > > > > > (6) Whatever we want to do next ... > > > > > > How does this sound? > > > > Some remarks to the code you posted. > > > > DynaClass: > > - As explained above, should ALWAYS be immutable. No add() > methods in the > > interface. The implementation constructor(s) could accept > lists and/or > > arrays of PropertyDescriptors; > > In the interest of simplest possible basic interfaces, I agree with this. > However, I'm thinking that there will be cases where mutable DynaClasses > will be useful - but that can be a specialization later. As above, maybe it should be a specialized DynaBean implementation with a private DynaClass - just a DynaBean with mutable structure. Or do you miss changing the structure of several DynaBeans at once? > ... > > > - Interesting the idea of using straight PropertyDescriptor for the > > properties. I am checking if I can do just that with all the > > implementations I have. (Yes, it should be obvious to use what "is > > already there".) > > =:o) > > > > It has it's own wrinkles at implementation time, but seemed like a good > idea -- especially since I was already using them in BeanUtils. Yes, I have been staring for some minutes at the JavaDocs for PropertyDescriptor and FeatureDescriptor and wondering about how attached are they to javabeans. I am quite curious about this one. > > DynaBean: > > - I still do not use indexed properties but I see how they > are needed to > > cover all types of JavaBean properties; > > - However, why mapped properties are needed, as in > > public Object get(String name, String key); > > public void set(String name, String key, Object value); > > > > This has no parallel in JDK 1.3 beans and it looks to me like its > > usefulness can be achieved handled just by having some other type of > > property, e.g. a Map property. > > (So, my question is "Why?".) > > > > Mapped properties have several motivations for me: > > * To cover all the things that BeanUtils and PropertyUtils already > know how to do (for the goal of transparent access to DynaBeans > through BeanUtils APIs). > > * Lend themselves naturally to an expression language syntax (BeanUtils > uses square brackets for real indexed subscripts and parentheses for > String-based "subscripts"). > > * Several projects that try to use XPath syntax to navigate Java > object trees (instead of XML documents) have a very elegant mapping > of mapped properties to the search syntax. This has the effect of > reducing the amount of knowledge that the user needs of the "actual" > shape of the objet tree being navigated. You just need to know the > access expression, and let the underlying expression evaluator figure > out if you're referencing a scope, a bean, a Map value, or a property. > (One example of this kind of package is the JXPath commons project). So, the smartness is in the DynaClass implementation. But then, to keep the access to all the methods of the original property class (lets say a Map), you can access it with both: public Object get(String name, String key); and public Object get(String name); This is the way to be able to do both: Object myVal = myBean.get("myMapProp", "myKey"); and final int myMapPropCount = ((Map)(myBean.get("myMapProp"))).size(); Right? > * Allows you to have an "extensible" DynaBean even if the underlying > DynaClass is immutable. Well, that is a syntactic sugar over adding a key to a Map property. > Craig Have fun, Paulo Gaspar http://www.krankikom.de http://www.ruhronline.de -- To unsubscribe, e-mail: For additional commands, e-mail: