From: Chris H. <han...@gm...> - 2009-08-11 05:51:51
|
Today, a colleague of mine, let's call him James E., requested a Pojomatic.copyOf(x) feature today for use in unit testing. I told him that we had considered but rejected the idea mostly because we initially wanted to stick to basic functionality (e.g. hashCode(), equals(), and toString()) and it did not seem like a very common need at the time. It is possible that we should reconsider this case specifically, but this got me thinking about ways of exposing an API for processing properties (i.e. making Pojomatic extensible), and I have an initial proposal for doing so. This would not need to be in 1.0 per se, but could be added later. We could add the following methods to Pojomator (and similarly to Pojomatic): <R> R process(NullaryPojoProcessor<R> processor); //used to inspect the properties of the class <R> R process(UnaryPojoProcessor<R, T> processor, T instance); //e.g. hashCode() and toString() <R> R process(BinaryPojoProcessor<R, T> processor, T instance, T other); //e.g. equals() <R> R process(PojoProcessor<R, T> processor, T... instances); //a catch-all which loses some type-safety, aka N-aryPojoProcessor With the corresponding interface methods (perhaps with an initialzation method on each): NullaryPojoProcessor: R process(PropertyElement element); UnaryPojoProcessor: R process(PropertyElement element, T instance); BinaryPojoProcessor: R process(PropertyElement element, T instance, T other); PojoProcessor: R process(PropertyElement element, T... instances); //or use T[] here Alternatively, we could simply omit all but PojoProcessor since the only bit of type-safety lost is that the correct number of arguments is passed in. If we went this route, we could have the PojoProcessor specify how many arguments it expected and then do the check at runtime, but the caller would lose the compile-time check and code completion. Is it too much of a hassle to have to define all of the other interfaces and overloaded method signatures for this gain? I think the ability to extend the functionality of Pojomatic would be great because there are much more potential uses for the property information than we can provide (and maintain). For example, in addition to the basic three we have diff(), isEmpty(), and copyOf() without thinking too hard. Furthermore, this type of functionality would make it possible to provide custom serialization for an object, marshalling (XML, JSON, etc.), or even ORM if someone is so inclined. Granted, some of those specific ideas would definitely be re-inventing the wheel, but the point is the range of possibilities this functionality would enable. This seems worth the extra complexity. Do you agree? Any other thoughts or ideas about how to achieve extensibility? -Chris |
From: Ian R. <ian...@gm...> - 2009-08-13 04:43:25
|
I think that one reason we didn't do this originally was that it would have complicated the annotation process. In particular, the PojomaticPolicy enum encapsulates precisely the options for equals, hashCode and toString (along with contractual relationships between them), so that annotations can stay relatively "lightweight". To make use of process(...) methods, one would need to write a PojoProcessor which inspected each PropertyElement, calling getElement() and then looking for a custom annotation. Notably, this work would need to be done on every call, where as PojomatorImpl eagerly caches the properties to be used for each of equals, toString and hashCode. Of course, we could have a version of process which took in a PropertyRole, so that for methods which happened to allign with one of equals, hashCode or toString, they could benefit from pre-cached lists. diff naturally uses the EQUALS role, but I'm not sure what isEmpty or copyOf should use. (BTW, what would copyOf do? I'm assuming make a copy; the other natural interpretation looks awfully similar to equals. If it is a clone-like thing, then pojomatic isn't a great fit, since it focuses only on reading properties. It doesn't look for setters to match getters, and it doesn't care about whether a field is final or not.) Now all that said, I'm not opposed to the idea per se. I am just having a hard time seeing how it would play out in a complete example without it ending up being hardly easier for a new method implementor (or client) to use pojomatic than to do something from scratch. - Ian On Mon, Aug 10, 2009 at 11:51 PM, Chris Hansen <han...@gm...>wrote: > Today, a colleague of mine, let's call him James E., requested a > Pojomatic.copyOf(x) feature today for use in unit testing. I told him > that we had considered but rejected the idea mostly because we > initially wanted to stick to basic functionality (e.g. hashCode(), > equals(), and toString()) and it did not seem like a very common need > at the time. It is possible that we should reconsider this case > specifically, but this got me thinking about ways of exposing an API > for processing properties (i.e. making Pojomatic extensible), and I > have an initial proposal for doing so. This would not need to be in > 1.0 per se, but could be added later. > > We could add the following methods to Pojomator (and similarly to > Pojomatic): > <R> R process(NullaryPojoProcessor<R> processor); //used to inspect > the properties of the class > <R> R process(UnaryPojoProcessor<R, T> processor, T instance); > //e.g. hashCode() and toString() > <R> R process(BinaryPojoProcessor<R, T> processor, T instance, T > other); //e.g. equals() > <R> R process(PojoProcessor<R, T> processor, T... instances); //a > catch-all which loses some type-safety, aka N-aryPojoProcessor > > With the corresponding interface methods (perhaps with an > initialzation method on each): > NullaryPojoProcessor: > R process(PropertyElement element); > UnaryPojoProcessor: > R process(PropertyElement element, T instance); > BinaryPojoProcessor: > R process(PropertyElement element, T instance, T other); > PojoProcessor: > R process(PropertyElement element, T... instances); //or use T[] here > > Alternatively, we could simply omit all but PojoProcessor since the > only bit of type-safety lost is that the correct number of arguments > is passed in. If we went this route, we could have the PojoProcessor > specify how many arguments it expected and then do the check at > runtime, but the caller would lose the compile-time check and code > completion. Is it too much of a hassle to have to define all of the > other interfaces and overloaded method signatures for this gain? > > I think the ability to extend the functionality of Pojomatic would be > great because there are much more potential uses for the property > information than we can provide (and maintain). For example, in > addition to the basic three we have diff(), isEmpty(), and copyOf() > without thinking too hard. Furthermore, this type of functionality > would make it possible to provide custom serialization for an object, > marshalling (XML, JSON, etc.), or even ORM if someone is so inclined. > Granted, some of those specific ideas would definitely be re-inventing > the wheel, but the point is the range of possibilities this > functionality would enable. This seems worth the extra complexity. Do > you agree? Any other thoughts or ideas about how to achieve > extensibility? > > -Chris > > > ------------------------------------------------------------------------------ > Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day > trial. Simplify your report design, integration and deployment - and focus > on > what you do best, core application coding. Discover what's new with > Crystal Reports now. http://p.sf.net/sfu/bobj-july > _______________________________________________ > Pojomatic-users mailing list > Poj...@li... > https://lists.sourceforge.net/lists/listinfo/pojomatic-users > |
From: Chris H. <han...@gm...> - 2009-08-13 16:18:02
|
In that case, I think a good approach would be to create a branch, make the changes, and implement some processors via PojoProcessor and by hand. It should be clear very quickly whether or not the PojoProcessor way is easier. I will volunteer to do that, but only after we do our next (and hopefully last before 1.0) release. In other words, let's not hold up 1.0 for this. -Chris On Wed, Aug 12, 2009 at 10:43 PM, Ian Robertson<ian...@gm...> wrote: > I think that one reason we didn't do this originally was that it would have > complicated the annotation process. In particular, the PojomaticPolicy enum > encapsulates precisely the options for equals, hashCode and toString (along > with contractual relationships between them), so that annotations can stay > relatively "lightweight". > > To make use of process(...) methods, one would need to write a PojoProcessor > which inspected each PropertyElement, calling getElement() and then looking > for a custom annotation. Notably, this work would need to be done on every > call, where as PojomatorImpl eagerly caches the properties to be used for > each of equals, toString and hashCode. Of course, we could have a version > of process which took in a PropertyRole, so that for methods which happened > to allign with one of equals, hashCode or toString, they could benefit from > pre-cached lists. diff naturally uses the EQUALS role, but I'm not sure > what isEmpty or copyOf should use. (BTW, what would copyOf do? I'm > assuming make a copy; the other natural interpretation looks awfully similar > to equals. If it is a clone-like thing, then pojomatic isn't a great fit, > since it focuses only on reading properties. It doesn't look for setters to > match getters, and it doesn't care about whether a field is final or not.) > > Now all that said, I'm not opposed to the idea per se. I am just having a > hard time seeing how it would play out in a complete example without it > ending up being hardly easier for a new method implementor (or client) to > use pojomatic than to do something from scratch. > > - Ian > > On Mon, Aug 10, 2009 at 11:51 PM, Chris Hansen <han...@gm...> > wrote: >> >> Today, a colleague of mine, let's call him James E., requested a >> Pojomatic.copyOf(x) feature today for use in unit testing. I told him >> that we had considered but rejected the idea mostly because we >> initially wanted to stick to basic functionality (e.g. hashCode(), >> equals(), and toString()) and it did not seem like a very common need >> at the time. It is possible that we should reconsider this case >> specifically, but this got me thinking about ways of exposing an API >> for processing properties (i.e. making Pojomatic extensible), and I >> have an initial proposal for doing so. This would not need to be in >> 1.0 per se, but could be added later. >> >> We could add the following methods to Pojomator (and similarly to >> Pojomatic): >> <R> R process(NullaryPojoProcessor<R> processor); //used to inspect >> the properties of the class >> <R> R process(UnaryPojoProcessor<R, T> processor, T instance); >> //e.g. hashCode() and toString() >> <R> R process(BinaryPojoProcessor<R, T> processor, T instance, T >> other); //e.g. equals() >> <R> R process(PojoProcessor<R, T> processor, T... instances); //a >> catch-all which loses some type-safety, aka N-aryPojoProcessor >> >> With the corresponding interface methods (perhaps with an >> initialzation method on each): >> NullaryPojoProcessor: >> R process(PropertyElement element); >> UnaryPojoProcessor: >> R process(PropertyElement element, T instance); >> BinaryPojoProcessor: >> R process(PropertyElement element, T instance, T other); >> PojoProcessor: >> R process(PropertyElement element, T... instances); //or use T[] here >> >> Alternatively, we could simply omit all but PojoProcessor since the >> only bit of type-safety lost is that the correct number of arguments >> is passed in. If we went this route, we could have the PojoProcessor >> specify how many arguments it expected and then do the check at >> runtime, but the caller would lose the compile-time check and code >> completion. Is it too much of a hassle to have to define all of the >> other interfaces and overloaded method signatures for this gain? >> >> I think the ability to extend the functionality of Pojomatic would be >> great because there are much more potential uses for the property >> information than we can provide (and maintain). For example, in >> addition to the basic three we have diff(), isEmpty(), and copyOf() >> without thinking too hard. Furthermore, this type of functionality >> would make it possible to provide custom serialization for an object, >> marshalling (XML, JSON, etc.), or even ORM if someone is so inclined. >> Granted, some of those specific ideas would definitely be re-inventing >> the wheel, but the point is the range of possibilities this >> functionality would enable. This seems worth the extra complexity. Do >> you agree? Any other thoughts or ideas about how to achieve >> extensibility? >> >> -Chris >> >> >> ------------------------------------------------------------------------------ >> Let Crystal Reports handle the reporting - Free Crystal Reports 2008 >> 30-Day >> trial. Simplify your report design, integration and deployment - and focus >> on >> what you do best, core application coding. Discover what's new with >> Crystal Reports now. http://p.sf.net/sfu/bobj-july >> _______________________________________________ >> Pojomatic-users mailing list >> Poj...@li... >> https://lists.sourceforge.net/lists/listinfo/pojomatic-users > > |