001 // Copyright 2010 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry5.func; 016 017 /** 018 * A Tuple holds two values of two different types. 019 * 020 * @param <A> 021 * @param <B> 022 * @since 5.3 023 */ 024 public class Tuple<A, B> 025 { 026 public final A first; 027 028 public final B second; 029 030 public Tuple(A first, B second) 031 { 032 this.first = first; 033 this.second = second; 034 } 035 036 public static <X, Y> Tuple<X, Y> create(X first, Y second) 037 { 038 return new Tuple<X, Y>(first, second); 039 } 040 041 /** 042 * Returns the values of the tuple, separated by commas, enclosed in parenthesis. Example: 043 * <code>("Ace", "Spades")</code>. 044 */ 045 @Override 046 public String toString() 047 { 048 StringBuilder builder = new StringBuilder("("); 049 050 builder.append(String.valueOf(first)); 051 builder.append(", "); 052 builder.append(String.valueOf(second)); 053 054 extendDescription(builder); 055 056 return builder.append(")").toString(); 057 } 058 059 /** 060 * Overriden in subclasses to write additional values into the 061 * description. 062 * 063 * @param builder 064 */ 065 protected void extendDescription(StringBuilder builder) 066 { 067 } 068 069 /** Utility for comparing two values, either of which may be null. */ 070 static boolean isEqual(Object left, Object right) 071 { 072 return left == right || (left != null && left.equals(right)); 073 } 074 075 /** 076 * Compares this Tuple to another object. Equality is defined by: other object is not null, 077 * is same class as this Tuple, and all values are themselves equal. 078 */ 079 @Override 080 public boolean equals(Object obj) 081 { 082 if (obj == this) 083 return true; 084 085 if (obj == null || !(obj.getClass() == getClass())) 086 return false; 087 088 return isMatch(obj); 089 } 090 091 /** 092 * The heart of {@link #equals(Object)}; the other object is the same class as this object. 093 * 094 * @param other 095 * other tuple to compare 096 * @return true if all values stored in tuple match 097 */ 098 protected boolean isMatch(Object other) 099 { 100 Tuple<?, ?> tuple = (Tuple<?, ?>) other; 101 102 return isEqual(first, tuple.first) && isEqual(second, tuple.second); 103 } 104 }