KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > event > MetaTagAdjuster


1 package net.sf.saxon.event;
2
3 import net.sf.saxon.om.AttributeCollectionImpl;
4 import net.sf.saxon.om.NamePool;
5 import net.sf.saxon.om.NamespaceConstant;
6 import net.sf.saxon.style.StandardNames;
7 import net.sf.saxon.trans.XPathException;
8
9 import javax.xml.transform.OutputKeys JavaDoc;
10 import java.util.Properties JavaDoc;
11
12 /**
13  * The MetaTagAdjuster adds a meta element to the content of the head element, indicating
14  * the required content type and encoding; it also removes any existing meta element
15  * containing this information
16  */

17
18 public class MetaTagAdjuster extends ProxyReceiver {
19
20     boolean seekingHead = true;
21     int droppingMetaTags = -1;
22     boolean inMetaTag = false;
23     boolean foundHead = false;
24     int metaCode;
25     short requiredURICode = 0;
26     AttributeCollectionImpl attributes;
27     String JavaDoc encoding;
28     String JavaDoc mediaType;
29     int level = 0;
30     boolean isXHTML = false;
31
32     /**
33     * Set output properties
34     */

35
36     public void setOutputProperties(Properties JavaDoc details) throws XPathException {
37         encoding = details.getProperty(OutputKeys.ENCODING);
38         if (encoding == null) {
39             encoding = "UTF-8";
40         }
41         mediaType = details.getProperty(OutputKeys.MEDIA_TYPE);
42         if (mediaType == null) {
43             mediaType = "text/html";
44         }
45     }
46
47     /**
48      * Indicate whether we're handling HTML or XHTML
49      */

50
51     public void setIsXHTML(boolean xhtml) {
52         isXHTML = xhtml;
53         if (xhtml) {
54             requiredURICode = getNamePool().getCodeForURI(NamespaceConstant.XHTML);
55         } else {
56             requiredURICode = 0;
57         }
58     }
59
60     /**
61      * Compare a name: case-blindly in the case of HTML, case-sensitive for XHTML
62      */

63
64     private boolean comparesEqual(String JavaDoc name1, String JavaDoc name2) {
65         if (isXHTML) {
66             return name1.equals(name2);
67         } else {
68             return name1.equalsIgnoreCase(name2);
69         }
70
71     }
72
73     /**
74      * Notify the start of an element
75      *
76      * @param nameCode integer code identifying the name of the element within the name pool.
77      * @param typeCode integer code identifying the element's type within the name pool.
78      * @param properties properties of the element node
79      */

80
81     public void startElement(int nameCode, int typeCode, int locationId, int properties) throws XPathException {
82         if (droppingMetaTags == level) {
83             metaCode = nameCode;
84             int uriCode = getNamePool().getURICode(nameCode);
85             String JavaDoc localName = getNamePool().getLocalName(nameCode);
86             if (uriCode == requiredURICode && comparesEqual(localName, "meta")) {
87                 inMetaTag = true;
88                 attributes.clear();
89                 return;
90             }
91         }
92         level++;
93         super.startElement(nameCode, typeCode, locationId, properties);
94         if (seekingHead) {
95             NamePool namePool = getNamePool();
96             int uriCode = namePool.getURICode(nameCode);
97             String JavaDoc localName = namePool.getLocalName(nameCode);
98             if (uriCode == requiredURICode && comparesEqual(localName, "head")) {
99                 foundHead = true;
100             }
101         }
102
103     }
104
105     /**
106      * Notify an attribute. Attributes are notified after the startElement event, and before any
107      * children. Namespaces and attributes may be intermingled.
108      *
109      * @param nameCode The name of the attribute, as held in the name pool
110      * @param typeCode The type of the attribute, as held in the name pool
111      * @param properties Bit significant value. The following bits are defined:
112      * <dd>DISABLE_ESCAPING</dd> <dt>Disable escaping for this attribute</dt>
113      * <dd>NO_SPECIAL_CHARACTERS</dd> <dt>Attribute value contains no special characters</dt>
114      * @throws IllegalStateException: attempt to output an attribute when there is no open element
115      * start tag
116      */

117
118     public void attribute(int nameCode, int typeCode, CharSequence JavaDoc value, int locationId, int properties) throws XPathException {
119         if (inMetaTag) {
120             attributes.addAttribute(nameCode, typeCode, value.toString(), locationId, properties);
121         } else {
122             super.attribute(nameCode, typeCode, value, locationId, properties);
123         }
124     }
125
126     /**
127      * Notify the start of the content, that is, the completion of all attributes and namespaces.
128      * Note that the initial receiver of output from XSLT instructions will not receive this event,
129      * it has to detect it itself. Note that this event is reported for every element even if it has
130      * no attributes, no namespaces, and no content.
131      */

132
133
134     public void startContent() throws XPathException {
135         if (foundHead) {
136             foundHead = false;
137             NamePool namePool = getNamePool();
138             super.startContent();
139             int metaCode = namePool.allocate("", requiredURICode, "meta");
140             super.startElement(metaCode, StandardNames.XDT_UNTYPED, 0, 0);
141             int httpEquivCode = namePool.allocate("", "", "http-equiv");
142             super.attribute(httpEquivCode, StandardNames.XDT_UNTYPED_ATOMIC, "Content-Type", 0, 0);
143             int contentCode = namePool.allocate("", "", "content");
144             super.attribute(contentCode, StandardNames.XDT_UNTYPED_ATOMIC, mediaType + "; charset=" + encoding, 0, 0);
145             super.startContent();
146             droppingMetaTags = level;
147             seekingHead = false;
148             attributes = new AttributeCollectionImpl(namePool);
149             super.endElement();
150         }
151         if (!inMetaTag) {
152             super.startContent();
153         }
154     }
155
156     /**
157      * End of element
158      */

159
160     public void endElement() throws XPathException {
161         if (inMetaTag) {
162             inMetaTag = false;
163             // if there was an http-equiv="ContentType" attribute, discard the meta element entirely
164
boolean found = false;
165             for (int i=0; i<attributes.getLength(); i++) {
166                 String JavaDoc name = attributes.getLocalName(i);
167                 if (comparesEqual(name, "http-equiv")) {
168                     String JavaDoc value = attributes.getValue(i).trim();
169                     if (value.equalsIgnoreCase("Content-Type")) {
170                         // case-blind comparison even for XHTML
171
found = true;
172                         break;
173                     }
174                 }
175             }
176             if (!found) {
177                 // this was a meta element, but not one of the kind that we discard
178
super.startElement(metaCode, StandardNames.XDT_UNTYPED, 0, 0);
179                 for (int i=0; i<attributes.getLength(); i++) {
180                     int nameCode = attributes.getNameCode(i);
181                     int typeCode = attributes.getTypeAnnotation(i);
182                     String JavaDoc value = attributes.getValue(i);
183                     int locationId = attributes.getLocationId(i);
184                     int properties = attributes.getProperties(i);
185                     super.attribute(nameCode, typeCode, value, locationId, properties);
186                 }
187                 super.startContent();
188                 super.endElement();
189             }
190         } else {
191             level--;
192             if (droppingMetaTags == level+1) {
193                 droppingMetaTags = -1;
194             }
195             super.endElement();
196         }
197     }
198
199 }
200
201 //
202
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
203
// you may not use this file except in compliance with the License. You may obtain a copy of the
204
// License at http://www.mozilla.org/MPL/
205
//
206
// Software distributed under the License is distributed on an "AS IS" basis,
207
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
208
// See the License for the specific language governing rights and limitations under the License.
209
//
210
// The Original Code is: all this file.
211
//
212
// The Initial Developer of the Original Code is Michael H. Kay.
213
//
214
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
215
//
216
// Contributor(s): none.
217
//
218

219
Popular Tags