001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: WidenerInput.java,v 1.3.2.3 2008/01/07 15:14:20 cwl Exp $
007: */
008:
009: package com.sleepycat.persist.impl;
010:
011: import java.math.BigInteger;
012:
013: /**
014: * Widens a value returned by another input when any readXxx method is called.
015: * Used to cause an Accessor to read a widened value.
016: *
017: * For non-key fields we support all Java primitive widening:
018: * - byte to short, int, long, float, double or BigInteger
019: * - short to int, long, float, double or BigInteger
020: * - char to int, long, float, double or BigInteger
021: * - int to long, float, double or BigInteger
022: * - long to float, double or BigInteger
023: * - float to double
024: *
025: * For non-key fields we also support:
026: * - Java reference widening
027: * - primitive to primitive wrapper
028: * - Java primitive widening to corresponding primitive wrappers
029: * - Java widening of primitive wrapper to primitive wrapper
030: *
031: * For secondary keys fields we ONLY support:
032: * - primitive to primitive wrapper
033: *
034: * But for primary keys and composite key fields we ONLY support:
035: * - primitive to primitive wrapper
036: * - primitive wrapper to primitive
037: * These conversions don't require any converter, since the stored format is
038: * not changed. A WidenerInput is not used for these changes.
039: *
040: * @author Mark Hayes
041: */
042: class WidenerInput extends AbstractInput {
043:
044: private EntityInput input;
045: private int fromFormatId;
046: private int toFormatId;
047:
048: /**
049: * Returns whether widening is supported by this class. If false is
050: * returned by this method, then widening is disallowed and a field
051: * converter or deleter is necessary.
052: */
053: static boolean isWideningSupported(Format fromFormat,
054: Format toFormat, boolean isSecKeyField) {
055: int fromFormatId = fromFormat.getId();
056: int toFormatId = toFormat.getId();
057:
058: switch (fromFormatId) {
059: case Format.ID_BOOL:
060: switch (toFormatId) {
061: case Format.ID_BOOL_W:
062: return true;
063: default:
064: return false;
065: }
066: case Format.ID_BYTE:
067: switch (toFormatId) {
068: case Format.ID_BYTE_W:
069: return true;
070: case Format.ID_SHORT:
071: case Format.ID_SHORT_W:
072: case Format.ID_INT:
073: case Format.ID_INT_W:
074: case Format.ID_LONG:
075: case Format.ID_LONG_W:
076: case Format.ID_FLOAT:
077: case Format.ID_FLOAT_W:
078: case Format.ID_DOUBLE:
079: case Format.ID_DOUBLE_W:
080: case Format.ID_BIGINT:
081: return !isSecKeyField;
082: default:
083: return false;
084: }
085: case Format.ID_BYTE_W:
086: switch (toFormatId) {
087: case Format.ID_SHORT_W:
088: case Format.ID_INT_W:
089: case Format.ID_LONG_W:
090: case Format.ID_FLOAT_W:
091: case Format.ID_DOUBLE_W:
092: case Format.ID_BIGINT:
093: return !isSecKeyField;
094: default:
095: return false;
096: }
097: case Format.ID_SHORT:
098: switch (toFormatId) {
099: case Format.ID_SHORT_W:
100: return true;
101: case Format.ID_INT:
102: case Format.ID_INT_W:
103: case Format.ID_LONG:
104: case Format.ID_LONG_W:
105: case Format.ID_FLOAT:
106: case Format.ID_FLOAT_W:
107: case Format.ID_DOUBLE:
108: case Format.ID_DOUBLE_W:
109: case Format.ID_BIGINT:
110: return !isSecKeyField;
111: default:
112: return false;
113: }
114: case Format.ID_SHORT_W:
115: switch (toFormatId) {
116: case Format.ID_INT_W:
117: case Format.ID_LONG_W:
118: case Format.ID_FLOAT_W:
119: case Format.ID_DOUBLE_W:
120: case Format.ID_BIGINT:
121: return !isSecKeyField;
122: default:
123: return false;
124: }
125: case Format.ID_INT:
126: switch (toFormatId) {
127: case Format.ID_INT_W:
128: return true;
129: case Format.ID_LONG:
130: case Format.ID_LONG_W:
131: case Format.ID_FLOAT:
132: case Format.ID_FLOAT_W:
133: case Format.ID_DOUBLE:
134: case Format.ID_DOUBLE_W:
135: case Format.ID_BIGINT:
136: return !isSecKeyField;
137: default:
138: return false;
139: }
140: case Format.ID_INT_W:
141: switch (toFormatId) {
142: case Format.ID_LONG_W:
143: case Format.ID_FLOAT_W:
144: case Format.ID_DOUBLE_W:
145: case Format.ID_BIGINT:
146: return !isSecKeyField;
147: default:
148: return false;
149: }
150: case Format.ID_LONG:
151: switch (toFormatId) {
152: case Format.ID_LONG_W:
153: return true;
154: case Format.ID_FLOAT:
155: case Format.ID_FLOAT_W:
156: case Format.ID_DOUBLE:
157: case Format.ID_DOUBLE_W:
158: case Format.ID_BIGINT:
159: return !isSecKeyField;
160: default:
161: return false;
162: }
163: case Format.ID_LONG_W:
164: switch (toFormatId) {
165: case Format.ID_FLOAT_W:
166: case Format.ID_DOUBLE_W:
167: case Format.ID_BIGINT:
168: return !isSecKeyField;
169: default:
170: return false;
171: }
172: case Format.ID_FLOAT:
173: switch (toFormatId) {
174: case Format.ID_FLOAT_W:
175: return true;
176: case Format.ID_DOUBLE:
177: case Format.ID_DOUBLE_W:
178: return !isSecKeyField;
179: default:
180: return false;
181: }
182: case Format.ID_FLOAT_W:
183: switch (toFormatId) {
184: case Format.ID_DOUBLE_W:
185: return !isSecKeyField;
186: default:
187: return false;
188: }
189: case Format.ID_DOUBLE:
190: switch (toFormatId) {
191: case Format.ID_DOUBLE_W:
192: return true;
193: default:
194: return false;
195: }
196: case Format.ID_CHAR:
197: switch (toFormatId) {
198: case Format.ID_CHAR_W:
199: return true;
200: case Format.ID_INT:
201: case Format.ID_INT_W:
202: case Format.ID_LONG:
203: case Format.ID_LONG_W:
204: case Format.ID_FLOAT:
205: case Format.ID_FLOAT_W:
206: case Format.ID_DOUBLE:
207: case Format.ID_DOUBLE_W:
208: case Format.ID_BIGINT:
209: return !isSecKeyField;
210: default:
211: return false;
212: }
213: case Format.ID_CHAR_W:
214: switch (toFormatId) {
215: case Format.ID_INT_W:
216: case Format.ID_LONG_W:
217: case Format.ID_FLOAT_W:
218: case Format.ID_DOUBLE_W:
219: case Format.ID_BIGINT:
220: return !isSecKeyField;
221: default:
222: return false;
223: }
224: default:
225: return false;
226: }
227: }
228:
229: WidenerInput(EntityInput input, int fromFormatId, int toFormatId) {
230: super (input.getCatalog(), input.isRawAccess());
231: this .input = input;
232: this .fromFormatId = fromFormatId;
233: this .toFormatId = toFormatId;
234: }
235:
236: public void registerPriKeyObject(Object o) {
237: input.registerPriKeyObject(o);
238: }
239:
240: public int readArrayLength() {
241: throw new UnsupportedOperationException();
242: }
243:
244: public int readEnumConstant(String[] names) {
245: throw new UnsupportedOperationException();
246: }
247:
248: public void skipField(Format declaredFormat) {
249: throw new UnsupportedOperationException();
250: }
251:
252: public String readString() {
253: throw new UnsupportedOperationException();
254: }
255:
256: public Object readKeyObject(Format fromFormat) {
257: return readObject();
258: }
259:
260: public Object readObject() {
261: switch (fromFormatId) {
262: case Format.ID_BOOL:
263: checkToFormat(Format.ID_BOOL_W);
264: return input.readBoolean();
265: case Format.ID_BYTE:
266: return byteToObject(input.readByte());
267: case Format.ID_BYTE_W:
268: Byte b = (Byte) input.readObject();
269: return (b != null) ? byteToObject(b) : null;
270: case Format.ID_SHORT:
271: return shortToObject(input.readShort());
272: case Format.ID_SHORT_W:
273: Short s = (Short) input.readObject();
274: return (s != null) ? shortToObject(s) : null;
275: case Format.ID_INT:
276: return intToObject(input.readInt());
277: case Format.ID_INT_W:
278: Integer i = (Integer) input.readObject();
279: return (i != null) ? intToObject(i) : null;
280: case Format.ID_LONG:
281: return longToObject(input.readLong());
282: case Format.ID_LONG_W:
283: Long l = (Long) input.readObject();
284: return (l != null) ? longToObject(l) : null;
285: case Format.ID_FLOAT:
286: return floatToObject(input.readSortedFloat());
287: case Format.ID_FLOAT_W:
288: Float f = (Float) input.readObject();
289: return (f != null) ? floatToObject(f) : null;
290: case Format.ID_DOUBLE:
291: checkToFormat(Format.ID_DOUBLE_W);
292: return input.readSortedDouble();
293: case Format.ID_CHAR:
294: return charToObject(input.readChar());
295: case Format.ID_CHAR_W:
296: Character c = (Character) input.readObject();
297: return (c != null) ? charToObject(c) : null;
298: default:
299: throw new IllegalStateException(String
300: .valueOf(fromFormatId));
301: }
302: }
303:
304: private Object byteToObject(byte v) {
305: switch (toFormatId) {
306: case Format.ID_BYTE:
307: case Format.ID_BYTE_W:
308: return Byte.valueOf(v);
309: case Format.ID_SHORT:
310: case Format.ID_SHORT_W:
311: return Short.valueOf(v);
312: case Format.ID_INT:
313: case Format.ID_INT_W:
314: return Integer.valueOf(v);
315: case Format.ID_LONG:
316: case Format.ID_LONG_W:
317: return Long.valueOf(v);
318: case Format.ID_FLOAT:
319: case Format.ID_FLOAT_W:
320: return Float.valueOf(v);
321: case Format.ID_DOUBLE:
322: case Format.ID_DOUBLE_W:
323: return Double.valueOf(v);
324: case Format.ID_BIGINT:
325: return BigInteger.valueOf(v);
326: default:
327: throw new IllegalStateException(String.valueOf(toFormatId));
328: }
329: }
330:
331: private Object shortToObject(short v) {
332: switch (toFormatId) {
333: case Format.ID_SHORT:
334: case Format.ID_SHORT_W:
335: return Short.valueOf(v);
336: case Format.ID_INT:
337: case Format.ID_INT_W:
338: return Integer.valueOf(v);
339: case Format.ID_LONG:
340: case Format.ID_LONG_W:
341: return Long.valueOf(v);
342: case Format.ID_FLOAT:
343: case Format.ID_FLOAT_W:
344: return Float.valueOf(v);
345: case Format.ID_DOUBLE:
346: case Format.ID_DOUBLE_W:
347: return Double.valueOf(v);
348: case Format.ID_BIGINT:
349: return BigInteger.valueOf(v);
350: default:
351: throw new IllegalStateException(String.valueOf(toFormatId));
352: }
353: }
354:
355: private Object intToObject(int v) {
356: switch (toFormatId) {
357: case Format.ID_INT:
358: case Format.ID_INT_W:
359: return Integer.valueOf(v);
360: case Format.ID_LONG:
361: case Format.ID_LONG_W:
362: return Long.valueOf(v);
363: case Format.ID_FLOAT:
364: case Format.ID_FLOAT_W:
365: return Float.valueOf(v);
366: case Format.ID_DOUBLE:
367: case Format.ID_DOUBLE_W:
368: return Double.valueOf(v);
369: case Format.ID_BIGINT:
370: return BigInteger.valueOf(v);
371: default:
372: throw new IllegalStateException(String.valueOf(toFormatId));
373: }
374: }
375:
376: private Object longToObject(long v) {
377: switch (toFormatId) {
378: case Format.ID_LONG:
379: case Format.ID_LONG_W:
380: return Long.valueOf(v);
381: case Format.ID_FLOAT:
382: case Format.ID_FLOAT_W:
383: return Float.valueOf(v);
384: case Format.ID_DOUBLE:
385: case Format.ID_DOUBLE_W:
386: return Double.valueOf(v);
387: case Format.ID_BIGINT:
388: return BigInteger.valueOf(v);
389: default:
390: throw new IllegalStateException(String.valueOf(toFormatId));
391: }
392: }
393:
394: private Object floatToObject(float v) {
395: switch (toFormatId) {
396: case Format.ID_FLOAT:
397: case Format.ID_FLOAT_W:
398: return Float.valueOf(v);
399: case Format.ID_DOUBLE:
400: case Format.ID_DOUBLE_W:
401: return Double.valueOf(v);
402: default:
403: throw new IllegalStateException(String.valueOf(toFormatId));
404: }
405: }
406:
407: private Object charToObject(char v) {
408: switch (toFormatId) {
409: case Format.ID_CHAR:
410: case Format.ID_CHAR_W:
411: return Character.valueOf(v);
412: case Format.ID_INT:
413: case Format.ID_INT_W:
414: return Integer.valueOf(v);
415: case Format.ID_LONG:
416: case Format.ID_LONG_W:
417: return Long.valueOf(v);
418: case Format.ID_FLOAT:
419: case Format.ID_FLOAT_W:
420: return Float.valueOf(v);
421: case Format.ID_DOUBLE:
422: case Format.ID_DOUBLE_W:
423: return Double.valueOf(v);
424: case Format.ID_BIGINT:
425: return BigInteger.valueOf(v);
426: default:
427: throw new IllegalStateException(String.valueOf(toFormatId));
428: }
429: }
430:
431: public char readChar() {
432: throw new IllegalStateException(String.valueOf(fromFormatId));
433: }
434:
435: public boolean readBoolean() {
436: throw new IllegalStateException(String.valueOf(fromFormatId));
437: }
438:
439: public byte readByte() {
440: throw new IllegalStateException(String.valueOf(fromFormatId));
441: }
442:
443: public short readShort() {
444: checkToFormat(Format.ID_SHORT);
445: switch (fromFormatId) {
446: case Format.ID_BYTE:
447: return input.readByte();
448: default:
449: throw new IllegalStateException(String
450: .valueOf(fromFormatId));
451: }
452: }
453:
454: public int readInt() {
455: checkToFormat(Format.ID_INT);
456: switch (fromFormatId) {
457: case Format.ID_BYTE:
458: return input.readByte();
459: case Format.ID_SHORT:
460: return input.readShort();
461: case Format.ID_CHAR:
462: return input.readChar();
463: default:
464: throw new IllegalStateException(String
465: .valueOf(fromFormatId));
466: }
467: }
468:
469: public long readLong() {
470: checkToFormat(Format.ID_LONG);
471: switch (fromFormatId) {
472: case Format.ID_BYTE:
473: return input.readByte();
474: case Format.ID_SHORT:
475: return input.readShort();
476: case Format.ID_INT:
477: return input.readInt();
478: case Format.ID_CHAR:
479: return input.readChar();
480: default:
481: throw new IllegalStateException(String
482: .valueOf(fromFormatId));
483: }
484: }
485:
486: public float readSortedFloat() {
487: checkToFormat(Format.ID_FLOAT);
488: switch (fromFormatId) {
489: case Format.ID_BYTE:
490: return input.readByte();
491: case Format.ID_SHORT:
492: return input.readShort();
493: case Format.ID_INT:
494: return input.readInt();
495: case Format.ID_LONG:
496: return input.readLong();
497: case Format.ID_CHAR:
498: return input.readChar();
499: default:
500: throw new IllegalStateException(String
501: .valueOf(fromFormatId));
502: }
503: }
504:
505: public double readSortedDouble() {
506: checkToFormat(Format.ID_DOUBLE);
507: switch (fromFormatId) {
508: case Format.ID_BYTE:
509: return input.readByte();
510: case Format.ID_SHORT:
511: return input.readShort();
512: case Format.ID_INT:
513: return input.readInt();
514: case Format.ID_LONG:
515: return input.readLong();
516: case Format.ID_FLOAT:
517: return input.readSortedFloat();
518: case Format.ID_CHAR:
519: return input.readChar();
520: default:
521: throw new IllegalStateException(String
522: .valueOf(fromFormatId));
523: }
524: }
525:
526: public BigInteger readBigInteger() {
527: checkToFormat(Format.ID_BIGINT);
528: switch (fromFormatId) {
529: case Format.ID_BYTE:
530: return BigInteger.valueOf(input.readByte());
531: case Format.ID_SHORT:
532: return BigInteger.valueOf(input.readShort());
533: case Format.ID_INT:
534: return BigInteger.valueOf(input.readInt());
535: case Format.ID_LONG:
536: return BigInteger.valueOf(input.readLong());
537: case Format.ID_CHAR:
538: return BigInteger.valueOf(input.readChar());
539: default:
540: throw new IllegalStateException(String
541: .valueOf(fromFormatId));
542: }
543: }
544:
545: private void checkToFormat(int id) {
546: if (toFormatId != id) {
547: throw new IllegalStateException(String.valueOf(toFormatId));
548: }
549: }
550: }
|