001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: SimpleCatalog.java,v 1.19.2.5 2008/01/07 15:14:20 cwl Exp $
007: */
008:
009: package com.sleepycat.persist.impl;
010:
011: import java.util.ArrayList;
012: import java.util.HashMap;
013: import java.util.IdentityHashMap;
014: import java.util.List;
015: import java.util.Map;
016: import java.util.NoSuchElementException;
017:
018: import com.sleepycat.persist.model.EntityModel;
019: import com.sleepycat.persist.raw.RawObject;
020:
021: /**
022: * A static catalog containing simple types only. Once created, this catalog
023: * is immutable.
024: *
025: * For bindings accessed by a PersistComparator during recovery, the
026: * SimpleCatalog provides formats for all simple types. To reduce redundant
027: * format objects, the SimpleCatalog's formats are copied when creating a
028: * regular PersistCatalog.
029: *
030: * This class also contains utility methods for dealing with primitives.
031: *
032: * @author Mark Hayes
033: */
034: public class SimpleCatalog implements Catalog {
035:
036: private static final Map<String, Class> keywordToPrimitive;
037: static {
038: keywordToPrimitive = new HashMap<String, Class>(8);
039: keywordToPrimitive.put("boolean", Boolean.TYPE);
040: keywordToPrimitive.put("char", Character.TYPE);
041: keywordToPrimitive.put("byte", Byte.TYPE);
042: keywordToPrimitive.put("short", Short.TYPE);
043: keywordToPrimitive.put("int", Integer.TYPE);
044: keywordToPrimitive.put("long", Long.TYPE);
045: keywordToPrimitive.put("float", Float.TYPE);
046: keywordToPrimitive.put("double", Double.TYPE);
047: }
048:
049: private static final Map<Class, Class> primitiveTypeToWrapper;
050: static {
051: primitiveTypeToWrapper = new HashMap<Class, Class>(8);
052: primitiveTypeToWrapper.put(Boolean.TYPE, Boolean.class);
053: primitiveTypeToWrapper.put(Character.TYPE, Character.class);
054: primitiveTypeToWrapper.put(Byte.TYPE, Byte.class);
055: primitiveTypeToWrapper.put(Short.TYPE, Short.class);
056: primitiveTypeToWrapper.put(Integer.TYPE, Integer.class);
057: primitiveTypeToWrapper.put(Long.TYPE, Long.class);
058: primitiveTypeToWrapper.put(Float.TYPE, Float.class);
059: primitiveTypeToWrapper.put(Double.TYPE, Double.class);
060: }
061:
062: private static final SimpleCatalog instance = new SimpleCatalog();
063:
064: static SimpleCatalog getInstance() {
065: return instance;
066: }
067:
068: static boolean isSimpleType(Class type) {
069: return instance.formatMap.containsKey(type.getName());
070: }
071:
072: static Class primitiveToWrapper(Class type) {
073: Class cls = primitiveTypeToWrapper.get(type);
074: if (cls == null) {
075: throw new IllegalStateException(type.getName());
076: }
077: return cls;
078: }
079:
080: public static Class keyClassForName(String className) {
081: Class cls = keywordToPrimitive.get(className);
082: if (cls != null) {
083: cls = primitiveTypeToWrapper.get(cls);
084: } else {
085: try {
086: cls = EntityModel.classForName(className);
087: } catch (ClassNotFoundException e) {
088: throw new IllegalArgumentException(
089: "Key class not found: " + className);
090: }
091: }
092: return cls;
093: }
094:
095: public static String keyClassName(String className) {
096: Class cls = keywordToPrimitive.get(className);
097: if (cls != null) {
098: cls = primitiveTypeToWrapper.get(cls);
099: return cls.getName();
100: } else {
101: return className;
102: }
103: }
104:
105: public static Class classForName(String className)
106: throws ClassNotFoundException {
107:
108: Class cls = keywordToPrimitive.get(className);
109: if (cls == null) {
110: cls = EntityModel.classForName(className);
111: }
112: return cls;
113: }
114:
115: static SimpleFormat getSimpleFormat(Class type) {
116: return instance.formatMap.get(type.getName());
117: }
118:
119: static List<Format> copyFormatList() {
120: return new ArrayList<Format>(instance.formatList);
121: }
122:
123: static boolean copyMissingFormats(List<Format> copyToList) {
124: boolean anyCopied = false;
125: for (int i = 0; i <= Format.ID_PREDEFINED; i += 1) {
126: Format this Format = instance.formatList.get(i);
127: Format otherFormat = copyToList.get(i);
128: if (this Format != null && otherFormat == null) {
129: copyToList.set(i, this Format);
130: anyCopied = true;
131: }
132: }
133: return anyCopied;
134: }
135:
136: private List<SimpleFormat> formatList;
137: private Map<String, SimpleFormat> formatMap;
138:
139: private SimpleCatalog() {
140:
141: /*
142: * Reserve slots for all predefined IDs, so that that next ID assigned
143: * will be Format.ID_PREDEFINED plus one.
144: */
145: int initCapacity = Format.ID_PREDEFINED * 2;
146: formatList = new ArrayList<SimpleFormat>(initCapacity);
147: formatMap = new HashMap<String, SimpleFormat>(initCapacity);
148:
149: for (int i = 0; i <= Format.ID_PREDEFINED; i += 1) {
150: formatList.add(null);
151: }
152:
153: /* Initialize all predefined formats. */
154: setFormat(Format.ID_BOOL, new SimpleFormat.FBool(true));
155: setFormat(Format.ID_BOOL_W, new SimpleFormat.FBool(false));
156: setFormat(Format.ID_BYTE, new SimpleFormat.FByte(true));
157: setFormat(Format.ID_BYTE_W, new SimpleFormat.FByte(false));
158: setFormat(Format.ID_SHORT, new SimpleFormat.FShort(true));
159: setFormat(Format.ID_SHORT_W, new SimpleFormat.FShort(false));
160: setFormat(Format.ID_INT, new SimpleFormat.FInt(true));
161: setFormat(Format.ID_INT_W, new SimpleFormat.FInt(false));
162: setFormat(Format.ID_LONG, new SimpleFormat.FLong(true));
163: setFormat(Format.ID_LONG_W, new SimpleFormat.FLong(false));
164: setFormat(Format.ID_FLOAT, new SimpleFormat.FFloat(true));
165: setFormat(Format.ID_FLOAT_W, new SimpleFormat.FFloat(false));
166: setFormat(Format.ID_DOUBLE, new SimpleFormat.FDouble(true));
167: setFormat(Format.ID_DOUBLE_W, new SimpleFormat.FDouble(false));
168: setFormat(Format.ID_CHAR, new SimpleFormat.FChar(true));
169: setFormat(Format.ID_CHAR_W, new SimpleFormat.FChar(false));
170: setFormat(Format.ID_STRING, new SimpleFormat.FString());
171: setFormat(Format.ID_BIGINT, new SimpleFormat.FBigInt());
172: /*
173: setFormat(Format.ID_BIGDEC, new SimpleFormat.FBigDec());
174: */
175: setFormat(Format.ID_DATE, new SimpleFormat.FDate());
176:
177: /* Tell primitives about their wrapper class. */
178: setWrapper(Format.ID_BOOL, Format.ID_BOOL_W);
179: setWrapper(Format.ID_BYTE, Format.ID_BYTE_W);
180: setWrapper(Format.ID_SHORT, Format.ID_SHORT_W);
181: setWrapper(Format.ID_INT, Format.ID_INT_W);
182: setWrapper(Format.ID_LONG, Format.ID_LONG_W);
183: setWrapper(Format.ID_FLOAT, Format.ID_FLOAT_W);
184: setWrapper(Format.ID_DOUBLE, Format.ID_DOUBLE_W);
185: setWrapper(Format.ID_CHAR, Format.ID_CHAR_W);
186: }
187:
188: /**
189: * Sets a format for which space in the formatList has been preallocated,
190: * and makes it the current format for the class.
191: */
192: private void setFormat(int id, SimpleFormat format) {
193: format.setId(id);
194: format.initializeIfNeeded(this );
195: formatList.set(id, format);
196: formatMap.put(format.getClassName(), format);
197: }
198:
199: /**
200: * Tells a primitive format about the format for its corresponding
201: * primitive wrapper class.
202: */
203: private void setWrapper(int primitiveId, int wrapperId) {
204: SimpleFormat primitiveFormat = formatList.get(primitiveId);
205: SimpleFormat wrapperFormat = formatList.get(wrapperId);
206: primitiveFormat.setWrapperFormat(wrapperFormat);
207: }
208:
209: public int getInitVersion(Format format, boolean forReader) {
210: return Catalog.CURRENT_VERSION;
211: }
212:
213: public Format getFormat(int formatId) {
214: Format format;
215: try {
216: format = formatList.get(formatId);
217: if (format == null) {
218: throw new IllegalStateException("Not a simple type: "
219: + formatId);
220: }
221: return format;
222: } catch (NoSuchElementException e) {
223: throw new IllegalStateException("Not a simple type: "
224: + formatId);
225: }
226: }
227:
228: public Format getFormat(Class cls) {
229: Format format = formatMap.get(cls.getName());
230: if (format == null) {
231: throw new IllegalArgumentException("Not a simple type: "
232: + cls.getName());
233: }
234: return format;
235: }
236:
237: public Format getFormat(String className) {
238: return formatMap.get(className);
239: }
240:
241: public Format createFormat(String clsName,
242: Map<String, Format> newFormats) {
243: throw new IllegalStateException();
244: }
245:
246: public Format createFormat(Class type,
247: Map<String, Format> newFormats) {
248: throw new IllegalStateException();
249: }
250:
251: public boolean isRawAccess() {
252: return false;
253: }
254:
255: public Object convertRawObject(RawObject o,
256: IdentityHashMap converted) {
257: throw new IllegalStateException();
258: }
259: }
|