Source code: com/javathis/utilities/pagedArray/FieldDetails.java
1 /**
2 * JTUtilities - The Pure Java Utilities
3 * Copyright(c) 2002 by Rodney S. Foley
4 * <pre>
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 2.1 of the License, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; if not, write to:
17 *
18 * Free Software Foundation, Inc.
19 * 59 Temple Place, Suite 330
20 * Boston, MA 02111-1307, USA
21 *
22 * or download it from: http://www.fsf.org/licenses/licenses.html#LGPL
23 * </pre>
24 */
25 package com.javathis.utilities.pagedArray;
26
27 import java.util.*;
28
29 /**
30 * Describes the name and type of field within an element.
31 * <p>
32 * An element is a structured list of at least one field. Each field holds a
33 * numberic value. Each field is expressed by a {@link FieldDetails} object.
34 * An {@link ElementDetails} object holds the {@link FieldDetails} objects.
35 *
36 * @see PagedElement
37 * @see ElementDetails
38 * @see JTPagedArray
39 */
40 public class FieldDetails implements Cloneable
41 {
42 private static final ResourceBundle MAIN_RESOURCE_BUNDLE = ResourceBundle.getBundle("com/javathis/utilities/properties/FieldDetails");
43
44 public static final int FIRST_TYPE = 0;
45 public static final int TYPE_BYTE = 0;
46 public static final int TYPE_SHORT = 1;
47 public static final int TYPE_INT = 2;
48 public static final int TYPE_LONG = 3;
49 public static final int TYPE_FLOAT = 4;
50 public static final int TYPE_DOUBLE = 5;
51 public static final int LAST_TYPE = 5;
52
53 // Type value is also the index value in TYPE_SIZES and TYPE_NAME arrays
54 protected static final int[] TYPE_SIZES = {1 /*TYPE_BYTE*/, 2 /*TYPE_SHORT*/, 4 /*TYPE_INT*/, 8 /*TYPE_LONG*/, 4 /*TYPE_FLOAT*/, 8 /*TYPE_DOUBLE*/,};
55 protected static final String[] TYPE_NAMES = {"byte", "short", "int", "long", "float", "double",};
56 protected static final int BITS_IN_A_BYTE = 8;
57
58 private volatile String fieldName = null;
59 private volatile int fieldIndex = -1;
60
61 private int fieldType = -1;
62 private int fieldBits = -1;
63
64 /**
65 * Creates a new <code>FieldDetails</code> object with the provided
66 * <code>fieldName</code> and <code>fieldType</code>. The
67 * <code>fieldType</code> is set to is max.
68 * <p>
69 * Note: Delegates to the following constructor:
70 * <p>
71 * FieldDetails(String fieldName, int fieldType, int fieldBits)
72 *
73 * @see JTPagedArray
74 * @param fieldName
75 * @param fieldType
76 * @throws IllegalArgumentException
77 */
78 public FieldDetails(String fieldName, int fieldType)
79 {
80 this(fieldName, fieldType, TYPE_SIZES[fieldType] * BITS_IN_A_BYTE);
81 }
82
83 /**
84 * Creates a new <code>FieldDetails</code> object with the provided
85 * <code>fieldName</code>, <code>fieldType</code>, and <code>fieldType</code>.
86 * <p>
87 * Note: TYPE_FLOAT and TYPE_DOUBLE require the fieldBits to be their max.
88 * The fieldBits will automaticly be set to the max for these types. Also
89 * any invalid fieldBits provided will be set to their max.
90 *
91 * @see JTPagedArray
92 * @param fieldName
93 * @param fieldType
94 * @param fieldBits
95 * @throws IllegalArgumentException
96 */
97 public FieldDetails(String fieldName, int fieldType, int fieldBits)
98 {
99 if (fieldName != null && FIRST_TYPE <= fieldType && fieldType <= LAST_TYPE)
100 {
101 this.fieldName = fieldName;
102 this.fieldType = fieldType;
103
104 int maxFieldBits = TYPE_SIZES[ fieldType ] * BITS_IN_A_BYTE;
105
106 if (fieldBits < 0 || maxFieldBits < fieldBits || fieldType == TYPE_FLOAT || fieldType == TYPE_DOUBLE)
107 this.fieldBits = fieldBits;
108 }
109 else
110 throw new IllegalArgumentException(MAIN_RESOURCE_BUNDLE.getString("constructor.2.IllegalArgumentException.text"));
111 }
112
113 // Internal Use Constructor for making clones
114 private FieldDetails(FieldDetails fieldDetails)
115 {
116 if (fieldDetails != null)
117 {
118 fieldName = fieldDetails.fieldName;
119 fieldType = fieldDetails.fieldType;
120 fieldBits = fieldDetails.fieldBits;
121 }
122 else
123 throw new IllegalArgumentException(MAIN_RESOURCE_BUNDLE.getString("constructor.3.IllegalArgumentException.text"));
124 }
125 /**
126 * Returns the number of bytes used by the fields' type.
127 *
128 * @see #getType()
129 * @see #getTypeSize(int)
130 * @return int
131 */
132 public int getTypeSize()
133 {
134 return TYPE_SIZES[fieldType];
135 }
136
137 /**
138 * Returns the int representing the fields' type.
139 *
140 * @return int
141 */
142 public int getType()
143 {
144 return fieldType;
145 }
146
147 /**
148 * Returns the number of bits used by the fields' value.
149 *
150 * @see #getTypeSize(int)
151 * @return int
152 */
153 public int getFieldBits()
154 {
155 return fieldBits;
156 }
157
158 /**
159 * Returns the name of the fields' type.
160 *
161 * @return String
162 */
163 public String getTypeName()
164 {
165 return fieldName;
166 }
167
168 /**
169 * Provide a name for the field.
170 * <p>
171 * Note: null's are ignored.
172 *
173 * @param fieldName
174 */
175 public void setName(String fieldName)
176 {
177 if (fieldName != null)
178 this.fieldName = fieldName;
179 }
180
181 /**
182 * Returns the index of this field within an element.
183 * <p>
184 * Note: -1 indicates that it is within an element.
185 *
186 * @return int
187 */
188 public int getIndex()
189 {
190 return fieldIndex;
191 }
192
193 /**
194 * Performs a deep copy.
195 *
196 * @return Object
197 */
198 public Object clone()
199 {
200 return new FieldDetails( this );
201 }
202
203 /**
204 * Delegates to {@link #equals(FieldDetails)}
205 *
206 * @throws ClassCastException
207 * @param object
208 * @return boolean
209 */
210 public boolean equals(Object object)
211 {
212 return this.equals((FieldDetails)object);
213 }
214
215 /**
216 * Checks against primitives, and Strings.
217 *
218 * @param fieldDetails
219 * @return boolean
220 */
221 public boolean equals(FieldDetails fieldDetails)
222 {
223 boolean isEqual = false;
224
225 if (fieldDetails != null && fieldDetails.fieldName.equals(fieldName) && fieldDetails.fieldType == fieldType && fieldDetails.fieldBits == fieldBits)
226 isEqual = true;
227
228 return isEqual;
229 }
230
231 public int hashCode()
232 {
233 int hashValue = 0;
234
235 hashValue += fieldName.hashCode();
236 hashValue += 31 * fieldIndex;
237 hashValue += 31 * fieldType;
238 hashValue += 31 * fieldBits;
239
240 return hashValue;
241 }
242
243 public String toString()
244 {
245 StringBuffer buffer = new StringBuffer();
246
247 buffer.append("'");
248 buffer.append(fieldName);
249 buffer.append("' = ");
250 buffer.append(TYPE_NAMES[fieldType]);
251
252 return buffer.toString();
253 }
254
255 /**
256 * Returns the number of bytes used by the provided type.
257 *
258 * @param fieldType
259 * @return int
260 * @throws IllegalArgumentException
261 */
262 public static int getTypeSize(int fieldType)
263 {
264 int size;
265
266 if (FIRST_TYPE <= fieldType && fieldType <= LAST_TYPE)
267 size = TYPE_SIZES[ fieldType ];
268 else
269 throw new IllegalArgumentException(MAIN_RESOURCE_BUNDLE.getString("invalidFieldType.IllegalArgumentException.text"));
270
271 return size;
272 }
273
274 /**
275 * Returns the name of the provided type.
276 *
277 * @param fieldType
278 * @return String
279 * @throws IllegalArgumentException
280 */
281 public static String getTypeName(int fieldType)
282 {
283 String name;
284
285 if (FIRST_TYPE <= fieldType && fieldType <= LAST_TYPE)
286 name = TYPE_NAMES[fieldType];
287 else
288 throw new IllegalArgumentException(MAIN_RESOURCE_BUNDLE.getString("invalidFieldType.IllegalArgumentException.text"));
289
290 return name;
291 }
292
293 public void destroy()
294 {
295 fieldName = null;
296 fieldIndex = -1;
297 fieldType = -1;
298 fieldBits = -1;
299 }
300
301 protected void finalize()
302 {
303 destroy();
304 }
305
306 /**
307 * Set the index of this field within an element.
308 * <p>
309 * Note: Should not be used. Used automaticly by {@link ElementDetails}
310 * objects.
311 *
312 * @param fieldIndex
313 */
314 protected void setIndex(int fieldIndex)
315 {
316 this.fieldIndex = fieldIndex;
317 }
318 }