View Javadoc

1   /*
2   
3       stax  Stack API for XML.
4       Copyright (c) 2001-2006 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 2.1 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.gnu.org/copyleft/lesser.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package net.sf.stax;
25  
26  import java.util.Map;
27  import java.util.Set;
28  import java.util.List;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.Iterator;
32  import java.util.ArrayList;
33  
34  import org.xml.sax.SAXException;
35  
36  /***
37   * Default implementation of <b>IdMapper</b>.
38   *
39   * @author  Thomas Down
40   * @author  Matthew Pocock
41   * @author  Michael Heuer
42   * @version $Revision: 1.2 $ $Date: 2006/01/02 20:37:34 $
43   */
44  class IdMapperImpl
45      implements IdMapper
46  {
47      /*** List of global listeners. */
48      private final List globalListeners;
49  
50      /*** Map of IdListeners keyed by ids. */
51      private final Map idListeners;
52  
53      /*** Map of ids to items. */
54      private final Map idToItem;
55  
56  
57      /***
58       * Create a new default implementation of <b>IdMapper</b>.
59       */
60      public IdMapperImpl()
61      {
62          globalListeners = new ArrayList();
63          idListeners = new HashMap();
64          idToItem = new HashMap();
65      }
66  
67      /***
68       * Create a new default implementation of <b>IdMapper</b>
69       * with the specified map of existing ids to items.
70       *
71       * @param existingIds map of existing ids to items.
72       */
73      public IdMapperImpl(final Map existingIds)
74      {
75          this();
76          idToItem.putAll(existingIds);
77      }
78  
79  
80      /***
81       * Return the set of unresolved ids.
82       *
83       * @return the set of unresolved ids
84       */
85      public Set getUnresolvedIds()
86      {
87          return idListeners.keySet();
88      }
89  
90      /*** @see IdMapper */
91      public void registerItemForId(final Object id, final Object item)
92          throws SAXException
93      {
94          // complain if we've seen this before
95          if (idToItem.containsKey(id))
96          {
97              throw new SAXException("id already mapped: " + id + " -> " + idToItem.get(id));
98          }
99  
100         // store for later
101         idToItem.put(id, item);
102 
103         // inform each listener that's id agnostic
104         for (Iterator i = globalListeners.iterator(); i.hasNext();)
105         {
106             IdListener l = (IdListener) i.next();
107             l.idRegistered(id, item);
108         }
109 
110         // inform each listener that is keen about this id and then remove them
111         Object listeners = idListeners.get(id);
112         if (listeners != null)
113         {
114             // more than one listener all kept in a set
115             if (listeners instanceof Set)
116             {
117                 for (Iterator i = ((Set) listeners).iterator(); i.hasNext();)
118                 {
119                     IdListener l = (IdListener) i.next();
120                     l.idRegistered(id, item);
121                 }
122             }
123             else
124             {
125                 // just one listener
126                 IdListener l = (IdListener) listeners;
127                 l.idRegistered(id, item);
128             }
129         }
130         idListeners.remove(id);
131     }
132 
133 
134     /*** @see IdMapper */
135     public void addIdListener(final IdListener listener)
136         throws SAXException
137     {
138         // add this listener
139         globalListeners.add(listener);
140 
141         // tell it about all past id mappings
142         for (Iterator i = idToItem.keySet().iterator(); i.hasNext();)
143         {
144             Object id = i.next();
145             listener.idRegistered(id, idToItem.get(id));
146         }
147     }
148 
149     /*** @see IdMapper */
150     public void removeIdListener(final IdListener listener)
151         throws SAXException
152     {
153         // empty
154     }
155 
156     /*** @see IdMapper */
157     public void addIdListener(final IdListener listener, final Object id)
158         throws SAXException
159     {
160         if (idToItem.containsKey(id))
161         {
162             // if we know the id mapping, then just invoke the callback directly
163             listener.idRegistered(id, idToItem.get(id));
164         }
165         else
166         {
167             // ok - we don't know the mapping yet, so let's store the listener away
168             Object ls = idListeners.get(id);
169             if (ls == null)
170             {
171                 idListeners.put(id, listener);
172             }
173             else if (ls instanceof IdListener)
174             {
175                 Set lSet = new HashSet();
176                 lSet.add(ls);
177                 lSet.add(listener);
178                 idListeners.put(id, lSet);
179             }
180             else
181             {
182                 Set lSet = (Set) ls;
183                 lSet.add(listener);
184             }
185         }
186     }
187 
188     /*** @see IdMapper */
189     public void removeIdListener(final IdListener listener, final Object id)
190         throws SAXException
191     {
192         // empty
193     }
194 }