KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hpsf > MutablePropertySet


1 /* ====================================================================
2    Copyright 2002-2004 Apache Software Foundation
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8        http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 ==================================================================== */

16         
17 package org.apache.poi.hpsf;
18
19 import java.io.ByteArrayInputStream JavaDoc;
20 import java.io.ByteArrayOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.io.UnsupportedEncodingException JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.ListIterator JavaDoc;
28
29 import org.apache.poi.util.LittleEndian;
30 import org.apache.poi.util.LittleEndianConsts;
31
32
33
34 /**
35  * <p>Adds writing support to the {@link PropertySet} class.</p>
36  *
37  * <p>Please be aware that this class' functionality will be merged into the
38  * {@link PropertySet} class at a later time, so the API will change.</p>
39  *
40  * @author Rainer Klute <a
41  * HREF="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
42  * @version $Id: MutablePropertySet.java,v 1.7 2004/08/31 20:47:09 klute Exp $
43  * @since 2003-02-19
44  */

45 public class MutablePropertySet extends PropertySet
46 {
47
48     /**
49      * <p>Constructs a <code>MutablePropertySet</code> instance. Its
50      * primary task is to initialize the immutable field with their proper
51      * values. It also sets fields that might change to reasonable defaults.</p>
52      */

53     public MutablePropertySet()
54     {
55         /* Initialize the "byteOrder" field. */
56         byteOrder = LittleEndian.getUShort(BYTE_ORDER_ASSERTION);
57
58         /* Initialize the "format" field. */
59         format = LittleEndian.getUShort(FORMAT_ASSERTION);
60
61         /* Initialize "osVersion" field as if the property has been created on
62          * a Win32 platform, whether this is the case or not. */

63         osVersion = (OS_WIN32 << 16) | 0x0A04;
64
65         /* Initailize the "classID" field. */
66         classID = new ClassID();
67
68         /* Initialize the sections. Since property set must have at least
69          * one section it is added right here. */

70         sections = new LinkedList JavaDoc();
71         sections.add(new MutableSection());
72     }
73
74
75
76     /**
77      * <p>Constructs a <code>MutablePropertySet</code> by doing a deep copy of
78      * an existing <code>PropertySet</code>. All nested elements, i.e.
79      * <code>Section</code>s and <code>Property</code> instances, will be their
80      * mutable counterparts in the new <code>MutablePropertySet</code>.</p>
81      *
82      * @param ps The property set to copy
83      */

84     public MutablePropertySet(final PropertySet ps)
85     {
86         byteOrder = ps.getByteOrder();
87         format = ps.getFormat();
88         osVersion = ps.getOSVersion();
89         setClassID(ps.getClassID());
90         clearSections();
91         for (final Iterator JavaDoc i = ps.getSections().iterator(); i.hasNext();)
92         {
93             final MutableSection s = new MutableSection((Section) (i.next()));
94             addSection(s);
95         }
96     }
97
98
99
100     /**
101      * <p>The length of the property set stream header.</p>
102      */

103     private final int OFFSET_HEADER =
104         BYTE_ORDER_ASSERTION.length + /* Byte order */
105         FORMAT_ASSERTION.length + /* Format */
106         LittleEndianConsts.INT_SIZE + /* OS version */
107         ClassID.LENGTH + /* Class ID */
108         LittleEndianConsts.INT_SIZE; /* Section count */
109
110
111
112     /**
113      * <p>Sets the "byteOrder" property.</p>
114      *
115      * @param byteOrder the byteOrder value to set
116      */

117     public void setByteOrder(final int byteOrder)
118     {
119         this.byteOrder = byteOrder;
120     }
121
122
123
124     /**
125      * <p>Sets the "format" property.</p>
126      *
127      * @param format the format value to set
128      */

129     public void setFormat(final int format)
130     {
131         this.format = format;
132     }
133
134
135
136     /**
137      * <p>Sets the "osVersion" property.</p>
138      *
139      * @param osVersion the osVersion value to set
140      */

141     public void setOSVersion(final int osVersion)
142     {
143         this.osVersion = osVersion;
144     }
145
146
147
148     /**
149      * <p>Sets the property set stream's low-level "class ID"
150      * field.</p>
151      *
152      * @param classID The property set stream's low-level "class ID" field.
153      *
154      * @see #getClassID
155      */

156     public void setClassID(final ClassID classID)
157     {
158         this.classID = classID;
159     }
160
161
162
163     /**
164      * <p>Removes all sections from this property set.</p>
165      */

166     public void clearSections()
167     {
168         sections = null;
169     }
170
171
172
173     /**
174      * <p>Adds a section to this property set.</p>
175      *
176      * @param section The {@link Section} to add. It will be appended
177      * after any sections that are already present in the property set
178      * and thus become the last section.
179      */

180     public void addSection(final Section section)
181     {
182         if (sections == null)
183             sections = new LinkedList JavaDoc();
184         sections.add(section);
185     }
186
187
188
189     /**
190      * <p>Writes the property set to an output stream.</p>
191      *
192      * @param out the output stream to write the section to
193      * @exception IOException if an error when writing to the output stream
194      * occurs
195      * @exception WritingNotSupportedException if HPSF does not yet support
196      * writing a property's variant type.
197      */

198     public void write(final OutputStream JavaDoc out)
199         throws WritingNotSupportedException, IOException JavaDoc
200     {
201         /* Write the number of sections in this property set stream. */
202         final int nrSections = sections.size();
203         int length = 0;
204
205         /* Write the property set's header. */
206         length += TypeWriter.writeToStream(out, (short) getByteOrder());
207         length += TypeWriter.writeToStream(out, (short) getFormat());
208         length += TypeWriter.writeToStream(out, (int) getOSVersion());
209         length += TypeWriter.writeToStream(out, getClassID());
210         length += TypeWriter.writeToStream(out, (int) nrSections);
211         int offset = OFFSET_HEADER;
212
213         /* Write the section list, i.e. the references to the sections. Each
214          * entry in the section list consist of the section's class ID and the
215          * section's offset relative to the beginning of the stream. */

216         offset += nrSections * (ClassID.LENGTH + LittleEndian.INT_SIZE);
217         final int sectionsBegin = offset;
218         for (final ListIterator JavaDoc i = sections.listIterator(); i.hasNext();)
219         {
220             final MutableSection s = (MutableSection) i.next();
221             final ClassID formatID = s.getFormatID();
222             if (formatID == null)
223                 throw new NoFormatIDException();
224             length += TypeWriter.writeToStream(out, s.getFormatID());
225             length += TypeWriter.writeUIntToStream(out, offset);
226             try
227             {
228                 offset += s.getSize();
229             }
230             catch (HPSFRuntimeException ex)
231             {
232                 final Throwable JavaDoc cause = ex.getReason();
233                 if (cause instanceof UnsupportedEncodingException JavaDoc)
234                     throw new IllegalPropertySetDataException(cause);
235                 else
236                     throw ex;
237             }
238         }
239
240         /* Write the sections themselves. */
241         offset = sectionsBegin;
242         for (final ListIterator JavaDoc i = sections.listIterator(); i.hasNext();)
243         {
244             final MutableSection s = (MutableSection) i.next();
245             offset += s.write(out);
246         }
247     }
248
249
250
251     /**
252      * <p>Returns the contents of this property set stream as an input stream.
253      * The latter can be used for example to write the property set into a POIFS
254      * document. The input stream represents a snapshot of the property set.
255      * If the latter is modified while the input stream is still being
256      * read, the modifications will not be reflected in the input stream but in
257      * the {@link MutablePropertySet} only.</p>
258      *
259      * @return the contents of this property set stream
260      *
261      * @throws WritingNotSupportedException if HPSF does not yet support writing
262      * of a property's variant type.
263      * @throws IOException if an I/O exception occurs.
264      */

265     public InputStream JavaDoc toInputStream()
266         throws IOException JavaDoc, WritingNotSupportedException
267     {
268         final ByteArrayOutputStream JavaDoc psStream = new ByteArrayOutputStream JavaDoc();
269         write(psStream);
270         psStream.close();
271         final byte[] streamData = psStream.toByteArray();
272         return new ByteArrayInputStream JavaDoc(streamData);
273     }
274
275 }
276
Popular Tags