Using commons lang for object comparison
- Using the Apache commons-lang package is the generally accepted way to do object comparisons (e.g. equals) in Sakai tools
- Adding the commons-lang dependency to your project.xml
- Add the following to the dependencies block of your project.xml file to include the commons-lang:
<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>${sakai.commons.lang.version}</version> </dependency>
- The commons-lang package is included in shared/lib by Sakai itself so you do not need to package it in your tool war file (hence there is no <war.bundle>true</war.bundle>)
- Do not specify a version, use the version that Sakai is placing in the shared/lib by using the property (sakai.commons.lang.version) as shown above
- Add the following to the dependencies block of your project.xml file to include the commons-lang:
- Using the lang functions in your object or object implementation code - Apache commons-lang API
Note: All code below should go in the object or object implementation- Add the required imports
import org.apache.commons.lang.builder.CompareToBuilder; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder;
- Create an equals function using the EqualsBuilder
public boolean equals(Object obj) { if (null == obj) return false; if (obj instanceof org.sakaiproject.tool.mytool.MyObject == false) { return false; } if (this == obj) { return true; } org.sakaiproject.tool.mytool.MyObject castObj = (org.sakaiproject.tool.mytool.MyObject) obj; return new EqualsBuilder() .append(this.getId(), castObj.getId()) .isEquals(); }
- This simple example only compares the id values of the 2 objects, however you could compare many values by doing something like this:
return new EqualsBuilder() .append(this.field1, castObj.getField1()) .append(this.field2, castObj.getField2()) .append(this.field3, castObj.getField3()) .isEquals();
- This simple example only compares the id values of the 2 objects, however you could compare many values by doing something like this:
- Create a hashCode function using the HashCodeBuilder
public int hashCode() { // pick 2 hard-coded, odd, >0 ints as args return new HashCodeBuilder(1, 31) .append(this.id) .toHashCode(); }
- Like the previous example, this only uses the id for creating the hashCode but you can easily append more properties
- Create a compareTo function using the CompareToBuilder
public int compareTo(Object obj) { org.sakaiproject.tool.mytool.MyObject castObj = (org.sakaiproject.tool.mytool.MyObject) obj; return new CompareToBuilder() .append(this.getId(), castObj.getId()) .toComparison(); }
- Like the previous examples, this only uses the id for comparison but you can easily append more properties
- Create a toString function using the ToStringBuilder
public String toString() { return new ToStringBuilder(this) .append(this.id) .toString(); }
- Like the previous examples, this only uses the id for string generation but you can easily append more properties
- Add the required imports
- Your object should now be comparable to objects of the same type that have the same data
- A sample of an object which demostrates use of the commons-lang builders: TaskImpl.java
- A sample of implemented functions using commons-lang:
public boolean equals(Object obj) { if (obj == null) return false; if (obj instanceof Task == false) return false; if (this == obj) return true; Task castObj = (Task) obj; return new EqualsBuilder() .append(this.getId(), castObj.getId()) .append(this.getOwner(), castObj.getOwner()) .append(this.getSiteId(), castObj.getSiteId()) .isEquals(); } public int hashCode() { // pick 2 hard-coded, odd, >0 ints as args return new HashCodeBuilder(1, 31) .append(this.id) .append(this.owner) .append(this.siteId) .toHashCode(); } public int compareTo(Object obj) { Task castObj = (Task) obj; return new CompareToBuilder() .append(this.getId(), castObj.getId()) .append(this.getOwner(), castObj.getOwner()) .toComparison(); } public String toString() { return new ToStringBuilder(this) .append(this.id) .append(this.owner) .append(this.siteId) .append(this.creationDate) .append(this.task) .toString(); }