1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: RawAbstractInput.java,v 1.1 2008/02/07 17:12:27 mark Exp $ 7 */ 8 9package com.sleepycat.persist.impl; 10 11import java.math.BigInteger; 12import java.util.IdentityHashMap; 13 14import com.sleepycat.persist.raw.RawObject; 15 16/** 17 * Base class for EntityInput implementations that type-check RawObject 18 * instances and convert them to regular persistent objects, via the 19 * Format.convertRawObject method. 20 * 21 * The subclass implements readNext which should call checkAndConvert before 22 * returning the final value. 23 * 24 * @author Mark Hayes 25 */ 26abstract class RawAbstractInput extends AbstractInput { 27 28 private IdentityHashMap converted; 29 30 RawAbstractInput(Catalog catalog, 31 boolean rawAccess, 32 IdentityHashMap converted) { 33 super(catalog, rawAccess); 34 this.converted = converted; 35 } 36 37 public Object readObject() { 38 return readNext(); 39 } 40 41 public Object readKeyObject(Format format) { 42 return readNext(); 43 } 44 45 public void registerPriKeyObject(Object o) { 46 } 47 48 public int readArrayLength() { 49 throw new UnsupportedOperationException(); 50 } 51 52 public int readEnumConstant(String[] names) { 53 throw new UnsupportedOperationException(); 54 } 55 56 public void skipField(Format declaredFormat) { 57 } 58 59 abstract Object readNext(); 60 61 Object checkAndConvert(Object o, Format declaredFormat) { 62 if (o == null) { 63 if (declaredFormat.isPrimitive()) { 64 throw new IllegalArgumentException 65 ("A primitive type may not be null or missing: " + 66 declaredFormat.getClassName()); 67 } 68 } else if (declaredFormat.isSimple()) { 69 if (declaredFormat.isPrimitive()) { 70 if (o.getClass() != 71 declaredFormat.getWrapperFormat().getType()) { 72 throw new IllegalArgumentException 73 ("Raw value class: " + o.getClass().getName() + 74 " must be the wrapper class for a primitive type: " + 75 declaredFormat.getClassName()); 76 } 77 } else { 78 if (o.getClass() != declaredFormat.getType()) { 79 throw new IllegalArgumentException 80 ("Raw value class: " + o.getClass().getName() + 81 " must be the declared class for a simple type: " + 82 declaredFormat.getClassName()); 83 } 84 } 85 } else { 86 if (o instanceof RawObject) { 87 Object o2 = null; 88 if (!rawAccess) { 89 if (converted != null) { 90 o2 = converted.get(o); 91 } else { 92 converted = new IdentityHashMap(); 93 } 94 } 95 if (o2 != null) { 96 o = o2; 97 } else { 98 if (!rawAccess) { 99 o = catalog.convertRawObject((RawObject) o, converted); 100 } 101 } 102 } else { 103 if (!SimpleCatalog.isSimpleType(o.getClass())) { 104 throw new IllegalArgumentException 105 ("Raw value class: " + o.getClass().getName() + 106 " must be RawObject a simple type"); 107 } 108 } 109 if (rawAccess) { 110 checkRawType(catalog, o, declaredFormat); 111 } else { 112 if (!declaredFormat.getType().isAssignableFrom(o.getClass())) { 113 throw new IllegalArgumentException 114 ("Raw value class: " + o.getClass().getName() + 115 " is not assignable to type: " + 116 declaredFormat.getClassName()); 117 } 118 } 119 } 120 return o; 121 } 122 123 static Format checkRawType(Catalog catalog, 124 Object o, 125 Format declaredFormat) { 126 assert declaredFormat != null; 127 Format format; 128 if (o instanceof RawObject) { 129 format = (Format) ((RawObject) o).getType(); 130 } else { 131 format = catalog.getFormat(o.getClass()); 132 if (!format.isSimple() || format.isEnum()) { 133 throw new IllegalArgumentException 134 ("Not a RawObject or a non-enum simple type: " + 135 format.getClassName()); 136 } 137 } 138 if (!format.isAssignableTo(declaredFormat)) { 139 throw new IllegalArgumentException 140 ("Not a subtype of the field's declared class " + 141 declaredFormat.getClassName() + ": " + 142 format.getClassName()); 143 } 144 if (!format.isCurrentVersion()) { 145 throw new IllegalArgumentException 146 ("Raw type version is not current. Class: " + 147 format.getClassName() + " Version: " + 148 format.getVersion()); 149 } 150 Format proxiedFormat = format.getProxiedFormat(); 151 if (proxiedFormat != null) { 152 format = proxiedFormat; 153 } 154 return format; 155 } 156 157 /* The following methods are a subset of the methods in TupleInput. */ 158 159 public String readString() { 160 return (String) readNext(); 161 } 162 163 public char readChar() { 164 return ((Character) readNext()).charValue(); 165 } 166 167 public boolean readBoolean() { 168 return ((Boolean) readNext()).booleanValue(); 169 } 170 171 public byte readByte() { 172 return ((Byte) readNext()).byteValue(); 173 } 174 175 public short readShort() { 176 return ((Short) readNext()).shortValue(); 177 } 178 179 public int readInt() { 180 return ((Integer) readNext()).intValue(); 181 } 182 183 public long readLong() { 184 return ((Long) readNext()).longValue(); 185 } 186 187 public float readSortedFloat() { 188 return ((Float) readNext()).floatValue(); 189 } 190 191 public double readSortedDouble() { 192 return ((Double) readNext()).doubleValue(); 193 } 194 195 public BigInteger readBigInteger() { 196 return (BigInteger) readNext(); 197 } 198} 199