KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xml > utils > StylesheetPIHandler


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: StylesheetPIHandler.java,v 1.2 2004/02/17 04:21:14 minchau Exp $
18  */

19 package org.apache.xml.utils;
20
21 import java.util.StringTokenizer JavaDoc;
22 import java.util.Vector JavaDoc;
23
24 import javax.xml.transform.Source JavaDoc;
25 import javax.xml.transform.TransformerException JavaDoc;
26 import javax.xml.transform.URIResolver JavaDoc;
27 import javax.xml.transform.sax.SAXSource JavaDoc;
28
29 import org.apache.xml.utils.SystemIDResolver;
30
31 import org.xml.sax.Attributes JavaDoc;
32 import org.xml.sax.InputSource JavaDoc;
33 import org.xml.sax.helpers.DefaultHandler JavaDoc;
34
35 /**
36  * Search for the xml-stylesheet processing instructions in an XML document.
37  * @see <a HREF="http://www.w3.org/TR/xml-stylesheet/">Associating Style Sheets with XML documents, Version 1.0</a>
38  */

39 public class StylesheetPIHandler extends DefaultHandler JavaDoc
40 {
41   /** The baseID of the document being processed. */
42   String JavaDoc m_baseID;
43
44   /** The desired media criteria. */
45   String JavaDoc m_media;
46
47   /** The desired title criteria. */
48   String JavaDoc m_title;
49
50   /** The desired character set criteria. */
51   String JavaDoc m_charset;
52
53   /** A list of SAXSource objects that match the criteria. */
54   Vector JavaDoc m_stylesheets = new Vector JavaDoc();
55   
56   // Add code to use a URIResolver. Patch from Dmitri Ilyin.
57

58   /**
59    * The object that implements the URIResolver interface,
60    * or null.
61    */

62   URIResolver JavaDoc m_uriResolver;
63
64   /**
65    * Get the object that will be used to resolve URIs in href
66    * in xml-stylesheet processing instruction.
67    *
68    * @param resolver An object that implements the URIResolver interface,
69    * or null.
70    */

71   public void setURIResolver(URIResolver JavaDoc resolver)
72   {
73     m_uriResolver = resolver;
74   }
75
76   /**
77    * Get the object that will be used to resolve URIs in href
78    * in xml-stylesheet processing instruction.
79    *
80    * @return The URIResolver that was set with setURIResolver.
81    */

82   public URIResolver JavaDoc getURIResolver()
83   {
84     return m_uriResolver;
85   }
86
87   /**
88    * Construct a StylesheetPIHandler instance that will search
89    * for xml-stylesheet PIs based on the given criteria.
90    *
91    * @param baseID The base ID of the XML document, needed to resolve
92    * relative IDs.
93    * @param media The desired media criteria.
94    * @param title The desired title criteria.
95    * @param charset The desired character set criteria.
96    */

97   public StylesheetPIHandler(String JavaDoc baseID, String JavaDoc media, String JavaDoc title,
98                              String JavaDoc charset)
99   {
100
101     m_baseID = baseID;
102     m_media = media;
103     m_title = title;
104     m_charset = charset;
105   }
106
107   /**
108    * Return the last stylesheet found that match the constraints.
109    *
110    * @return Source object that references the last stylesheet reference
111    * that matches the constraints.
112    */

113   public Source JavaDoc getAssociatedStylesheet()
114   {
115
116     int sz = m_stylesheets.size();
117
118     if (sz > 0)
119     {
120       Source JavaDoc source = (Source JavaDoc) m_stylesheets.elementAt(sz-1);
121       return source;
122     }
123     else
124       return null;
125   }
126
127   /**
128    * Handle the xml-stylesheet processing instruction.
129    *
130    * @param target The processing instruction target.
131    * @param data The processing instruction data, or null if
132    * none is supplied.
133    * @throws org.xml.sax.SAXException Any SAX exception, possibly
134    * wrapping another exception.
135    * @see org.xml.sax.ContentHandler#processingInstruction
136    * @see <a HREF="http://www.w3.org/TR/xml-stylesheet/">Associating Style Sheets with XML documents, Version 1.0</a>
137    */

138   public void processingInstruction(String JavaDoc target, String JavaDoc data)
139           throws org.xml.sax.SAXException JavaDoc
140   {
141
142     if (target.equals("xml-stylesheet"))
143     {
144       String JavaDoc href = null; // CDATA #REQUIRED
145
String JavaDoc type = null; // CDATA #REQUIRED
146
String JavaDoc title = null; // CDATA #IMPLIED
147
String JavaDoc media = null; // CDATA #IMPLIED
148
String JavaDoc charset = null; // CDATA #IMPLIED
149
boolean alternate = false; // (yes|no) "no"
150
StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(data, " \t=\n", true);
151       boolean lookedAhead = false;
152       Source JavaDoc source = null;
153
154       String JavaDoc token = "";
155       while (tokenizer.hasMoreTokens())
156       {
157         if (!lookedAhead)
158           token = tokenizer.nextToken();
159         else
160           lookedAhead = false;
161         if (tokenizer.hasMoreTokens() &&
162                (token.equals(" ") || token.equals("\t") || token.equals("=")))
163           continue;
164           
165         String JavaDoc name = token;
166         if (name.equals("type"))
167         {
168           token = tokenizer.nextToken();
169           while (tokenizer.hasMoreTokens() &&
170                (token.equals(" " ) || token.equals("\t") || token.equals("=")))
171             token = tokenizer.nextToken();
172           type = token.substring(1, token.length() - 1);
173           
174         }
175         else if (name.equals("href"))
176         {
177           token = tokenizer.nextToken();
178           while (tokenizer.hasMoreTokens() &&
179                (token.equals(" " ) || token.equals("\t") || token.equals("=")))
180             token = tokenizer.nextToken();
181           href = token;
182           if (tokenizer.hasMoreTokens())
183           {
184             token = tokenizer.nextToken();
185             // If the href value has parameters to be passed to a
186
// servlet(something like "foobar?id=12..."),
187
// we want to make sure we get them added to
188
// the href value. Without this check, we would move on
189
// to try to process another attribute and that would be
190
// wrong.
191
// We need to set lookedAhead here to flag that we
192
// already have the next token.
193
while ( token.equals("=") && tokenizer.hasMoreTokens())
194             {
195               href = href + token + tokenizer.nextToken();
196               if (tokenizer.hasMoreTokens())
197               {
198                 token = tokenizer.nextToken();
199                 lookedAhead = true;
200               }
201               else
202               {
203                 break;
204               }
205             }
206           }
207           href = href.substring(1, href.length() - 1);
208           try
209           {
210             // Add code to use a URIResolver. Patch from Dmitri Ilyin.
211
if (m_uriResolver != null)
212             {
213               source = m_uriResolver.resolve(href, m_baseID);
214             }
215            else
216             {
217               href = SystemIDResolver.getAbsoluteURI(href, m_baseID);
218               source = new SAXSource JavaDoc(new InputSource JavaDoc(href));
219             }
220           }
221           catch(TransformerException JavaDoc te)
222           {
223             throw new org.xml.sax.SAXException JavaDoc(te);
224           }
225         }
226         else if (name.equals("title"))
227         {
228           token = tokenizer.nextToken();
229           while (tokenizer.hasMoreTokens() &&
230                (token.equals(" " ) || token.equals("\t") || token.equals("=")))
231             token = tokenizer.nextToken();
232           title = token.substring(1, token.length() - 1);
233         }
234         else if (name.equals("media"))
235         {
236           token = tokenizer.nextToken();
237           while (tokenizer.hasMoreTokens() &&
238                (token.equals(" " ) || token.equals("\t") || token.equals("=")))
239             token = tokenizer.nextToken();
240           media = token.substring(1, token.length() - 1);
241         }
242         else if (name.equals("charset"))
243         {
244           token = tokenizer.nextToken();
245           while (tokenizer.hasMoreTokens() &&
246               (token.equals(" " ) || token.equals("\t") || token.equals("=")))
247             token = tokenizer.nextToken();
248           charset = token.substring(1, token.length() - 1);
249         }
250         else if (name.equals("alternate"))
251         {
252           token = tokenizer.nextToken();
253           while (tokenizer.hasMoreTokens() &&
254                (token.equals(" " ) || token.equals("\t") || token.equals("=")))
255             token = tokenizer.nextToken();
256           alternate = token.substring(1, token.length()
257                                              - 1).equals("yes");
258         }
259         
260       }
261
262       if ((null != type)
263           && (type.equals("text/xsl") || type.equals("text/xml") || type.equals("application/xml+xslt"))
264           && (null != href))
265       {
266         if (null != m_media)
267         {
268           if (null != media)
269           {
270             if (!media.equals(m_media))
271               return;
272           }
273           else
274             return;
275         }
276
277         if (null != m_charset)
278         {
279           if (null != charset)
280           {
281             if (!charset.equals(m_charset))
282               return;
283           }
284           else
285             return;
286         }
287
288         if (null != m_title)
289         {
290           if (null != title)
291           {
292             if (!title.equals(m_title))
293               return;
294           }
295           else
296             return;
297         }
298
299         m_stylesheets.addElement(source);
300       }
301     }
302   }
303   
304   
305   /**
306    * The spec notes that "The xml-stylesheet processing instruction is allowed only in the prolog of an XML document.",
307    * so, at least for right now, I'm going to go ahead an throw a TransformerException
308    * in order to stop the parse.
309    *
310    * @param uri The Namespace URI, or an empty string.
311    * @param localName The local name (without prefix), or empty string if not namespace processing.
312    * @param rawName The qualified name (with prefix).
313    * @param attributes The specified or defaulted attributes.
314    *
315    * @throws StopParseException since there can be no valid xml-stylesheet processing
316    * instructions past the first element.
317    */

318   public void startElement(
319           String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc atts)
320             throws org.xml.sax.SAXException JavaDoc
321   {
322     throw new StopParseException();
323   }
324
325   /**
326     * Added additional getter and setter methods for the Base Id
327     * to fix bugzilla bug 24187
328     *
329     */

330    public void setBaseId(String JavaDoc baseId) {
331        m_baseID = baseId;
332  
333    }
334    public String JavaDoc getBaseId() {
335        return m_baseID ;
336    }
337
338 }
339
Popular Tags