poi-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject cvs commit: jakarta-poi/src/testcases/org/apache/poi/hpsf/data Test0313rur.adm TestEditTime.doc TestMickey.doc
Date Sat, 20 Sep 2003 15:43:08 GMT
klute       2003/09/20 08:43:08

  Modified:    src/documentation/content/xdocs/hpsf how-to.xml
               src/examples/src/org/apache/poi/hpsf/examples
                        ReadCustomPropertySets.java ReadTitle.java
                        WriteAuthorAndTitle.java WriteTitle.java
               src/java/org/apache/poi/hpsf Section.java Util.java
  Added:       src/examples/src/org/apache/poi/hpsf/examples
                        CopyCompare.java
               src/testcases/org/apache/poi/hpsf/data Test0313rur.adm
                        TestEditTime.doc TestMickey.doc
  Log:
  - Comparing sections refined: For the dictionary (property 0) only the value (Map) is relevant.
The dictionary's codepage (property 1) is disregarded.
  - New sample application CopyCompare. I'll turn that into a testcase later.
  
  Revision  Changes    Path
  1.9       +15 -15    jakarta-poi/src/documentation/content/xdocs/hpsf/how-to.xml
  
  Index: how-to.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/documentation/content/xdocs/hpsf/how-to.xml,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- how-to.xml	19 Sep 2003 14:20:02 -0000	1.8
  +++ how-to.xml	20 Sep 2003 15:43:07 -0000	1.9
  @@ -700,16 +700,16 @@
         <tr>
          <td>0</td>
          <td>The property's value is a <strong>dictionary</strong>, i.e.
a
  -	mapping from property IDs to strings.</td>
  +        mapping from property IDs to strings.</td>
         </tr>
   
         <tr>
          <td>1</td>
          <td>The property's value is the number of a <strong>codepage</strong>,
  -	i.e. a mapping from character codes to characters. All strings in the
  -	section containing this property must be interpreted using this
  -	codepage. Typical property values are 1252 (8-bit "western" characters)
  -	or 1200 (16-bit Unicode characters).</td>
  +        i.e. a mapping from character codes to characters. All strings in the
  +        section containing this property must be interpreted using this
  +        codepage. Typical property values are 1252 (8-bit "western" characters)
  +        or 1200 (16-bit Unicode characters).</td>
         </tr>
        </table>
       </section>
  @@ -1036,15 +1036,15 @@
        <p>The <code>MutableSection</code> the sample application retrieved
from
         the <code>MutablePropertySet</code> is still empty. It contains no
         properties and does not have a format ID. As you have read <link
  -       href="#sec3">above</link> the format ID of the first section in a property
