Source Code Cross Referenced for CopyCompare.java in  » Collaboration » poi-3.0.2-beta2 » org » apache » poi » hpsf » examples » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Collaboration » poi 3.0.2 beta2 » org.apache.poi.hpsf.examples 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.hpsf.examples;
019:
020:        import java.io.ByteArrayInputStream;
021:        import java.io.ByteArrayOutputStream;
022:        import java.io.File;
023:        import java.io.FileInputStream;
024:        import java.io.FileNotFoundException;
025:        import java.io.FileOutputStream;
026:        import java.io.IOException;
027:        import java.io.InputStream;
028:        import java.io.OutputStream;
029:        import java.io.UnsupportedEncodingException;
030:        import java.util.HashMap;
031:        import java.util.Iterator;
032:        import java.util.Map;
033:
034:        import org.apache.poi.hpsf.HPSFRuntimeException;
035:        import org.apache.poi.hpsf.MarkUnsupportedException;
036:        import org.apache.poi.hpsf.MutablePropertySet;
037:        import org.apache.poi.hpsf.NoPropertySetStreamException;
038:        import org.apache.poi.hpsf.PropertySet;
039:        import org.apache.poi.hpsf.PropertySetFactory;
040:        import org.apache.poi.hpsf.Util;
041:        import org.apache.poi.hpsf.WritingNotSupportedException;
042:        import org.apache.poi.poifs.eventfilesystem.POIFSReader;
043:        import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
044:        import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
045:        import org.apache.poi.poifs.filesystem.DirectoryEntry;
046:        import org.apache.poi.poifs.filesystem.DocumentEntry;
047:        import org.apache.poi.poifs.filesystem.DocumentInputStream;
048:        import org.apache.poi.poifs.filesystem.Entry;
049:        import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
050:        import org.apache.poi.poifs.filesystem.POIFSFileSystem;
051:        import org.apache.poi.util.TempFile;
052:
053:        /**
054:         * <p>This class copies a POI file system to a new file and compares the copy
055:         * with the original.</p>
056:         * 
057:         * <p>Property set streams are copied logically, i.e. the application
058:         * establishes a {@link org.apache.poi.hpsf.PropertySet} of an original property
059:         * set, creates a {@link org.apache.poi.hpsf.MutablePropertySet} from the
060:         * {@link org.apache.poi.hpsf.PropertySet} and writes the
061:         * {@link org.apache.poi.hpsf.MutablePropertySet} to the destination POI file
062:         * system. - Streams which are no property set streams are copied bit by
063:         * bit.</p>
064:         * 
065:         * <p>The comparison of the POI file systems is done logically. That means that
066:         * the two disk files containing the POI file systems do not need to be
067:         * exactly identical. However, both POI file systems must contain the same
068:         * files, and most of these files must be bitwise identical. Property set
069:         * streams, however, are compared logically: they must have the same sections
070:         * with the same attributs, and the sections must contain the same properties.
071:         * Details like the ordering of the properties do not matter.</p>
072:         *
073:         * @author Rainer Klute <a
074:         * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
075:         * @version $Id: CopyCompare.java 489730 2006-12-22 19:18:16Z bayard $
076:         * @since 2003-09-19
077:         */
078:        public class CopyCompare {
079:            /**
080:             * <p>Runs the example program. The application expects one or two
081:             * arguments:</p>
082:             * 
083:             * <ol>
084:             * 
085:             * <li><p>The first argument is the disk file name of the POI filesystem to
086:             * copy.</p></li>
087:             * 
088:             * <li><p>The second argument is optional. If it is given, it is the name of
089:             * a disk file the copy of the POI filesystem will be written to. If it is
090:             * not given, the copy will be written to a temporary file which will be
091:             * deleted at the end of the program.</p></li>
092:             * 
093:             * </ol>
094:             *
095:             * @param args Command-line arguments.
096:             * @exception MarkUnsupportedException if a POI document stream does not
097:             * support the mark() operation.
098:             * @exception NoPropertySetStreamException if the application tries to
099:             * create a property set from a POI document stream that is not a property
100:             * set stream.
101:             * @exception IOException if any I/O exception occurs.
102:             * @exception UnsupportedEncodingException if a character encoding is not
103:             * supported.
104:             */
105:            public static void main(final String[] args)
106:                    throws NoPropertySetStreamException,
107:                    MarkUnsupportedException, UnsupportedEncodingException,
108:                    IOException {
109:                String originalFileName = null;
110:                String copyFileName = null;
111:
112:                /* Check the command-line arguments. */
113:                if (args.length == 1) {
114:                    originalFileName = args[0];
115:                    File f = TempFile.createTempFile("CopyOfPOIFileSystem-",
116:                            ".ole2");
117:                    f.deleteOnExit();
118:                    copyFileName = f.getAbsolutePath();
119:                } else if (args.length == 2) {
120:                    originalFileName = args[0];
121:                    copyFileName = args[1];
122:                } else {
123:                    System.err.println("Usage: " + CopyCompare.class.getName()
124:                            + "originPOIFS [copyPOIFS]");
125:                    System.exit(1);
126:                }
127:
128:                /* Read the origin POIFS using the eventing API. The real work is done
129:                 * in the class CopyFile which is registered here as a POIFSReader. */
130:                final POIFSReader r = new POIFSReader();
131:                final CopyFile cf = new CopyFile(copyFileName);
132:                r.registerListener(cf);
133:                r.read(new FileInputStream(originalFileName));
134:
135:                /* Write the new POIFS to disk. */
136:                cf.close();
137:
138:                /* Read all documents from the original POI file system and compare them
139:                 * with the equivalent document from the copy. */
140:                final POIFSFileSystem opfs = new POIFSFileSystem(
141:                        new FileInputStream(originalFileName));
142:                final POIFSFileSystem cpfs = new POIFSFileSystem(
143:                        new FileInputStream(copyFileName));
144:
145:                final DirectoryEntry oRoot = opfs.getRoot();
146:                final DirectoryEntry cRoot = cpfs.getRoot();
147:                final StringBuffer messages = new StringBuffer();
148:                if (equal(oRoot, cRoot, messages))
149:                    System.out.println("Equal");
150:                else
151:                    System.out.println("Not equal: " + messages.toString());
152:            }
153:
154:            /**
155:             * <p>Compares two {@link DirectoryEntry} instances of a POI file system.
156:             * The directories must contain the same streams with the same names and
157:             * contents.</p>
158:             *
159:             * @param d1 The first directory.
160:             * @param d2 The second directory.
161:             * @param msg The method may append human-readable comparison messages to
162:             * this string buffer. 
163:             * @return <code>true</code> if the directories are equal, else
164:             * <code>false</code>.
165:             * @exception MarkUnsupportedException if a POI document stream does not
166:             * support the mark() operation.
167:             * @exception NoPropertySetStreamException if the application tries to
168:             * create a property set from a POI document stream that is not a property
169:             * set stream.
170:             * @throws UnsupportedEncodingException 
171:             * @exception IOException if any I/O exception occurs.
172:             */
173:            private static boolean equal(final DirectoryEntry d1,
174:                    final DirectoryEntry d2, final StringBuffer msg)
175:                    throws NoPropertySetStreamException,
176:                    MarkUnsupportedException, UnsupportedEncodingException,
177:                    IOException {
178:                boolean equal = true;
179:                /* Iterate over d1 and compare each entry with its counterpart in d2. */
180:                for (final Iterator i = d1.getEntries(); equal && i.hasNext();) {
181:                    final Entry e1 = (Entry) i.next();
182:                    final String n1 = e1.getName();
183:                    Entry e2 = null;
184:                    try {
185:                        e2 = d2.getEntry(n1);
186:                    } catch (FileNotFoundException ex) {
187:                        msg.append("Document \"" + e1
188:                                + "\" exists, document \"" + e2
189:                                + "\" does not.\n");
190:                        equal = false;
191:                        break;
192:                    }
193:
194:                    if (e1.isDirectoryEntry() && e2.isDirectoryEntry())
195:                        equal = equal((DirectoryEntry) e1, (DirectoryEntry) e2,
196:                                msg);
197:                    else if (e1.isDocumentEntry() && e2.isDocumentEntry())
198:                        equal = equal((DocumentEntry) e1, (DocumentEntry) e2,
199:                                msg);
200:                    else {
201:                        msg
202:                                .append("One of \""
203:                                        + e1
204:                                        + "\" and \""
205:                                        + e2
206:                                        + "\" is a "
207:                                        + "document while the other one is a directory.\n");
208:                        equal = false;
209:                    }
210:                }
211:
212:                /* Iterate over d2 just to make sure that there are no entries in d2
213:                 * that are not in d1. */
214:                for (final Iterator i = d2.getEntries(); equal && i.hasNext();) {
215:                    final Entry e2 = (Entry) i.next();
216:                    final String n2 = e2.getName();
217:                    Entry e1 = null;
218:                    try {
219:                        e1 = d1.getEntry(n2);
220:                    } catch (FileNotFoundException ex) {
221:                        msg.append("Document \"" + e2
222:                                + "\" exitsts, document \"" + e1
223:                                + "\" does not.\n");
224:                        equal = false;
225:                        break;
226:                    }
227:                }
228:                return equal;
229:            }
230:
231:            /**
232:             * <p>Compares two {@link DocumentEntry} instances of a POI file system.
233:             * Documents that are not property set streams must be bitwise identical.
234:             * Property set streams must be logically equal.</p>
235:             *
236:             * @param d1 The first document.
237:             * @param d2 The second document.
238:             * @param msg The method may append human-readable comparison messages to
239:             * this string buffer. 
240:             * @return <code>true</code> if the documents are equal, else
241:             * <code>false</code>.
242:             * @exception MarkUnsupportedException if a POI document stream does not
243:             * support the mark() operation.
244:             * @exception NoPropertySetStreamException if the application tries to
245:             * create a property set from a POI document stream that is not a property
246:             * set stream.
247:             * @throws UnsupportedEncodingException 
248:             * @exception IOException if any I/O exception occurs.
249:             */
250:            private static boolean equal(final DocumentEntry d1,
251:                    final DocumentEntry d2, final StringBuffer msg)
252:                    throws NoPropertySetStreamException,
253:                    MarkUnsupportedException, UnsupportedEncodingException,
254:                    IOException {
255:                boolean equal = true;
256:                final DocumentInputStream dis1 = new DocumentInputStream(d1);
257:                final DocumentInputStream dis2 = new DocumentInputStream(d2);
258:                if (PropertySet.isPropertySetStream(dis1)
259:                        && PropertySet.isPropertySetStream(dis2)) {
260:                    final PropertySet ps1 = PropertySetFactory.create(dis1);
261:                    final PropertySet ps2 = PropertySetFactory.create(dis2);
262:                    equal = ps1.equals(ps2);
263:                    if (!equal) {
264:                        msg.append("Property sets are not equal.\n");
265:                        return equal;
266:                    }
267:                } else {
268:                    int i1;
269:                    int i2;
270:                    do {
271:                        i1 = dis1.read();
272:                        i2 = dis2.read();
273:                        if (i1 != i2) {
274:                            equal = false;
275:                            msg.append("Documents are not equal.\n");
276:                            break;
277:                        }
278:                    } while (equal && i1 == -1);
279:                }
280:                return true;
281:            }
282:
283:            /**
284:             * <p>This class does all the work. Its method {@link
285:             * #processPOIFSReaderEvent(POIFSReaderEvent)} is called for each file in
286:             * the original POI file system. Except for property set streams it copies
287:             * everything unmodified to the destination POI filesystem. Property set
288:             * streams are copied by creating a new {@link PropertySet} from the
289:             * original property set by using the {@link
290:             * MutablePropertySet#MutablePropertySet(PropertySet)} constructor.</p>
291:             */
292:            static class CopyFile implements  POIFSReaderListener {
293:                String dstName;
294:                OutputStream out;
295:                POIFSFileSystem poiFs;
296:
297:                /**
298:                 * <p>The constructor of a {@link CopyFile} instance creates the target
299:                 * POIFS. It also stores the name of the file the POIFS will be written
300:                 * to once it is complete.</p>
301:                 * 
302:                 * @param dstName The name of the disk file the destination POIFS is to
303:                 * be written to.
304:                 */
305:                public CopyFile(final String dstName) {
306:                    this .dstName = dstName;
307:                    poiFs = new POIFSFileSystem();
308:                }
309:
310:                /**
311:                 * <p>The method is called by POI's eventing API for each file in the
312:                 * origin POIFS.</p>
313:                 */
314:                public void processPOIFSReaderEvent(final POIFSReaderEvent event) {
315:                    /* The following declarations are shortcuts for accessing the
316:                     * "event" object. */
317:                    final POIFSDocumentPath path = event.getPath();
318:                    final String name = event.getName();
319:                    final DocumentInputStream stream = event.getStream();
320:
321:                    Throwable t = null;
322:
323:                    try {
324:                        /* Find out whether the current document is a property set
325:                         * stream or not. */
326:                        if (PropertySet.isPropertySetStream(stream)) {
327:                            /* Yes, the current document is a property set stream.
328:                             * Let's create a PropertySet instance from it. */
329:                            PropertySet ps = null;
330:                            try {
331:                                ps = PropertySetFactory.create(stream);
332:                            } catch (NoPropertySetStreamException ex) {
333:                                /* This exception will not be thrown because we already
334:                                 * checked above. */
335:                            }
336:
337:                            /* Copy the property set to the destination POI file
338:                             * system. */
339:                            copy(poiFs, path, name, ps);
340:                        } else
341:                            /* No, the current document is not a property set stream. We
342:                             * copy it unmodified to the destination POIFS. */
343:                            copy(poiFs, event.getPath(), event.getName(),
344:                                    stream);
345:                    } catch (MarkUnsupportedException ex) {
346:                        t = ex;
347:                    } catch (IOException ex) {
348:                        t = ex;
349:                    } catch (WritingNotSupportedException ex) {
350:                        t = ex;
351:                    }
352:
353:                    /* According to the definition of the processPOIFSReaderEvent method
354:                     * we cannot pass checked exceptions to the caller. The following
355:                     * lines check whether a checked exception occured and throws an
356:                     * unchecked exception. The message of that exception is that of
357:                     * the underlying checked exception. */
358:                    if (t != null) {
359:                        throw new HPSFRuntimeException("Could not read file \""
360:                                + path + "/" + name + "\". Reason: "
361:                                + Util.toString(t));
362:                    }
363:                }
364:
365:                /**
366:                 * <p>Writes a {@link PropertySet} to a POI filesystem.</p>
367:                 *
368:                 * @param poiFs The POI filesystem to write to.
369:                 * @param path The file's path in the POI filesystem.
370:                 * @param name The file's name in the POI filesystem.
371:                 * @param ps The property set to write.
372:                 * @throws WritingNotSupportedException 
373:                 * @throws IOException 
374:                 */
375:                public void copy(final POIFSFileSystem poiFs,
376:                        final POIFSDocumentPath path, final String name,
377:                        final PropertySet ps)
378:                        throws WritingNotSupportedException, IOException {
379:                    final DirectoryEntry de = getPath(poiFs, path);
380:                    final MutablePropertySet mps = new MutablePropertySet(ps);
381:                    de.createDocument(name, mps.toInputStream());
382:                }
383:
384:                /**
385:                 * <p>Copies the bytes from a {@link DocumentInputStream} to a new
386:                 * stream in a POI filesystem.</p>
387:                 *
388:                 * @param poiFs The POI filesystem to write to.
389:                 * @param path The source document's path.
390:                 * @param name The source document's name.
391:                 * @param stream The stream containing the source document.
392:                 * @throws IOException 
393:                 */
394:                public void copy(final POIFSFileSystem poiFs,
395:                        final POIFSDocumentPath path, final String name,
396:                        final DocumentInputStream stream) throws IOException {
397:                    final DirectoryEntry de = getPath(poiFs, path);
398:                    final ByteArrayOutputStream out = new ByteArrayOutputStream();
399:                    int c;
400:                    while ((c = stream.read()) != -1)
401:                        out.write(c);
402:                    stream.close();
403:                    out.close();
404:                    final InputStream in = new ByteArrayInputStream(out
405:                            .toByteArray());
406:                    de.createDocument(name, in);
407:                }
408:
409:                /**
410:                 * <p>Writes the POI file system to a disk file.</p>
411:                 *
412:                 * @throws FileNotFoundException
413:                 * @throws IOException
414:                 */
415:                public void close() throws FileNotFoundException, IOException {
416:                    out = new FileOutputStream(dstName);
417:                    poiFs.writeFilesystem(out);
418:                    out.close();
419:                }
420:
421:                /** Contains the directory paths that have already been created in the
422:                 * output POI filesystem and maps them to their corresponding
423:                 * {@link org.apache.poi.poifs.filesystem.DirectoryNode}s. */
424:                private final Map paths = new HashMap();
425:
426:                /**
427:                 * <p>Ensures that the directory hierarchy for a document in a POI
428:                 * fileystem is in place. When a document is to be created somewhere in
429:                 * a POI filesystem its directory must be created first. This method
430:                 * creates all directories between the POI filesystem root and the
431:                 * directory the document should belong to which do not yet exist.</p>
432:                 * 
433:                 * <p>Unfortunately POI does not offer a simple method to interrogate
434:                 * the POIFS whether a certain child node (file or directory) exists in
435:                 * a directory. However, since we always start with an empty POIFS which
436:                 * contains the root directory only and since each directory in the
437:                 * POIFS is created by this method we can maintain the POIFS's directory
438:                 * hierarchy ourselves: The {@link DirectoryEntry} of each directory
439:                 * created is stored in a {@link Map}. The directories' path names map
440:                 * to the corresponding {@link DirectoryEntry} instances.</p>
441:                 *
442:                 * @param poiFs The POI filesystem the directory hierarchy is created
443:                 * in, if needed.
444:                 * @param path The document's path. This method creates those directory
445:                 * components of this hierarchy which do not yet exist.
446:                 * @return The directory entry of the document path's parent. The caller
447:                 * should use this {@link DirectoryEntry} to create documents in it.
448:                 */
449:                public DirectoryEntry getPath(final POIFSFileSystem poiFs,
450:                        final POIFSDocumentPath path) {
451:                    try {
452:                        /* Check whether this directory has already been created. */
453:                        final String s = path.toString();
454:                        DirectoryEntry de = (DirectoryEntry) paths.get(s);
455:                        if (de != null)
456:                            /* Yes: return the corresponding DirectoryEntry. */
457:                            return de;
458:
459:                        /* No: We have to create the directory - or return the root's
460:                         * DirectoryEntry. */
461:                        int l = path.length();
462:                        if (l == 0)
463:                            /* Get the root directory. It does not have to be created
464:                             * since it always exists in a POIFS. */
465:                            de = poiFs.getRoot();
466:                        else {
467:                            /* Create a subordinate directory. The first step is to
468:                             * ensure that the parent directory exists: */
469:                            de = getPath(poiFs, path.getParent());
470:                            /* Now create the target directory: */
471:                            de = de.createDirectory(path.getComponent(path
472:                                    .length() - 1));
473:                        }
474:                        paths.put(s, de);
475:                        return de;
476:                    } catch (IOException ex) {
477:                        /* This exception will be thrown if the directory already
478:                         * exists. However, since we have full control about directory
479:                         * creation we can ensure that this will never happen. */
480:                        ex.printStackTrace(System.err);
481:                        throw new RuntimeException(ex.toString());
482:                        /* FIXME (2): Replace the previous line by the following once we
483:                         * no longer need JDK 1.3 compatibility. */
484:                        // throw new RuntimeException(ex);
485:                    }
486:                }
487:            }
488:
489:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.