1    
2    /* ====================================================================
3     * The Apache Software License, Version 1.1
4     *
5     * Copyright (c) 2002 The Apache Software Foundation.  All rights
6     * reserved.
7     *
8     * Redistribution and use in source and binary forms, with or without
9     * modification, are permitted provided that the following conditions
10    * are met:
11    *
12    * 1. Redistributions of source code must retain the above copyright
13    *    notice, this list of conditions and the following disclaimer.
14    *
15    * 2. Redistributions in binary form must reproduce the above copyright
16    *    notice, this list of conditions and the following disclaimer in
17    *    the documentation and/or other materials provided with the
18    *    distribution.
19    *
20    * 3. The end-user documentation included with the redistribution,
21    *    if any, must include the following acknowledgment:
22    *       "This product includes software developed by the
23    *        Apache Software Foundation (http://www.apache.org/)."
24    *    Alternately, this acknowledgment may appear in the software itself,
25    *    if and wherever such third-party acknowledgments normally appear.
26    *
27    * 4. The names "Apache" and "Apache Software Foundation" and
28    *    "Apache POI" must not be used to endorse or promote products
29    *    derived from this software without prior written permission. For
30    *    written permission, please contact apache@apache.org.
31    *
32    * 5. Products derived from this software may not be called "Apache",
33    *    "Apache POI", nor may "Apache" appear in their name, without
34    *    prior written permission of the Apache Software Foundation.
35    *
36    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47    * SUCH DAMAGE.
48    * ====================================================================
49    *
50    * This software consists of voluntary contributions made by many
51    * individuals on behalf of the Apache Software Foundation.  For more
52    * information on the Apache Software Foundation, please see
53    * <http://www.apache.org/>.
54    */
55   
56   package org.apache.poi.poifs.eventfilesystem;
57   
58   import java.util.*;
59   
60   import org.apache.poi.poifs.filesystem.DocumentDescriptor;
61   import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
62   
63   /**
64    * A registry for POIFSReaderListeners and the DocumentDescriptors of
65    * the documents those listeners are interested in
66    *
67    * @author Marc Johnson (mjohnson at apache dot org)
68    * @version %I%, %G%
69    */
70   
71   class POIFSReaderRegistry
72   {
73   
74       // the POIFSReaderListeners who listen to all POIFSReaderEvents
75       private Set omnivorousListeners;
76   
77       // Each mapping in this Map has a key consisting of a
78       // POIFSReaderListener and a value cosisting of a Set of
79       // DocumentDescriptors for the documents that POIFSReaderListener
80       // is interested in; used to efficiently manage the registry
81       private Map selectiveListeners;
82   
83       // Each mapping in this Map has a key consisting of a
84       // DocumentDescriptor and a value consisting of a Set of
85       // POIFSReaderListeners for the document matching that
86       // DocumentDescriptor; used when a document is found, to quickly
87       // get the listeners interested in that document
88       private Map chosenDocumentDescriptors;
89   
90       /**
91        * Construct the registry
92        */
93   
94       POIFSReaderRegistry()
95       {
96           omnivorousListeners       = new HashSet();
97           selectiveListeners        = new HashMap();
98           chosenDocumentDescriptors = new HashMap();
99       }
100  
101      /**
102       * register a POIFSReaderListener for a particular document
103       *
104       * @param listener the listener
105       * @param path the path of the document of interest
106       * @param documentName the name of the document of interest
107       */
108  
109      void registerListener(final POIFSReaderListener listener,
110                            final POIFSDocumentPath path,
111                            final String documentName)
112      {
113          if (!omnivorousListeners.contains(listener))
114          {
115  
116              // not an omnivorous listener (if it was, this method is a
117              // no-op)
118              Set descriptors = ( Set ) selectiveListeners.get(listener);
119  
120              if (descriptors == null)
121              {
122  
123                  // this listener has not registered before
124                  descriptors = new HashSet();
125                  selectiveListeners.put(listener, descriptors);
126              }
127              DocumentDescriptor descriptor = new DocumentDescriptor(path,
128                                                  documentName);
129  
130              if (descriptors.add(descriptor))
131              {
132  
133                  // this listener wasn't already listening for this
134                  // document -- add the listener to the set of
135                  // listeners for this document
136                  Set listeners =
137                      ( Set ) chosenDocumentDescriptors.get(descriptor);
138  
139                  if (listeners == null)
140                  {
141  
142                      // nobody was listening for this document before
143                      listeners = new HashSet();
144                      chosenDocumentDescriptors.put(descriptor, listeners);
145                  }
146                  listeners.add(listener);
147              }
148          }
149      }
150  
151      /**
152       * register for all documents
153       *
154       * @param listener the listener who wants to get all documents
155       */
156  
157      void registerListener(final POIFSReaderListener listener)
158      {
159          if (!omnivorousListeners.contains(listener))
160          {
161  
162              // wasn't already listening for everything, so drop
163              // anything listener might have been listening for and
164              // then add the listener to the set of omnivorous
165              // listeners
166              removeSelectiveListener(listener);
167              omnivorousListeners.add(listener);
168          }
169      }
170  
171      /**
172       * get am iterator of listeners for a particular document
173       *
174       * @param path the document path
175       * @param name the name of the document
176       *
177       * @return an Iterator POIFSReaderListeners; may be empty
178       */
179  
180      Iterator getListeners(final POIFSDocumentPath path, final String name)
181      {
182          Set rval               = new HashSet(omnivorousListeners);
183          Set selectiveListeners =
184              ( Set ) chosenDocumentDescriptors.get(new DocumentDescriptor(path,
185                  name));
186  
187          if (selectiveListeners != null)
188          {
189              rval.addAll(selectiveListeners);
190          }
191          return rval.iterator();
192      }
193  
194      private void removeSelectiveListener(final POIFSReaderListener listener)
195      {
196          Set selectedDescriptors = ( Set ) selectiveListeners.remove(listener);
197  
198          if (selectedDescriptors != null)
199          {
200              Iterator iter = selectedDescriptors.iterator();
201  
202              while (iter.hasNext())
203              {
204                  dropDocument(listener, ( DocumentDescriptor ) iter.next());
205              }
206          }
207      }
208  
209      private void dropDocument(final POIFSReaderListener listener,
210                                final DocumentDescriptor descriptor)
211      {
212          Set listeners = ( Set ) chosenDocumentDescriptors.get(descriptor);
213  
214          listeners.remove(listener);
215          if (listeners.size() == 0)
216          {
217              chosenDocumentDescriptors.remove(descriptor);
218          }
219      }
220  }   // end package scope class POIFSReaderRegistry
221  
222