/* ====================================================================
   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.poifs.poibrowser;

import java.util.HashMap;
import java.util.Map;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;

import org.apache.poi.hpsf.HPSFException;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;

/**
 * <p>Organizes document information in a tree model in order to be
 * e.g. displayed in a Swing {@link javax.swing.JTree}. An instance of this
 * class is created with a root tree node ({@link MutableTreeNode}) and
 * registered as a {@link POIFSReaderListener} with a {@link
 * org.apache.poi.poifs.eventfilesystem.POIFSReader}. While the latter processes
 * a POI filesystem it calls this class' {@link #processPOIFSReaderEvent} for
 * each document it has been registered for. This method appends the document it
 * processes at the appropriate position into the tree rooted at the
 * above mentioned root tree node.</p>
 *
 * <p>The root tree node should be the root tree node of a {@link
 * javax.swing.tree.TreeModel}.</p>
 *
 * <p>A top-level element in the tree model, i.e. an immediate child
 * node of the root node, describes a POI filesystem as such. It is
 * suggested to use the file's name (as seen by the operating system)
 * but it could be any other string.</p>
 *
 * <p>The value of a tree node is a {@link DocumentDescriptor}. Unlike
 * a {@link org.apache.poi.poifs.filesystem.POIFSDocument} which may be as heavy
 * as many megabytes, an instance of {@link DocumentDescriptor} is a
 * light-weight object and contains only some meta-information about a
 * document.</p>
 */
public class TreeReaderListener implements POIFSReaderListener
{

    /**
     * <p>The tree's root node. POI filesystems get attached to this
     * node as children.</p>
     */
    protected MutableTreeNode rootNode;

    /**
     * <p>Maps filenames and POI document paths to their associated
     * tree nodes.</p>
     */
    protected Map<Object,MutableTreeNode> pathToNode;

    /**
     * <p>The name of the file this {@link TreeReaderListener}
     * processes. It is used to identify a top-level element in the
     * tree. Alternatively any other string can be used. It is just a
     * label which should identify a POI filesystem.</p>
     */
    protected String filename;



    /**
     * <p>Creates a {@link TreeReaderListener} which should then be
     * registered with a
     * {@link org.apache.poi.poifs.eventfilesystem.POIFSReader}.</p>
     *
     * @param filename The name of the POI filesystem, i.e. the name
     * of the file the POI filesystem resides in. Alternatively any
     * other string can be used.
     *
     * @param rootNode All document information will be attached as
     * descendands to this tree node.
     */
    public TreeReaderListener(final String filename,
                              final MutableTreeNode rootNode)
    {
        this.filename = filename;
        this.rootNode = rootNode;
        pathToNode = new HashMap<Object,MutableTreeNode>(15); // Should be a reasonable guess.
    }



    /** <p>The number of bytes to dump.</p> */
    private int nrOfBytes = 50;

    public void setNrOfBytes(final int nrOfBytes)
    {
        this.nrOfBytes = nrOfBytes;
    }

    public int getNrOfBytes()
    {
        return nrOfBytes;
    }



    /**
     * <p>A document in the POI filesystem has been opened for
     * reading. This method retrieves properties of the document and
     * adds them to a tree model.</p>
     */
    @Override
    public void processPOIFSReaderEvent(final POIFSReaderEvent event)
    {
        DocumentDescriptor d;
        final DocumentInputStream is = event.getStream();
        if (!is.markSupported())
            throw new UnsupportedOperationException(is.getClass().getName() +
                " does not support mark().");

        /* Try do handle this document as a property set. We receive
         * an exception if is no property set and handle it as a
         * document of some other format. We are not concerned about
         * that document's details. */
        try
        {
            d = new PropertySetDescriptor(event.getName(), event.getPath(),
                                          is, nrOfBytes);
        }
        catch (HPSFException ex)
        {
            d = new DocumentDescriptor(event.getName(), event.getPath(),
                                       is, nrOfBytes);
        }
        catch (Exception t)
        {
            System.err.println
                ("Unexpected exception while processing " +
                event.getName() + " in " + event.getPath().toString());
            t.printStackTrace(System.err);
            throw new RuntimeException(t.getMessage());
        }

        is.close();

        final MutableTreeNode parentNode = getNode(d.path, filename, rootNode);
        final MutableTreeNode nameNode = new DefaultMutableTreeNode(d.name);
        parentNode.insert(nameNode, 0);
        final MutableTreeNode dNode = new DefaultMutableTreeNode(d);
        nameNode.insert(dNode, 0);
    }



    /**
     * <p>Locates the parent node for a document entry in the tree
     * model. If the parent node does not yet exist it will be
     * created, too. This is done recursively, if needed.</p>
     *
     * @param path The tree node for this path is located.
     *
     * @param fsName The name of the POI filesystem. This is just a
     * string which is displayed in the tree at the top lovel.
     *
     * @param root The root node.
     */
    private MutableTreeNode getNode(final POIFSDocumentPath path,
                                    final String fsName,
                                    final MutableTreeNode root)
    {
        MutableTreeNode n = pathToNode.get(path);
        if (n != null)
            /* Node found in map, just return it. */
            return n;
        if (path.length() == 0)
        {
            /* This is the root path of the POI filesystem. Its tree
             * node is resp. must be located below the tree node of
             * the POI filesystem itself. This is a tree node with the
             * POI filesystem's name (this the operating system file's
             * name) as its key it the path-to-node map. */
            n = pathToNode.get(fsName);
            if (n == null)
            {
                /* A tree node for the POI filesystem does not yet
                 * exist. */
                n = new DefaultMutableTreeNode(fsName);
                pathToNode.put(fsName, n);
                root.insert(n, 0);
            }
            return n;
        }
        /* else - The path is somewhere down in the POI filesystem's
         * hierarchy. We need the tree node of this path's parent
         * and attach our new node to it. */
        final String name = path.getComponent(path.length() - 1);
        final POIFSDocumentPath parentPath = path.getParent();
        final MutableTreeNode parentNode =
            getNode(parentPath, fsName, root);
        n = new DefaultMutableTreeNode(name);
        pathToNode.put(path, n);
        parentNode.insert(n, 0);
        return n;
    }
}
