001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi;
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.ByteArrayOutputStream;
022: import java.io.IOException;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import org.apache.poi.hpsf.DocumentSummaryInformation;
027: import org.apache.poi.hpsf.MutablePropertySet;
028: import org.apache.poi.hpsf.PropertySet;
029: import org.apache.poi.hpsf.PropertySetFactory;
030: import org.apache.poi.hpsf.SummaryInformation;
031: import org.apache.poi.poifs.filesystem.DirectoryEntry;
032: import org.apache.poi.poifs.filesystem.DocumentEntry;
033: import org.apache.poi.poifs.filesystem.DocumentInputStream;
034: import org.apache.poi.poifs.filesystem.Entry;
035: import org.apache.poi.poifs.filesystem.POIFSFileSystem;
036: import org.apache.poi.util.POILogFactory;
037: import org.apache.poi.util.POILogger;
038:
039: /**
040: * This holds the common functionality for all POI
041: * Document classes.
042: * Currently, this relates to Document Information Properties
043: *
044: * @author Nick Burch
045: */
046: public abstract class POIDocument {
047: /** Holds metadata on our document */
048: protected SummaryInformation sInf;
049: /** Holds further metadata on our document */
050: protected DocumentSummaryInformation dsInf;
051: /** The open POIFS FileSystem that contains our document */
052: protected POIFSFileSystem filesystem;
053:
054: /** For our own logging use */
055: protected POILogger logger = POILogFactory.getLogger(this
056: .getClass());
057:
058: /**
059: * Fetch the Document Summary Information of the document
060: */
061: public DocumentSummaryInformation getDocumentSummaryInformation() {
062: return dsInf;
063: }
064:
065: /**
066: * Fetch the Summary Information of the document
067: */
068: public SummaryInformation getSummaryInformation() {
069: return sInf;
070: }
071:
072: /**
073: * Find, and create objects for, the standard
074: * Documment Information Properties (HPSF)
075: */
076: protected void readProperties() {
077: // DocumentSummaryInformation
078: dsInf = (DocumentSummaryInformation) getPropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
079:
080: // SummaryInformation
081: sInf = (SummaryInformation) getPropertySet(SummaryInformation.DEFAULT_STREAM_NAME);
082: }
083:
084: /**
085: * For a given named property entry, either return it or null if
086: * if it wasn't found
087: */
088: protected PropertySet getPropertySet(String setName) {
089: DocumentInputStream dis;
090: try {
091: // Find the entry, and get an input stream for it
092: dis = filesystem.createDocumentInputStream(setName);
093: } catch (IOException ie) {
094: // Oh well, doesn't exist
095: logger.log(POILogger.WARN,
096: "Error getting property set with name " + setName
097: + "\n" + ie);
098: return null;
099: }
100:
101: try {
102: // Create the Property Set
103: PropertySet set = PropertySetFactory.create(dis);
104: return set;
105: } catch (IOException ie) {
106: // Must be corrupt or something like that
107: logger.log(POILogger.WARN,
108: "Error creating property set with name " + setName
109: + "\n" + ie);
110: } catch (org.apache.poi.hpsf.HPSFException he) {
111: // Oh well, doesn't exist
112: logger.log(POILogger.WARN,
113: "Error creating property set with name " + setName
114: + "\n" + he);
115: }
116: return null;
117: }
118:
119: /**
120: * Writes out the standard Documment Information Properties (HPSF)
121: * @param outFS the POIFSFileSystem to write the properties into
122: */
123: protected void writeProperties(POIFSFileSystem outFS)
124: throws IOException {
125: writeProperties(outFS, null);
126: }
127:
128: /**
129: * Writes out the standard Documment Information Properties (HPSF)
130: * @param outFS the POIFSFileSystem to write the properties into
131: * @param writtenEntries a list of POIFS entries to add the property names too
132: */
133: protected void writeProperties(POIFSFileSystem outFS,
134: List writtenEntries) throws IOException {
135: if (sInf != null) {
136: writePropertySet(SummaryInformation.DEFAULT_STREAM_NAME,
137: sInf, outFS);
138: if (writtenEntries != null) {
139: writtenEntries
140: .add(SummaryInformation.DEFAULT_STREAM_NAME);
141: }
142: }
143: if (dsInf != null) {
144: writePropertySet(
145: DocumentSummaryInformation.DEFAULT_STREAM_NAME,
146: dsInf, outFS);
147: if (writtenEntries != null) {
148: writtenEntries
149: .add(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
150: }
151: }
152: }
153:
154: /**
155: * Writes out a given ProperySet
156: * @param name the (POIFS Level) name of the property to write
157: * @param set the PropertySet to write out
158: * @param outFS the POIFSFileSystem to write the property into
159: */
160: protected void writePropertySet(String name, PropertySet set,
161: POIFSFileSystem outFS) throws IOException {
162: try {
163: MutablePropertySet mSet = new MutablePropertySet(set);
164: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
165:
166: mSet.write(bOut);
167: byte[] data = bOut.toByteArray();
168: ByteArrayInputStream bIn = new ByteArrayInputStream(data);
169: outFS.createDocument(bIn, name);
170:
171: logger.log(POILogger.INFO, "Wrote property set " + name
172: + " of size " + data.length);
173: } catch (org.apache.poi.hpsf.WritingNotSupportedException wnse) {
174: System.err.println("Couldn't write property set with name "
175: + name + " as not supported by HPSF yet");
176: }
177: }
178:
179: /**
180: * Copies nodes from one POIFS to the other minus the excepts
181: * @param source is the source POIFS to copy from
182: * @param target is the target POIFS to copy to
183: * @param excepts is a list of Strings specifying what nodes NOT to copy
184: */
185: protected void copyNodes(POIFSFileSystem source,
186: POIFSFileSystem target, List excepts) throws IOException {
187: //System.err.println("CopyNodes called");
188:
189: DirectoryEntry root = source.getRoot();
190: DirectoryEntry newRoot = target.getRoot();
191:
192: Iterator entries = root.getEntries();
193:
194: while (entries.hasNext()) {
195: Entry entry = (Entry) entries.next();
196: if (!isInList(entry.getName(), excepts)) {
197: copyNodeRecursively(entry, newRoot);
198: }
199: }
200: }
201:
202: /**
203: * Checks to see if the String is in the list, used when copying
204: * nodes between one POIFS and another
205: */
206: private boolean isInList(String entry, List list) {
207: for (int k = 0; k < list.size(); k++) {
208: if (list.get(k).equals(entry)) {
209: return true;
210: }
211: }
212: return false;
213: }
214:
215: /**
216: * Copies an Entry into a target POIFS directory, recursively
217: */
218: private void copyNodeRecursively(Entry entry, DirectoryEntry target)
219: throws IOException {
220: //System.err.println("copyNodeRecursively called with "+entry.getName()+
221: // ","+target.getName());
222: DirectoryEntry newTarget = null;
223: if (entry.isDirectoryEntry()) {
224: newTarget = target.createDirectory(entry.getName());
225: Iterator entries = ((DirectoryEntry) entry).getEntries();
226:
227: while (entries.hasNext()) {
228: copyNodeRecursively((Entry) entries.next(), newTarget);
229: }
230: } else {
231: DocumentEntry dentry = (DocumentEntry) entry;
232: DocumentInputStream dstream = new DocumentInputStream(
233: dentry);
234: target.createDocument(dentry.getName(), dstream);
235: dstream.close();
236: }
237: }
238: }
|