You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(12) |
Nov
(2) |
Dec
(15) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(7) |
Feb
(2) |
Mar
|
Apr
(22) |
May
|
Jun
|
Jul
(1) |
Aug
(29) |
Sep
(17) |
Oct
(4) |
Nov
|
Dec
(19) |
2010 |
Jan
|
Feb
(9) |
Mar
(2) |
Apr
(34) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(25) |
Nov
(22) |
Dec
(3) |
2014 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <iro...@us...> - 2010-02-25 16:45:57
|
Revision: 189 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=189&view=rev Author: iroberts Date: 2010-02-25 16:45:45 +0000 (Thu, 25 Feb 2010) Log Message: ----------- unused import Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java 2010-02-25 16:45:01 UTC (rev 188) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java 2010-02-25 16:45:45 UTC (rev 189) @@ -1,6 +1,5 @@ package org.pojomatic.formatter; -import java.lang.reflect.AnnotatedElement; import java.util.Arrays; import org.pojomatic.annotations.Property; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2010-02-25 16:45:08
|
Revision: 188 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=188&view=rev Author: iroberts Date: 2010-02-25 16:45:01 +0000 (Thu, 25 Feb 2010) Log Message: ----------- warning cleanup Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java Modified: trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java 2009-12-07 17:31:22 UTC (rev 187) +++ trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java 2010-02-25 16:45:01 UTC (rev 188) @@ -3,7 +3,7 @@ public class Implementation implements Interface { private final String name; - public Implementation(String name, String value) { + public Implementation(String name) { this.name = name; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-12-07 17:31:41
|
Revision: 187 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=187&view=rev Author: chriswhansen Date: 2009-12-07 17:31:22 +0000 (Mon, 07 Dec 2009) Log Message: ----------- Ignore Eclipse files. Property Changed: ---------------- trunk/PojomaticAll/ trunk/PojomaticAll/Pojomatic/ trunk/PojomaticAll/PojomaticTestUtils/ Property changes on: trunk/PojomaticAll ___________________________________________________________________ Modified: svn:ignore - target + target .settings .project Property changes on: trunk/PojomaticAll/Pojomatic ___________________________________________________________________ Modified: svn:ignore - target bin + target .settings .project .classpath Property changes on: trunk/PojomaticAll/PojomaticTestUtils ___________________________________________________________________ Modified: svn:ignore - target + target .settings .project .classpath This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 04:08:33
|
Revision: 186 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=186&view=rev Author: iroberts Date: 2009-12-07 04:08:25 +0000 (Mon, 07 Dec 2009) Log Message: ----------- [maven-release-plugin] prepare for next development iteration Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/pom.xml trunk/PojomaticAll/PojomaticTestUtils/pom.xml trunk/PojomaticAll/pom.xml Modified: trunk/PojomaticAll/Pojomatic/pom.xml =================================================================== --- trunk/PojomaticAll/Pojomatic/pom.xml 2009-12-07 04:08:17 UTC (rev 185) +++ trunk/PojomaticAll/Pojomatic/pom.xml 2009-12-07 04:08:25 UTC (rev 186) @@ -2,7 +2,7 @@ <parent> <artifactId>pojomatic-all</artifactId> <groupId>org.pojomatic</groupId> - <version>1.0-RC3</version> + <version>trunk-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> @@ -14,9 +14,9 @@ equals(Object), toString() and hashCode() methods inherited from java.lang.Object </description> <scm> - <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</connection> - <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</developerConnection> - <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</url> + <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/pojomatic-all/pojomatic</connection> + <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/pojomatic-all/pojomatic</developerConnection> + <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/pojomatic-all/pojomatic</url> </scm> <reporting> Modified: trunk/PojomaticAll/PojomaticTestUtils/pom.xml =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/pom.xml 2009-12-07 04:08:17 UTC (rev 185) +++ trunk/PojomaticAll/PojomaticTestUtils/pom.xml 2009-12-07 04:08:25 UTC (rev 186) @@ -2,7 +2,7 @@ <parent> <artifactId>pojomatic-all</artifactId> <groupId>org.pojomatic</groupId> - <version>1.0-RC3</version> + <version>trunk-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> Modified: trunk/PojomaticAll/pom.xml =================================================================== --- trunk/PojomaticAll/pom.xml 2009-12-07 04:08:17 UTC (rev 185) +++ trunk/PojomaticAll/pom.xml 2009-12-07 04:08:25 UTC (rev 186) @@ -3,7 +3,7 @@ <groupId>org.pojomatic</groupId> <artifactId>pojomatic-all</artifactId> <packaging>pom</packaging> - <version>1.0-RC3</version> + <version>trunk-SNAPSHOT</version> <name>PojomaticAll</name> <description> Parent and aggregator for all artifacts related to the Pojomatic project. @@ -11,9 +11,9 @@ <url>http://www.pojomatic.org</url> <inceptionYear>2008</inceptionYear> <scm> - <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</connection> - <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</developerConnection> - <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</url> + <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/PojomaticAll</connection> + <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/PojomaticAll</developerConnection> + <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/PojomaticAll</url> </scm> <dependencies> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 04:08:23
|
Revision: 185 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=185&view=rev Author: iroberts Date: 2009-12-07 04:08:17 +0000 (Mon, 07 Dec 2009) Log Message: ----------- [maven-scm] copy for tag pojomatic-all-1.0-RC3 Added Paths: ----------- tags/pojomatic-all-1.0-RC3/ Property changes on: tags/pojomatic-all-1.0-RC3 ___________________________________________________________________ Added: svn:ignore + target Added: svn:mergeinfo + /branches/TestUtils:133-144 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 04:08:10
|
Revision: 184 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=184&view=rev Author: iroberts Date: 2009-12-07 04:08:03 +0000 (Mon, 07 Dec 2009) Log Message: ----------- [maven-release-plugin] prepare release pojomatic-all-1.0-RC3 Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/pom.xml trunk/PojomaticAll/PojomaticTestUtils/pom.xml trunk/PojomaticAll/pom.xml Modified: trunk/PojomaticAll/Pojomatic/pom.xml =================================================================== --- trunk/PojomaticAll/Pojomatic/pom.xml 2009-12-07 04:05:07 UTC (rev 183) +++ trunk/PojomaticAll/Pojomatic/pom.xml 2009-12-07 04:08:03 UTC (rev 184) @@ -2,7 +2,7 @@ <parent> <artifactId>pojomatic-all</artifactId> <groupId>org.pojomatic</groupId> - <version>trunk-SNAPSHOT</version> + <version>1.0-RC3</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> @@ -14,9 +14,9 @@ equals(Object), toString() and hashCode() methods inherited from java.lang.Object </description> <scm> - <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/pojomatic-all/pojomatic</connection> - <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/pojomatic-all/pojomatic</developerConnection> - <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/pojomatic-all/pojomatic</url> + <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</connection> + <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</developerConnection> + <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</url> </scm> <reporting> Modified: trunk/PojomaticAll/PojomaticTestUtils/pom.xml =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/pom.xml 2009-12-07 04:05:07 UTC (rev 183) +++ trunk/PojomaticAll/PojomaticTestUtils/pom.xml 2009-12-07 04:08:03 UTC (rev 184) @@ -1,9 +1,8 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <parent> <artifactId>pojomatic-all</artifactId> <groupId>org.pojomatic</groupId> - <version>trunk-SNAPSHOT</version> + <version>1.0-RC3</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> Modified: trunk/PojomaticAll/pom.xml =================================================================== --- trunk/PojomaticAll/pom.xml 2009-12-07 04:05:07 UTC (rev 183) +++ trunk/PojomaticAll/pom.xml 2009-12-07 04:08:03 UTC (rev 184) @@ -3,7 +3,7 @@ <groupId>org.pojomatic</groupId> <artifactId>pojomatic-all</artifactId> <packaging>pom</packaging> - <version>trunk-SNAPSHOT</version> + <version>1.0-RC3</version> <name>PojomaticAll</name> <description> Parent and aggregator for all artifacts related to the Pojomatic project. @@ -11,9 +11,9 @@ <url>http://www.pojomatic.org</url> <inceptionYear>2008</inceptionYear> <scm> - <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/PojomaticAll</connection> - <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/PojomaticAll</developerConnection> - <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/trunk/PojomaticAll</url> + <connection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</connection> + <developerConnection>scm:svn:https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</developerConnection> + <url>https://pojomatic.svn.sourceforge.net/svnroot/pojomatic/tags/pojomatic-all-1.0-RC3</url> </scm> <dependencies> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 04:05:13
|
Revision: 183 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=183&view=rev Author: iroberts Date: 2009-12-07 04:05:07 +0000 (Mon, 07 Dec 2009) Log Message: ----------- document message param Modified Paths: -------------- trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/junit/PojomaticAssert.java Modified: trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/junit/PojomaticAssert.java =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/junit/PojomaticAssert.java 2009-12-07 04:04:53 UTC (rev 182) +++ trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/junit/PojomaticAssert.java 2009-12-07 04:05:07 UTC (rev 183) @@ -31,6 +31,7 @@ * * @param expected the expected object * @param actual the object which should be tested to equal the expected object + * @param message the identifying message for the {@code AssertionError} ({@code null} okay) * @throws AssertionError if the objects are not equal, with details of the differences * included in the message */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 04:05:00
|
Revision: 182 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=182&view=rev Author: iroberts Date: 2009-12-07 04:04:53 +0000 (Mon, 07 Dec 2009) Log Message: ----------- typo Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt Modified: trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt =================================================================== --- trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt 2009-12-07 04:04:28 UTC (rev 181) +++ trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt 2009-12-07 04:04:53 UTC (rev 182) @@ -2,7 +2,7 @@ Changes in Pojomatic ~~~~ -* Release 1.0-RC3 (2009-012-06) +* Release 1.0-RC3 (2009-12-06) ~~~~ * <<<Pojomatic.equals()>>> now properly handles inheritance, including comparing instances of two separate child classes of a This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 04:04:36
|
Revision: 181 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=181&view=rev Author: iroberts Date: 2009-12-07 04:04:28 +0000 (Mon, 07 Dec 2009) Log Message: ----------- No point in overriding empty method with empty method Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java 2009-12-07 03:44:04 UTC (rev 180) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/AccountNumberFormatter.java 2009-12-07 04:04:28 UTC (rev 181) @@ -21,11 +21,6 @@ private char fillChar = DEFAULT_FILL_CHAR; @Override - public void initialize(AnnotatedElement element) { - //nothing to initialize - } - - @Override public String format(Object value) { String rep = super.format(value); int repLength = rep.length(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 03:44:11
|
Revision: 180 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=180&view=rev Author: iroberts Date: 2009-12-07 03:44:04 +0000 (Mon, 07 Dec 2009) Log Message: ----------- link to bug Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt Modified: trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt =================================================================== --- trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt 2009-12-07 03:19:15 UTC (rev 179) +++ trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt 2009-12-07 03:44:04 UTC (rev 180) @@ -6,7 +6,8 @@ ~~~~ * <<<Pojomatic.equals()>>> now properly handles inheritance, including comparing instances of two separate child classes of a - parent class (Bug 2845939). + parent class + ({{{https://sourceforge.net/tracker/?func=detail&aid=2845939&group_id=239113&atid=1108645}bug 2845939}}). * A <<<Pojomator>>> can now be created for an interface. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-07 03:19:25
|
Revision: 179 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=179&view=rev Author: iroberts Date: 2009-12-07 03:19:15 +0000 (Mon, 07 Dec 2009) Log Message: ----------- Add documentation for interfaces. Update changelog. Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java trunk/PojomaticAll/Pojomatic/src/main/javadoc/overview.html trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt Added Paths: ----------- trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java trunk/PojomaticAll/Pojomatic/src/test/java/examples/Interface.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java 2009-12-06 05:37:10 UTC (rev 178) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java 2009-12-07 03:19:15 UTC (rev 179) @@ -31,24 +31,40 @@ * </p> * Under the covers, these methods are referencing a {@link org.pojomatic.Pojomator Pojomator} instance * which is created lazily and cached on a per-class basis. The performance penalty for this is - * negligible, but if profiling suggests that it is a bottleneck, one can do this by hand: - * <p style="background-color:#EEEEFF; margin: 1em"> + * negligible, but if an interface is annotated for Pojomation, using the {@code Pojomator} directly + * is required, since the {@code Pojomator} for a class will only reference properties in the class + * and it's superclasses, but not any implemented interfaces. To do this, first define a static + * constant {@code POJOMATOR} in the interface: + * <p style="background-color:#EEEEFF; margin: 1em"> * <code> - * <font color="#ffffff"> </font><font color="#7f0055"><b>private final static </b></font><font color="#000000">Pojomator<Manual> POJOMATOR = Pojomatic.pojomator</font><font color="#000000">(</font><font color="#000000">Manual.</font><font color="#7f0055"><b>class</b></font><font color="#000000">)</font><font color="#000000">;</font><br /> - * <font color="#ffffff"></font><br /> - * <font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>boolean </b></font><font color="#000000">equals</font><font color="#000000">(</font><font color="#000000">Object other</font><font color="#000000">) {</font><br /> - * <font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">POJOMATOR.doEquals</font><font color="#000000">(</font><font color="#000000">this, other</font><font color="#000000">)</font><font color="#000000">;</font><br /> - * <font color="#ffffff"> </font><font color="#000000">}</font><br /> - * <font color="#ffffff"></font><br /> - * <font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>int </b></font><font color="#000000">hashCode</font><font color="#000000">() {</font><br /> - * <font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">POJOMATOR.doHashCode</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br /> - * <font color="#ffffff"> </font><font color="#000000">}</font><br /> - * <font color="#ffffff"></font><br /> - * <font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#000000">String toString</font><font color="#000000">() {</font><br /> - * <font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">POJOMATOR.doToString</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br /> - * <font color="#ffffff"> </font><font color="#000000">}</font> - * </code> + * <font color="#7f0055"><b>import </b></font>org.pojomatic.annotations.AutoProperty;<br /> + * <font color="#7f0055"><b>import </b></font>org.pojomatic.Pojomator;<br /> + * <font color="#7f0055"><b>import </b></font>org.pojomatic.Pojomatic;<br /> + * <br /> + * <font color="#646464">@AutoProperty</font><br /> + * <font color="#7f0055"><b>public interface </b></font>Interface {<br /> + * <font color="#7f0055"><b>static </b></font>Pojomator<Interface> POJOMATOR = Pojomatic.pojomator(Interface.<font color="#7f0055"><b>class</b></font>);<br /> + * ...<br /> + * }</code> * </p> + * and then delegate to {@code POJOMATOR} in the implementing classes: + * <p style="background-color:#EEEEFF; margin: 1em"> + * <code> + * <font color="#7f0055"><b>public class </b></font>Implementation <font color="#7f0055"><b>implements </b></font>Interface {<br /> + * <font color="#646464">@Override</font> <font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>int </b></font>hashCode() {<br /> + * <font color="#7f0055"><b>return </b></font>POJOMATOR.doHashCode(<font color="#7f0055"><b>this</b></font>);<br /> + * }<br /> + * <br /> + * <font color="#646464">@Override</font> <font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>boolean </b></font>equals(Object other) {<br /> + * <font color="#7f0055"><b>return </b></font>POJOMATOR.doEquals(this, other);<br /> + * }<br /> + * <br /> + * <font color="#646464">@Override</font> <font color="#7f0055"><b>public </b></font>String toString() {<br /> + * <font color="#7f0055"><b>return </b></font>POJOMATOR.doToString(<font color="#7f0055"><b>this</b></font>);<br /> + * }<br /> + * ...<br /> + * }</code> + * </p> * * @see Pojomator */ Modified: trunk/PojomaticAll/Pojomatic/src/main/javadoc/overview.html =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/javadoc/overview.html 2009-12-06 05:37:10 UTC (rev 178) +++ trunk/PojomaticAll/Pojomatic/src/main/javadoc/overview.html 2009-12-07 03:19:15 UTC (rev 179) @@ -15,42 +15,89 @@ the three methods. <h2>Annotations</h2> -Pojomatic behavior is controlled by annotations; these can be on a property-by-property basis, a -class-wide basis, or a mix of the two. Class wide behavior can be controlled by the -{@link org.pojomatic.annotations.AutoProperty AutoProperty} and -{@link org.pojomatic.annotations.PojoFormat PojoFormat}, while property-specific behavior can be -controlled by the {@link org.pojomatic.annotations.Property Property} and -{@link org.pojomatic.annotations.PropertyFormat PropertyFormat} annotations. A recommended practice is -to provide an {@code AutoProperty} annotation at the class level, and then override the behavior it -specifies on a per-property basis as needed. This minimizes both the number of annotations needed, -as well as the number of additional steps needed when adding new properties to a class. - -<h2>Implementing equals, hashCode and toString</h2> -To implement equals, hashCode and toString, simply annotate the class for pojomation (see below), +<p> + Pojomatic behavior is controlled by annotations; these can be on a property-by-property basis, a + class-wide basis, or a mix of the two. Class wide behavior can be controlled by the + {@link org.pojomatic.annotations.AutoProperty AutoProperty} and + {@link org.pojomatic.annotations.PojoFormat PojoFormat}, while property-specific behavior can be + controlled by the {@link org.pojomatic.annotations.Property Property} and + {@link org.pojomatic.annotations.PropertyFormat PropertyFormat} annotations. A recommended + practice is to provide an {@code AutoProperty} annotation at the class level, and then override + the behavior it specifies on a per-property basis as needed. This minimizes both the number of + annotations needed, as well as the number of additional steps needed when adding new properties to + a class. +</p> +<p> + The annotations {@link org.pojomatic.annotations.OverridesEquals} and + {@link org.pojomatic.annotations.SubclassCannotOverrideEquals} can be used to control the behavior + of {@code equals} for inheritance hierarchies. If instances of a child class cannot possibly be + equal to instances of the parent class which are not themselves instance of the child class, + annotating the child class with {@code OverridesEquals} can inform Pojomatic of this (although + if any additional properties have been added for inclusion in the {@code equals} method by the child + class, Pojomatic will infer this automatically). Conversely, one can declare via the + {@code SubclassCannotOverrideEquals} annotation that no additional properties will be added by + child classes. +</p> +<h2>Implementing {@code equals}, {@code hashCode} and {@code toString}</h2> +To implement {@code equals}, {@code hashCode} and {@code toString}, simply annotate the class for pojomation (see below), and delegate to the static methods in {@link org.pojomatic.Pojomatic Pojomatic}: <p style="background-color:#EEEEFF; margin: 1em"> <code> -<font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>int </b></font><font color="#000000">hashCode</font><font color="#000000">() {</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">Pojomatic.hashCode</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br /> -<font color="#ffffff"> </font><font color="#000000">}</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#000000">String toString</font><font color="#000000">() {</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">Pojomatic.toString</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br /> -<font color="#ffffff"> </font><font color="#000000">}</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>boolean </b></font><font color="#000000">equals</font><font color="#000000">(</font><font color="#000000">Object o</font><font color="#000000">) {</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">Pojomatic.equals</font><font color="#000000">(</font><font color="#000000">this, o</font><font color="#000000">)</font><font color="#000000">;</font><br /> -<font color="#ffffff"> </font><font color="#000000">}</font></code> + <font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>int </b></font>hashCode() {<br /> + <font color="#7f0055"><b>return </b></font>Pojomatic.hashCode(<font color="#7f0055"><b>this</b></font>);<br /> + }<br /> +<br /> + <font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font>String toString() {<br /> + <font color="#7f0055"><b>return </b></font>Pojomatic.toString(<font color="#7f0055"><b>this</b></font>);<br /> + }<br /> +<br /> + <font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>boolean </b></font>equals(Object o) {<br /> + <font color="#7f0055"><b>return </b></font>Pojomatic.equals(this, o);<br /> + }</code> </p> +<h2>Implementing {@code equals}, {@code hashCode} and {@code toString} for interfaces</h2> +To implement {@code equals}, {@code hashCode} and {@code toString} for an interface, first annotate the interface for +pojomation (see below) and define a static constant {@code POJOMATOR} in the interface: +<p style="background-color:#EEEEFF; margin: 1em"> +<code> + <font color="#7f0055"><b>import </b></font>org.pojomatic.annotations.AutoProperty;<br /> + <font color="#7f0055"><b>import </b></font>org.pojomatic.Pojomator;<br /> + <font color="#7f0055"><b>import </b></font>org.pojomatic.Pojomatic;<br /> + <br /> + <font color="#646464">@AutoProperty</font><br /> + <font color="#7f0055"><b>public interface </b></font>Interface {<br /> + <font color="#7f0055"><b>static </b></font>Pojomator<Interface> POJOMATOR = Pojomatic.pojomator(Interface.<font color="#7f0055"><b>class</b></font>);<br /> + ...<br /> +}</code> +</p> +and then delegate to {@code POJOMATOR} in the implementing classes: +<p style="background-color:#EEEEFF; margin: 1em"> +<code> + <font color="#7f0055"><b>public class </b></font>Implementation <font color="#7f0055"><b>implements </b></font>Interface {<br /> + <font color="#646464">@Override</font> <font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>int </b></font>hashCode() {<br /> + <font color="#7f0055"><b>return </b></font>POJOMATOR.doHashCode(<font color="#7f0055"><b>this</b></font>);<br /> + }<br /> + <br /> + <font color="#646464">@Override</font> <font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>boolean </b></font>equals(Object other) {<br /> + <font color="#7f0055"><b>return </b></font>POJOMATOR.doEquals(this, other);<br /> + }<br /> + <br /> + <font color="#646464">@Override</font> <font color="#7f0055"><b>public </b></font>String toString() {<br /> + <font color="#7f0055"><b>return </b></font>POJOMATOR.doToString(<font color="#7f0055"><b>this</b></font>);<br /> + }<br /> + ...<br /> + }</code> +</p> + <h2>Example Annotations</h2> The simplest way to annotate a class for pojomation is to add a single {@code AutoProperty} annotation: <p style="background-color:#EEEEFF; margin: 1em"> <code> <font color="#646464">@AutoProperty </font><font color="#3f7f5f">//all fields are included by default</font><br /> -<font color="#7f0055"><b>public class </b></font><font color="#000000">Common </font><font color="#000000">{</font><br /> +<font color="#7f0055"><b>public class </b></font>Common {<br /> ...<br /> }<br /> </code> @@ -71,12 +118,12 @@ <p style="background-color:#EEEEFF; margin: 1em"> <code> <font color="#646464">@AutoProperty</font><br /> -<font color="#7f0055"><b>public class </b></font><font color="#000000">Employee </font><font color="#000000">{</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>private final </b></font><font color="#000000">String firstName;</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>private final </b></font><font color="#000000">String lastName;</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#646464">@Property</font><font color="#000000">(</font><font color="#000000">policy=PojomaticPolicy.EQUALS_TO_STRING</font><font color="#000000">)</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>private </b></font><font color="#000000">String securityLevel;</font><br /> +<font color="#7f0055"><b>public class </b></font>Employee {<br /> + <font color="#7f0055"><b>private final </b></font>String firstName;<br /> + <font color="#7f0055"><b>private final </b></font>String lastName;<br /> +<br /> + <font color="#646464">@Property</font>(policy=PojomaticPolicy.EQUALS_TO_STRING)<br /> + <font color="#7f0055"><b>private </b></font>String securityLevel;<br /> ...<br /> }<br /> </code> @@ -99,36 +146,36 @@ <p style="background-color:#EEEEFF; margin: 1em"> <code> <font color="#646464">@AutoProperty</font><br /> -<font color="#7f0055"><b>public class </b></font><font color="#000000">Customer </font><font color="#000000">{</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>private final </b></font><font color="#000000">String firstName;</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>private final </b></font><font color="#000000">String lastName;</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#646464">@PropertyFormat</font><font color="#000000">(</font><font color="#000000">AccountNumberFormatter.</font><font color="#7f0055"><b>class</b></font><font color="#000000">)</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>private final </b></font><font color="#000000">String accountNumber;</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>public </b></font><font color="#000000">Customer</font><font color="#000000">(</font><font color="#000000">String accountNumber, String firstName, String lastName</font><font color="#000000">) {</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>this</b></font><font color="#000000">.accountNumber = accountNumber;</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>this</b></font><font color="#000000">.firstName = firstName;</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>this</b></font><font color="#000000">.lastName = lastName;</font><br /> -<font color="#ffffff"> </font><font color="#000000">}</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>public </b></font><font color="#000000">String getFirstName</font><font color="#000000">() { </font><font color="#7f0055"><b>return </b></font><font color="#000000">firstName; </font><font color="#000000">}</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>public </b></font><font color="#000000">String getLastName</font><font color="#000000">() { </font><font color="#7f0055"><b>return </b></font><font color="#000000">lastName; </font><font color="#000000">}</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>public </b></font><font color="#000000">String getAccountNumber</font><font color="#000000">() { </font><font color="#7f0055"><b>return </b></font><font color="#000000">accountNumber; </font><font color="#000000">}</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>int </b></font><font color="#000000">hashCode</font><font color="#000000">() {</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">Pojomatic.hashCode</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br /> -<font color="#ffffff"> </font><font color="#000000">}</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#000000">String toString</font><font color="#000000">() {</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">Pojomatic.toString</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br /> -<font color="#ffffff"> </font><font color="#000000">}</font><br /> -<font color="#ffffff"></font><br /> -<font color="#ffffff"> </font><font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>boolean </b></font><font color="#000000">equals</font><font color="#000000">(</font><font color="#000000">Object o</font><font color="#000000">) {</font><br /> -<font color="#ffffff"> </font><font color="#7f0055"><b>return </b></font><font color="#000000">Pojomatic.equals</font><font color="#000000">(</font><font color="#000000">this, o</font><font color="#000000">)</font><font color="#000000">;</font><br /> -<font color="#ffffff"> </font><font color="#000000">}</font><br /> -<font color="#000000">}</font></code> +<font color="#7f0055"><b>public class </b></font>Customer {<br /> + <font color="#7f0055"><b>private final </b></font>String firstName;<br /> +<br /> + <font color="#7f0055"><b>private final </b></font>String lastName;<br /> +<br /> + <font color="#646464">@PropertyFormat</font>(AccountNumberFormatter.<font color="#7f0055"><b>class</b></font>)<br /> + <font color="#7f0055"><b>private final </b></font>String accountNumber;<br /> +<br /> + <font color="#7f0055"><b>public </b></font>Customer(String accountNumber, String firstName, String lastName) {<br /> + <font color="#7f0055"><b>this</b></font>.accountNumber = accountNumber;<br /> + <font color="#7f0055"><b>this</b></font>.firstName = firstName;<br /> + <font color="#7f0055"><b>this</b></font>.lastName = lastName;<br /> + }<br /> +<br /> + <font color="#7f0055"><b>public </b></font>String getFirstName() { <font color="#7f0055"><b>return </b></font>firstName; }<br /> + <font color="#7f0055"><b>public </b></font>String getLastName() { <font color="#7f0055"><b>return </b></font>lastName; }<br /> + <font color="#7f0055"><b>public </b></font>String getAccountNumber() { <font color="#7f0055"><b>return </b></font>accountNumber; }<br /> +<br /> + <font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>int </b></font>hashCode() {<br /> + <font color="#7f0055"><b>return </b></font>Pojomatic.hashCode(<font color="#7f0055"><b>this</b></font>);<br /> + }<br /> +<br /> + <font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font>String toString() {<br /> + <font color="#7f0055"><b>return </b></font>Pojomatic.toString(<font color="#7f0055"><b>this</b></font>);<br /> + }<br /> +<br /> + <font color="#646464">@Override </font><font color="#7f0055"><b>public </b></font><font color="#7f0055"><b>boolean </b></font>equals(Object o) {<br /> + <font color="#7f0055"><b>return </b></font>Pojomatic.equals(this, o);<br /> + }<br /> +}</code> </p> </body> </html> Modified: trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt =================================================================== --- trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt 2009-12-06 05:37:10 UTC (rev 178) +++ trunk/PojomaticAll/Pojomatic/src/site/apt/changes.apt 2009-12-07 03:19:15 UTC (rev 179) @@ -1,6 +1,29 @@ Changes in Pojomatic + ~~~~ +* Release 1.0-RC3 (2009-012-06) +~~~~ + * <<<Pojomatic.equals()>>> now properly handles inheritance, + including comparing instances of two separate child classes of a + parent class (Bug 2845939). + + * A <<<Pojomator>>> can now be created for an interface. + + * New annotations, <<<OverridesEquals>>> and + <<<SubclassCannotOverrideEquals>>> help control how inheritance is + handled. + + * Properties from the parent class now come before those of the + child in <<<equals>>> calculations and in the <<<toString()>>> + representation. + + * Pojomatic will no longer add a method property multiple times if it is overridden + (even if the overridden method is explicitely annotated). + + * <<<Pojomatic.diff>>> no longer requires a non-null first argument. + +~~~~ * Release 1.0-RC2 (2009-04-07) ~~~~ * A new method, <<<Pojomatic.diff>>>, will show top-level differences between two instances @@ -14,6 +37,7 @@ * Static fields and methods are no longer picked up by <<<@AutoProperty>>> ({{{https://sourceforge.net/tracker/?func=detail&aid=2739467&group_id=239113&atid=1108645}bug 2739467}}) + ~~~~ * Release 1.0-RC1 (2009-01-01) ~~~~ Added: trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java (rev 0) +++ trunk/PojomaticAll/Pojomatic/src/test/java/examples/Implementation.java 2009-12-07 03:19:15 UTC (rev 179) @@ -0,0 +1,25 @@ +package examples; + +public class Implementation implements Interface { + private final String name; + + public Implementation(String name, String value) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override public int hashCode() { + return POJOMATOR.doHashCode(this); + } + + @Override public boolean equals(Object other) { + return POJOMATOR.doEquals(this, other); + } + + @Override public String toString() { + return POJOMATOR.doToString(this); + } +} Added: trunk/PojomaticAll/Pojomatic/src/test/java/examples/Interface.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/examples/Interface.java (rev 0) +++ trunk/PojomaticAll/Pojomatic/src/test/java/examples/Interface.java 2009-12-07 03:19:15 UTC (rev 179) @@ -0,0 +1,12 @@ +package examples; + +import org.pojomatic.annotations.AutoProperty; +import org.pojomatic.Pojomator; +import org.pojomatic.Pojomatic; + +@AutoProperty +public interface Interface { + static Pojomator<Interface> POJOMATOR = Pojomatic.pojomator(Interface.class); + + String getName(); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-06 05:37:17
|
Revision: 178 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=178&view=rev Author: iroberts Date: 2009-12-06 05:37:10 +0000 (Sun, 06 Dec 2009) Log Message: ----------- increase test coverage Modified Paths: -------------- trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/junit/PojomaticAssertTest.java trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertTest.java trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertUtilsTest.java trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/testng/PojomaticAssertTest.java Modified: trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/junit/PojomaticAssertTest.java =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/junit/PojomaticAssertTest.java 2009-12-06 04:05:00 UTC (rev 177) +++ trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/junit/PojomaticAssertTest.java 2009-12-06 05:37:10 UTC (rev 178) @@ -5,8 +5,8 @@ public class PojomaticAssertTest extends AssertTest { @Override - protected void performAssertEquals(Object first, Object second) { - PojomaticAssert.assertEqualsWithDiff(first, second); + protected void performAssertEquals(Object first, Object second, String message) { + PojomaticAssert.assertEqualsWithDiff(first, second, message); } } Modified: trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertTest.java =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertTest.java 2009-12-06 04:05:00 UTC (rev 177) +++ trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertTest.java 2009-12-06 05:37:10 UTC (rev 178) @@ -1,6 +1,6 @@ package org.pojomatic.test; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.Test; import org.pojomatic.Pojomatic; @@ -18,23 +18,23 @@ * @param first the object which should appear first if the assertion fails. Note that this * could be either "expected" or "actual". * @param second the object which should appear second if the assertion fails. Note that this - * could be either "expected" or "actual". + * @param message the messaage to include with the assertion */ - protected abstract void performAssertEquals(Object first, Object second); + protected abstract void performAssertEquals(Object first, Object second, String message); @Test public final void assertEqualsBothNull() { - performAssertEquals(null, null); + performAssertEquals(null, null, null); } @Test(expected=AssertionError.class) public final void assertEqualsNullExpected() { - performAssertEquals(null, new Container(null)); + performAssertEquals(null, new Container(null), null); } @Test(expected=AssertionError.class) public final void assertEqualsNullActual() { - performAssertEquals(new Container(null), null); + performAssertEquals(new Container(null), null, null); } /** @@ -48,45 +48,24 @@ OnlyPojomaticEqual first = new OnlyPojomaticEqual(); OnlyPojomaticEqual second = new OnlyPojomaticEqual(); - performAssertEquals(first, second); + performAssertEquals(first, second, null); } @Test - public final void assertEqualsMessagingOrder() { + public final void assertEqualsMessage() { String first = "foo"; String second = "bar"; try { - performAssertEquals(new Container(first), new Container(second)); + performAssertEquals(new Container(first), new Container(second), null); } catch (AssertionError e) { - //expected, check the message - assertAppearanceOrder(e.getMessage(), first, second); + assertEquals("[test: {foo} versus {bar}]", e.getMessage()); } - } - - /** - * Asserts that {@code first} appears before {@code second} in {@code text}. - * - * @param text must contain both {@code first} and {@code second} - * @param first cannot be {@code null} - * @param second cannot be {@code null} - * @throws NullPointerException if {@code first} or {@code second} is {@code null} - * @throws IllegalArgumentException if {@code text} does not contain both - * {@code first} and {@code second} - */ - protected final void assertAppearanceOrder(String text, String first, String second) { - if (first == null || second == null) { - throw new NullPointerException(); + try { + performAssertEquals(new Container(first), new Container(second), "custom message"); } - int firstIndex = text.indexOf(first); - int secondIndex = text.indexOf(second); - if (firstIndex < 0 || secondIndex < 0) { - throw new IllegalArgumentException("The string \"" + text + "\" does not conatin " + - "both \"" + first + "\" and \"" + second + "\""); + catch (AssertionError e) { + assertEquals("custom message [test: {foo} versus {bar}]", e.getMessage()); } - String message = "In the string \"" + text + "\", " + - "\"" + first + "\" should come before \"" + second + "\""; - assertTrue(message, firstIndex < secondIndex); } - } Modified: trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertUtilsTest.java =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertUtilsTest.java 2009-12-06 04:05:00 UTC (rev 177) +++ trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/test/AssertUtilsTest.java 2009-12-06 05:37:10 UTC (rev 178) @@ -7,8 +7,8 @@ public class AssertUtilsTest extends AssertTest { @Override - protected void performAssertEquals(Object first, Object second) { - AssertUtils.assertEquals(null, first, second); + protected void performAssertEquals(Object first, Object second, String message) { + AssertUtils.assertEquals(message, first, second); } @Test Modified: trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/testng/PojomaticAssertTest.java =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/testng/PojomaticAssertTest.java 2009-12-06 04:05:00 UTC (rev 177) +++ trunk/PojomaticAll/PojomaticTestUtils/src/test/java/org/pojomatic/testng/PojomaticAssertTest.java 2009-12-06 05:37:10 UTC (rev 178) @@ -5,9 +5,9 @@ public class PojomaticAssertTest extends AssertTest { @Override - protected void performAssertEquals(Object first, Object second) { + protected void performAssertEquals(Object first, Object second, String message) { //in TestNG, the arguments are included in any failure message in reverse order - PojomaticAssert.assertEqualsWithDiff(second, first); + PojomaticAssert.assertEqualsWithDiff(second, first, message); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-06 04:05:08
|
Revision: 177 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=177&view=rev Author: iroberts Date: 2009-12-06 04:05:00 +0000 (Sun, 06 Dec 2009) Log Message: ----------- Use a StringBuilder Modified Paths: -------------- trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/test/AssertUtils.java Modified: trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/test/AssertUtils.java =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/test/AssertUtils.java 2009-12-06 03:54:21 UTC (rev 176) +++ trunk/PojomaticAll/PojomaticTestUtils/src/main/java/org/pojomatic/test/AssertUtils.java 2009-12-06 04:05:00 UTC (rev 177) @@ -42,12 +42,12 @@ } private static String buildMessage(String message, Differences differences) { - String formatted = ""; + StringBuilder formatted = new StringBuilder(); if (message != null) { - formatted = message + " "; + formatted.append(message).append(" "); } - return formatted + differences.toString(); + return formatted.append(differences).toString(); } private AssertUtils() {} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-06 03:54:27
|
Revision: 176 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=176&view=rev Author: iroberts Date: 2009-12-06 03:54:21 +0000 (Sun, 06 Dec 2009) Log Message: ----------- refer to the interface, not the implementation Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/PojoFormatter.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/PojoFormatter.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/PojoFormatter.java 2009-12-06 03:43:06 UTC (rev 175) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/formatter/PojoFormatter.java 2009-12-06 03:54:21 UTC (rev 176) @@ -1,13 +1,11 @@ package org.pojomatic.formatter; import org.pojomatic.PropertyElement; -import org.pojomatic.internal.PojomatorImpl; +import org.pojomatic.Pojomator; /** * A formatter to aid in creating a {@code String} representation of a POJO. A new instance will be - * created for each time that {@link PojomatorImpl#doToString(Object)} is called. - * - * @see PojomatorImpl#doToString(Object) + * created for each time that {@link Pojomator#doToString(Object)} is called. */ public interface PojoFormatter { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-06 03:43:14
|
Revision: 175 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=175&view=rev Author: iroberts Date: 2009-12-06 03:43:06 +0000 (Sun, 06 Dec 2009) Log Message: ----------- ClassProperties instances are obtained via a factory method Modified Paths: -------------- trunk/PojomaticAll/pojomatic-benchmark/src/main/java/org/pojomatic/Bean.java Modified: trunk/PojomaticAll/pojomatic-benchmark/src/main/java/org/pojomatic/Bean.java =================================================================== --- trunk/PojomaticAll/pojomatic-benchmark/src/main/java/org/pojomatic/Bean.java 2009-12-06 03:41:29 UTC (rev 174) +++ trunk/PojomaticAll/pojomatic-benchmark/src/main/java/org/pojomatic/Bean.java 2009-12-06 03:43:06 UTC (rev 175) @@ -25,7 +25,7 @@ } private static void setUpPojomaticHandrolled() { - ClassProperties classProperties = new ClassProperties(Bean.class); + ClassProperties classProperties = ClassProperties.forClass(Bean.class); for (PropertyElement prop: classProperties.getHashCodeProperties()) { if ("integer".equals(prop.getName())) { getInteger = prop; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-06 03:41:37
|
Revision: 174 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=174&view=rev Author: iroberts Date: 2009-12-06 03:41:29 +0000 (Sun, 06 Dec 2009) Log Message: ----------- latest findbugs Modified Paths: -------------- trunk/PojomaticAll/pom.xml Modified: trunk/PojomaticAll/pom.xml =================================================================== --- trunk/PojomaticAll/pom.xml 2009-12-06 03:40:41 UTC (rev 173) +++ trunk/PojomaticAll/pom.xml 2009-12-06 03:41:29 UTC (rev 174) @@ -155,10 +155,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> - <version>1.1.1</version> - <configuration> - <excludeFilterFile>${basedir}/FindBugsFilter.xml</excludeFilterFile> - </configuration> + <version>2.0.1</version> </plugin> <plugin> <artifactId>maven-surefire-report-plugin</artifactId> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-06 03:40:47
|
Revision: 173 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=173&view=rev Author: iroberts Date: 2009-12-06 03:40:41 +0000 (Sun, 06 Dec 2009) Log Message: ----------- remove eclipse files Removed Paths: ------------- trunk/PojomaticAll/Pojomatic/.classpath trunk/PojomaticAll/Pojomatic/.project trunk/PojomaticAll/Pojomatic/.settings/ trunk/PojomaticAll/PojomaticTestUtils/.classpath trunk/PojomaticAll/PojomaticTestUtils/.project trunk/PojomaticAll/PojomaticTestUtils/.settings/ Deleted: trunk/PojomaticAll/Pojomatic/.classpath =================================================================== --- trunk/PojomaticAll/Pojomatic/.classpath 2009-12-05 20:54:36 UTC (rev 172) +++ trunk/PojomaticAll/Pojomatic/.classpath 2009-12-06 03:40:41 UTC (rev 173) @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry including="**/*.java" kind="src" path="src/main/java"/> - <classpathentry including="**/*.java" kind="src" path="src/test/java"/> - <classpathentry kind="con" path="org.devzuz.q.maven.jdt.core.mavenClasspathContainer"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="output" path="bin"/> -</classpath> Deleted: trunk/PojomaticAll/Pojomatic/.project =================================================================== --- trunk/PojomaticAll/Pojomatic/.project 2009-12-05 20:54:36 UTC (rev 172) +++ trunk/PojomaticAll/Pojomatic/.project 2009-12-06 03:40:41 UTC (rev 173) @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>Pojomatic</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.devzuz.q.maven.jdt.core.mavenIncrementalBuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.devzuz.q.maven.jdt.core.mavenNature</nature> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> Deleted: trunk/PojomaticAll/PojomaticTestUtils/.classpath =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/.classpath 2009-12-05 20:54:36 UTC (rev 172) +++ trunk/PojomaticAll/PojomaticTestUtils/.classpath 2009-12-06 03:40:41 UTC (rev 173) @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" output="target/classes" path="src/main/java"/> - <classpathentry kind="src" output="target/test-classes" path="src/test/java"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> - <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/> - <classpathentry kind="output" path="target/classes"/> -</classpath> Deleted: trunk/PojomaticAll/PojomaticTestUtils/.project =================================================================== --- trunk/PojomaticAll/PojomaticTestUtils/.project 2009-12-05 20:54:36 UTC (rev 172) +++ trunk/PojomaticAll/PojomaticTestUtils/.project 2009-12-06 03:40:41 UTC (rev 173) @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>PojomaticTestUtils</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.iam.jdt.core.mavenIncrementalBuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.maven.ide.eclipse.maven2Builder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.maven.ide.eclipse.maven2Nature</nature> - <nature>org.eclipse.iam.jdt.core.mavenNature</nature> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-05 20:54:45
|
Revision: 172 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=172&view=rev Author: iroberts Date: 2009-12-05 20:54:36 +0000 (Sat, 05 Dec 2009) Log Message: ----------- we now walk the class hierarchy from top to bottom. Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-12-05 20:53:13 UTC (rev 171) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-12-05 20:54:36 UTC (rev 172) @@ -38,9 +38,7 @@ private Class<?> clazz = Object.class; public void noteContribution(Class<?> contributingClass) { - if (clazz.isAssignableFrom(contributingClass)) { - clazz = contributingClass; - } + clazz = contributingClass; } public Class<?> getMostSpecificContributingClass() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-12-05 20:53:19
|
Revision: 171 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=171&view=rev Author: iroberts Date: 2009-12-05 20:53:13 +0000 (Sat, 05 Dec 2009) Log Message: ----------- test coverage Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java Modified: trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-12-05 01:07:39 UTC (rev 170) +++ trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-12-05 20:53:13 UTC (rev 171) @@ -291,6 +291,22 @@ } } + @Test public void testSubclassCannotOverrideEquals() { + class ChildOfInterface implements Interface { + public int getFoo() { return 0; } + public int bar() { return 0; } + public int baz() { return 0; } + } + + assertTrue( + ClassProperties.forClass(Interface.class).isCompatibleForEquals(ChildOfInterface.class)); + + @SubclassCannotOverrideEquals class A { @Property int x; } + class B extends A { @Property int y; } + assertTrue(ClassProperties.forClass(A.class).isCompatibleForEquals(B.class)); + assertFalse(ClassProperties.forClass(B.class).isCompatibleForEquals(A.class)); + } + //Not all classes can be made internal. In particular, autodetect=FIELD classes cannot, because of the synthetic //$this, and classes requiring static elements cannot. @@ -398,14 +414,6 @@ @Property public static int a() { return 1; } } - public static interface UnannotatedInterface { @Property int getX(); } - - @SubclassCannotOverrideEquals public static interface AnnotatedInterface { @Property int getX(); } - - @SubclassCannotOverrideEquals public static class AnnotatedClass { - @Property int getX() { return 1; } - } - private static Set<PropertyElement> asSet(PropertyElement... elements) { return new HashSet<PropertyElement>(Arrays.asList(elements)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-12-05 01:07:45
|
Revision: 170 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=170&view=rev Author: chriswhansen Date: 2009-12-05 01:07:39 +0000 (Sat, 05 Dec 2009) Log Message: ----------- Unnecessary throws Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/SelfPopulatingMapTest.java Modified: trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/SelfPopulatingMapTest.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/SelfPopulatingMapTest.java 2009-12-05 01:06:01 UTC (rev 169) +++ trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/SelfPopulatingMapTest.java 2009-12-05 01:07:39 UTC (rev 170) @@ -44,7 +44,7 @@ } @Test - public void testBadConstructionFirstTime() throws Exception { + public void testBadConstructionFirstTime() { final AtomicBoolean firstTime = new AtomicBoolean(false); final SelfPopulatingMap<String, String> selfPopulatingMap = new SelfPopulatingMap<String, String>() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-12-05 01:06:12
|
Revision: 169 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=169&view=rev Author: chriswhansen Date: 2009-12-05 01:06:01 +0000 (Sat, 05 Dec 2009) Log Message: ----------- Trade SubclassCanOverrideEquals for SubclassCannotOverrideEquals. Correct JavaDoc. Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomator.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java Added Paths: ----------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCannotOverrideEquals.java Removed Paths: ------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomator.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomator.java 2009-10-21 03:59:18 UTC (rev 168) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomator.java 2009-12-05 01:06:01 UTC (rev 169) @@ -1,6 +1,17 @@ package org.pojomatic; +import java.util.Arrays; +import java.util.List; + +import org.pojomatic.annotations.OverridesEquals; +import org.pojomatic.annotations.PojomaticPolicy; +import org.pojomatic.annotations.Property; +import org.pojomatic.annotations.SubclassCannotOverrideEquals; import org.pojomatic.diff.Differences; +import org.pojomatic.formatter.DefaultPojoFormatter; +import org.pojomatic.formatter.DefaultPropertyFormatter; +import org.pojomatic.formatter.PojoFormatter; +import org.pojomatic.formatter.PropertyFormatter; /** * A provider of the three standard {@code Object} methods, @@ -12,37 +23,108 @@ /** * Compute the hashCode for a given instance of {@code T}. + * This is done by computing the hashCode of each property which has a {@link PojomaticPolicy} of + * {@link PojomaticPolicy#HASHCODE_EQUALS HASHCODE_EQUALS} or {@link PojomaticPolicy#ALL ALL} + * (using 0 when the property is null), and combining them in a fashion similar to that of + * {@link List#hashCode()}. * * @param instance the instance to compute the hashCode for - must not be {@code null} * @return the hashCode of {@code instance} + * @throws NullPointerException if {@code instance} is {@code null} * @see Object#hashCode() */ int doHashCode(T instance); /** - * Compute the {@code toString} representation for a given instance of {@code T} + * Compute the {@code toString} representation for a given instance of {@code T}. + * <p> + * The format used depends on the + * {@link PojoFormatter} used for the POJO, and the {@link PropertyFormatter} of each property. + * <p> + * For example, suppose a class {@code Person} has properties {@code firstName} and + * {@code lastName} which are included in its {@code String} representation. + * No {@code PojoFormatter} or {@code PropertyFormatter} are specified, so the defaults are used. + * In particular, instances of {@code DefaultPropertyFormatter} will be created for + * {@code firstName} and {@code lastName} (referred to here as {@code firstNameFormatter} and + * {@code lastNameFormatter}, respectively). Let {@code firstNameProperty} and + * {@code lastNameProperty} refer to the instances of {@link PropertyElement} referring to the + * properties {@code firstName} and {@code lastName} respectively. + * </p> + * <p> + * For a non-null {@code Person} instance, the {@code String} representation will be created by + * creating an instance of {@code DefaultPojoFormatter} for the {@code Person} class (referred to + * here as {@code personFormatter}), and then concatenating the results of following: + * <ol> + * <li>{@link DefaultPojoFormatter#getToStringPrefix(Class) personFormatter.getToStringPrefix(Person.class)}</li> + * <li>{@link DefaultPojoFormatter#getPropertyPrefix(PropertyElement) personFormatter.getPropertyPrefix(firstNameProperty)}</li> + * <li>{@link DefaultPropertyFormatter#format(Object) firstNameFormatter.format(firstName)}</li> + * <li>{@link DefaultPojoFormatter#getPropertySuffix(PropertyElement) personFormatter.getPropertySuffix(firstNameProperty)}</li> + * <li>{@link DefaultPojoFormatter#getPropertyPrefix(PropertyElement) personFormatter.getPropertyPrefix(lastNameProperty)}</li> + * <li>{@link DefaultPropertyFormatter#format(Object) lastNameFormatter.format(lastName)}</li> + * <li>{@link DefaultPojoFormatter#getPropertySuffix(PropertyElement) personFormatter.getPropertySuffix(lasttNameProperty)}</li> + * <li>{@link DefaultPojoFormatter#getToStringSuffix(Class) personFormatter.getToStringSuffix(Person.class)}</li> + * </ol> + * </p> * * @param instance the instance to compute the {@code toString} representation for - must not be {@code null} * @return the {@code toString} representation of {@code instance} + * @throws NullPointerException if {@code instance} is {@code null} * @see Object#toString() + * @see Property#name() */ String doToString(T instance); /** * Compute whether {@code instance} and {@code other} are equal to each other in the sense of * {@code Object}'s {@link Object#equals(Object) equals} method. - * + * <p> + * For two instances to be considered equal, the first requirement is that their classes must be + * compatible for equality. Classes {@code A} and {@code B} are compatible for equality if + * they share a common superclass {@code C}, and for every class {@code D} which + * is a proper subclass of {@code C} and a superclass of {@code A} or {@code B} (including + * the classes {@code A} and {@code B} themselves), the following hold: + * <ul> + * <li>{@code D} has not added additional properties for inclusion in the {@code equals} calculation, and</li> + * <li>{@code D} has not been annotated with {@link OverridesEquals}</li> + * </ul> + * If {@code T} is an interface or is annotated with {@link SubclassCannotOverrideEquals}, + * then all subclasses of {@code T} are automatically assumed by {@code T}'s {@code Pojomator} + * to be comapatible for equals with each other and with {@code T}. Note that in this case. + * to add an {@link OverridesEquals} annotation or additional + * properties for inclusion in {@code equals} to a subclass of {@code T} will + * result in a violation of the contract for {@link Object#equals(Object)}. + * </p> + * <p> + * More precisely, if {@code other} is null, this method returns {@code false}. Otherwise, it is verified that + * the class of {@code other} is compatible for {@code equals} with {@code T}; if not, then this method + * returns false. Otherwise, this method will return true provided that each property of {@code + * instance} which has a {@code PojomaticPolicy} other than {@code TO_STRING} or + * {@code NONE} is equal to the corresponding property of {@code other} in the following sense: + * <ul> + * <li>Both are {@code null}, or</li> + * <li>Both are reference-equals (==) to each other, or</li> + * <li>Both are primitive of the same type, and equal to each other, or</li> + * <li>Both are of array type, with matching primitive component types, and the corresponding + * {@code} equals method of {@link Arrays} returns true, or</li> + * <li>Both are of array type with non-primitive component types, and + * {@link Arrays#deepEquals(Object[], Object[])} returns true, or</li> + * <li>The property {@code p} in {@code instance} is an object not of array type, and {@code + * instanceP.equals(otherP)} returns true. + * </ul> + * </p> * @param instance the instance to test against - must not be {@code null} * @param other the instance to test * @return {@code true} if {@code instance} should be considered equal to {@code other}, and * {@code false} otherwise. + * @throws NullPointerException if {@code instance} is {@code null} * @see Object#equals(Object) */ boolean doEquals(T instance, Object other); /** * Compute the differences between {@code instance} and {@code other} among the properties - * examined by {@link #doEquals(Object, Object)}. It is guaranteed that invoking + * examined by {@link #doEquals(Object, Object)}. Assuming that {@code instance} and {@code other} + * are both non-null and have types which are compatible for equals, it is guaranteed that invoking * {@link Differences#areEqual()} on the returned object will return true iff * {@code instance.equals(other)}. * @@ -50,6 +132,8 @@ * @param other the instance to diff * @return the differences between {@code instance} and {@code other} * among the properties examined by {@link #doEquals(Object, Object)}. + * + * @see #doEquals(Object, Object) */ Differences doDiff(T instance, T other); } Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java 2009-10-21 03:59:18 UTC (rev 168) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java 2009-12-05 01:06:01 UTC (rev 169) @@ -1,13 +1,18 @@ package org.pojomatic.annotations; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.pojomatic.Pojomator; + /** - * Declares that the annotated type overrides the behavior of {@link Object#equals(Object) equals}. - * This can serve as a hint to - * {@link org.pojomatic.Pojomatic#equals(Object, Object)} Pojomatic.equals(pojo, other) to defer - * to {@code other.equals(this)} in certain cases. - * @see SubclassCanOverrideEquals + * Declares that the annotated type overrides the behavior of {@link Object#equals(Object) equals}, + * and hence is not compatible for equals with its superclasses. + * + * @see Pojomator#doEquals(Object, Object) */ @Documented @Target(ElementType.TYPE) Deleted: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java 2009-10-21 03:59:18 UTC (rev 168) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java 2009-12-05 01:06:01 UTC (rev 169) @@ -1,31 +0,0 @@ -package org.pojomatic.annotations; - -import java.lang.annotation.*; - -/** - * Declares whether a subclass of the annotated type can override the behavior of equals. Suppose - * {@code pojo} is an instance of the annotated class, and {@code other} is an instance of a proper - * subclass of the annotated class. If {@code value} is {@code true}, then - * {@link org.pojomatic.Pojomatic#equals(Object, Object)} Pojomatic.equals(pojo, other)} will defer - * to {@code other.equals(pojo)} provided that at least one of the following holds for - * {@code other}'s class, or any superclass of {@code other}'s class which is a proper subclass - * of the annotated type: - * <ul > - * <li>The class has introduced additioanl properties which are annotated (via either - * {@link Property @Property} or {@link AutoProperty @AutoProperty}) to take part in the - * {@code equals} calculation, or - * <li>The class is annotated with {@link OverridesEquals}. - * </ul> - * If {@code value} is {@code false}, then - * {@link org.pojomatic.Pojomatic#equals(Object, Object)} Pojomatic.equals(pojo, other)} will never - * defer to {@code other.equals(this}). - * <p> - * Abent this annotation, it is assumed that subclasses cannot override {@code equals} for interface - * types, and can for other types. - */ -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface SubclassCanOverrideEquals { - public boolean value() default true; -} Copied: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCannotOverrideEquals.java (from rev 168, trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java) =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCannotOverrideEquals.java (rev 0) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCannotOverrideEquals.java 2009-12-05 01:06:01 UTC (rev 169) @@ -0,0 +1,19 @@ +package org.pojomatic.annotations; + +import java.lang.annotation.*; + +import org.pojomatic.Pojomator; + +/** + * Declares that a subclass of the annotated type cannot override the behavior of equals. + * + * Abent this annotation, it is assumed that subclasses cannot override {@code equals} for interface + * types, and can for other types. + * + * @see Pojomator#doEquals(Object, Object) + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface SubclassCannotOverrideEquals { +} Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-10-21 03:59:18 UTC (rev 168) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-12-05 01:06:01 UTC (rev 169) @@ -24,7 +24,7 @@ private final Class<?> equalsParentClass; - private final boolean subclassCanOverrideEquals; + private final boolean subclassCannotOverrideEquals; private final static SelfPopulatingMap<Class<?>, ClassProperties> INSTANCES = new SelfPopulatingMap<Class<?>, ClassProperties>() { @@ -77,11 +77,8 @@ equalsParentClass = classContributionTracker.getMostSpecificContributingClass(); } verifyPropertiesNotEmpty(pojoClass); - SubclassCanOverrideEquals subclassCanOverrideEqualsAnnotation - = pojoClass.getAnnotation(SubclassCanOverrideEquals.class); - subclassCanOverrideEquals = (subclassCanOverrideEqualsAnnotation != null) - ? subclassCanOverrideEqualsAnnotation.value() - : !pojoClass.isInterface(); + subclassCannotOverrideEquals = pojoClass.isAnnotationPresent(SubclassCannotOverrideEquals.class) + || pojoClass.isInterface(); } /** @@ -120,7 +117,7 @@ return false; } else { - if (!subclassCanOverrideEquals) { + if (subclassCannotOverrideEquals) { return true; } else { Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-10-21 03:59:18 UTC (rev 168) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-12-05 01:06:01 UTC (rev 169) @@ -8,8 +8,6 @@ import org.pojomatic.Pojomator; import org.pojomatic.PropertyElement; import org.pojomatic.annotations.PojoFormat; -import org.pojomatic.annotations.PojomaticPolicy; -import org.pojomatic.annotations.Property; import org.pojomatic.annotations.PropertyFormat; import org.pojomatic.diff.Difference; import org.pojomatic.diff.DifferenceFromNull; @@ -67,38 +65,6 @@ return format == null ? DefaultPojoFormatter.class : format.value(); } - /** - * {@inheritDoc} - * <p> - * In essence, two objects will be considered equal if they have the same set of properties with a - * {@link PojomaticPolicy} other than {@link PojomaticPolicy#TO_STRING TO_STRING} or - * {@link PojomaticPolicy#NONE NONE}, and for each property, the values are equal as described - * below. Note that two properties cannot be considered the same if they come from different - * declaring classes. - * <p> - * More precisely, if {@code other} is null, this method returns {@code false}. If {@code other} - * is a an instance of a proper subclass of the class of {@code instance}, then this method - * returns the result of calling {@code other.equals(instance)}. Otherwise, it is verified that - * the class of {@code other} either the same as or a subclass of the most specific class - * contributing a property with a {@code PojomaticPolicy} other than {@code TO_STRING} or - * {@code NONE}; if not, then this method - * returns false. Otherwise, this method will return true provided that each property of {@code - * instance} which has a {@code PojomaticPolicy} other than {@code TO_STRING} or - * {@code NONE} is equal to the corresponding property of {@code other} in the following sense: - * <ul> - * <li>Both are {@code null}, or</li> - * <li>Both are reference-equals (==) to each other, or</li> - * <li>Both are primitive of the same type, and equal to each other, or</li> - * <li>Both are of array type, with matching primitive component types, and the corresponding - * {@code} equals method of {@link Arrays} returns true, or</li> - * <li>Both are of array type with non-primitive component types, and - * {@link Arrays#deepEquals(Object[], Object[])} returns true, or</li> - * <li>The property {@code p} in {@code instance} is an object not of array type, and {@code - * instanceP.equals(otherP)} returns true. - * </ul> - * - * @throws NullPointerException if {@code instance} is null - */ public boolean doEquals(T instance, Object other) { if (instance == null) { throw new NullPointerException("instance must not be null"); @@ -123,16 +89,6 @@ return true; } - /** - * {@inheritDoc} - *<p> - * This is done by computing the hashCode of each property which has a {@link PojomaticPolicy} of - * {@link PojomaticPolicy#HASHCODE_EQUALS HASHCODE_EQUALS} or {@link PojomaticPolicy#ALL ALL} - * (using 0 when the property is null), and combining them in a fashion similar to that of - * {@link List#hashCode()}. - * - * @throws NullPointerException if {@code instance} is null - */ public int doHashCode(T instance) { int hashCode = HASH_CODE_SEED; if (instance == null) { @@ -193,40 +149,6 @@ } } - /** - * {@inheritDoc} - * <p> - * The format used depends on the - * {@link PojoFormatter} used for the POJO, and the {@link PropertyFormatter} of each property. - * <p> - * For example, suppose a class {@code Person} has properties {@code firstName} and - * {@code lastName} which are included in its {@code String} representation. - * No {@code PojoFormatter} or {@code PropertyFormatter} are specified, so the defaults are used. - * In particular, instances of {@code DefaultPropertyFormatter} will be created for - * {@code firstName} and {@code lastName} (referred to here as {@code firstNameFormatter} and - * {@code lastNameFormatter}, respectively). Let {@code firstNameProperty} and - * {@code lastNameProperty} refer to the instances of {@link PropertyElement} referring to the - * properties {@code firstName} and {@code lastName} respectively. - * </p> - * <p> - * For a non-null {@code Person} instance, the {@code String} representation will be created by - * creating an instance of {@code DefaultPojoFormatter} for the {@code Person} class (referred to - * here as {@code personFormatter}), and then concatenating the results of following: - * <ol> - * <li>{@link DefaultPojoFormatter#getToStringPrefix(Class) personFormatter.getToStringPrefix(Person.class)}</li> - * <li>{@link DefaultPojoFormatter#getPropertyPrefix(PropertyElement) personFormatter.getPropertyPrefix(firstNameProperty)}</li> - * <li>{@link DefaultPropertyFormatter#format(Object) firstNameFormatter.format(firstName)}</li> - * <li>{@link DefaultPojoFormatter#getPropertySuffix(PropertyElement) personFormatter.getPropertySuffix(firstNameProperty)}</li> - * <li>{@link DefaultPojoFormatter#getPropertyPrefix(PropertyElement) personFormatter.getPropertyPrefix(lastNameProperty)}</li> - * <li>{@link DefaultPropertyFormatter#format(Object) lastNameFormatter.format(lastName)}</li> - * <li>{@link DefaultPojoFormatter#getPropertySuffix(PropertyElement) personFormatter.getPropertySuffix(lasttNameProperty)}</li> - * <li>{@link DefaultPojoFormatter#getToStringSuffix(Class) personFormatter.getToStringSuffix(Person.class)}</li> - * </ol> - * </p> - * - * @throws NullPointerException if {@code instance} is null - * @see Property#name() - */ public String doToString(T instance) { if (instance == null) { throw new NullPointerException("instance must not be null"); Modified: trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-10-21 03:59:18 UTC (rev 168) +++ trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-12-05 01:06:01 UTC (rev 169) @@ -400,14 +400,12 @@ public static interface UnannotatedInterface { @Property int getX(); } - @SubclassCanOverrideEquals public static interface AnnotatedInterface { @Property int getX(); } + @SubclassCannotOverrideEquals public static interface AnnotatedInterface { @Property int getX(); } - @SubclassCanOverrideEquals(true) - public static interface AnnotatedInterfaceWithTrue { @Property int getX(); } + @SubclassCannotOverrideEquals public static class AnnotatedClass { + @Property int getX() { return 1; } + } - @SubclassCanOverrideEquals(false) - public static interface AnnotatedInterfaceWithFalse { @Property int getX(); } - private static Set<PropertyElement> asSet(PropertyElement... elements) { return new HashSet<PropertyElement>(Arrays.asList(elements)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-10-21 03:59:24
|
Revision: 168 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=168&view=rev Author: iroberts Date: 2009-10-21 03:59:18 +0000 (Wed, 21 Oct 2009) Log Message: ----------- Misc cleanups Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/DefaultPojomaticPolicy.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/PojomaticPolicy.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/OverridableMethods.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java 2009-10-21 00:02:46 UTC (rev 167) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/Pojomatic.java 2009-10-21 03:59:18 UTC (rev 168) @@ -54,7 +54,7 @@ */ public class Pojomatic { - private static SelfPopulatingMap<Class<?>, Pojomator<?>> POJOMATORS = + private final static SelfPopulatingMap<Class<?>, Pojomator<?>> POJOMATORS = new SelfPopulatingMap<Class<?>, Pojomator<?>>() { @Override @SuppressWarnings("unchecked") Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/DefaultPojomaticPolicy.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/DefaultPojomaticPolicy.java 2009-10-21 00:02:46 UTC (rev 167) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/DefaultPojomaticPolicy.java 2009-10-21 03:59:18 UTC (rev 168) @@ -2,7 +2,7 @@ import java.util.Collections; import java.util.EnumSet; -import java.util.Set; +import java.util.Set;import java.util.Arrays; import org.pojomatic.Pojomatic; import org.pojomatic.internal.PropertyRole; @@ -68,9 +68,7 @@ private DefaultPojomaticPolicy(PropertyRole... roles) { Set<PropertyRole> roleSet = EnumSet.noneOf(PropertyRole.class); - for (PropertyRole role: roles) { - roleSet.add(role); - } + roleSet.addAll(Arrays.asList(roles)); this.roles = Collections.unmodifiableSet(roleSet); } Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/PojomaticPolicy.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/PojomaticPolicy.java 2009-10-21 00:02:46 UTC (rev 167) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/PojomaticPolicy.java 2009-10-21 03:59:18 UTC (rev 168) @@ -1,5 +1,6 @@ package org.pojomatic.annotations; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.Set; @@ -79,9 +80,7 @@ private PojomaticPolicy(PropertyRole... roles) { Set<PropertyRole> roleSet = EnumSet.noneOf(PropertyRole.class); - for (PropertyRole role: roles) { - roleSet.add(role); - } + roleSet.addAll(Arrays.asList(roles)); this.roles = Collections.unmodifiableSet(roleSet); } Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/OverridableMethods.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/OverridableMethods.java 2009-10-21 00:02:46 UTC (rev 167) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/OverridableMethods.java 2009-10-21 03:59:18 UTC (rev 168) @@ -82,8 +82,8 @@ pakage = method.getDeclaringClass().getPackage(); } - String name; - Package pakage; + final String name; + final Package pakage; @Override public int hashCode() { Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-10-21 00:02:46 UTC (rev 167) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-10-21 03:59:18 UTC (rev 168) @@ -262,8 +262,8 @@ private final Class<? extends PojoFormatter> pojoFormatterClass; private static class FormattablePropertyElement { - private PropertyElement propertyElement; - private PropertyFormatter propertyFormatter; + private final PropertyElement propertyElement; + private final PropertyFormatter propertyFormatter; public FormattablePropertyElement( PropertyElement propertyElement, PropertyFormatter propertyFormatter) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-10-21 00:02:52
|
Revision: 167 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=167&view=rev Author: iroberts Date: 2009-10-21 00:02:46 +0000 (Wed, 21 Oct 2009) Log Message: ----------- We say we're caching, we really should. Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-10-21 00:00:37 UTC (rev 166) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-10-21 00:02:46 UTC (rev 167) @@ -56,7 +56,7 @@ * with Pojomatic. */ public static ClassProperties forClass(Class<?> pojoClass) throws IllegalArgumentException { - return new ClassProperties(pojoClass); + return INSTANCES.get(pojoClass); } /** Modified: trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-10-21 00:00:37 UTC (rev 166) +++ trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-10-21 00:02:46 UTC (rev 167) @@ -14,6 +14,11 @@ public class ClassPropertiesTest { + @Test public void testForClass() { + ClassProperties interfaceProperties = ClassProperties.forClass(Interface.class); + assertSame(interfaceProperties, ClassProperties.forClass(Interface.class)); + } + @Test public void testAnnotatedFields() throws Exception { final PropertyElement privateStringField = TestUtils.field(FieldPojo.class, "privateString"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-10-21 00:00:45
|
Revision: 166 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=166&view=rev Author: iroberts Date: 2009-10-21 00:00:37 +0000 (Wed, 21 Oct 2009) Log Message: ----------- Stop calling other.equals(this); just rely on whether the ClassProperties for the pojoClass believes that instances of other.getClass() can be equal to instances of pojoClass. Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/PojomatorImplTest.java Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-10-19 06:57:37 UTC (rev 165) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-10-21 00:00:37 UTC (rev 166) @@ -28,6 +28,7 @@ private final static SelfPopulatingMap<Class<?>, ClassProperties> INSTANCES = new SelfPopulatingMap<Class<?>, ClassProperties>() { + @Override protected ClassProperties create(Class<?> key) { return new ClassProperties(key); } @@ -108,25 +109,26 @@ } /** - * Get the class which any class must inherit from in order for its instances to be candidates for - * being considered equal by {@link PojomatorImpl#doEquals(Object, Object)}. - * @return the class which any class must inherit from in order for its instances to be candidates - * for being considered equal by {@link PojomatorImpl#doEquals(Object, Object)}. + * Whether instances of {@code otherClass} are candidates for being equal to instances of + * {@code pojoClass} + * @param otherClass + * @return {@code true} if instances of {@code otherClass} are candidates for being equal to + * instances of {@code pojoClass}, or {@code false} otherwise. */ - public Class<?> getEqualsParentClass() { - return equalsParentClass; + public boolean isCompatibleForEquals(Class<?> otherClass) { + if (!equalsParentClass.isAssignableFrom(otherClass)) { + return false; + } + else { + if (!subclassCanOverrideEquals) { + return true; + } + else { + return equalsParentClass.equals(forClass(otherClass).equalsParentClass); + } + } } - /** - * Whether subclasses of this class can override the {@link Object#equals(Object)} method defined - * in {@code pojoClass}. - * @return {@code true} if subclasses of this class can override the {@link Object#equals(Object)} - * method defined in {@code pojoClass}, and {@code false} otherwise. - */ - public boolean subclassCanOverrideEquals() { - return subclassCanOverrideEquals; - } - private void walkHierarchy( Class<?> clazz, OverridableMethods overridableMethods, @@ -145,8 +147,8 @@ OverridableMethods overridableMethods, ClassContributionTracker classContributionTracker) { AutoProperty autoProperty = clazz.getAnnotation(AutoProperty.class); - final DefaultPojomaticPolicy classPolicy = - (autoProperty != null) ? autoProperty.policy() : null; + final DefaultPojomaticPolicy classPolicy = + (autoProperty != null) ? autoProperty.policy() : null; final AutoDetectPolicy autoDetectPolicy = (autoProperty != null) ? autoProperty.autoDetect() : null; @@ -174,7 +176,7 @@ continue; } } - + PojomaticPolicy propertyPolicy = null; if (property != null) { if (!methodSignatureIsAccessor(method)) { @@ -203,7 +205,7 @@ } private void extractFields( - Class<?> clazz, + Class<?> clazz, final DefaultPojomaticPolicy classPolicy, final AutoDetectPolicy autoDetectPolicy, final ClassContributionTracker classContributionTracker) { @@ -219,7 +221,7 @@ continue; } } - + final PojomaticPolicy propertyPolicy = (property != null) ? property.policy() : null; /* add all fields that are explicitly annotated or auto-detected */ Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-10-19 06:57:37 UTC (rev 165) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-10-21 00:00:37 UTC (rev 166) @@ -80,10 +80,10 @@ * is a an instance of a proper subclass of the class of {@code instance}, then this method * returns the result of calling {@code other.equals(instance)}. Otherwise, it is verified that * the class of {@code other} either the same as or a subclass of the most specific class - * contributing a property with a {@code PojomaticPolicy} other than {@code TO_STRING} or + * contributing a property with a {@code PojomaticPolicy} other than {@code TO_STRING} or * {@code NONE}; if not, then this method * returns false. Otherwise, this method will return true provided that each property of {@code - * instance} which has a {@code PojomaticPolicy} other than {@code TO_STRING} or + * instance} which has a {@code PojomaticPolicy} other than {@code TO_STRING} or * {@code NONE} is equal to the corresponding property of {@code other} in the following sense: * <ul> * <li>Both are {@code null}, or</li> @@ -110,15 +110,8 @@ return false; } if (!instance.getClass().equals(other.getClass())) { - if (classProperties.subclassCanOverrideEquals()) { - if (instance.getClass().isAssignableFrom(other.getClass())) { - return other.equals(instance); - } - if ((!classProperties.getEqualsParentClass().isAssignableFrom(other.getClass())) - || !classProperties.getEqualsParentClass().equals( - ClassProperties.forClass(other.getClass()).getEqualsParentClass())) { - return false; - } + if (!classProperties.isCompatibleForEquals(other.getClass())) { + return false; } } Modified: trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-10-19 06:57:37 UTC (rev 165) +++ trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-10-21 00:00:37 UTC (rev 166) @@ -257,52 +257,33 @@ assertEquals(asSet(getFoo, baz), asSet(classProperties.getEqualsProperties())); } - @Test public void testSubclassCanOverrideEqualsForClasses() { - class Parent { @Property int getX() { return 3; } } // simplify subsequent class defs - - class Unannotated extends Parent {} - @SubclassCanOverrideEquals class Annotated extends Parent {} - @SubclassCanOverrideEquals(true) class AnnotatedWithTrue extends Parent {} - @SubclassCanOverrideEquals(false) class AnnotatedWithFalse extends Parent {} - - assertTrue(ClassProperties.forClass(Unannotated.class).subclassCanOverrideEquals()); - assertTrue(ClassProperties.forClass(Annotated.class).subclassCanOverrideEquals()); - assertTrue(ClassProperties.forClass(AnnotatedWithTrue.class).subclassCanOverrideEquals()); - assertFalse(ClassProperties.forClass(AnnotatedWithFalse.class).subclassCanOverrideEquals()); - } - - @Test public void testSubclassCanOverrideEqualsForInterfaces() { - assertFalse(ClassProperties.forClass(UnannotatedInterface.class).subclassCanOverrideEquals()); - assertTrue(ClassProperties.forClass(AnnotatedInterface.class).subclassCanOverrideEquals()); - assertTrue(ClassProperties.forClass(AnnotatedInterfaceWithTrue.class).subclassCanOverrideEquals()); - assertFalse(ClassProperties.forClass(AnnotatedInterfaceWithFalse.class).subclassCanOverrideEquals()); - } - - @Test public void testEqualsParentClassForInterface() { - assertEquals( - UnannotatedInterface.class, - ClassProperties.forClass(UnannotatedInterface.class).getEqualsParentClass()); - } - - @Test public void testEqualsParentClassForClasses() { - class Parent { @Property int getX() { return 3; } } + @Test public void testIsCompatibleForEquals() { + class Parent { @SuppressWarnings("unused") @Property int getX() { return 3; } } class NonContributingChild extends Parent {} @OverridesEquals class AnnotatedNonContributingChild extends Parent {} - class ContributingChild extends Parent{ @Property int getY() { return 3; } } + class ContributingChild extends Parent{ @SuppressWarnings("unused") @Property int getY() { return 3; } } class ChildOfContributingChild extends ContributingChild{} - assertEquals(Parent.class, ClassProperties.forClass(Parent.class).getEqualsParentClass()); - assertEquals( - Parent.class, ClassProperties.forClass(NonContributingChild.class).getEqualsParentClass()); - assertEquals( - AnnotatedNonContributingChild.class, - ClassProperties.forClass(AnnotatedNonContributingChild.class).getEqualsParentClass()); - assertEquals( - ContributingChild.class, - ClassProperties.forClass(ContributingChild.class).getEqualsParentClass()); - assertEquals( - ContributingChild.class, - ClassProperties.forClass(ChildOfContributingChild.class).getEqualsParentClass()); + @SuppressWarnings("unchecked") + List<List<Class<?>>> partitions = Arrays.asList( + Arrays.<Class<?>>asList(Parent.class, NonContributingChild.class), + Arrays.<Class<?>>asList(ContributingChild.class, ChildOfContributingChild.class), + Arrays.<Class<?>>asList(AnnotatedNonContributingChild.class), + Arrays.<Class<?>>asList(Interface.class)); + for (List<Class<?>> partition: partitions) { + for (Class<?> clazz: partition) { + for(List<Class<?>> otherPartition: partitions) { + for(Class<?> otherClazz: otherPartition) { + if (partition == otherPartition) { + assertTrue(ClassProperties.forClass(clazz).isCompatibleForEquals(otherClazz)); + } + else { + assertFalse(ClassProperties.forClass(clazz).isCompatibleForEquals(otherClazz)); + } + } + } + } + } } //Not all classes can be made internal. In particular, autodetect=FIELD classes cannot, because of the synthetic Modified: trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/PojomatorImplTest.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/PojomatorImplTest.java 2009-10-19 06:57:37 UTC (rev 165) +++ trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/PojomatorImplTest.java 2009-10-21 00:00:37 UTC (rev 166) @@ -334,6 +334,7 @@ HASH_CODE_MULTIPLIER + 2)*HASH_CODE_MULTIPLIER + "hello".hashCode(), pojomator.doHashCode(new Impl1())); assertTrue(pojomator.doEquals(new Impl1(), new Impl2("hello"))); assertFalse(pojomator.doEquals(new Impl1(), new Impl2("goodbye"))); + assertFalse(pojomator.doEquals(new Impl1(), "not even in the right hierarchy")); } @PojoFormat(SimplePojoFormatter.class) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <iro...@us...> - 2009-10-19 06:57:48
|
Revision: 165 http://pojomatic.svn.sourceforge.net/pojomatic/?rev=165&view=rev Author: iroberts Date: 2009-10-19 06:57:37 +0000 (Mon, 19 Oct 2009) Log Message: ----------- Properly handle inheritance for interfaces and regular classes. Modified Paths: -------------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java Added Paths: ----------- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java Added: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java (rev 0) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/OverridesEquals.java 2009-10-19 06:57:37 UTC (rev 165) @@ -0,0 +1,16 @@ +package org.pojomatic.annotations; + +import java.lang.annotation.*; + +/** + * Declares that the annotated type overrides the behavior of {@link Object#equals(Object) equals}. + * This can serve as a hint to + * {@link org.pojomatic.Pojomatic#equals(Object, Object)} Pojomatic.equals(pojo, other) to defer + * to {@code other.equals(this)} in certain cases. + * @see SubclassCanOverrideEquals + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface OverridesEquals { +} Added: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java (rev 0) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/annotations/SubclassCanOverrideEquals.java 2009-10-19 06:57:37 UTC (rev 165) @@ -0,0 +1,31 @@ +package org.pojomatic.annotations; + +import java.lang.annotation.*; + +/** + * Declares whether a subclass of the annotated type can override the behavior of equals. Suppose + * {@code pojo} is an instance of the annotated class, and {@code other} is an instance of a proper + * subclass of the annotated class. If {@code value} is {@code true}, then + * {@link org.pojomatic.Pojomatic#equals(Object, Object)} Pojomatic.equals(pojo, other)} will defer + * to {@code other.equals(pojo)} provided that at least one of the following holds for + * {@code other}'s class, or any superclass of {@code other}'s class which is a proper subclass + * of the annotated type: + * <ul > + * <li>The class has introduced additioanl properties which are annotated (via either + * {@link Property @Property} or {@link AutoProperty @AutoProperty}) to take part in the + * {@code equals} calculation, or + * <li>The class is annotated with {@link OverridesEquals}. + * </ul> + * If {@code value} is {@code false}, then + * {@link org.pojomatic.Pojomatic#equals(Object, Object)} Pojomatic.equals(pojo, other)} will never + * defer to {@code other.equals(this}). + * <p> + * Abent this annotation, it is assumed that subclasses cannot override {@code equals} for interface + * types, and can for other types. + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface SubclassCanOverrideEquals { + public boolean value() default true; +} Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-09-25 22:48:41 UTC (rev 164) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/ClassProperties.java 2009-10-19 06:57:37 UTC (rev 165) @@ -11,11 +11,7 @@ import java.util.regex.Pattern; import org.pojomatic.PropertyElement; -import org.pojomatic.annotations.AutoDetectPolicy; -import org.pojomatic.annotations.AutoProperty; -import org.pojomatic.annotations.DefaultPojomaticPolicy; -import org.pojomatic.annotations.PojomaticPolicy; -import org.pojomatic.annotations.Property; +import org.pojomatic.annotations.*; /** * The properties of a class used for {@link PojomatorImpl#doHashCode(Object)}, @@ -28,23 +24,63 @@ private final Class<?> equalsParentClass; + private final boolean subclassCanOverrideEquals; + + private final static SelfPopulatingMap<Class<?>, ClassProperties> INSTANCES = + new SelfPopulatingMap<Class<?>, ClassProperties>() { + protected ClassProperties create(Class<?> key) { + return new ClassProperties(key); + } + }; + + private final static class ClassContributionTracker { + private Class<?> clazz = Object.class; + + public void noteContribution(Class<?> contributingClass) { + if (clazz.isAssignableFrom(contributingClass)) { + clazz = contributingClass; + } + } + + public Class<?> getMostSpecificContributingClass() { + return clazz; + } + } /** + * Get an instance for the given {@code pojoClass}. Instances are cached, so calling this method + * repeatedly is not inefficient. + * @param pojoClass the class to inspect for properties + * @return The {@code ClassProperties} for {@code pojoClass}. + * @throws IllegalArgumentException if {@code pojoClass} has no properties annotated for use + * with Pojomatic. + */ + public static ClassProperties forClass(Class<?> pojoClass) throws IllegalArgumentException { + return new ClassProperties(pojoClass); + } + + /** * Creates an instance for the given {@code pojoClass}. * * @param pojoClass the class to inspect for properties * @throws IllegalArgumentException if {@code pojoClass} has no properties annotated for use * with Pojomatic. */ - public ClassProperties(Class<?> pojoClass) throws IllegalArgumentException { + private ClassProperties(Class<?> pojoClass) throws IllegalArgumentException { if (pojoClass.isInterface()) { - extractClassProperties(pojoClass, new OverridableMethods()); + extractClassProperties(pojoClass, new OverridableMethods(), new ClassContributionTracker()); equalsParentClass = pojoClass; } else { - walkHierarchy(pojoClass, new OverridableMethods()); - equalsParentClass = findMostSpecificClassContributingToEquals(); + ClassContributionTracker classContributionTracker = new ClassContributionTracker(); + walkHierarchy(pojoClass, new OverridableMethods(), classContributionTracker); + equalsParentClass = classContributionTracker.getMostSpecificContributingClass(); } verifyPropertiesNotEmpty(pojoClass); + SubclassCanOverrideEquals subclassCanOverrideEqualsAnnotation + = pojoClass.getAnnotation(SubclassCanOverrideEquals.class); + subclassCanOverrideEquals = (subclassCanOverrideEqualsAnnotation != null) + ? subclassCanOverrideEqualsAnnotation.value() + : !pojoClass.isInterface(); } /** @@ -72,38 +108,60 @@ } /** - * Get the class which any class must inherit from in order for its instances to be candidates for being considered - * equal by {@link PojomatorImpl#doEquals(Object, Object)}. - * @return the class which any class must inherit from in order for its instances to be candidates for being - * considered equal by {@link PojomatorImpl#doEquals(Object, Object)}. + * Get the class which any class must inherit from in order for its instances to be candidates for + * being considered equal by {@link PojomatorImpl#doEquals(Object, Object)}. + * @return the class which any class must inherit from in order for its instances to be candidates + * for being considered equal by {@link PojomatorImpl#doEquals(Object, Object)}. */ public Class<?> getEqualsParentClass() { return equalsParentClass; } - private void walkHierarchy(Class<?> clazz, OverridableMethods overridableMethods) { + /** + * Whether subclasses of this class can override the {@link Object#equals(Object)} method defined + * in {@code pojoClass}. + * @return {@code true} if subclasses of this class can override the {@link Object#equals(Object)} + * method defined in {@code pojoClass}, and {@code false} otherwise. + */ + public boolean subclassCanOverrideEquals() { + return subclassCanOverrideEquals; + } + + private void walkHierarchy( + Class<?> clazz, + OverridableMethods overridableMethods, + ClassContributionTracker classContributionTracker) { if (clazz != Object.class) { - walkHierarchy(clazz.getSuperclass(), overridableMethods); - extractClassProperties(clazz, overridableMethods); + walkHierarchy(clazz.getSuperclass(), overridableMethods, classContributionTracker); + extractClassProperties(clazz, overridableMethods, classContributionTracker); + if (clazz.isAnnotationPresent(OverridesEquals.class)) { + classContributionTracker.noteContribution(clazz); + } } } - private void extractClassProperties(Class<?> clazz, OverridableMethods overridableMethods) { + private void extractClassProperties( + Class<?> clazz, + OverridableMethods overridableMethods, + ClassContributionTracker classContributionTracker) { AutoProperty autoProperty = clazz.getAnnotation(AutoProperty.class); final DefaultPojomaticPolicy classPolicy = (autoProperty != null) ? autoProperty.policy() : null; final AutoDetectPolicy autoDetectPolicy = (autoProperty != null) ? autoProperty.autoDetect() : null; - extractFields(clazz, classPolicy, autoDetectPolicy); - extractMethods(clazz, classPolicy, autoDetectPolicy, overridableMethods); + extractFields( + clazz, classPolicy, autoDetectPolicy, classContributionTracker); + extractMethods( + clazz, classPolicy, autoDetectPolicy, overridableMethods, classContributionTracker); } private void extractMethods( Class<?> clazz, final DefaultPojomaticPolicy classPolicy, final AutoDetectPolicy autoDetectPolicy, - final OverridableMethods overridableMethods) { + final OverridableMethods overridableMethods, + final ClassContributionTracker classContributionTracker) { for (Method method : clazz.getDeclaredMethods()) { Property property = method.getAnnotation(Property.class); if (isStatic(method)) { @@ -136,13 +194,19 @@ for (PropertyRole role : overridableMethods.checkAndMaybeAddRolesToMethod( method, PropertyFilter.getRoles(propertyPolicy, classPolicy))) { properties.get(role).add(new PropertyAccessor(method, getPropertyName(property))); + if (PropertyRole.EQUALS == role) { + classContributionTracker.noteContribution(clazz); + } } } } } - private void extractFields(Class<?> clazz, final DefaultPojomaticPolicy classPolicy, - final AutoDetectPolicy autoDetectPolicy) { + private void extractFields( + Class<?> clazz, + final DefaultPojomaticPolicy classPolicy, + final AutoDetectPolicy autoDetectPolicy, + final ClassContributionTracker classContributionTracker) { for (Field field : clazz.getDeclaredFields()) { Property property = field.getAnnotation(Property.class); if (isStatic(field)) { @@ -162,6 +226,9 @@ if (propertyPolicy != null || AutoDetectPolicy.FIELD == autoDetectPolicy) { for (PropertyRole role : PropertyFilter.getRoles(propertyPolicy, classPolicy)) { properties.get(role).add(new PropertyField(field, getPropertyName(property))); + if (PropertyRole.EQUALS == role) { + classContributionTracker.noteContribution(clazz); + } } } } @@ -177,16 +244,6 @@ "Class " + pojoClass.getName() + " has no Pojomatic properties"); } - private Class<?> findMostSpecificClassContributingToEquals() { - Class<?> clazz = Object.class; - for (PropertyElement propertyElement : properties.get(PropertyRole.EQUALS)) { - if (clazz.isAssignableFrom(propertyElement.getDeclaringClass())) { - clazz = propertyElement.getDeclaringClass(); - } - } - return clazz; - } - private String getPropertyName(Property property) { return property == null ? "" : property.name(); } Modified: trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-09-25 22:48:41 UTC (rev 164) +++ trunk/PojomaticAll/Pojomatic/src/main/java/org/pojomatic/internal/PojomatorImpl.java 2009-10-19 06:57:37 UTC (rev 165) @@ -38,7 +38,7 @@ */ public PojomatorImpl(Class<T> clazz) throws IllegalArgumentException { this.clazz = clazz; - classProperties = new ClassProperties(clazz); + classProperties = ClassProperties.forClass(clazz); pojoFormatterClass = findPojoFormatterClass(clazz); for (PropertyElement prop: classProperties.getToStringProperties()) { PropertyFormatter propertyFormatter = findPropertyFormatter(prop.getElement()); @@ -110,12 +110,16 @@ return false; } if (!instance.getClass().equals(other.getClass())) { - if (instance.getClass().isAssignableFrom(other.getClass())) { - return other.equals(instance); + if (classProperties.subclassCanOverrideEquals()) { + if (instance.getClass().isAssignableFrom(other.getClass())) { + return other.equals(instance); + } + if ((!classProperties.getEqualsParentClass().isAssignableFrom(other.getClass())) + || !classProperties.getEqualsParentClass().equals( + ClassProperties.forClass(other.getClass()).getEqualsParentClass())) { + return false; + } } - if (!classProperties.getEqualsParentClass().isAssignableFrom(other.getClass())) { - return false; - } } for (PropertyElement prop: classProperties.getEqualsProperties()) { Modified: trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java =================================================================== --- trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-09-25 22:48:41 UTC (rev 164) +++ trunk/PojomaticAll/Pojomatic/src/test/java/org/pojomatic/internal/ClassPropertiesTest.java 2009-10-19 06:57:37 UTC (rev 165) @@ -7,11 +7,7 @@ import org.junit.Test; import org.pojomatic.PropertyElement; import org.pojomatic.TestUtils; -import org.pojomatic.annotations.AutoDetectPolicy; -import org.pojomatic.annotations.AutoProperty; -import org.pojomatic.annotations.DefaultPojomaticPolicy; -import org.pojomatic.annotations.PojomaticPolicy; -import org.pojomatic.annotations.Property; +import org.pojomatic.annotations.*; import org.pojomatic.internal.a.C1; import org.pojomatic.internal.b.C2; import org.pojomatic.internal.b.C4; @@ -26,7 +22,7 @@ final PropertyElement forEqualsAndToString = TestUtils.field(FieldPojo.class, "forEqualsAndToString"); - ClassProperties classProperties = new ClassProperties(FieldPojo.class); + ClassProperties classProperties = ClassProperties.forClass(FieldPojo.class); assertEquals( asSet(privateStringField, publicIntField, forEqualsAndToString), @@ -45,7 +41,7 @@ final PropertyElement stringField = TestUtils.field(AutoFieldPojo.class, "string"); final PropertyElement allInDoubleField = TestUtils.field(AutoFieldPojo.class, "allInDouble"); - ClassProperties classProperties = new ClassProperties(AutoFieldPojo.class); + ClassProperties classProperties = ClassProperties.forClass(AutoFieldPojo.class); assertEquals(asSet(allInDoubleField), asSet(classProperties.getEqualsProperties())); assertEquals(asSet(allInDoubleField), asSet(classProperties.getHashCodeProperties())); @@ -67,7 +63,7 @@ final PropertyElement privateStringMethod = TestUtils.method(MethodPojo.class, "privateString"); final PropertyElement onlyForEqualsMethod = TestUtils.method(MethodPojo.class, "onlyForEquals"); - ClassProperties classProperties = new ClassProperties(MethodPojo.class); + ClassProperties classProperties = ClassProperties.forClass(MethodPojo.class); assertEquals( asSet(getIntMethod, privateStringMethod, onlyForEqualsMethod), @@ -91,7 +87,7 @@ new HashSet<PropertyElement>(commonProperties); equalsHashCodeProperties.add(TestUtils.method(AutoMethodPojo.class, "getHashCodeAndEquals")); - ClassProperties classProperties = new ClassProperties(AutoMethodPojo.class); + ClassProperties classProperties = ClassProperties.forClass(AutoMethodPojo.class); assertEquals(equalsHashCodeProperties, asSet(classProperties.getEqualsProperties())); assertEquals(equalsHashCodeProperties, asSet(classProperties.getHashCodeProperties())); @@ -101,7 +97,7 @@ @Test(expected=IllegalArgumentException.class) public void testAnnotatedMethodReturningVoid() { class MethodReturnsVoidPojo { @SuppressWarnings("unused") @Property public void noReturn() {} } - new ClassProperties(MethodReturnsVoidPojo.class); + ClassProperties.forClass(MethodReturnsVoidPojo.class); } @Test(expected=IllegalArgumentException.class) @@ -110,18 +106,18 @@ @SuppressWarnings("unused") @Property public int takesArgs(String death) { return death.length(); } } - new ClassProperties(MethodTakesArgsPojo.class); + ClassProperties.forClass(MethodTakesArgsPojo.class); } @Test public void testAnnotatedInheritance() throws Exception { Set<PropertyElement> expectedParent = asSet(TestUtils.method(ParentPojo.class, "getFoo")); - ClassProperties parentClassProperties = new ClassProperties(ParentPojo.class); + ClassProperties parentClassProperties = ClassProperties.forClass(ParentPojo.class); assertEquals(expectedParent, asSet(parentClassProperties.getEqualsProperties())); assertEquals(expectedParent, asSet(parentClassProperties.getHashCodeProperties())); assertEquals(expectedParent, asSet(parentClassProperties.getToStringProperties())); - ClassProperties childClassProperties = new ClassProperties(ChildPojo.class); + ClassProperties childClassProperties = ClassProperties.forClass(ChildPojo.class); Set<PropertyElement> expectedChild = asSet( TestUtils.method(ParentPojo.class, "getFoo"), TestUtils.field(ChildPojo.class, "other")); assertEquals(expectedChild, asSet(childClassProperties.getEqualsProperties())); @@ -132,12 +128,12 @@ @Test public void testAutoInheritanceBothAuto() throws Exception { Set<PropertyElement> expectedParent = asSet(TestUtils.method(ParentAutoPojo.class, "getFoo")); - ClassProperties parentClassProperties = new ClassProperties(ParentAutoPojo.class); + ClassProperties parentClassProperties = ClassProperties.forClass(ParentAutoPojo.class); assertEquals(expectedParent, asSet(parentClassProperties.getEqualsProperties())); assertEquals(Collections.EMPTY_SET, asSet(parentClassProperties.getHashCodeProperties())); assertEquals(Collections.EMPTY_SET, asSet(parentClassProperties.getToStringProperties())); - ClassProperties childClassProperties = new ClassProperties(ChildAutoFieldPojo.class); + ClassProperties childClassProperties = ClassProperties.forClass(ChildAutoFieldPojo.class); Set<PropertyElement> expectedChild = asSet( TestUtils.field(ChildAutoFieldPojo.class, "other")); assertEquals(expectedParent, asSet(childClassProperties.getEqualsProperties())); @@ -153,7 +149,7 @@ @SuppressWarnings("unused") public int getBar() { return 2; } } - ClassProperties childClassProperties = new ClassProperties(ChildAutoMethodPojo.class); + ClassProperties childClassProperties = ClassProperties.forClass(ChildAutoMethodPojo.class); Set<PropertyElement> expected = asSet( TestUtils.method(ParentPojo.class, "getFoo"), TestUtils.method(ChildAutoMethodPojo.class, "getBar")); @@ -171,12 +167,12 @@ } Set<PropertyElement> expectedParent = asSet(TestUtils.method(ParentPojo.class, "getFoo")); - ClassProperties parentClassProperties = new ClassProperties(ParentPojo.class); + ClassProperties parentClassProperties = ClassProperties.forClass(ParentPojo.class); assertEquals(expectedParent, asSet(parentClassProperties.getEqualsProperties())); assertEquals(expectedParent, asSet(parentClassProperties.getHashCodeProperties())); assertEquals(expectedParent, asSet(parentClassProperties.getToStringProperties())); - ClassProperties childClassProperties = new ClassProperties(ChildExtendsAnnotatedPojo.class); + ClassProperties childClassProperties = ClassProperties.forClass(ChildExtendsAnnotatedPojo.class); Set<PropertyElement> expectedChild = asSet( TestUtils.method(ParentPojo.class, "getFoo"), TestUtils.method(ChildExtendsAnnotatedPojo.class, "getMyString")); @@ -194,12 +190,12 @@ } Set<PropertyElement> expectedParent = asSet(TestUtils.method(ParentAutoPojo.class, "getFoo")); - ClassProperties parentClassProperties = new ClassProperties(ParentAutoPojo.class); + ClassProperties parentClassProperties = ClassProperties.forClass(ParentAutoPojo.class); assertEquals(expectedParent, asSet(parentClassProperties.getEqualsProperties())); assertEquals(Collections.EMPTY_SET, asSet(parentClassProperties.getHashCodeProperties())); assertEquals(Collections.EMPTY_SET, asSet(parentClassProperties.getToStringProperties())); - ClassProperties childClassProperties = new ClassProperties(ChildExtendsAutoPojo.class); + ClassProperties childClassProperties = ClassProperties.forClass(ChildExtendsAutoPojo.class); Set<PropertyElement> expectedChildEquals = asSet( TestUtils.method(ParentAutoPojo.class, "getFoo"), TestUtils.field(ChildExtendsAutoPojo.class, "other")); @@ -212,7 +208,7 @@ @Test public void testOverriddenMethods() throws Exception { - ClassProperties classProperties = new ClassProperties(C4.class); + ClassProperties classProperties = ClassProperties.forClass(C4.class); assertEquals( asSet( TestUtils.method(C1.class, "packagePrivate"), @@ -229,7 +225,7 @@ @Test public void testAnnotatedStaticField() { try { - new ClassProperties(StaticField.class); + ClassProperties.forClass(StaticField.class); fail("Exception expected"); } catch (IllegalArgumentException e) { @@ -242,7 +238,7 @@ @Test public void testAnnotatedStaticMethod() { try { - new ClassProperties(StaticMethod.class); + ClassProperties.forClass(StaticMethod.class); fail("Exception expected"); } catch (IllegalArgumentException e) { @@ -253,7 +249,7 @@ } @Test public void testInterface() throws Exception { - ClassProperties classProperties = new ClassProperties(Interface.class); + ClassProperties classProperties = ClassProperties.forClass(Interface.class); PropertyElement getFoo = TestUtils.method(Interface.class, "getFoo"); PropertyElement baz = TestUtils.method(Interface.class, "baz"); assertEquals(asSet(getFoo), asSet(classProperties.getHashCodeProperties())); @@ -261,6 +257,54 @@ assertEquals(asSet(getFoo, baz), asSet(classProperties.getEqualsProperties())); } + @Test public void testSubclassCanOverrideEqualsForClasses() { + class Parent { @Property int getX() { return 3; } } // simplify subsequent class defs + + class Unannotated extends Parent {} + @SubclassCanOverrideEquals class Annotated extends Parent {} + @SubclassCanOverrideEquals(true) class AnnotatedWithTrue extends Parent {} + @SubclassCanOverrideEquals(false) class AnnotatedWithFalse extends Parent {} + + assertTrue(ClassProperties.forClass(Unannotated.class).subclassCanOverrideEquals()); + assertTrue(ClassProperties.forClass(Annotated.class).subclassCanOverrideEquals()); + assertTrue(ClassProperties.forClass(AnnotatedWithTrue.class).subclassCanOverrideEquals()); + assertFalse(ClassProperties.forClass(AnnotatedWithFalse.class).subclassCanOverrideEquals()); + } + + @Test public void testSubclassCanOverrideEqualsForInterfaces() { + assertFalse(ClassProperties.forClass(UnannotatedInterface.class).subclassCanOverrideEquals()); + assertTrue(ClassProperties.forClass(AnnotatedInterface.class).subclassCanOverrideEquals()); + assertTrue(ClassProperties.forClass(AnnotatedInterfaceWithTrue.class).subclassCanOverrideEquals()); + assertFalse(ClassProperties.forClass(AnnotatedInterfaceWithFalse.class).subclassCanOverrideEquals()); + } + + @Test public void testEqualsParentClassForInterface() { + assertEquals( + UnannotatedInterface.class, + ClassProperties.forClass(UnannotatedInterface.class).getEqualsParentClass()); + } + + @Test public void testEqualsParentClassForClasses() { + class Parent { @Property int getX() { return 3; } } + class NonContributingChild extends Parent {} + @OverridesEquals class AnnotatedNonContributingChild extends Parent {} + class ContributingChild extends Parent{ @Property int getY() { return 3; } } + class ChildOfContributingChild extends ContributingChild{} + + assertEquals(Parent.class, ClassProperties.forClass(Parent.class).getEqualsParentClass()); + assertEquals( + Parent.class, ClassProperties.forClass(NonContributingChild.class).getEqualsParentClass()); + assertEquals( + AnnotatedNonContributingChild.class, + ClassProperties.forClass(AnnotatedNonContributingChild.class).getEqualsParentClass()); + assertEquals( + ContributingChild.class, + ClassProperties.forClass(ContributingChild.class).getEqualsParentClass()); + assertEquals( + ContributingChild.class, + ClassProperties.forClass(ChildOfContributingChild.class).getEqualsParentClass()); + } + //Not all classes can be made internal. In particular, autodetect=FIELD classes cannot, because of the synthetic //$this, and classes requiring static elements cannot. @@ -368,6 +412,16 @@ @Property public static int a() { return 1; } } + public static interface UnannotatedInterface { @Property int getX(); } + + @SubclassCanOverrideEquals public static interface AnnotatedInterface { @Property int getX(); } + + @SubclassCanOverrideEquals(true) + public static interface AnnotatedInterfaceWithTrue { @Property int getX(); } + + @SubclassCanOverrideEquals(false) + public static interface AnnotatedInterfaceWithFalse { @Property int getX(); } + private static Set<PropertyElement> asSet(PropertyElement... elements) { return new HashSet<PropertyElement>(Arrays.asList(elements)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |