View Javadoc

1   /*
2    * Copyright (C) 2003-2006 Christian Siefkes <christian@siefkes.net>.
3    * Development of this software is supported by the German Research Society,
4    * Berlin-Brandenburg Graduate School in Distributed Information Systems
5    * (DFG grant no. GRK 316).
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, visit
19   * http://www.gnu.org/licenses/gpl.html or write to the Free Software
20   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21   */
22  package de.fu_berlin.ties.xml;
23  
24  import org.apache.commons.collections.Bag;
25  import org.apache.commons.collections.bag.HashBag;
26  
27  /***
28   * A container that keeps track of unprocessed start and end tags during XML
29   * adjustment.
30   *
31   * @author Christian Siefkes
32   * @version $Revision: 1.5 $, $Date: 2006/10/21 16:04:29 $, $Author: siefkes $
33   */
34  public class UnprocessedTags extends TagContainer {
35  
36      /***
37       * A bag (multi-set) that counts how often each start tag appears in the
38       * container.
39       */
40      private Bag startTagBag = new HashBag();
41  
42      /***
43       * A bag (multi-set) that counts how often each end tag appears in the
44       * container.
45       */
46      private Bag endTagBag = new HashBag();
47  
48      /***
49       * Creates a new instance.
50       */
51      public UnprocessedTags() {
52          super();
53      }
54  
55      /***
56       * Returns the number of end tags with the specified name contained in
57       * this container.
58       *
59       * @param tagName the name of the tags to count
60       * @return the number of matching end tags contained (0 or more)
61       */
62      public int endTagCount(final String tagName) {
63          return endTagBag.getCount(tagName);
64      }
65  
66      /***
67       * Inserts an appearance of a tag into the container. The name of the
68       * tag is used as key; the whole constituent is inserted in the list of
69       * appearances stored for this tag name. Instances of this class accept only
70       * start and end tags.
71       *
72       * @param tag the tag to insert
73       * @param appendAtEnd whether to insert the tag at the end or at the begin
74       * of appearances within a series
75       * @throws IllegalArgumentException if the specified tag is not a start or
76       * end tag
77       */
78      public void push(final TagConstituent tag, final boolean appendAtEnd)
79              throws IllegalArgumentException {
80          final String tagName = tag.getName();
81          final int tagType = tag.getType();
82  
83          // increase count in appropriate bag
84          switch (tagType) {
85              case TagConstituent.START_TAG :
86                  startTagBag.add(tagName);
87                  break;
88  
89              case TagConstituent.END_TAG :
90                  endTagBag.add(tagName);
91                  break;
92  
93              default :
94                  throw new IllegalArgumentException("UnprocessedTags allows "
95                      + " only start or end tags, not tags of type "
96                      + tag.getType() + " (" + tag + ")");
97          }
98  
99          // delegate to superclass
100         super.push(tag, appendAtEnd);
101     }
102 
103     /***
104      * Removes a single appearance of a tag from the container.
105      *
106      * @param tag the tag to remove
107      * @return <code>true</code> if the specified TagConstituent was
108      * removed successfully; <code>false</code> otherwise (the specified
109      * constituent wasn't found in the container)
110      */
111     public boolean remove(final TagConstituent tag) {
112         if (super.remove(tag)) {
113             // removed from superclass: remove from appropriate bag
114             final String tagName = tag.getName();
115             final int tagType = tag.getType();
116             final boolean myResult;
117 
118             // increase count in appropriate bag
119             switch (tagType) {
120                 case TagConstituent.START_TAG :
121                     myResult = startTagBag.remove(tagName, 1);
122                     break;
123 
124                 case TagConstituent.END_TAG :
125                     myResult = endTagBag.remove(tagName, 1);
126                     break;
127 
128                 default :
129                     // normally this should be prevented by push + super.remove
130                     // -- just a sanity check
131                     throw new IllegalArgumentException("UnprocessedTags allows "
132                         + " only start or end tags, not tags of type "
133                         + tag.getType() + " (" + tag + ")");
134             }
135 
136             return myResult;
137         } else {
138             // not found by superclass
139             return false;
140         }
141     }
142 
143     /***
144      * Returns the number of start tags with the specified name contained in
145      * this container.
146      *
147      * @param tagName the name of the tags to count
148      * @return the number of matching start tags contained (0 or more)
149      */
150     public int startTagCount(final String tagName) {
151         return startTagBag.getCount(tagName);
152     }
153 }