/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.hpsf.examples;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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.Map;

import org.apache.poi.hpsf.HPSFRuntimeException;
import org.apache.poi.hpsf.MarkUnsupportedException;
import org.apache.poi.hpsf.MutablePropertySet;
import org.apache.poi.hpsf.MutableSection;
import org.apache.poi.hpsf.NoPropertySetStreamException;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hpsf.Util;
import org.apache.poi.hpsf.Variant;
import org.apache.poi.hpsf.WritingNotSupportedException;
import org.apache.poi.hpsf.wellknown.PropertyIDMap;
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.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 * <p>This class is a sample application which shows how to write or modify the
 * author and title property of an OLE 2 document. This could be done in two
 * different ways:</p>
 * 
 * <ul>
 * 
 * <li><p>The first approach is to open the OLE 2 file as a POI filesystem
 * (see class {@link POIFSFileSystem}), read the summary information property
 * set (see classes {@link SummaryInformation} and {@link PropertySet}), write
 * the author and title properties into it and write the property set back into
 * the POI filesystem.</p></li>
 * 
 * <li><p>The second approach does not modify the original POI filesystem, but
 * instead creates a new one. All documents from the original POIFS are copied
 * to the destination POIFS, except for the summary information stream. The
 * latter is modified by setting the author and title property before writing
 * it to the destination POIFS. It there are several summary information streams
 * in the original POIFS - e.g. in subordinate directories - they are modified
 * just the same.</p></li>
 * 
 * </ul>
 * 
 * <p>This sample application takes the second approach. It expects the name of
 * the existing POI filesystem's name as its first command-line parameter and
 * the name of the output POIFS as the second command-line argument. The
 * program then works as described above: It copies nearly all documents
 * unmodified from the input POI filesystem to the output POI filesystem. If it
 * encounters a summary information stream it reads its properties. Then it sets
 * the "author" and "title" properties to new values and writes the modified
 * summary information stream into the output file.</p>
 * 
 * <p>Further explanations can be found in the HPSF HOW-TO.</p>
 */
public class WriteAuthorAndTitle
{
    /**
     * <p>Runs the example program.</p>
     *
     * @param args Command-line arguments. The first command-line argument must
     * be the name of a POI filesystem to read.
     * @throws IOException if any I/O exception occurs.
     */
    public static void main(final String[] args) throws IOException
    {
        /* Check whether we have exactly two command-line arguments. */
        if (args.length != 2)
        {
            System.err.println("Usage: " + WriteAuthorAndTitle.class.getName() +
                               " originPOIFS destinationPOIFS");
            System.exit(1);
        }
        
        /* Read the names of the origin and destination POI filesystems. */
        final String srcName = args[0];
        final String dstName = args[1];

        /* Read the origin POIFS using the eventing API. The real work is done
         * in the class ModifySICopyTheRest which is registered here as a
         * POIFSReader. */
        final POIFSReader r = new POIFSReader();
        final ModifySICopyTheRest msrl = new ModifySICopyTheRest(dstName);
        r.registerListener(msrl);
        FileInputStream fis = new FileInputStream(srcName);
        r.read(fis);
        fis.close();
        
        /* Write the new POIFS to disk. */
        msrl.close();
    }



    /**
     * <p>This class does all the work. As its name implies it modifies a
     * summary information property set and copies everything else unmodified
     * to the destination POI filesystem. Since an instance of it is registered
     * as a {@link POIFSReader} its method {@link 
     * #processPOIFSReaderEvent(POIFSReaderEvent)} is called for each document
     * in the origin POIFS.</p>
     */
    static class ModifySICopyTheRest implements POIFSReaderListener
    {
        private String dstName;
        private OutputStream out;
        private POIFSFileSystem poiFs;


        /**
         * <p>The constructor of a {@link ModifySICopyTheRest} 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.
         */
        public ModifySICopyTheRest(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>
         */
        @Override
        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)) {
                    try {
                        /* Yes, the current document is a property set stream.
                         * Let's create a PropertySet instance from it. */
                        PropertySet ps = PropertySetFactory.create(stream);

                        /* Now we know that we really have a property set. The next
                         * step is to find out whether it is a summary information
                         * or not. */
                        if (ps.isSummaryInformation()) {
                            /* Yes, it is a summary information. We will modify it
                             * and write the result to the destination POIFS. */
                            editSI(poiFs, path, name, ps);
                        } else {
                            /* No, it is not a summary information. We don't care
                             * about its internals and copy it unmodified to the
                             * destination POIFS. */
                            copy(poiFs, path, name, ps);
                        }
                    } catch (NoPropertySetStreamException ex) {
                        /* This exception will not be thrown because we already
                         * checked above. */
                    }
                } 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>Receives a summary information property set modifies (or creates)
         * its "author" and "title" properties and writes the result under the
         * same path and name as the origin to a destination POI filesystem.</p>
         *
         * @param poiFs The POI filesystem to write to.
         * @param path The original (and destination) stream's path.
         * @param name The original (and destination) stream's name.
         * @param si The property set. It should be a summary information
         * property set.
         * @throws IOException 
         * @throws WritingNotSupportedException 
         */
        public void editSI(final POIFSFileSystem poiFs,
                           final POIFSDocumentPath path,
                           final String name,
                           final PropertySet si)
        throws WritingNotSupportedException, IOException
            
        {
            /* Get the directory entry for the target stream. */
            final DirectoryEntry de = getPath(poiFs, path);

            /* Create a mutable property set as a copy of the original read-only
             * property set. */
            final MutablePropertySet mps = new MutablePropertySet(si);
            
            /* Retrieve the section containing the properties to modify. A
             * summary information property set contains exactly one section. */
            final MutableSection s =
                (MutableSection) mps.getSections().get(0);

            /* Set the properties. */
            s.setProperty(PropertyIDMap.PID_AUTHOR, Variant.VT_LPSTR,
                          "Rainer Klute");
            s.setProperty(PropertyIDMap.PID_TITLE, Variant.VT_LPWSTR,
                          "Test");

            /* Create an input stream containing the bytes the property set
             * stream consists of. */
            final InputStream pss = mps.toInputStream();

            /* Write the property set stream to the POIFS. */
            de.createDocument(name, pss);
        }


        /**
         * <p>Writes a {@link PropertySet} to a POI filesystem. This method is
         * simpler than {@link #editSI} because the origin property set has just
         * to be copied.</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.
         * @throws WritingNotSupportedException 
         * @throws IOException 
         */
        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 name The source document's name.
         * @param stream The stream containing the source document.
         * @throws IOException 
         */
        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<String, DirectoryEntry> paths = new HashMap<String, DirectoryEntry>();



        /**
         * <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 = 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);
            }
        }
    }

}