set
  -       determines the property set's type. Since our property set should become
  -       a SummaryInformation property set we have to set the format ID of its
  -       first (and only) section to
  -       <code>F29F85E0-4FF9-1068-AB-91-08-00-2B-27-B3-D9</code>. However, you
  -       won't have to remember that ID: HPSF has it defined as the well-known
  -       constant <code>SectionIDMap.SUMMARY_INFORMATION_ID</code>. The sample
  -       application writes it to the section using the
  -       <code>setFormatID(byte[])</code> method:</p>
  +       href="#sec3">above</link> the format ID of the first section in a
  +      property set determines the property set's type. Since our property set
  +      should become a SummaryInformation property set we have to set the format
  +      ID of its first (and only) section to
  +      <code>F29F85E0-4FF9-1068-AB-91-08-00-2B-27-B3-D9</code>. However, you
  +      won't have to remember that ID: HPSF has it defined as the well-known
  +      constant <code>SectionIDMap.SUMMARY_INFORMATION_ID</code>. The sample
  +      application writes it to the section using the
  +      <code>setFormatID(byte[])</code> method:</p>
   
        <source>ms.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID);</source>
   
  
  
  
  1.3       +5 -5      jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java
  
  Index: ReadCustomPropertySets.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReadCustomPropertySets.java	1 Sep 2003 18:49:52 -0000	1.2
  +++ ReadCustomPropertySets.java	20 Sep 2003 15:43:08 -0000	1.3
  @@ -70,13 +70,13 @@
   import org.apache.poi.util.HexDump;
   
   /**
  - * <p>Sample application showing how to read a custom property set of
  - * a document. Call it with the document's file name as command line
  - * parameter.</p>
  + * <p>Sample application showing how to read a document's custom property set.
  + * Call it with the document's file name as command-line parameter.</p>
    *
    * <p>Explanations can be found in the HPSF HOW-TO.</p>
    *
  - * @author Rainer Klute (klute@rainer-klute.de)
  + * @author Rainer Klute <a
  + * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
    * @version $Id$
    * @since 2003-02-01
    */
  
  
  
  1.4       +3 -2      jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/ReadTitle.java
  
  Index: ReadTitle.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/ReadTitle.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ReadTitle.java	1 Sep 2003 18:49:52 -0000	1.3
  +++ ReadTitle.java	20 Sep 2003 15:43:08 -0000	1.4
  @@ -70,7 +70,8 @@
    *
    * <p>Explanations can be found in the HPSF HOW-TO.</p>
    *
  - * @author Rainer Klute (klute@rainer-klute.de)
  + * @author Rainer Klute <a
  + * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
    * @version $Id$
    * @since 2003-02-01
    */
  
  
  
  1.3       +3 -2      jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java
  
  Index: WriteAuthorAndTitle.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- WriteAuthorAndTitle.java	18 Sep 2003 18:56:35 -0000	1.2
  +++ WriteAuthorAndTitle.java	20 Sep 2003 15:43:08 -0000	1.3
  @@ -118,7 +118,8 @@
    * 
    * <p>Further explanations can be found in the HPSF HOW-TO.</p>
    *
  - * @author Rainer Klute (klute@rainer-klute.de)
  + * @author Rainer Klute <a
  + * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
    * @version $Id$
    * @since 2003-09-01
    */
  
  
  
  1.4       +3 -2      jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/WriteTitle.java
  
  Index: WriteTitle.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/WriteTitle.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- WriteTitle.java	18 Sep 2003 18:56:35 -0000	1.3
  +++ WriteTitle.java	20 Sep 2003 15:43:08 -0000	1.4
  @@ -72,7 +72,8 @@
    * <p>This class is a simple sample application showing how to create a property
    * set and write it to disk.</p>
    *
  - * @author Rainer Klute (klute@rainer-klute.de)
  + * @author Rainer Klute <a
  + * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
    * @version $Id$
    * @since 2003-09-12
    */
  
  
  
  1.1                  jakarta-poi/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java
  
  Index: CopyCompare.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2000 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" must
   *  not be used to endorse or promote products derived from this
   *  software without prior written permission. For written
   *  permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  nor may "Apache" appear in their name, without prior written
   *  permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package org.apache.poi.hpsf.examples;
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.poi.hpsf.HPSFRuntimeException;
  import org.apache.poi.hpsf.MarkUnsupportedException;
  import org.apache.poi.hpsf.MutablePropertySet;
  import org.apache.poi.hpsf.NoPropertySetStreamException;
  import org.apache.poi.hpsf.PropertySet;
  import org.apache.poi.hpsf.PropertySetFactory;
  import org.apache.poi.hpsf.Util;
  import org.apache.poi.hpsf.WritingNotSupportedException;
  import org.apache.poi.poifs.eventfilesystem.POIFSReader;
  import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
  import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
  import org.apache.poi.poifs.filesystem.DirectoryEntry;
  import org.apache.poi.poifs.filesystem.DocumentEntry;
  import org.apache.poi.poifs.filesystem.DocumentInputStream;
  import org.apache.poi.poifs.filesystem.Entry;
  import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
  import org.apache.poi.poifs.filesystem.POIFSFileSystem;
  
  /**
   * <p>This class copies a POI file system to a new file and compares the copy
   * with the original.</p>
   * 
   * <p>Property set streams are copied logically, i.e. the application
   * establishes a {@link org.apache.poi.hpsf.PropertySet} of an original property
   * set, creates a {@link org.apache.poi.hpsf.MutablePropertySet} from the
   * {@link org.apache.poi.hpsf.PropertySet} and writes the
   * {@link org.apache.poi.hpsf.MutablePropertySet} to the destination POI file
   * system. - Streams which are no property set streams are copied bit by
   * bit.</p>
   * 
   * <p>The comparison of the POI file systems is done logically. That means that
   * the two disk files containing the POI file systems do not need to be
   * exactly identical. However, both POI file systems must contain the same
   * files, and most of these files must be bitwise identical. Property set
   * streams, however, are compared logically: they must have the same sections
   * with the same attributs, and the sections must contain the same properties.
   * Details like the ordering of the properties do not matter.</p>
   *
   * @author Rainer Klute <a
   * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
   * @version $Id: CopyCompare.java,v 1.1 2003/09/20 15:43:08 klute Exp $
   * @since 2003-09-19
   */
  public class CopyCompare
  {
      /**
       * <p>Runs the example program. The application expects one or two
       * arguments:</p>
       * 
       * <ol>
       * 
       * <li><p>The first argument is the disk file name of the POI filesystem
to
       * copy.</p></li>
       * 
       * <li><p>The second argument is optional. If it is given, it is the name
of
       * a disk file the copy of the POI filesystem will be written to. If it is
       * not given, the copy will be written to a temporary file which will be
       * deleted at the end of the program.</p></li>
       * 
       * </ol>
       *
       * @param args Command-line arguments.
       * @exception MarkUnsupportedException if a POI document stream does not
       * support the mark() operation.
       * @exception NoPropertySetStreamException if the application tries to
       * create a property set from a POI document stream that is not a property
       * set stream.
       * @exception IOException if any I/O exception occurs.
       */
      public static void main(final String[] args)
      throws MarkUnsupportedException, NoPropertySetStreamException, IOException
      {
          String originalFileName = null;
          String copyFileName = null;
  
          /* Check the command-line arguments. */
          if (args.length == 1)
          {
              originalFileName = args[0];
              File f = File.createTempFile("CopyOfPOIFileSystem-", ".ole2");
              f.deleteOnExit();
              copyFileName = f.getAbsolutePath();
          }
          else if (args.length == 2)
          {
              originalFileName = args[0];
              copyFileName = args[1];
          }
          else
          {
              System.err.println("Usage: " + CopyCompare.class.getName() +
                                 "originPOIFS [copyPOIFS]");
              System.exit(1);
          }
  
          /* Read the origin POIFS using the eventing API. The real work is done
           * in the class CopyFile which is registered here as a POIFSReader. */
          final POIFSReader r = new POIFSReader();
          final CopyFile cf = new CopyFile(copyFileName);
          r.registerListener(cf);
          r.read(new FileInputStream(originalFileName));
          
          /* Write the new POIFS to disk. */
          cf.close();
  
          /* Read all documents from the original POI file system and compare them
           * with the equivalent document from the copy. */
          final POIFSFileSystem opfs =
              new POIFSFileSystem(new FileInputStream(originalFileName));
          final POIFSFileSystem cpfs =
              new POIFSFileSystem(new FileInputStream(copyFileName));
  
          final DirectoryEntry oRoot = opfs.getRoot();
          final DirectoryEntry cRoot = cpfs.getRoot();
          final StringBuffer messages = new StringBuffer();
          if (equal(oRoot, cRoot, messages))
              System.out.println("Equal");
          else
              System.out.println("Not equal: " + messages.toString());
      }
  
  
  
      /**
       * <p>Compares two {@link DirectoryEntry} instances of a POI file system.
       * The directories must contain the same streams with the same names and
       * contents.</p>
       *
       * @param d1 The first directory.
       * @param d2 The second directory.
       * @param msg The method may append human-readable comparison messages to
       * this string buffer. 
       * @return <code>true</code> if the directories are equal, else
       * <code>false</code>.
       * @exception MarkUnsupportedException if a POI document stream does not
       * support the mark() operation.
       * @exception NoPropertySetStreamException if the application tries to
       * create a property set from a POI document stream that is not a property
       * set stream.
       * @exception IOException if any I/O exception occurs.
       */
      private static boolean equal(final DirectoryEntry d1,
                                   final DirectoryEntry d2,
                                   final StringBuffer msg)
      throws MarkUnsupportedException, NoPropertySetStreamException, IOException
      {
          boolean equal = true;
          /* Iterate over d1 and compare each entry with its counterpart in d2. */
          for (final Iterator i = d1.getEntries(); equal && i.hasNext();)
          {
              final Entry e1 = (Entry) i.next();
              final String n1 = e1.getName();
              Entry e2 = null;
              try
              {
                  e2 = d2.getEntry(n1);
              }
              catch (FileNotFoundException ex)
              {
                  msg.append("Document \"" + e1 + "\" exitsts, document \"" +
                             e2 + "\" does not.\n");
                  equal = false;
                  break;
              }
  
              if (e1.isDirectoryEntry() && e2.isDirectoryEntry())
                  equal = equal((DirectoryEntry) e1, (DirectoryEntry) e2, msg);
              else if (e1.isDocumentEntry() && e2.isDocumentEntry())
                  equal = equal((DocumentEntry) e1, (DocumentEntry) e2, msg);
              else
              {
                  msg.append("One of \"" + e1 + "\" and \"" + e2 + "\" is a " +
                             "document while the other one is a directory.\n");
                  equal = false;
              }
          }
  
          /* Iterate over d2 just to make sure that there are no entries in d2
           * that are not in d1. */
          for (final Iterator i = d2.getEntries(); equal && i.hasNext();)
          {
              final Entry e2 = (Entry) i.next();
              final String n2 = e2.getName();
              Entry e1 = null;
              try
              {
                  e1 = d1.getEntry(n2);
              }
              catch (FileNotFoundException ex)
              {
                  msg.append("Document \"" + e2 + "\" exitsts, document \"" +
                             e1 + "\" does not.\n");
                  equal = false;
                  break;
              }
          }
          return equal;
      }
  
  
  
      /**
       * <p>Compares two {@link DocumentEntry} instances of a POI file system.
       * Documents that are not property set streams must be bitwise identical.
       * Property set streams must be logically equal.</p>
       *
       * @param d1 The first document.
       * @param d2 The second document.
       * @param msg The method may append human-readable comparison messages to
       * this string buffer. 
       * @return <code>true</code> if the documents are equal, else
       * <code>false</code>.
       * @exception MarkUnsupportedException if a POI document stream does not
       * support the mark() operation.
       * @exception NoPropertySetStreamException if the application tries to
       * create a property set from a POI document stream that is not a property
       * set stream.
       * @exception IOException if any I/O exception occurs.
       */
      private static boolean equal(final DocumentEntry d1, final DocumentEntry d2,
                                   final StringBuffer msg)
      throws MarkUnsupportedException, NoPropertySetStreamException, IOException
      {
          boolean equal = true;
          final DocumentInputStream dis1 = new DocumentInputStream(d1);
          final DocumentInputStream dis2 = new DocumentInputStream(d2);
          if (PropertySet.isPropertySetStream(dis1) &&
              PropertySet.isPropertySetStream(dis2))
          {
              final PropertySet ps1 = PropertySetFactory.create(dis1);
              final PropertySet ps2 = PropertySetFactory.create(dis2);
              equal = ps1.equals(ps2);
              if (!equal)
              {
                  msg.append("Property sets are not equal.\n");
                  return equal;
              }
          }
          else
          {
              int i1;
              int i2;
              do
              {
                  i1 = dis1.read();
                  i2 = dis2.read();
                  if (i1 != i2)
                  {
                      equal = false;
                      msg.append("Documents are not equal.\n");
                      break;
                  }
              }
              while (equal && i1 == -1);
          }
          return true;
      }
  
  
  
      /**
       * <p>This class does all the work. Its method {@link
       * #processPOIFSReaderEvent(POIFSReaderEvent)} is called for each file in
       * the original POI file system. Except for property set streams it copies
       * everything unmodified to the destination POI filesystem. Property set
       * streams are copied by creating a new {@link PropertySet} from the
       * original property set by using the {@link
       * MutablePropertySet#MutablePropertySet(PropertySet) constructor.</p>
       */
      static class CopyFile implements POIFSReaderListener
      {
          String dstName;
          OutputStream out;
          POIFSFileSystem poiFs;
  
  
          /**
           * <p>The constructor of a {@link CopyFile} instance creates the target
           * POIFS. It also stores the name of the file the POIFS will be written
           * to once it is complete.</p>
           * 
           * @param dstName The name of the disk file the destination POIFS is to
           * be written to.
           * @throws FileNotFoundException
           */
          public CopyFile(final String dstName)
          {
              this.dstName = dstName;
              poiFs = new POIFSFileSystem();
          }
  
  
          /**
           * <p>The method is called by POI's eventing API for each file in the
           * origin POIFS.</p>
           */
          public void processPOIFSReaderEvent(final POIFSReaderEvent event)
          {
              /* The following declarations are shortcuts for accessing the
               * "event" object. */
              final POIFSDocumentPath path = event.getPath();
              final String name = event.getName();
              final DocumentInputStream stream = event.getStream();
  
              Throwable t = null;
  
              try
              {
                  /* Find out whether the current document is a property set
                   * stream or not. */
                  if (PropertySet.isPropertySetStream(stream))
                  {
                      /* Yes, the current document is a property set stream.
                       * Let's create a PropertySet instance from it. */
                      PropertySet ps = null;
                      try
                      {
                          ps = PropertySetFactory.create(stream);
                      }
                      catch (NoPropertySetStreamException ex)
                      {
                          /* This exception will not be thrown because we already
                           * checked above. */
                      }
  
                      /* Copy the property set to the destination POI file
                       * system. */
                      copy(poiFs, path, name, ps);
                  }
                  else
                      /* No, the current document is not a property set stream. We
                       * copy it unmodified to the destination POIFS. */
                      copy(poiFs, event.getPath(), event.getName(), stream);
              }
              catch (MarkUnsupportedException ex)
              {
                  t = ex;
              }
              catch (IOException ex)
              {
                  t = ex;
              }
              catch (WritingNotSupportedException ex)
              {
                  t = ex;
              }
  
              /* According to the definition of the processPOIFSReaderEvent method
               * we cannot pass checked exceptions to the caller. The following
               * lines check whether a checked exception occured and throws an
               * unchecked exception. The message of that exception is that of
               * the underlying checked exception. */
              if (t != null)
              {
                  throw new HPSFRuntimeException
                      ("Could not read file \"" + path + "/" + name +
                       "\". Reason: " + Util.toString(t));
              }
          }
  
  
  
          /**
           * <p>Writes a {@link PropertySet} to a POI filesystem.</p>
           *
           * @param poiFs The POI filesystem to write to.
           * @param path The file's path in the POI filesystem.
           * @param name The file's name in the POI filesystem.
           * @param ps The property set to write.
           */
          public void copy(final POIFSFileSystem poiFs,
                           final POIFSDocumentPath path,
                           final String name,
                           final PropertySet ps)
              throws WritingNotSupportedException, IOException
          {
              final DirectoryEntry de = getPath(poiFs, path);
              final MutablePropertySet mps = new MutablePropertySet(ps);
              de.createDocument(name, mps.toInputStream());
          }
  
  
  
          /**
           * <p>Copies the bytes from a {@link DocumentInputStream} to a new
           * stream in a POI filesystem.</p>
           *
           * @param poiFs The POI filesystem to write to.
           * @param path The source document's path.
           * @param stream The stream containing the source document.
           */
          public void copy(final POIFSFileSystem poiFs,
                           final POIFSDocumentPath path,
                           final String name,
                           final DocumentInputStream stream) throws IOException
          {
              final DirectoryEntry de = getPath(poiFs, path);
              final ByteArrayOutputStream out = new ByteArrayOutputStream();
              int c;
              while ((c = stream.read()) != -1)
                  out.write(c);
              stream.close();
              out.close();
              final InputStream in =
                  new ByteArrayInputStream(out.toByteArray());
              de.createDocument(name, in);
          }
  
  
          /**
           * <p>Writes the POI file system to a disk file.</p>
           *
           * @throws FileNotFoundException
           * @throws IOException
           */
          public void close() throws FileNotFoundException, IOException
          {
              out = new FileOutputStream(dstName);
              poiFs.writeFilesystem(out);
              out.close();
          }
  
  
  
          /** Contains the directory paths that have already been created in the
           * output POI filesystem and maps them to their corresponding
           * {@link org.apache.poi.poifs.filesystem.DirectoryNode}s. */
          private final Map paths = new HashMap();
  
  
  
          /**
           * <p>Ensures that the directory hierarchy for a document in a POI
           * fileystem is in place. When a document is to be created somewhere in
           * a POI filesystem its directory must be created first. This method
           * creates all directories between the POI filesystem root and the
           * directory the document should belong to which do not yet exist.</p>
           * 
           * <p>Unfortunately POI does not offer a simple method to interrogate
           * the POIFS whether a certain child node (file or directory) exists in
           * a directory. However, since we always start with an empty POIFS which
           * contains the root directory only and since each directory in the
           * POIFS is created by this method we can maintain the POIFS's directory
           * hierarchy ourselves: The {@link DirectoryEntry} of each directory
           * created is stored in a {@link Map}. The directories' path names map
           * to the corresponding {@link DirectoryEntry} instances.</p>
           *
           * @param poiFs The POI filesystem the directory hierarchy is created
           * in, if needed.
           * @param path The document's path. This method creates those directory
           * components of this hierarchy which do not yet exist.
           * @return The directory entry of the document path's parent. The caller
           * should use this {@link DirectoryEntry} to create documents in it.
           */
          public DirectoryEntry getPath(final POIFSFileSystem poiFs,
                                        final POIFSDocumentPath path)
          {
              try
              {
                  /* Check whether this directory has already been created. */
                  final String s = path.toString();
                  DirectoryEntry de = (DirectoryEntry) paths.get(s);
                  if (de != null)
                      /* Yes: return the corresponding DirectoryEntry. */
                      return de;
  
                  /* No: We have to create the directory - or return the root's
                   * DirectoryEntry. */
                  int l = path.length();
                  if (l == 0)
                      /* Get the root directory. It does not have to be created
                       * since it always exists in a POIFS. */
                      de = poiFs.getRoot();
                  else
                  {
                      /* Create a subordinate directory. The first step is to
                       * ensure that the parent directory exists: */
                      de = getPath(poiFs, path.getParent());
                      /* Now create the target directory: */
                      de = de.createDirectory(path.getComponent
                                              (path.length() - 1));
                  }
                  paths.put(s, de);
                  return de;
              }
              catch (IOException ex)
              {
                  /* This exception will be thrown if the directory already
                   * exists. However, since we have full control about directory
                   * creation we can ensure that this will never happen. */
                  ex.printStackTrace(System.err);
                  throw new RuntimeException(ex);
              }
          }
      }
  
  }
  
  
  
  1.19      +72 -2     jakarta-poi/src/java/org/apache/poi/hpsf/Section.java
  
  Index: Section.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/Section.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- Section.java	18 Sep 2003 18:56:35 -0000	1.18
  +++ Section.java	20 Sep 2003 15:43:08 -0000	1.19
  @@ -504,7 +504,77 @@
               return false;
           if (s.getPropertyCount() != getPropertyCount())
               return false;
  -        return Util.equals(s.getProperties(), getProperties());
  +
  +        /* Compare all properties except 0 and 1 as they must be handled 
  +         * specially. */
  +        Property[] pa1 = new Property[getProperties().length];
  +        Property[] pa2 = new Property[s.getProperties().length];
  +        System.arraycopy(getProperties(), 0, pa1, 0, pa1.length);
  +        System.arraycopy(s.getProperties(), 0, pa2, 0, pa2.length);
  +
  +        /* Extract properties 0 and 1 and remove them from the copy of the
  +         * arrays. */
  +        Property p10 = null;
  +        Property p11;
  +        Property p20 = null;
  +        Property p21;
  +        for (int i = 0; i < pa1.length; i++)
  +        {
  +            final long id = pa1[i].getID();
  +            if (id == 0)
  +            {
  +                p10 = pa1[i];
  +                pa1 = remove(pa1, i);
  +                i--;
  +            }
  +            if (id == 1)
  +            {
  +                p11 = pa1[i];
  +                pa1 = remove(pa1, i);
  +                i--;
  +            }
  +        }
  +        for (int i = 0; i < pa2.length; i++)
  +        {
  +            final long id = pa2[i].getID();
  +            if (id == 0)
  +            {
  +                p20 = pa2[i];
  +                pa2 = remove(pa2, i);
  +                i--;
  +            }
  +            if (id == 1)
  +            {
  +                p21 = pa2[i];
  +                pa2 = remove(pa2, i);
  +                i--;
  +            }
  +        }
  +
  +        boolean dictionaryEqual = true;
  +        if (p10 != null && p20 != null)
  +            dictionaryEqual = p10.getValue().equals(p20.getValue());
  +        else if (p10 != null || p20 != null)
  +            dictionaryEqual = false;
  +        if (!dictionaryEqual)
  +            return false;
  +        else
  +            return Util.equals(pa1, pa2);
  +    }
  +
  +
  +
  +    /**
  +     * <p>Removes a field from a property array. The resulting array is
  +     * compactified and returned.</p>
  +     */
  +    private Property[] remove(final Property[] pa, final int i)
  +    {
  +        final Property[] h = new Property[pa.length - 1];
  +        if (i > 0)
  +            System.arraycopy(pa, 0, h, 0, i);
  +        System.arraycopy(pa, i + 1, h, i, h.length - i);
  +        return h;
       }
   
   
  
  
  
  1.13      +6 -2      jakarta-poi/src/java/org/apache/poi/hpsf/Util.java
  
  Index: Util.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/Util.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Util.java	4 Sep 2003 20:15:24 -0000	1.12
  +++ Util.java	20 Sep 2003 15:43:08 -0000	1.13
  @@ -263,13 +263,17 @@
       {
           for (int i1 = 0; i1 < o1.length; i1++)
           {
  +            final Object obj1 = o1[i1];
               boolean matchFound = false;
               for (int i2 = 0; !matchFound && i2 < o1.length; i2++)
  -                if (o1[i1].equals(o2[i2]))
  +            {
  +                final Object obj2 = o2[i2];
  +                if (obj1.equals(obj2))
                   {
                       matchFound = true;
                       o2[i2] = null;
                   }
  +            }
               if (!matchFound)
                   return false;
           }
  
  
  
  1.1                  jakarta-poi/src/testcases/org/apache/poi/hpsf/data/Test0313rur.adm
  
  	<<Binary file>>
  
  
  1.1                  jakarta-poi/src/testcases/org/apache/poi/hpsf/data/TestEditTime.doc
  
  	<<Binary file>>
  
  
  1.1                  jakarta-poi/src/testcases/org/apache/poi/hpsf/data/TestMickey.doc
  
  	<<Binary file>>
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: poi-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: poi-dev-help@jakarta.apache.org


Mime
View raw message