001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v2.codegen.bean;
024:
025: import java.util.*;
026: import java.io.IOException;
027: import com.mchange.v2.codegen.IndentedWriter;
028:
029: /**
030: * Note: this class pays no attention to whether users have marked any property variables as transient.
031: * In fact, it will work most efficiently if users mark ALL variables as transient... to define transient
032: * properties for this class, use the constructor which allows a user-specified set of transients.
033: */
034: public class SerializableExtension implements GeneratorExtension {
035: Set transientProperties;
036: Map transientPropertyInitializers;
037:
038: /**
039: * @param transientProperties a set of Strings, the names of all properties that should be considered transient and not serialized
040: * @param transientPropertyInitializers an optional Map of a subset of the transient property names to non-default initialization
041: * expressions, which should be unterminated expressions, and which will be used verbatim in
042: * the generated code.
043: */
044: public SerializableExtension(Set transientProperties,
045: Map transientPropertyInitializers) {
046: this .transientProperties = transientProperties;
047: this .transientPropertyInitializers = transientPropertyInitializers;
048: }
049:
050: public SerializableExtension() {
051: this (Collections.EMPTY_SET, null);
052: }
053:
054: public Collection extraGeneralImports() {
055: return Collections.EMPTY_SET;
056: }
057:
058: public Collection extraSpecificImports() {
059: Set set = new HashSet();
060: set.add("java.io.IOException");
061: set.add("java.io.Serializable");
062: set.add("java.io.ObjectOutputStream");
063: set.add("java.io.ObjectInputStream");
064: return set;
065: }
066:
067: public Collection extraInterfaceNames() {
068: Set set = new HashSet();
069: set.add("Serializable");
070: return set;
071: }
072:
073: public void generate(ClassInfo info, Class super classType,
074: Property[] props, Class[] propTypes, IndentedWriter iw)
075: throws IOException {
076: iw.println("private static final long serialVersionUID = 1;");
077: iw.println("private static final short VERSION = 0x0001;");
078: iw.println();
079: iw
080: .println("private void writeObject( ObjectOutputStream oos ) throws IOException");
081: iw.println("{");
082: iw.upIndent();
083:
084: iw.println("oos.writeShort( VERSION );");
085:
086: for (int i = 0, len = props.length; i < len; ++i) {
087: Property prop = props[i];
088: if (!transientProperties.contains(prop.getName())) {
089: Class propType = propTypes[i];
090: if (propType != null && propType.isPrimitive()) //primitives should always resolve, object types may not, and be null
091: {
092: if (propType == byte.class)
093: iw.println("oos.writeByte(" + prop.getName()
094: + ");");
095: else if (propType == char.class)
096: iw.println("oos.writeChar(" + prop.getName()
097: + ");");
098: else if (propType == short.class)
099: iw.println("oos.writeShort(" + prop.getName()
100: + ");");
101: else if (propType == int.class)
102: iw.println("oos.writeInt(" + prop.getName()
103: + ");");
104: else if (propType == boolean.class)
105: iw.println("oos.writeBoolean(" + prop.getName()
106: + ");");
107: else if (propType == long.class)
108: iw.println("oos.writeLong(" + prop.getName()
109: + ");");
110: else if (propType == float.class)
111: iw.println("oos.writeFloat(" + prop.getName()
112: + ");");
113: else if (propType == double.class)
114: iw.println("oos.writeDouble(" + prop.getName()
115: + ");");
116: } else
117: writeStoreObject(prop, propType, iw);
118: }
119: }
120: generateExtraSerWriteStatements(info, super classType, props,
121: propTypes, iw);
122: iw.downIndent();
123: iw.println("}");
124: iw.println();
125:
126: iw
127: .println("private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException");
128: iw.println("{");
129: iw.upIndent();
130: iw.println("short version = ois.readShort();");
131: iw.println("switch (version)");
132: iw.println("{");
133: iw.upIndent();
134:
135: iw.println("case VERSION:");
136: iw.upIndent();
137: for (int i = 0, len = props.length; i < len; ++i) {
138: Property prop = props[i];
139: if (!transientProperties.contains(prop.getName())) {
140: Class propType = propTypes[i];
141: if (propType != null && propType.isPrimitive()) //if a propType is unresolvable, it ain't a primitive
142: {
143: if (propType == byte.class)
144: iw.println("this." + prop.getName()
145: + " = ois.readByte();");
146: else if (propType == char.class)
147: iw.println("this." + prop.getName()
148: + " = ois.readChar();");
149: else if (propType == short.class)
150: iw.println("this." + prop.getName()
151: + " = ois.readShort();");
152: else if (propType == int.class)
153: iw.println("this." + prop.getName()
154: + " = ois.readInt();");
155: else if (propType == boolean.class)
156: iw.println("this." + prop.getName()
157: + " = ois.readBoolean();");
158: else if (propType == long.class)
159: iw.println("this." + prop.getName()
160: + " = ois.readLong();");
161: else if (propType == float.class)
162: iw.println("this." + prop.getName()
163: + " = ois.readFloat();");
164: else if (propType == double.class)
165: iw.println("this." + prop.getName()
166: + " = ois.readDouble();");
167: } else
168: writeUnstoreObject(prop, propType, iw);
169: } else {
170: String initializer = (String) transientPropertyInitializers
171: .get(prop.getName());
172: if (initializer != null)
173: iw.println("this." + prop.getName() + " = "
174: + initializer + ';');
175: }
176: }
177: generateExtraSerInitializers(info, super classType, props,
178: propTypes, iw);
179: iw.println("break;");
180: iw.downIndent();
181: iw.println("default:");
182: iw.upIndent();
183: iw
184: .println("throw new IOException(\"Unsupported Serialized Version: \" + version);");
185: iw.downIndent();
186:
187: iw.downIndent();
188: iw.println("}");
189:
190: iw.downIndent();
191: iw.println("}");
192: }
193:
194: protected void writeStoreObject(Property prop, Class propType,
195: IndentedWriter iw) throws IOException {
196: iw.println("oos.writeObject( " + prop.getName() + " );");
197: }
198:
199: protected void writeUnstoreObject(Property prop, Class propType,
200: IndentedWriter iw) throws IOException {
201: iw.println("this." + prop.getName() + " = ("
202: + prop.getSimpleTypeName() + ") ois.readObject();");
203: }
204:
205: protected void generateExtraSerWriteStatements(ClassInfo info,
206: Class super classType, Property[] props, Class[] propTypes,
207: IndentedWriter iw) throws IOException {
208: }
209:
210: protected void generateExtraSerInitializers(ClassInfo info,
211: Class super classType, Property[] props, Class[] propTypes,
212: IndentedWriter iw) throws IOException {
213: }
214:
215: }
|