1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.io;
19
20/**
21 * An EmulatedFieldsForDumping is an object that represents a set of emulated
22 * fields for an object being dumped. It is a concrete implementation for
23 * ObjectOutputStream.PutField
24 *
25 *
26 * @see ObjectOutputStream.PutField
27 * @see EmulatedFieldsForLoading
28 */
29class EmulatedFieldsForDumping extends ObjectOutputStream.PutField {
30    // Record the ObjectOutputStream that created this PutField for checking in 'write'.
31    private final ObjectOutputStream oos;
32
33    // The actual representation, with a more powerful API (set&get)
34    private EmulatedFields emulatedFields;
35
36    /**
37     * Constructs a new instance of EmulatedFieldsForDumping.
38     *
39     * @param streamClass
40     *            a ObjectStreamClass, which describe the fields to be emulated
41     *            (names, types, etc).
42     */
43    EmulatedFieldsForDumping(ObjectOutputStream oos, ObjectStreamClass streamClass) {
44        this.oos = oos;
45        this.emulatedFields = new EmulatedFields(streamClass.fields(), (ObjectStreamField[]) null);
46    }
47
48    /**
49     * Return the actual EmulatedFields instance used by the receiver. We have
50     * the actual work in a separate class so that the code can be shared. The
51     * receiver has to be of a subclass of PutField.
52     *
53     * @return array of ObjectSlot the receiver represents.
54     */
55    EmulatedFields emulatedFields() {
56        return emulatedFields;
57    }
58
59    /**
60     * Find and set the byte value of a given field named <code>name</code> in
61     * the receiver.
62     *
63     * @param name
64     *            A String, the name of the field to set
65     * @param value
66     *            New value for the field.
67     */
68    @Override
69    public void put(String name, byte value) {
70        emulatedFields.put(name, value);
71    }
72
73    /**
74     * Find and set the char value of a given field named <code>name</code> in
75     * the receiver.
76     *
77     * @param name
78     *            A String, the name of the field to set
79     * @param value
80     *            New value for the field.
81     */
82    @Override
83    public void put(String name, char value) {
84        emulatedFields.put(name, value);
85    }
86
87    /**
88     * Find and set the double value of a given field named <code>name</code>
89     * in the receiver.
90     *
91     * @param name
92     *            A String, the name of the field to set
93     * @param value
94     *            New value for the field.
95     */
96    @Override
97    public void put(String name, double value) {
98        emulatedFields.put(name, value);
99    }
100
101    /**
102     * Find and set the float value of a given field named <code>name</code>
103     * in the receiver.
104     *
105     * @param name
106     *            A String, the name of the field to set
107     * @param value
108     *            New value for the field.
109     */
110    @Override
111    public void put(String name, float value) {
112        emulatedFields.put(name, value);
113    }
114
115    /**
116     * Find and set the int value of a given field named <code>name</code> in
117     * the receiver.
118     *
119     * @param name
120     *            A String, the name of the field to set
121     * @param value
122     *            New value for the field.
123     */
124    @Override
125    public void put(String name, int value) {
126        emulatedFields.put(name, value);
127    }
128
129    /**
130     * Find and set the long value of a given field named <code>name</code> in
131     * the receiver.
132     *
133     * @param name
134     *            A String, the name of the field to set
135     * @param value
136     *            New value for the field.
137     */
138    @Override
139    public void put(String name, long value) {
140        emulatedFields.put(name, value);
141    }
142
143    /**
144     * Find and set the Object value of a given field named <code>name</code>
145     * in the receiver.
146     *
147     * @param name
148     *            A String, the name of the field to set
149     * @param value
150     *            New value for the field.
151     */
152    @Override
153    public void put(String name, Object value) {
154        emulatedFields.put(name, value);
155    }
156
157    /**
158     * Find and set the short value of a given field named <code>name</code>
159     * in the receiver.
160     *
161     * @param name
162     *            A String, the name of the field to set
163     * @param value
164     *            New value for the field.
165     */
166    @Override
167    public void put(String name, short value) {
168        emulatedFields.put(name, value);
169    }
170
171    /**
172     * Find and set the boolean value of a given field named <code>name</code>
173     * in the receiver.
174     *
175     * @param name
176     *            A String, the name of the field to set
177     * @param value
178     *            New value for the field.
179     */
180    @Override
181    public void put(String name, boolean value) {
182        emulatedFields.put(name, value);
183    }
184
185    /**
186     * Write the field values to the specified ObjectOutput.
187     *
188     * @param output
189     *            the ObjectOutput
190     *
191     * @throws IOException
192     *             If an IO exception happened when writing the field values.
193     */
194    @Override
195    @Deprecated
196    public void write(ObjectOutput output) throws IOException {
197        if (!output.equals(oos)) {
198            throw new IllegalArgumentException("Attempting to write to a different stream than the one that created this PutField");
199        }
200        for (EmulatedFields.ObjectSlot slot : emulatedFields.slots()) {
201            Object fieldValue = slot.getFieldValue();
202            Class<?> type = slot.getField().getType();
203            if (type == int.class) {
204                output.writeInt(fieldValue != null ? ((Integer) fieldValue).intValue() : 0);
205            } else if (type == byte.class) {
206                output.writeByte(fieldValue != null ? ((Byte) fieldValue).byteValue() : 0);
207            } else if (type == char.class) {
208                output.writeChar(fieldValue != null ? ((Character) fieldValue).charValue() : 0);
209            } else if (type == short.class) {
210                output.writeShort(fieldValue != null ? ((Short) fieldValue).shortValue() : 0);
211            } else if (type == boolean.class) {
212                output.writeBoolean(fieldValue != null ? ((Boolean) fieldValue).booleanValue() : false);
213            } else if (type == long.class) {
214                output.writeLong(fieldValue != null ? ((Long) fieldValue).longValue() : 0);
215            } else if (type == float.class) {
216                output.writeFloat(fieldValue != null ? ((Float) fieldValue).floatValue() : 0);
217            } else if (type == double.class) {
218                output.writeDouble(fieldValue != null ? ((Double) fieldValue).doubleValue() : 0);
219            } else {
220                // Either array or Object
221                output.writeObject(fieldValue);
222            }
223        }
224    }
225}
226