You can subscribe to this list here.
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(4) |
Aug
(10) |
Sep
|
Oct
(1) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2010 |
Jan
|
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Ian R. <ian...@gm...> - 2014-07-28 16:22:36
|
Carfield, You can always grab jars from maven directly. For example, to get the pojomatic jars, you can go to search.maven.org <http://search.maven.org/#search%7Cga%7C1%7Cpojomatic> and search for pojomatic, or just go directly to http://central.maven.org/maven2/org/pojomatic/. Please let us know if you have any further questions! - Ian On Mon, Jul 28, 2014 at 4:41 AM, Carfield Yim <Car...@ma...> wrote: > Hi, I would like to try Pojomatic out. But I am not using Maven, is there > any JAR distribution? Or I have to check out the source and built it? > > NOTICE > > The information contained in this email is confidential. If you are not > the intended recipient, you must not disclose or use the information in > this email in any way. If you received it in error, please tell us > immediately by return email and delete the document. We do not guarantee > the integrity of any e-mails or attached files and are not responsible for > any changes made to them by any other person. > > > |
From: Ian R. <ian...@gm...> - 2010-02-25 17:35:34
|
Agreed on the Differences API. Do you think we would have to make backwards incompatible changes to expose details? If not, this can be a post 1.0 task. On the extensibility front, I question the value. Here's what I can see pojomatic offering to those who might wish to extend the API to support additional functions beyond equals, hashCode, toString and differences: - Creating a unique pojomator per class (SelfPopulatingMap). - As part of creating the pojomator, determine which properties are assigned to which roles. That doesn't really feel like a lot. On the flip side, in order to support additional functions, we would need to completely revamp the annotation strategy; IMHO, this would only be worthwhile if we could do so without requiring greater verbosity. A separate direction to extend the API would be supporting custom equals strategies; I could see a desire to do alternate handling of collection fields, for example. I think this is an area that would not require backwards-breaking changes, and so again could be postponed until after 1.0. - Ian On Thu, Feb 25, 2010 at 12:02 AM, Chris Hansen <han...@gm...>wrote: > I was (re)watching Bloch on API design the other day ( > http://www.infoq.com/presentations/effective-api-design ) and I had a > couple of takeaways which apply to Pojomatic. We need to discuss/address > these before it's too late, meaning before 1.0. > > 1) Provide programmatic access to all data available in string form. Among > other things, this prevents users from parsing the string output. > 1a) We can, and I think should, refactor the Differences API for > programmatic access. We could take a page out of the Google Collections book > on this one: > http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapDifference.html > > I will work on this one. > > 2) Design for extensibility. If you have a successful API, the users will > want to do more with it. Even if you get the API right the first time, you > won't get it complete the first time. > 2a) One way to do this would be to implement extension separately from the > existing hashCode(), equals(Object), and toString() functionality. That > would be a small API change which could be done as a point release after > 1.0, but then existing functionality would be inconsistent with the > extensible API and might even become a candidate for deprecation at that > point. > 2b) Another way to go would be to create the extensible API and refactor > the existing functionality to use that API right away. This is worse in the > short term because it delays 1.0, but might pay off in the long term. > > To me, the question is not if we should create an extensible API, but when. > What do you think? > > Thanks, > -Chris > > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > Pojomatic-users mailing list > Poj...@li... > https://lists.sourceforge.net/lists/listinfo/pojomatic-users > > |
From: Ian R. <ian...@gm...> - 2010-02-25 16:55:03
|
Agreed on the Differences API. Do you think we would have to make backwards incompatible changes to expose details? If not, this can be On Thu, Feb 25, 2010 at 12:02 AM, Chris Hansen <han...@gm...>wrote: > I was (re)watching Bloch on API design the other day ( > http://www.infoq.com/presentations/effective-api-design ) and I had a > couple of takeaways which apply to Pojomatic. We need to discuss/address > these before it's too late, meaning before 1.0. > > 1) Provide programmatic access to all data available in string form. Among > other things, this prevents users from parsing the string output. > 1a) We can, and I think should, refactor the Differences API for > programmatic access. We could take a page out of the Google Collections book > on this one: > http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapDifference.html > > I will work on this one. > > 2) Design for extensibility. If you have a successful API, the users will > want to do more with it. Even if you get the API right the first time, you > won't get it complete the first time. > 2a) One way to do this would be to implement extension separately from the > existing hashCode(), equals(Object), and toString() functionality. That > would be a small API change which could be done as a point release after > 1.0, but then existing functionality would be inconsistent with the > extensible API and might even become a candidate for deprecation at that > point. > 2b) Another way to go would be to create the extensible API and refactor > the existing functionality to use that API right away. This is worse in the > short term because it delays 1.0, but might pay off in the long term. > > To me, the question is not if we should create an extensible API, but when. > What do you think? > > Thanks, > -Chris > > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > Pojomatic-users mailing list > Poj...@li... > https://lists.sourceforge.net/lists/listinfo/pojomatic-users > > |
From: Chris H. <han...@gm...> - 2010-02-25 07:02:20
|
I was (re)watching Bloch on API design the other day ( http://www.infoq.com/presentations/effective-api-design ) and I had a couple of takeaways which apply to Pojomatic. We need to discuss/address these before it's too late, meaning before 1.0. 1) Provide programmatic access to all data available in string form. Among other things, this prevents users from parsing the string output. 1a) We can, and I think should, refactor the Differences API for programmatic access. We could take a page out of the Google Collections book on this one: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapDifference.html I will work on this one. 2) Design for extensibility. If you have a successful API, the users will want to do more with it. Even if you get the API right the first time, you won't get it complete the first time. 2a) One way to do this would be to implement extension separately from the existing hashCode(), equals(Object), and toString() functionality. That would be a small API change which could be done as a point release after 1.0, but then existing functionality would be inconsistent with the extensible API and might even become a candidate for deprecation at that point. 2b) Another way to go would be to create the extensible API and refactor the existing functionality to use that API right away. This is worse in the short term because it delays 1.0, but might pay off in the long term. To me, the question is not if we should create an extensible API, but when. What do you think? Thanks, -Chris |
From: Ian R. <ian...@gm...> - 2009-10-04 18:25:24
|
I've been thinking some more about equals and inheritance; things are not quite as simple as they seem. The strategy on trunk currently is (in part): - If other has the same class as instance, proceed. - Else, if other's class is a proper subclass of instance's class, then call other.equals(instance) - Else, if other is a subclass of the most specific class contributing equals properties to instance, then proceed. - Else, return false. There is a problem with this, exposed in the most recent unit test commit to trunk. Suppose that Child1 and Child2 are subclasses of Parent. Child1 contributes no new properties, but Child2 does. In this case, if instance is of class Child1 and other of class Child2, the algorithm will consider them candidates for equality. However, if instance is of class Child2 and other of class Child1, then they are not considered equal, thus breaking symmetry. The solution that's been considered for this is to modify the above algorithm in the case where other is not a proper subclass of instance to check the most specific contributing class for both equals and other, based on the assumption that both are strictly relying on Pojomatic, by means of looking at their respective pojomators. This runs afoul of interfaces, however; if Intf is a pojomated interface, then implementing classes will not have a pojomator. One solution is to change the rules for interface pojomators. I think a more general solution might be to make this user selectable, with defaults determined by whether the pojomated class is an interface or not. Specifically, I'm proposing adding a new class-level annotation, say, @InheritanceStrategy. It's value would by typed to an InheritanceStrategy enum with three values: SUBCLASSABLE, NOT_SUBCLASSABLE and DEFAULT; DEFAULT would map to SUBCLASSABLE for non-interfaces and NOT_SUBCLASSABLE for interfaces. Additionally, it would be useful to add a no-arg annotation, say, @NotEqualToParent, to handle cases where the child knows that it cannot be considered equal to the parent. This would be useful for at least two cases I can think of. One is where a child class is semantically distinct from it's parent, even if there are no new properties (the difference might lie in method implementations). A second would be where a child class needs to introduce custom equals logic that cannot be expressed via pojomatic. The impact of this annotation would be to ensure that ClassProperties getEqualsParentClass would return a class no higher in the hierarchy than the annotated class. Thoughts? |
From: Chris H. <han...@gm...> - 2009-08-31 06:24:34
|
On Sat, Aug 29, 2009 at 12:07 PM, Ian Robertson<ian...@gm...> wrote: > Taken together, these mean that two instances are equals() to each other iff > they share the same set of properties with the EQUALS role, and those > proeprties are equal to each other. This behavior sounds correct to me, but I'm wondering if this would be more maintainable and/or easier to implement exactly as stated above instead of doing non-intuitive things like calling other.equals(instance). I will attempt to explain what I mean. We could say that two properties are equal with respect to EQUALS if they "originate" from the same class in the inheritance hierarchy and are both included in the EQUALS role of the class in question. Then, two instances are equal if their properties are equal with respect to EQUALS for their Object.getClass(). We just need to come up with what "originate" means precisely, in the sentence above. Let me know if I'm not making myself clear and we can discuss this in person, at a whiteboard. > Currently, we have the rule that if an > override of a method chosen as a property for a given role (equals, toString > or hashCode) is overridden, and the override is also chosen as a property > for the same role, then only the parent method will be used. It seems to me like the overriding implementation (i.e. the child class) should always be called instead of the parent method. Am I missing something here? > I can see a few different ways of handling this. The easiest is to simply > declare that if a method property has role EQUALS and not HASH_CODE, then > subclasses can not add the HASH_CODE role to the method. While correct, it > is somewhat overrestrictive... I might start by doing the easy thing; > becoming more permisive in the future allowed. I think that makes sense. > In either case, a question arises of what should happen if someone requests > adding a property to a HASH_CODE role where it previously had only the > EQUALS role (ignoring the TO_STRING role here). One option is to silently > ignore. A second is to log a complaint. A third is to fail fast with a > RuntimeException. I lean towards the third - it's almost certainly a > programmer error. The only spot of roughness I can see here would be if a > project depended on two libraries, with one of the libraries extending a > pojomated class of another library. Updates to the library containing the > parent class could suddenly cause the child class to be in error, but the > error might be tolerable. A RuntimeException approach would make life > unpleasant for the project. On the other hand, I suspect this would be an > exceedingly rare case. In any event, we can throw an exception today and > then become more lenient in the future; going the other direction would not > be backwards compatible. I agree and I also like the RuntimeException approach. The message must be exceedingly clear, however. > Another wrinkle with the RuntimeException approach is the case where a child > class annotated with @AutoProperty(autoDetect=AutoDetect.METHOD) overrides a > method from a parent class which was given a role of EQUALS but not > HASH_CODE. Should this be an error, logged, or silently ignored? I think it should be a RuntimeException for the same reasons mentioned above. -Chris |
From: Ian R. <ian...@gm...> - 2009-08-31 02:54:29
|
On Sat, Aug 29, 2009 at 12:07 PM, Ian Robertson <ian...@gm...>wrote: > In either case, a question arises of what should happen if someone requests > adding a property to a HASH_CODE role where it previously had only the > EQUALS role (ignoring the TO_STRING role here). One option is to silently > ignore. A second is to log a complaint. A third is to fail fast with a > RuntimeException. I lean towards the third - it's almost certainly a > programmer error. The only spot of roughness I can see here would be if a > project depended on two libraries, with one of the libraries extending a > pojomated class of another library. Updates to the library containing the > parent class could suddenly cause the child class to be in error, but the > error might be tolerable. A RuntimeException approach would make life > unpleasant for the project. On the other hand, I suspect this would be an > exceedingly rare case. In any event, we can throw an exception today and > then become more lenient in the future; going the other direction would not > be backwards compatible. Another wrinkle with the RuntimeException approach is the case where a child class annotated with @AutoProperty(autoDetect=AutoDetect.METHOD) overrides a method from a parent class which was given a role of EQUALS but not HASH_CODE. Should this be an error, logged, or silently ignored? - Ian |
From: Ian R. <ian...@gm...> - 2009-08-29 18:07:54
|
I'm looking into addressing bug 2845939<https://sourceforge.net/tracker/?func=detail&aid=2845939&group_id=239113&atid=1108645>(equals doesn't play well with inheritance). The basic strategy for implementing doEquals(instance, other) in the Pojomator for class Pojoshould be: - if other.getClass() is a proper subclass of Pojo, then invoke other.equals(instance). - Otherwise, verify that other.getClass()is a subclass of the highest class in Pojo's heirarchy which contains all properties which are included in the EQUALS role for Pojo. If so, then do the standard property-by-property equals check. - Otherwise, return false. Taken together, these mean that two instances are equals() to each other iff they share the same set of properties with the EQUALS role, and those proeprties are equal to each other. Note that if a parent class has a method getFoo() which is not in the EQUALS role, and two distinct subclasses add getFoo() to the EQUALS role, these will be seen as distinct properties. Unfortunately, I'm realizing that another sticky issue is the relationship between equals and hashCode. Currently, we have the rule that if an override of a method chosen as a property for a given role (equals, toString or hashCode) is overridden, and the override is also chosen as a property for the same role, then only the parent method will be used. Unfortunately, we do this on a role-by role basis, without paying attention to interactions. This can cause a problem when a method is included in the equals computation in a parent class, and then a child class adds hashCode to it's roles. The result is that an instanceof the parent class might be equals() to an instance of the child class, but the two instances will have different hashCode values. I can see a few different ways of handling this. The easiest is to simply declare that if a method property has role EQUALS and not HASH_CODE, then subclasses can not add the HASH_CODE role to the method. While correct, it is somewhat overrestrictive. If the subclass has also added additional properties, then there is no risk of instances of the parent class being equals()to instances of the child class, so allowing parent properties to take on the additional HASH_CODE role would be fine. Implementing this is a bit more complicated, of course. I might start by doing the easy thing; becoming more permisive in the future allowed. In either case, a question arises of what should happen if someone requests adding a property to a HASH_CODE role where it previously had only the EQUALS role (ignoring the TO_STRING role here). One option is to silently ignore. A second is to log a complaint. A third is to fail fast with a RuntimeException. I lean towards the third - it's almost certainly a programmer error. The only spot of roughness I can see here would be if a project depended on two libraries, with one of the libraries extending a pojomated class of another library. Updates to the library containing the parent class could suddenly cause the child class to be in error, but the error might be tolerable. A RuntimeException approach would make life unpleasant for the project. On the other hand, I suspect this would be an exceedingly rare case. In any event, we can throw an exception today and then become more lenient in the future; going the other direction would not be backwards compatible. - Ian |
From: Chris H. <han...@gm...> - 2009-08-15 16:08:48
|
I agree 100% -Chris On Aug 15, 2009, at 9:50 AM, Ian Robertson <ian...@gm...> wrote: > Currently, pojomatic allows static fields and methods to be > annotated with @Property. While there is nothing technically wrong > with this, it seems highly likely to be a programmer error. Indeed, > it makes no sense to include a static in equals, and can only serve > to break hashCode by allowing instances to have their hashCode > change after insertion into a (key)set. At best, it could possibly > make sense in a toString implementation, though I can think of no > reasonable use case for that. > > I think we should throw an IllegalArgumentException at PojomatorImpl > construction time if a static is so annotated. Thoughts? > > - Ian > --- > --- > --- > --------------------------------------------------------------------- > 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: Ian R. <ian...@gm...> - 2009-08-15 15:50:45
|
Currently, pojomatic allows static fields and methods to be annotated with @Property. While there is nothing technically wrong with this, it seems highly likely to be a programmer error. Indeed, it makes no sense to include a static in equals, and can only serve to break hashCode by allowing instances to have their hashCode change after insertion into a (key)set. At best, it could possibly make sense in a toString implementation, though I can think of no reasonable use case for that. I think we should throw an IllegalArgumentException at PojomatorImpl construction time if a static is so annotated. Thoughts? - Ian |
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 > > |
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: Ian R. <ian...@gm...> - 2009-08-11 17:04:10
|
Chris Hansen wrote: I am in the process of writing org.pojomatic.junit.Assert.assertEqualsWithDiff() (similarly for org.pojomatic.testng.Assert), what do you think of the name? Using Pojomatic.diff(), I found it frustrating from an end-user standpoint that null is not allowed as the first argument, which means every call has to make the annoying check first. I understand why that is the case, but I think it would be better to add behavior to Pojomatic.diff(null, x) to return something like the opposite of DifferenceToNull: "{null} is different than the object {x}". It would mean that Pojomatic.diff() has different behavior than PojomatorImpl.diff(), but the API would be much easier to use. Also, we could lift the non-null restriction from PojomatorImpl.diff() as well. What do you think? -Chris I think this makes a lot of sense. In particular, while the intended use of doEquals, doHashCode and doToString is to have them called from an instance of T, doDiff will typically be called by an external object, passing two instances in. Since doesn't change any method signatures, and doesn't reduce functionality, I see no harm in making this change. - Ian |
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: Chris H. <han...@gm...> - 2009-08-11 05:48:07
|
Spoke with Ian offline and we came to the conclusion that the only problem with how inheritance works right now is the one case mentioned: when @Property accessors are overridden. So the easy answer is to prevent duplicates in that case instead of introducing a bunch of extra complexity. ;) -Chris On Wed, Jul 29, 2009 at 12:15 AM, Chris Hansen<han...@gm...> wrote: > I've always thought the way properties are handled with regard to > inheritance is a bit clunky. Right now, a class has no choice but to > inherit all properties from all superclasses, leading to duplicate > properties in some cases (e.g. when @Property accessors are > overridden). The following ideas are inspired by {@inheritDoc}. > > One possible alternative would be that properties are never inherited > unless explicitly requested via a class-level @InheritProperties > annotation. That would give the author of any given class full control > over the properties, but it would mean that inherited hashCode(), > equals(Object), and toString() methods would behave > counter-intuitively by default (i.e. without this annotation). > > Another alternative, which seems more promising, would be that > properties are inherited by default (as now), but there would be some > way to "switch off" property inheritance (e.g. > @AutoProperty(inheritance=None) or @DoNotInheritProperties on the > class). Subclasses would still have a reasonable default behavior with > the extra control. > > Thoughts? > > -Chris > |
From: Chris H. <han...@gm...> - 2009-07-29 06:15:49
|
I've always thought the way properties are handled with regard to inheritance is a bit clunky. Right now, a class has no choice but to inherit all properties from all superclasses, leading to duplicate properties in some cases (e.g. when @Property accessors are overridden). The following ideas are inspired by {@inheritDoc}. One possible alternative would be that properties are never inherited unless explicitly requested via a class-level @InheritProperties annotation. That would give the author of any given class full control over the properties, but it would mean that inherited hashCode(), equals(Object), and toString() methods would behave counter-intuitively by default (i.e. without this annotation). Another alternative, which seems more promising, would be that properties are inherited by default (as now), but there would be some way to "switch off" property inheritance (e.g. @AutoProperty(inheritance=None) or @DoNotInheritProperties on the class). Subclasses would still have a reasonable default behavior with the extra control. Thoughts? -Chris |
From: Chris H. <han...@gm...> - 2009-07-21 23:59:06
|
On Thu, Jul 9, 2009 at 9:46 AM, Ian Robertson<ian...@gm...> wrote: > On Wed, Jul 8, 2009 at 11:21 PM, Chris Hansen <han...@gm...> > wrote: >> >> I don't have strong feelings one way or another, so my opinions are >> based upon the "principle of least astonishment". >> >> My gut reaction is to include annotated properties from interfaces, >> just because they must have been placed for a purpose and it would >> therefore seem discourteous to ignore them ;) . A better reason is >> that the @Property annotations present on an interface can be seen as >> a part of the API that comes along with implementing the interface, >> the same way the properties are inherited when you extend a class. > > I've been thinking about this. If property annotations are "part of the > interface", then it's likely that the interface is defining what equals > means. In this case, it's likely that the implementors should not be > defining their own pojomators. Specifically, the point of an interface > defining what equals means is to allow equality between different > implementations (java.util.List provides a good example of this). For this > to work, the equals method needs to do it's instanceof check against the > interface class, not the implementing class. In turn, this means that the > pojomator would need to be defined on the interface class. > > So while having pojomatic walk the interface hierarchy for a class might > have pojomatic doing what the client expected, it very likely is not doing > what the client really wants. Or at least, not in any of the use cases I've > been able to come up with... I think that makes sense, and I agree. > >> >> As for creating a Pojomator instance for an interface, I think the >> expected behavior would be to walk up the inheritance hierarchy of the >> given interface only and use all @Property annotations found. I'm not >> quite sure if that is exactly what you proposed or slightly different. > > That is in line with what I was thinking. Although now I'm wondering > whether it even makes sense to walk up the hierarchy for an interface, based > on my comments above... I think that only the annotations on the interface should be used (i.e. do not walk up the hierarchy). Then, the creator of the interface could declare any methods from super-interfaces which should be included as properties. That would mean the creator of the interface would have full control over which properties are included/excluded. To me, having full control of the interface is more important than it would be for a concrete class because concrete classes already depend on some of the implementation details of their super-classes. Do you agree? > >> What do you think, Ian? Am I correct that these behaviors would be >> expected? >> >> Also, do you agree that (barring unforeseen events/bugs), the next >> release candidate should be the last before 1.0? > > Agreed. > >> >> Sorry it took so long for me to reply. > > No worries :). > > - Ian > >> >> -Chris >> >> > From: Ian Robertson <ian...@gm...> >> > Date: Fri, 19 Jun 2009 10:58:05 -0600 >> > To: <poj...@li...> >> > Subject: [Pojomatic-users] Handling annotations on interfaces >> > >> > Currently, Pojomatic ignores annotations on any interfaces a class might >> > implement. Moreover, it is not possible to create a pojomator for an >> > interface, since ClassProperties walks up the superclass hierarchy until >> > it >> > hits Object.class, but the superclass of an interface is null, so we >> > get a >> > NullPointerException. >> > >> > I can see at least two use cases for supporting Pojomators for >> > interfaces: >> > >> > If an interface defines the behavior of equals and hashCode as part of >> > its >> > contract, it could include @Property annotations and a public static >> > Pojomator instance which implementing classes could use for their equals >> > and >> > hashCode implementations. >> > If someone needs to be able to check equality on a subset of properties >> > of >> > SomeClass (independently of SomeClass's equals method), they can define >> > an >> > interface with only those properties, annotate those properties (on the >> > interface) and then have SomeClass implement that interface. Finally, >> > they >> > could use the pojomator for the interface to check equality of just the >> > properties in question. >> > >> > What I would like to propose is that if ClassProperties is constructed >> > for >> > an interface, that it walk up the implementors hierarchy instead of the >> > superclass hierarchy; classes would continue to be handled as they are >> > today. As such, this is a non-breaking change. However, I would not be >> > surprised to see an argument being made that, when constructing >> > ClassProperties for a class, that we should not only examine super >> > classes >> > for annotations, but also interfaces. >> > >> > My personal opinion is that the pojomator for a class should not include >> > properties annotated on any of interfaces which the class implements. >> > If an >> > interface wishes to specify how equals and hashCode should be >> > implemented, >> > it can do so as described in the first use case above. But in general, >> > a >> > class implementation should not need to worry about what annotations >> > might >> > or might not be present on its interfaces. >> > >> > What do others think about this? Should the pojomator for a class >> > include >> > annotated properties from interfaces or not? >> > >> > - Ian >> > >> >> >> ------------------------------------------------------------------------------ >> Enter the BlackBerry Developer Challenge >> This is your chance to win up to $100,000 in prizes! For a limited time, >> vendors submitting new applications to BlackBerry App World(TM) will have >> the opportunity to enter the BlackBerry Developer Challenge. See full >> prize >> details at: http://p.sf.net/sfu/Challenge >> _______________________________________________ >> Pojomatic-users mailing list >> Poj...@li... >> https://lists.sourceforge.net/lists/listinfo/pojomatic-users > > |
From: Ian R. <ian...@gm...> - 2009-07-09 15:47:06
|
On Wed, Jul 8, 2009 at 11:21 PM, Chris Hansen <han...@gm...>wrote: > I don't have strong feelings one way or another, so my opinions are > based upon the "principle of least astonishment". > > My gut reaction is to include annotated properties from interfaces, > just because they must have been placed for a purpose and it would > therefore seem discourteous to ignore them ;) . A better reason is > that the @Property annotations present on an interface can be seen as > a part of the API that comes along with implementing the interface, > the same way the properties are inherited when you extend a class. > I've been thinking about this. If property annotations are "part of the interface", then it's likely that the interface is defining what equals means. In this case, it's likely that the implementors should not be defining their own pojomators. Specifically, the point of an interface defining what equals means is to allow equality between different implementations (java.util.List provides a good example of this). For this to work, the equals method needs to do it's instanceof check against the interface class, not the implementing class. In turn, this means that the pojomator would need to be defined on the interface class. So while having pojomatic walk the interface hierarchy for a class might have pojomatic doing what the client expected, it very likely is not doing what the client really wants. Or at least, not in any of the use cases I've been able to come up with... > As for creating a Pojomator instance for an interface, I think the > expected behavior would be to walk up the inheritance hierarchy of the > given interface only and use all @Property annotations found. I'm not > quite sure if that is exactly what you proposed or slightly different. That is in line with what I was thinking. Although now I'm wondering whether it even makes sense to walk up the hierarchy for an interface, based on my comments above... What do you think, Ian? Am I correct that these behaviors would be expected? > > Also, do you agree that (barring unforeseen events/bugs), the next > release candidate should be the last before 1.0? Agreed. > Sorry it took so long for me to reply. No worries :). - Ian > -Chris > > > From: Ian Robertson <ian...@gm...> > > Date: Fri, 19 Jun 2009 10:58:05 -0600 > > To: <poj...@li...> > > Subject: [Pojomatic-users] Handling annotations on interfaces > > > > Currently, Pojomatic ignores annotations on any interfaces a class might > > implement. Moreover, it is not possible to create a pojomator for an > > interface, since ClassProperties walks up the superclass hierarchy until > it > > hits Object.class, but the superclass of an interface is null, so we get > a > > NullPointerException. > > > > I can see at least two use cases for supporting Pojomators for > interfaces: > > > > If an interface defines the behavior of equals and hashCode as part of > its > > contract, it could include @Property annotations and a public static > > Pojomator instance which implementing classes could use for their equals > and > > hashCode implementations. > > If someone needs to be able to check equality on a subset of properties > of > > SomeClass (independently of SomeClass's equals method), they can define > an > > interface with only those properties, annotate those properties (on the > > interface) and then have SomeClass implement that interface. Finally, > they > > could use the pojomator for the interface to check equality of just the > > properties in question. > > > > What I would like to propose is that if ClassProperties is constructed > for > > an interface, that it walk up the implementors hierarchy instead of the > > superclass hierarchy; classes would continue to be handled as they are > > today. As such, this is a non-breaking change. However, I would not be > > surprised to see an argument being made that, when constructing > > ClassProperties for a class, that we should not only examine super > classes > > for annotations, but also interfaces. > > > > My personal opinion is that the pojomator for a class should not include > > properties annotated on any of interfaces which the class implements. If > an > > interface wishes to specify how equals and hashCode should be > implemented, > > it can do so as described in the first use case above. But in general, a > > class implementation should not need to worry about what annotations > might > > or might not be present on its interfaces. > > > > What do others think about this? Should the pojomator for a class > include > > annotated properties from interfaces or not? > > > > - Ian > > > > > ------------------------------------------------------------------------------ > Enter the BlackBerry Developer Challenge > This is your chance to win up to $100,000 in prizes! For a limited time, > vendors submitting new applications to BlackBerry App World(TM) will have > the opportunity to enter the BlackBerry Developer Challenge. See full prize > details at: http://p.sf.net/sfu/Challenge > _______________________________________________ > Pojomatic-users mailing list > Poj...@li... > https://lists.sourceforge.net/lists/listinfo/pojomatic-users > |
From: Chris H. <han...@gm...> - 2009-07-09 05:21:13
|
I don't have strong feelings one way or another, so my opinions are based upon the "principle of least astonishment". My gut reaction is to include annotated properties from interfaces, just because they must have been placed for a purpose and it would therefore seem discourteous to ignore them ;) . A better reason is that the @Property annotations present on an interface can be seen as a part of the API that comes along with implementing the interface, the same way the properties are inherited when you extend a class. As for creating a Pojomator instance for an interface, I think the expected behavior would be to walk up the inheritance hierarchy of the given interface only and use all @Property annotations found. I'm not quite sure if that is exactly what you proposed or slightly different. What do you think, Ian? Am I correct that these behaviors would be expected? Also, do you agree that (barring unforeseen events/bugs), the next release candidate should be the last before 1.0? Sorry it took so long for me to reply. -Chris > From: Ian Robertson <ian...@gm...> > Date: Fri, 19 Jun 2009 10:58:05 -0600 > To: <poj...@li...> > Subject: [Pojomatic-users] Handling annotations on interfaces > > Currently, Pojomatic ignores annotations on any interfaces a class might > implement. Moreover, it is not possible to create a pojomator for an > interface, since ClassProperties walks up the superclass hierarchy until it > hits Object.class, but the superclass of an interface is null, so we get a > NullPointerException. > > I can see at least two use cases for supporting Pojomators for interfaces: > > If an interface defines the behavior of equals and hashCode as part of its > contract, it could include @Property annotations and a public static > Pojomator instance which implementing classes could use for their equals and > hashCode implementations. > If someone needs to be able to check equality on a subset of properties of > SomeClass (independently of SomeClass's equals method), they can define an > interface with only those properties, annotate those properties (on the > interface) and then have SomeClass implement that interface. Finally, they > could use the pojomator for the interface to check equality of just the > properties in question. > > What I would like to propose is that if ClassProperties is constructed for > an interface, that it walk up the implementors hierarchy instead of the > superclass hierarchy; classes would continue to be handled as they are > today. As such, this is a non-breaking change. However, I would not be > surprised to see an argument being made that, when constructing > ClassProperties for a class, that we should not only examine super classes > for annotations, but also interfaces. > > My personal opinion is that the pojomator for a class should not include > properties annotated on any of interfaces which the class implements. If an > interface wishes to specify how equals and hashCode should be implemented, > it can do so as described in the first use case above. But in general, a > class implementation should not need to worry about what annotations might > or might not be present on its interfaces. > > What do others think about this? Should the pojomator for a class include > annotated properties from interfaces or not? > > - Ian > |
From: Ian R. <ian...@gm...> - 2009-06-19 16:58:12
|
Currently, Pojomatic ignores annotations on any interfaces a class might implement. Moreover, it is not possible to create a pojomator for an interface, since ClassProperties walks up the superclass hierarchy until it hits Object.class, but the superclass of an interface is null, so we get a NullPointerException. I can see at least two use cases for supporting Pojomators for interfaces: 1. If an interface defines the behavior of equals and hashCode as part of its contract, it could include @Property annotations and a public static Pojomator instance which implementing classes could use for their equals and hashCode implementations. 2. If someone needs to be able to check equality on a subset of properties of SomeClass (independently of SomeClass's equals method), they can define an interface with only those properties, annotate those properties (on the interface) and then have SomeClass implement that interface. Finally, they could use the pojomator for the interface to check equality of just the properties in question. What I would like to propose is that if ClassProperties is constructed for an interface, that it walk up the implementors hierarchy instead of the superclass hierarchy; classes would continue to be handled as they are today. As such, this is a non-breaking change. However, I would not be surprised to see an argument being made that, when constructing ClassProperties for a class, that we should not only examine super classes for annotations, but also interfaces. My personal opinion is that the pojomator for a class should not include properties annotated on any of interfaces which the class implements. If an interface wishes to specify how equals and hashCode should be implemented, it can do so as described in the first use case above. But in general, a class implementation should not need to worry about what annotations might or might not be present on its interfaces. What do others think about this? Should the pojomator for a class include annotated properties from interfaces or not? - Ian |