KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > om > Stripper


1 package com.icl.saxon.om;
2 import com.icl.saxon.Mode;
3 import com.icl.saxon.Context;
4 import com.icl.saxon.Controller;
5 import com.icl.saxon.ContentEmitter;
6 import com.icl.saxon.expr.*;
7 import com.icl.saxon.output.ProxyEmitter;
8 import com.icl.saxon.pattern.*;
9 import com.icl.saxon.tree.ElementImpl;
10
11 import org.xml.sax.Attributes JavaDoc;
12
13 import javax.xml.transform.TransformerException JavaDoc;
14
15 /**
16   * The Stripper class maintains details of which elements need to be stripped.
17   * The code is written to act as a SAX filter to do the stripping.
18   * @author Michael H. Kay (mhkay@iclway.co.uk)
19   */

20   
21 public class Stripper extends ProxyEmitter
22 {
23     private boolean preserveAll; // true if all elements have whitespace preserved
24
private boolean stripAll; // true if all whitespace nodes are stripped
25

26     // stripStack is used to hold information used while stripping nodes. We avoid allocating
27
// space on the tree itself to keep the size of nodes down. Each entry on the stack is two
28
// booleans, one indicates the current value of xml-space is "preserve", the other indicates
29
// that we are in a space-preserving element.
30

31     // We implement our own stack to avod the overhead of allocating objects. The two booleans
32
// are held as the ls bits of a byte.
33

34     private byte[] stripStack = new byte[100];
35     private int top = 0;
36
37     // We use a collection of rules to determine whether to strip spaces; a collection
38
// of rules is known as a Mode. (We are reusing the code for template rule matching)
39

40     private Mode stripperMode;
41     
42     // Mode expects to test an Element, so we create a dummy element for it to test
43
private DummyElement element = new DummyElement();
44     
45     // Stripper needs a Controller (a) to create a dummy Context for evaluating patterns
46
// and (b) to provide reporting of rule conflicts.
47
private Context context;
48     
49     // Need the namePool to get URI codes from name codes
50
private NamePool namePool;
51
52     /**
53     * Default constructor for use in subclasses
54     */

55     
56     protected Stripper() {}
57     
58     /**
59     * create a Stripper and initialise variables
60     * @param stripperRules: defines which elements have whitespace stripped. If
61     * null, all whitespace is preserved.
62     */

63
64     public Stripper(Mode stripperRules) {
65         stripperMode = stripperRules;
66         preserveAll = (stripperRules==null);
67         stripAll = false;
68     }
69
70     /**
71     * Specify that all whitespace nodes are to be preserved
72     */

73     
74     public void setPreserveAll() {
75         preserveAll = true;
76         stripAll = false;
77     }
78
79     /**
80     * Determine if all whitespace is to be preserved (in this case, no further testing
81     * is needed)
82     */

83     
84     public boolean getPreserveAll() {
85         return preserveAll;
86     }
87
88     /**
89     * Specify that all whitespace nodes are to be stripped
90     */

91     
92     public void setStripAll() {
93         preserveAll = false;
94         stripAll = true;
95     }
96
97     /**
98     * Determine if all whitespace is to be stripped (in this case, no further testing
99     * is needed)
100     */

101     
102     public boolean getStripAll() {
103         return stripAll;
104     }
105     
106
107     /**
108     * Set the Controller to be used
109     */

110     
111     public void setController(Controller controller) {
112         context = controller.makeContext(element);
113         namePool = controller.getNamePool();
114     }
115     
116     /**
117     * Decide whether an element is in the set of white-space preserving element types
118     * @param uri The namespace URI of the element name
119     * @param localname The local part of the element name
120     * @return true if the element is in the set of white-space preserving element types
121     */

122
123     public boolean isSpacePreserving(int nameCode) {
124         try {
125             if (preserveAll) return true;
126             if (stripAll) return false;
127             element.setNameCode(nameCode);
128             Object JavaDoc rule = stripperMode.getRule(element, context);
129             if (rule==null) return true;
130             return ((Boolean JavaDoc)rule).booleanValue();
131         } catch (TransformerException JavaDoc err) {
132             return true;
133         }
134     }
135
136     /**
137     * Callback interface for SAX: not for application use
138     */

139
140     public void startDocument () throws TransformerException JavaDoc
141     {
142         // System.err.println("Stripper#startDocument()");
143
top = 0;
144         stripStack[top]=0x01; // {xml:preserve = false, preserve this element = true}
145
super.startDocument();
146     }
147
148     /**
149     * Callback interface for SAX: not for application use
150     */

151
152     public void startElement (int nameCode, Attributes JavaDoc atts, int[] namespaces, int nscount)
153     throws TransformerException JavaDoc
154     {
155         // System.err.println("startElement " + nameCode);
156
super.startElement(nameCode, atts, namespaces, nscount);
157
158         byte preserveParent = stripStack[top];
159         
160         String JavaDoc xmlspace = atts.getValue(Namespace.XML, "space");
161         byte preserve = (byte)(preserveParent & 0x02);
162         if (xmlspace!=null) {
163             if (xmlspace.equals("preserve")) preserve = 0x02;
164             if (xmlspace.equals("default")) preserve = 0x00;
165         }
166         if (isSpacePreserving(nameCode)) {
167             preserve |= 0x01;
168         }
169
170         // put "preserve" value on top of stack
171

172         top++;
173         if (top >= stripStack.length) {
174             byte[] newStack = new byte[top*2];
175             System.arraycopy(stripStack, 0, newStack, 0, top);
176             stripStack = newStack;
177         }
178         stripStack[top] = preserve;
179     }
180
181     /**
182     * Callback interface for SAX: not for application use
183     */

184
185     public void endElement (int nameCode) throws TransformerException JavaDoc
186     {
187         super.endElement(nameCode);
188         top--;
189     }
190
191     /**
192     * Callback interface for SAX: not for application use
193     */

194
195     public void characters (char ch[], int start, int length) throws TransformerException JavaDoc
196     {
197         // assume adjacent chunks of text are already concatenated
198

199         if (length > 0) {
200             if (stripStack[top]!=0 || !isWhite(ch, start, length)) {
201                 super.characters(ch, start, length);
202             }
203         }
204     }
205            
206     /**
207     * Decide whether the accumulated character data is all whitespace
208     */

209
210     private boolean isWhite(char[] ch, int start, int length) {
211         for (int i=start; i<start+length; i++) {
212             if ( (int)ch[i] > 0x20 ) {
213                 return false;
214             }
215         }
216         return true;
217     }
218     
219
220
221     private class DummyElement extends ElementImpl {
222         public short getURICode() {
223             return namePool.getURICode(getNameCode());
224         }
225         
226     }
227
228 } // end of class Stripper
229

230 //
231
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
232
// you may not use this file except in compliance with the License. You may obtain a copy of the
233
// License at http://www.mozilla.org/MPL/
234
//
235
// Software distributed under the License is distributed on an "AS IS" basis,
236
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
237
// See the License for the specific language governing rights and limitations under the License.
238
//
239
// The Original Code is: all this file.
240
//
241
// The Initial Developer of the Original Code is
242
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
243
//
244
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
245
//
246
// Contributor(s): none.
247
//
248
Popular Tags