001: /*
002:
003: Derby - Class org.apache.derby.iapi.services.io.FormatableHashtable
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.services.io;
023:
024: import org.apache.derby.iapi.services.io.ArrayInputStream;
025:
026: import org.apache.derby.iapi.services.io.StoredFormatIds;
027: import org.apache.derby.iapi.services.io.FormatIdUtil;
028: import org.apache.derby.iapi.services.io.Formatable;
029: import org.apache.derby.iapi.services.sanity.SanityManager;
030:
031: import java.util.Hashtable;
032: import java.util.Enumeration;
033: import java.io.ObjectOutput;
034: import java.io.ObjectInput;
035: import java.io.IOException;
036:
037: /**
038: * A formatable holder for a java.util.Hashtable.
039: * Used to avoid serializing Properties.
040: */
041: public class FormatableHashtable extends Hashtable implements
042: Formatable {
043: /********************************************************
044: **
045: ** This class implements Formatable. That means that it
046: ** can write itself to and from a formatted stream. If
047: ** you add more fields to this class, make sure that you
048: ** also write/read them with the writeExternal()/readExternal()
049: ** methods.
050: **
051: ** If, inbetween releases, you add more fields to this class,
052: ** then you should bump the version number emitted by the getTypeFormatId()
053: ** method.
054: **
055: ********************************************************/
056:
057: /**
058: * Niladic constructor for formatable
059: */
060: public FormatableHashtable() {
061: }
062:
063: /**
064: * Our special put method that wont barf
065: * on a null value.
066: * @see java.util.Hashtable
067: */
068: public Object put(Object key, Object value) {
069: if (value == null) {
070: return remove(key);
071: }
072:
073: if (SanityManager.DEBUG) {
074:
075: if ((value instanceof FormatableIntHolder)
076: || (value instanceof FormatableLongHolder)
077: || ((value instanceof java.io.Serializable)
078: && (!(value instanceof Formatable)) && (!(value instanceof String)))) {
079:
080: if (!value.getClass().isArray()) {
081:
082: // System.out.println("key " + key + " class " + value.getClass());
083: //new Throwable().printStackTrace(System.out);
084: //System.exit(1);
085: }
086: }
087: }
088: return super .put(key, value);
089: }
090:
091: public void putInt(Object key, int value) {
092:
093: super .put(key, new FormatableIntHolder(value));
094: }
095:
096: public int getInt(Object key) {
097:
098: return ((FormatableIntHolder) get(key)).getInt();
099: }
100:
101: public void putLong(Object key, long value) {
102:
103: super .put(key, new FormatableLongHolder(value));
104: }
105:
106: public long getLong(Object key) {
107:
108: return ((FormatableLongHolder) get(key)).getLong();
109: }
110:
111: public void putBoolean(Object key, boolean value) {
112:
113: putInt(key, value ? 1 : 0);
114: }
115:
116: public boolean getBoolean(Object key) {
117:
118: return getInt(key) == 0 ? false : true;
119:
120: }
121:
122: //////////////////////////////////////////////
123: //
124: // FORMATABLE
125: //
126: //////////////////////////////////////////////
127: /**
128: * Write the hash table out. Step through
129: * the enumeration and write the strings out
130: * in UTF.
131: *
132: * @param out write bytes here
133: *
134: * @exception IOException thrown on error
135: */
136: public void writeExternal(ObjectOutput out) throws IOException {
137: out.writeInt(size());
138: for (Enumeration e = keys(); e.hasMoreElements();) {
139: Object key = e.nextElement();
140: out.writeObject(key);
141: out.writeObject(get(key));
142:
143: if (SanityManager.DEBUG) {
144: Object value = get(key);
145: if (value instanceof Formatable[]) {
146: SanityManager
147: .THROWASSERT("you should be using FormatableArrayHolder rather than writing out an array of Formatables, otherwise you will get bad behavior for null Storables. Your class is a "
148: + value.getClass().getName());
149: }
150: }
151: }
152: }
153:
154: /**
155: * Read the hash table from a stream of stored objects.
156: *
157: * @param in read this.
158: *
159: * @exception IOException thrown on error
160: * @exception ClassNotFoundException thrown on error
161: */
162: public void readExternal(ObjectInput in) throws IOException,
163: ClassNotFoundException {
164: int size = in.readInt();
165: for (; size > 0; size--) {
166: super .put(in.readObject(), in.readObject());
167: }
168: }
169:
170: public void readExternal(ArrayInputStream in) throws IOException,
171: ClassNotFoundException {
172: int size = in.readInt();
173: for (; size > 0; size--) {
174: super .put(in.readObject(), in.readObject());
175: }
176: }
177:
178: /**
179: * Get the formatID which corresponds to this class.
180: *
181: * @return the formatID of this class
182: */
183: public int getTypeFormatId() {
184: return StoredFormatIds.FORMATABLE_HASHTABLE_V01_ID;
185: }
186: }
|