You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TreeReaderListener.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.contrib.poibrowser;
  16. import java.io.IOException;
  17. import java.util.HashMap;
  18. import java.util.Map;
  19. import javax.swing.tree.DefaultMutableTreeNode;
  20. import javax.swing.tree.MutableTreeNode;
  21. import org.apache.poi.hpsf.HPSFException;
  22. import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
  23. import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
  24. import org.apache.poi.poifs.filesystem.DocumentInputStream;
  25. import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
  26. /**
  27. * <p>Organizes document information in a tree model in order to be
  28. * e.g. displayed in a Swing {@link javax.swing.JTree}. An instance of this
  29. * class is created with a root tree node ({@link MutableTreeNode}) and
  30. * registered as a {@link POIFSReaderListener} with a {@link
  31. * org.apache.poi.poifs.eventfilesystem.POIFSReader}. While the latter processes
  32. * a POI filesystem it calls this class' {@link #processPOIFSReaderEvent} for
  33. * each document it has been registered for. This method appends the document it
  34. * processes at the appropriate position into the tree rooted at the
  35. * above mentioned root tree node.</p>
  36. *
  37. * <p>The root tree node should be the root tree node of a {@link
  38. * javax.swing.tree.TreeModel}.</p>
  39. *
  40. * <p>A top-level element in the tree model, i.e. an immediate child
  41. * node of the root node, describes a POI filesystem as such. It is
  42. * suggested to use the file's name (as seen by the operating system)
  43. * but it could be any other string.</p>
  44. *
  45. * <p>The value of a tree node is a {@link DocumentDescriptor}. Unlike
  46. * a {@link org.apache.poi.poifs.filesystem.POIFSDocument} which may be as heavy
  47. * as many megabytes, an instance of {@link DocumentDescriptor} is a
  48. * light-weight object and contains only some meta-information about a
  49. * document.</p>
  50. *
  51. * @author Rainer Klute <a
  52. * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
  53. * @version $Id$
  54. * @since 2002-01-24
  55. */
  56. public class TreeReaderListener implements POIFSReaderListener
  57. {
  58. /**
  59. * <p>The tree's root node. POI filesystems get attached to this
  60. * node as children.</p>
  61. */
  62. protected MutableTreeNode rootNode;
  63. /**
  64. * <p>Maps filenames and POI document paths to their associated
  65. * tree nodes.</p>
  66. */
  67. protected Map pathToNode;
  68. /**
  69. * <p>The name of the file this {@link TreeReaderListener}
  70. * processes. It is used to identify a top-level element in the
  71. * tree. Alternatively any other string can be used. It is just a
  72. * label which should identify a POI filesystem.</p>
  73. */
  74. protected String filename;
  75. /**
  76. * <p>Creates a {@link TreeReaderListener} which should then be
  77. * registered with a
  78. * {@link org.apache.poi.poifs.eventfilesystem.POIFSReader}.</p>
  79. *
  80. * @param filename The name of the POI filesystem, i.e. the name
  81. * of the file the POI filesystem resides in. Alternatively any
  82. * other string can be used.
  83. *
  84. * @param rootNode All document information will be attached as
  85. * descendands to this tree node.
  86. */
  87. public TreeReaderListener(final String filename,
  88. final MutableTreeNode rootNode)
  89. {
  90. this.filename = filename;
  91. this.rootNode = rootNode;
  92. pathToNode = new HashMap(15); // Should be a reasonable guess.
  93. }
  94. /** <p>The number of bytes to dump.</p> */
  95. private int nrOfBytes = 50;
  96. public void setNrOfBytes(final int nrOfBytes)
  97. {
  98. this.nrOfBytes = nrOfBytes;
  99. }
  100. public int getNrOfBytes()
  101. {
  102. return nrOfBytes;
  103. }
  104. /**
  105. * <p>A document in the POI filesystem has been opened for
  106. * reading. This method retrieves properties of the document and
  107. * adds them to a tree model.</p>
  108. */
  109. public void processPOIFSReaderEvent(final POIFSReaderEvent event)
  110. {
  111. DocumentDescriptor d;
  112. final DocumentInputStream is = event.getStream();
  113. if (!is.markSupported())
  114. throw new UnsupportedOperationException(is.getClass().getName() +
  115. " does not support mark().");
  116. /* Try do handle this document as a property set. We receive
  117. * an exception if is no property set and handle it as a
  118. * document of some other format. We are not concerned about
  119. * that document's details. */
  120. try
  121. {
  122. d = new PropertySetDescriptor(event.getName(), event.getPath(),
  123. is, nrOfBytes);
  124. }
  125. catch (HPSFException ex)
  126. {
  127. d = new DocumentDescriptor(event.getName(), event.getPath(),
  128. is, nrOfBytes);
  129. }
  130. catch (Throwable t)
  131. {
  132. System.err.println
  133. ("Unexpected exception while processing " +
  134. event.getName() + " in " + event.getPath().toString());
  135. t.printStackTrace(System.err);
  136. throw new RuntimeException(t.getMessage());
  137. }
  138. try
  139. {
  140. is.close();
  141. }
  142. catch (Exception ex)
  143. {
  144. System.err.println
  145. ("Unexpected exception while closing " +
  146. event.getName() + " in " + event.getPath().toString());
  147. ex.printStackTrace(System.err);
  148. }
  149. final MutableTreeNode parentNode = getNode(d.path, filename, rootNode);
  150. final MutableTreeNode nameNode = new DefaultMutableTreeNode(d.name);
  151. parentNode.insert(nameNode, 0);
  152. final MutableTreeNode dNode = new DefaultMutableTreeNode(d);
  153. nameNode.insert(dNode, 0);
  154. }
  155. /**
  156. * <p>Locates the parent node for a document entry in the tree
  157. * model. If the parent node does not yet exist it will be
  158. * created, too. This is done recursively, if needed.</p>
  159. *
  160. * @param path The tree node for this path is located.
  161. *
  162. * @param fsName The name of the POI filesystem. This is just a
  163. * string which is displayed in the tree at the top lovel.
  164. *
  165. * @param root The root node.
  166. */
  167. private MutableTreeNode getNode(final POIFSDocumentPath path,
  168. final String fsName,
  169. final MutableTreeNode root)
  170. {
  171. MutableTreeNode n = (MutableTreeNode) pathToNode.get(path);
  172. if (n != null)
  173. /* Node found in map, just return it. */
  174. return n;
  175. if (path.length() == 0)
  176. {
  177. /* This is the root path of the POI filesystem. Its tree
  178. * node is resp. must be located below the tree node of
  179. * the POI filesystem itself. This is a tree node with the
  180. * POI filesystem's name (this the operating system file's
  181. * name) as its key it the path-to-node map. */
  182. n = (MutableTreeNode) pathToNode.get(fsName);
  183. if (n == null)
  184. {
  185. /* A tree node for the POI filesystem does not yet
  186. * exist. */
  187. n = new DefaultMutableTreeNode(fsName);
  188. pathToNode.put(fsName, n);
  189. root.insert(n, 0);
  190. }
  191. return n;
  192. }
  193. else
  194. {
  195. /* The path is somewhere down in the POI filesystem's
  196. * hierarchy. We need the tree node of this path's parent
  197. * and attach our new node to it. */
  198. final String name = path.getComponent(path.length() - 1);
  199. final POIFSDocumentPath parentPath = path.getParent();
  200. final MutableTreeNode parentNode =
  201. getNode(parentPath, fsName, root);
  202. n = new DefaultMutableTreeNode(name);
  203. pathToNode.put(path, n);
  204. parentNode.insert(n, 0);
  205. return n;
  206. }
  207. }
  208. }