KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > torque > om > ComboKey


1 package org.apache.torque.om;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements. See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership. The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License. You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied. See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */

21
22 import java.util.ArrayList JavaDoc;
23 import org.apache.commons.lang.ObjectUtils;
24
25 /**
26  * This class can be used as an ObjectKey to uniquely identify an
27  * object within an application where the key consists of multiple
28  * entities (such a String[] representing a multi-column primary key).
29  *
30  * @author <a HREF="mailto:jmcnally@collab.net">John McNally</a>
31  * @author <a HREF="mailto:dlr@collab.net">Daniel Rall</a>
32  * @author <a HREF="mailto:drfish@cox.net">J. Russell Smyth</a>
33  * @version $Id: ComboKey.java 473821 2006-11-11 22:37:25Z tv $
34  */

35 public class ComboKey extends ObjectKey
36 {
37     /**
38      * Serial version
39      */

40     private static final long serialVersionUID = -264927663211141894L;
41
42     // might want to shift these to TR.props
43

44     /** The single character used to separate key values in a string. */
45     public static final char SEPARATOR = ':';
46
47     /** The single character used to separate key values in a string. */
48     public static final String JavaDoc SEPARATOR_STRING = ":";
49
50     /** The array of the keys */
51     private SimpleKey[] key;
52
53     /**
54      * Creates an ComboKey whose internal representation will be
55      * set later, through a set method
56      */

57     public ComboKey()
58     {
59     }
60
61     /**
62      * Creates a ComboKey whose internal representation is an
63      * array of SimpleKeys.
64      *
65      * @param keys the key values
66      */

67     public ComboKey(SimpleKey[] keys)
68     {
69         setValue(keys);
70     }
71
72     /**
73      * Sets the internal representation to a String array.
74      *
75      * @param keys the key values
76      * @see #toString()
77      */

78     public ComboKey(String JavaDoc keys)
79     {
80         setValue(keys);
81     }
82
83     /**
84      * Sets the internal representation using a SimpleKey array.
85      *
86      * @param keys the key values
87      */

88     public void setValue(SimpleKey[] keys)
89     {
90         this.key = keys;
91     }
92
93     /**
94      * Sets the internal representation using a String of the
95      * form produced by the toString method.
96      *
97      * @param keys the key values
98      */

99     public void setValue(String JavaDoc keys)
100     {
101         int startPtr = 0;
102         int indexOfSep = keys.indexOf(SEPARATOR);
103         ArrayList JavaDoc tmpKeys = new ArrayList JavaDoc();
104         while (indexOfSep != -1)
105         {
106             if (indexOfSep == startPtr)
107             {
108                 tmpKeys.add(null);
109             }
110             else
111             {
112                 char keyType = keys.charAt(startPtr);
113                 String JavaDoc keyString = keys.substring(startPtr + 1, indexOfSep);
114
115                 SimpleKey newKey = null;
116                 switch(keyType)
117                 {
118                     case 'N':
119                         newKey = new NumberKey(keyString);
120                         break;
121                     case 'S':
122                         newKey = new StringKey(keyString);
123                         break;
124                     case 'D':
125                         try
126                         {
127                             newKey = new DateKey(keyString);
128                         }
129                         catch (NumberFormatException JavaDoc nfe)
130                         {
131                             newKey = new DateKey();
132                         }
133                         break;
134                     default:
135                         // unextepcted key type
136
}
137                 tmpKeys.add(newKey);
138             }
139             startPtr = indexOfSep + 1;
140             indexOfSep = keys.indexOf(SEPARATOR, startPtr);
141         }
142
143         this.key = new SimpleKey[tmpKeys.size()];
144         for (int i = 0; i < this.key.length; i++)
145         {
146             this.key[i] = (SimpleKey) tmpKeys.get(i);
147         }
148     }
149
150     /**
151      * Sets the internal representation using a ComboKey.
152      *
153      * @param keys the key values
154      */

155     public void setValue(ComboKey keys)
156     {
157         setValue((SimpleKey[]) keys.getValue());
158     }
159
160     /**
161      * Get the underlying object.
162      *
163      * @return the underlying object
164      */

165     public Object JavaDoc getValue()
166     {
167         return key;
168     }
169
170     /**
171      * This method will return true if the conditions for a looseEquals
172      * are met and in addition no parts of the keys are null.
173      *
174      * @param keyObj the comparison value
175      * @return whether the two objects are equal
176      */

177     public boolean equals(Object JavaDoc keyObj)
178     {
179         boolean isEqual = false;
180
181         if (key != null)
182         {
183             // check that all keys are not null
184
isEqual = true;
185             SimpleKey[] keys = key;
186             for (int i = 0; i < keys.length && isEqual; i++)
187             {
188                 isEqual &= keys[i] != null && keys[i].getValue() != null;
189             }
190
191             isEqual &= looseEquals(keyObj);
192         }
193
194         return isEqual;
195     }
196
197     /**
198      * keyObj is equal to this ComboKey if keyObj is a ComboKey, String,
199      * ObjectKey[], or String[] that contains the same information this key
200      * contains.
201      * For example A String[] might be equal to this key, if this key was
202      * instantiated with a String[] and the arrays contain equal Strings.
203      * Another example, would be if keyObj is an ComboKey that was
204      * instantiated with a ObjectKey[] and this ComboKey was instantiated with
205      * a String[], but the ObjectKeys in the ObjectKey[] were instantiated
206      * with Strings that equal the Strings in this KeyObject's String[]
207      * This method is not as strict as the equals method which does not
208      * allow any null keys parts, while the internal key may not be null
209      * portions may be, and the two object will be considered equal if
210      * their null portions match.
211      *
212      * @param keyObj the comparison value
213      * @return whether the two objects are equal
214      */

215     public boolean looseEquals(Object JavaDoc keyObj)
216     {
217         boolean isEqual = false;
218
219         if (key != null)
220         {
221             // Checks a compound key (ObjectKey[] or String[]
222
// based) with the delimited String created by the
223
// toString() method. Slightly expensive, but should be less
224
// than parsing the String into its constituents.
225
if (keyObj instanceof String JavaDoc)
226             {
227                 isEqual = toString().equals(keyObj);
228             }
229             // check against a ObjectKey. Two keys are equal, if their
230
// internal keys equivalent.
231
else if (keyObj instanceof ComboKey)
232             {
233                 SimpleKey[] obj = (SimpleKey[])
234                     ((ComboKey) keyObj).getValue();
235
236                 SimpleKey[] keys1 = key;
237                 SimpleKey[] keys2 = obj;
238                 isEqual = keys1.length == keys2.length;
239                 for (int i = 0; i < keys1.length && isEqual; i++)
240                 {
241                     isEqual &= ObjectUtils.equals(keys1[i], keys2[i]);
242                 }
243             }
244             else if (keyObj instanceof SimpleKey[])
245             {
246                 SimpleKey[] keys1 = key;
247                 SimpleKey[] keys2 = (SimpleKey[]) keyObj;
248                 isEqual = keys1.length == keys2.length;
249                 for (int i = 0; i < keys1.length && isEqual; i++)
250                 {
251                     isEqual &= ObjectUtils.equals(keys1[i], keys2[i]);
252                 }
253             }
254         }
255         return isEqual;
256     }
257
258     /**
259      *
260      * @param sb the StringBuffer to append
261      * @see #toString()
262      */

263     public void appendTo(StringBuffer JavaDoc sb)
264     {
265         if (key != null)
266         {
267             SimpleKey[] keys = key;
268             for (int i = 0; i < keys.length; i++)
269             {
270                 if (keys[i] != null)
271                 {
272                     if (keys[i] instanceof StringKey)
273                     {
274                         sb.append("S");
275                     }
276                     else if (keys[i] instanceof NumberKey)
277                     {
278                         sb.append("N");
279                     }
280                     else if (keys[i] instanceof DateKey)
281                     {
282                         sb.append("D");
283                     }
284                     else
285                     {
286                         // unknown type
287
sb.append("U");
288                     }
289                     keys[i].appendTo(sb);
290                 }
291                 // MUST BE ADDED AFTER EACH KEY, IN CASE OF NULL KEY!
292
sb.append(SEPARATOR);
293             }
294         }
295     }
296
297     /**
298      * if the underlying key array is not null and the first element is
299      * not null this method returns the hashcode of the first element
300      * in the key. Otherwise calls ObjectKey.hashCode()
301      *
302      * @return an <code>int</code> value
303      */

304     public int hashCode()
305     {
306         if (key == null)
307         {
308             return super.hashCode();
309         }
310
311         SimpleKey sk = key[0];
312         if (sk == null)
313         {
314             return super.hashCode();
315         }
316
317         return sk.hashCode();
318     }
319
320     /**
321      * A String that may consist of one section or multiple sections
322      * separated by a colon. <br/>
323      * Each Key is represented by <code>[type N|S|D][value][:]</code>. <p/>
324      * Example: <br/>
325      * the ComboKey(StringKey("key1"), NumberKey(2)) is represented as
326      * <code><b>Skey1:N2:</b></code>
327      *
328      * @return a String representation
329      */

330     public String JavaDoc toString()
331     {
332         StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
333         appendTo(sbuf);
334         return sbuf.toString();
335     }
336 }
337
Popular Tags