KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > XtpPage


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.jsp;
31
32 import com.caucho.java.JavaCompiler;
33 import com.caucho.java.LineMap;
34 import com.caucho.log.Log;
35 import com.caucho.server.connection.CauchoRequest;
36 import com.caucho.server.connection.CauchoResponse;
37 import com.caucho.server.connection.RequestAdapter;
38 import com.caucho.server.connection.ResponseAdapter;
39 import com.caucho.server.dispatch.ServletConfigImpl;
40 import com.caucho.server.webapp.WebApp;
41 import com.caucho.util.Base64;
42 import com.caucho.util.CharBuffer;
43 import com.caucho.util.RegistryException;
44 import com.caucho.util.Semaphore;
45 import com.caucho.util.TimeUnit;
46 import com.caucho.vfs.Depend;
47 import com.caucho.vfs.Path;
48 import com.caucho.vfs.PersistentDependency;
49 import com.caucho.vfs.ReadStream;
50 import com.caucho.vfs.Vfs;
51 import com.caucho.vfs.WriteStream;
52 import com.caucho.xml.CauchoDocument;
53 import com.caucho.xml.Html;
54 import com.caucho.xml.Xml;
55 import com.caucho.xml.XmlParser;
56 import com.caucho.xml.XmlUtil;
57 import com.caucho.xpath.XPath;
58 import com.caucho.xpath.XPathException;
59 import com.caucho.xsl.CauchoStylesheet;
60 import com.caucho.xsl.StylesheetImpl;
61 import com.caucho.xsl.TransformerImpl;
62 import com.caucho.xsl.XslParseException;
63
64 import org.w3c.dom.Document JavaDoc;
65 import org.w3c.dom.ProcessingInstruction JavaDoc;
66
67 import javax.servlet.ServletException JavaDoc;
68 import javax.servlet.ServletRequest JavaDoc;
69 import javax.servlet.ServletResponse JavaDoc;
70 import javax.servlet.http.HttpServletRequest JavaDoc;
71 import javax.servlet.http.HttpServletResponse JavaDoc;
72 import javax.servlet.jsp.JspException JavaDoc;
73 import javax.servlet.jsp.JspFactory JavaDoc;
74 import javax.servlet.jsp.PageContext JavaDoc;
75 import javax.xml.transform.OutputKeys JavaDoc;
76 import javax.xml.transform.Templates JavaDoc;
77 import javax.xml.transform.TransformerConfigurationException JavaDoc;
78 import javax.xml.transform.dom.DOMSource JavaDoc;
79 import javax.xml.transform.stream.StreamResult JavaDoc;
80 import java.io.FileNotFoundException JavaDoc;
81 import java.io.IOException JavaDoc;
82 import java.lang.ref.SoftReference JavaDoc;
83 import java.util.ArrayList JavaDoc;
84 import java.util.HashMap JavaDoc;
85 import java.util.Iterator JavaDoc;
86 import java.util.Properties JavaDoc;
87 import java.util.logging.Level JavaDoc;
88 import java.util.logging.Logger JavaDoc;
89
90
91 /**
92  * XtpPage represents the compiled page.
93  */

94 class XtpPage extends Page {
95   private static final Logger JavaDoc log = Log.open(XtpPage.class);
96
97   private boolean _strictXml;
98   private boolean _toLower = true;
99   private boolean _entitiesAsText = false;
100
101   private Path _sourcePath;
102   private Path _pwd;
103   
104   private String JavaDoc _uri;
105   private String JavaDoc _className;
106   private String JavaDoc _errorPage;
107
108   private WebApp _webApp;
109
110   private XslManager _xslManager;
111
112   private Page _page;
113   
114   private HashMap JavaDoc<String JavaDoc,SoftReference JavaDoc<Page>> _varyMap;
115   private ArrayList JavaDoc<String JavaDoc> _paramNames;
116
117   private JspManager _jspManager;
118
119   private final Semaphore _compileSemaphore = new Semaphore(1, false);
120
121   /**
122    * Creates a new XTP page.
123    *
124    * @param path file containing the xtp page
125    * @param uri the request uri for the page
126    * @param className the mangled classname for the page
127    * @param uriPwd uri working dir for include() or forward()
128    * @param req the servlet request
129    * @param xslManager manager for the XSL stylesheets
130    * @param strictXml if true, use strict XML, now HTML
131    */

132   XtpPage(Path path, String JavaDoc uri, String JavaDoc className,
133           WebApp app,
134           XslManager xslManager, boolean strictXml)
135     throws ServletException JavaDoc, RegistryException
136   {
137     _sourcePath = path;
138     _sourcePath.setUserPath(uri);
139     _pwd = _sourcePath.getParent();
140     _className = className;
141     _webApp = app;
142     _strictXml = strictXml;
143     _xslManager = xslManager;
144     _uri = uri;
145
146     ServletConfigImpl config = new ServletConfigImpl();
147     config.setServletContext(_webApp);
148     
149     init(config);
150   }
151
152   /**
153    * Sets the JspManager for the page.
154    */

155   void setManager(JspManager manager)
156   {
157     _jspManager = manager;
158   }
159
160   /**
161    * When true, HTML in XTP is normalized to lower-case.
162    */

163   void setHtmlToLower(boolean toLower)
164   {
165     _toLower = toLower;
166   }
167
168   /**
169    * When true, XML entities are parsed as text.
170    */

171   void setEntitiesAsText(boolean entitiesAsText)
172   {
173     _entitiesAsText = entitiesAsText;
174   }
175
176   /**
177    * Returns true if the sources creating this page have been modified.
178    */

179   public boolean _caucho_isModified()
180   {
181     return false;
182   }
183
184   /**
185    * Handle a request.
186    *
187    * @param req the servlet request
188    * @param res the servlet response
189    */

190   public void service(ServletRequest JavaDoc request, ServletResponse JavaDoc response)
191     throws IOException JavaDoc, ServletException JavaDoc
192   {
193     CauchoRequest req;
194     
195     if (request instanceof CauchoRequest)
196       req = (CauchoRequest) request;
197     else
198       req = RequestAdapter.create((HttpServletRequest JavaDoc) request, _webApp);
199     
200     CauchoResponse res;
201     ResponseAdapter resAdapt = null;
202     
203     if (response instanceof CauchoResponse)
204       res = (CauchoResponse) response;
205     else {
206       resAdapt = ResponseAdapter.create((HttpServletResponse JavaDoc) response);
207       res = resAdapt;
208     }
209
210     try {
211       service(req, res);
212     } catch (InterruptedException JavaDoc e) {
213       log.log(Level.FINE, e.toString(), e);
214       
215       log.warning("XTP: interrupted for " + req.getPageURI());
216       
217       res.sendError(503, "Server busy: XTP generation delayed");
218     } finally {
219       if (resAdapt != null)
220     resAdapt.close();
221     }
222   }
223     
224
225   /**
226    * Handle a request.
227    *
228    * @param req the servlet request
229    * @param res the servlet response
230    */

231   public void service(CauchoRequest req, CauchoResponse res)
232     throws IOException JavaDoc, ServletException JavaDoc, InterruptedException JavaDoc
233   {
234     Page page = getPage(req, res);
235
236     if (page != null) {
237       page.pageservice(req, res);
238     }
239     else {
240       log.warning("XTP: server busy on " + req.getPageURI());
241
242       res.setHeader("Retry-After", "15");
243       res.sendError(503, "Server busy: XTP generation delayed");
244     }
245   }
246
247   /**
248    * Returns the page.
249    */

250   private Page getPage(CauchoRequest req, CauchoResponse res)
251     throws IOException JavaDoc, ServletException JavaDoc, InterruptedException JavaDoc
252   {
253     String JavaDoc ss = null;
254     String JavaDoc varyName = null;
255     Page page = _page;
256     Page deadPage = null;
257     
258     if (page == null) {
259       if (_varyMap != null) {
260     varyName = generateVaryName(req);
261
262     if (varyName != null) {
263       SoftReference JavaDoc<Page> ref = _varyMap.get(varyName);
264       page = ref != null ? ref.get() : null;
265     }
266       }
267     }
268
269     if (page != null && ! page.cauchoIsModified())
270       return page;
271
272     deadPage = page;
273     page = null;
274
275     long timeout = deadPage == null ? 30L : 5L;
276     
277     Thread.interrupted();
278     if (_compileSemaphore.tryAcquire(timeout, TimeUnit.SECONDS)) {
279       try {
280     varyName = generateVaryName(req);
281
282     page = getPrecompiledPage(req, varyName);
283
284     if (page == null) {
285       CauchoDocument doc;
286
287       try {
288         doc = parseXtp();
289       } catch (FileNotFoundException JavaDoc e) {
290         res.sendError(404);
291         throw e;
292       }
293
294       Templates JavaDoc stylesheet = compileStylesheet(req, doc);
295
296       // the new stylesheet affects the vary name
297
varyName = generateVaryName(req);
298
299       page = getPrecompiledPage(req, varyName);
300
301       if (page == null)
302         page = compileJspPage(req, res, doc, stylesheet, varyName);
303     }
304
305     if (page != null) {
306       ServletConfigImpl config = new ServletConfigImpl();
307       config.setServletContext(_webApp);
308
309       page.init(config);
310
311       if (varyName != null && _varyMap == null)
312         _varyMap = new HashMap JavaDoc<String JavaDoc,SoftReference JavaDoc<Page>>(8);
313         
314       if (varyName != null)
315         _varyMap.put(varyName, new SoftReference JavaDoc<Page>(page));
316       else
317         _page = page;
318     }
319     else if (deadPage != null) {
320       _page = null;
321
322       if (varyName != null && _varyMap != null)
323         _varyMap.remove(varyName);
324     }
325       } finally {
326     _compileSemaphore.release();
327       }
328     }
329     else {
330       log.warning("XTP: semaphore timed out on " + req.getPageURI());
331     }
332       
333
334     if (page != null)
335       return page;
336     else
337       return deadPage;
338   }
339
340   /**
341    * Try to load a precompiled version of the page.
342    *
343    * @param req the request for the page.
344    * @param varyName encoding for the variable stylesheet and parameters
345    * @return the precompiled page or null
346    */

347   private Page getPrecompiledPage(CauchoRequest req, String JavaDoc varyName)
348     throws IOException JavaDoc, ServletException JavaDoc
349   {
350     Page page = null;
351
352     String JavaDoc className = getClassName(varyName);
353     
354     try {
355       page = _jspManager.preload(className,
356                  _webApp.getClassLoader(),
357                  _webApp.getAppDir());
358
359       if (page != null) {
360     if (log.isLoggable(Level.FINE))
361       log.fine("XTP using precompiled page " + className);
362       
363         return page;
364       }
365     } catch (Throwable JavaDoc e) {
366       log.log(Level.FINE, e.toString(), e);
367     }
368
369     return null;
370   }
371
372   /**
373    * Parses the XTP file as either an XML document or an HTML document.
374    */

375   private CauchoDocument parseXtp()
376     throws IOException JavaDoc, ServletException JavaDoc
377   {
378     ReadStream is = _sourcePath.openRead();
379     try {
380       XmlParser parser;
381       
382       if (_strictXml) {
383     parser = new Xml();
384     parser.setEntitiesAsText(_entitiesAsText);
385       }
386       else {
387     parser = new Html();
388     parser.setAutodetectXml(true);
389     parser.setEntitiesAsText(true);
390     // parser.setXmlEntitiesAsText(entitiesAsText);
391
parser.setToLower(_toLower);
392       }
393
394       parser.setResinInclude(true);
395       parser.setJsp(true);
396
397       return (CauchoDocument) parser.parseDocument(is);
398     } catch (Exception JavaDoc e) {
399       JspParseException jspE = JspParseException.create(e);
400       
401       jspE.setErrorPage(_errorPage);
402       
403       throw jspE;
404     } finally {
405       is.close();
406     }
407   }
408
409   /**
410    * Compiles a stylesheet pages on request parameters and the parsed
411    * XML file.
412    *
413    * @param req the servlet request.
414    * @param doc the parsed XTP file as a DOM tree.
415    *
416    * @return the compiled stylesheet
417    */

418   private Templates JavaDoc compileStylesheet(CauchoRequest req, CauchoDocument doc)
419     throws IOException JavaDoc, ServletException JavaDoc
420   {
421     String JavaDoc ssName = (String JavaDoc) req.getAttribute("caucho.xsl.stylesheet");
422
423     Templates JavaDoc stylesheet = null;
424
425     try {
426       if (ssName == null)
427         ssName = getStylesheetHref(doc, null);
428     
429       stylesheet = _xslManager.get(ssName, req);
430     } catch (XslParseException e) {
431       JspParseException jspE;
432       if (e.getException() != null)
433     jspE = new JspParseException(e.getException());
434       else
435     jspE = new JspParseException(e);
436
437       jspE.setErrorPage(_errorPage);
438
439       throw jspE;
440     } catch (Exception JavaDoc e) {
441       JspParseException jspE;
442       
443       jspE = new JspParseException(e);
444
445       jspE.setErrorPage(_errorPage);
446
447       throw jspE;
448     }
449
450     ArrayList JavaDoc<String JavaDoc> params = null;
451     if (stylesheet instanceof StylesheetImpl) {
452       StylesheetImpl ss = (StylesheetImpl) stylesheet;
453       params = (ArrayList JavaDoc) ss.getProperty(CauchoStylesheet.GLOBAL_PARAM);
454     }
455
456     for (int i = 0; params != null && i < params.size(); i++) {
457       String JavaDoc param = params.get(i);
458
459       if (_paramNames == null)
460         _paramNames = new ArrayList JavaDoc<String JavaDoc>();
461
462       if (param.equals("xtp:context_path") ||
463       param.equals("xtp:servlet_path"))
464     continue;
465       
466       if (! _paramNames.contains(param))
467         _paramNames.add(param);
468     }
469
470     return stylesheet;
471   }
472
473   /**
474    * Mangles the page name to generate a unique page name.
475    *
476    * @param req the servlet request.
477    * @param res the servlet response.
478    * @param stylesheet the stylesheet.
479    * @param varyName the unique query.
480    *
481    * @return the compiled page.
482    */

483   private Page compileJspPage(CauchoRequest req,
484                               CauchoResponse res,
485                               CauchoDocument doc,
486                               Templates JavaDoc stylesheet,
487                               String JavaDoc varyName)
488     throws IOException JavaDoc, ServletException JavaDoc
489   {
490     // changing paramNames changes the varyName
491
varyName = generateVaryName(req);
492
493     String JavaDoc className = getClassName(varyName);
494
495     try {
496       return getJspPage(doc, stylesheet, req, res, className);
497     } catch (TransformerConfigurationException JavaDoc e) {
498       throw new ServletException JavaDoc(e);
499     } catch (JspException JavaDoc e) {
500       throw new ServletException JavaDoc(e);
501     }
502   }
503
504   /**
505    * Mangles the classname
506    */

507   private String JavaDoc getClassName(String JavaDoc varyName)
508   {
509     if (varyName == null)
510       return _className;
511     else
512       return _className + JavaCompiler.mangleName("?" + varyName);
513   }
514
515   /**
516    * Generates a unique string for the variable parameters. The parameters
517    * depend on:
518    * <ul>
519    * <li>The value of caucho.xsl.stylesheet selecting the stylesheet.
520    * <li>The top-level xsl:param variables, which use request parameters.
521    * <li>The request's path-info.
522    * </ul>
523    *
524    * @param req the page request.
525    *
526    * @return a unique string encoding the important variations of the request.
527    */

528   private String JavaDoc generateVaryName(CauchoRequest req)
529   {
530     CharBuffer cb = CharBuffer.allocate();
531
532     String JavaDoc ss = (String JavaDoc) req.getAttribute("caucho.xsl.stylesheet");
533
534     if (ss == null && (_paramNames == null || _paramNames.size() == 0))
535       return null;
536
537     if (ss != null) {
538       cb.append("ss.");
539       cb.append(ss);
540     }
541     
542     for (int i = 0; _paramNames != null && i < _paramNames.size(); i++) {
543       String JavaDoc name = (String JavaDoc) _paramNames.get(i);
544
545       String JavaDoc value;
546
547       if (name.equals("xtp:path_info"))
548         value = req.getPathInfo();
549       else
550         value = req.getParameter(name);
551       
552       cb.append(".");
553       cb.append(name);
554       
555       if (value != null) {
556         cb.append(".");
557         cb.append(value);
558       }
559     }
560
561     if (cb.length() == 0)
562       return null;
563
564     if (cb.length() < 64)
565       return cb.close();
566
567     long hash = 37;
568     for (int i = 0; i < cb.length(); i++)
569       hash = 65521 * hash + cb.charAt(i);
570
571     cb.setLength(32);
572     Base64.encode(cb, hash);
573
574     return cb.close();
575   }
576
577   /**
578    * Compile a JSP page.
579    *
580    * @param doc the parsed Serif page.
581    * @param stylesheet the stylesheet
582    * @param req the servlet request
583    * @param res the servlet response
584    * @param className the className of the generated page
585    *
586    * @return the compiled JspPage
587    */

588   private Page getJspPage(CauchoDocument doc, Templates JavaDoc stylesheet,
589                           CauchoRequest req, CauchoResponse res,
590               String JavaDoc className)
591     throws IOException JavaDoc, ServletException JavaDoc, JspException JavaDoc, TransformerConfigurationException JavaDoc
592   {
593     Path workDir = _jspManager.getClassDir();
594     String JavaDoc fullClassName = className;
595     Path path = workDir.lookup(fullClassName.replace('.', '/') + ".jsp");
596     path.getParent().mkdirs();
597
598     Properties JavaDoc output = stylesheet.getOutputProperties();
599     
600     String JavaDoc encoding = (String JavaDoc) output.get(OutputKeys.ENCODING);
601     String JavaDoc mimeType = (String JavaDoc) output.get(OutputKeys.MEDIA_TYPE);
602     String JavaDoc method = (String JavaDoc) output.get(OutputKeys.METHOD);
603
604     if (method == null || encoding != null) {
605     }
606     else if (method.equals("xml"))
607       encoding = "UTF-8";
608
609     javax.xml.transform.Transformer JavaDoc transformer;
610     transformer = stylesheet.newTransformer();
611       
612     for (int i = 0; _paramNames != null && i < _paramNames.size(); i++) {
613       String JavaDoc param = (String JavaDoc) _paramNames.get(i);
614
615       transformer.setParameter(param, req.getParameter(param));
616     }
617
618     String JavaDoc contextPath = req.getContextPath();
619     if (contextPath != null && ! contextPath.equals(""))
620       transformer.setParameter("xtp:context_path", contextPath);
621
622     String JavaDoc servletPath = req.getServletPath();
623     if (servletPath != null && ! servletPath.equals(""))
624       transformer.setParameter("xtp:servlet_path", servletPath);
625
626     String JavaDoc pathInfo = req.getPathInfo();
627     if (pathInfo != null && ! pathInfo.equals(""))
628       transformer.setParameter("xtp:path_info", pathInfo);
629
630     transformer.setOutputProperty("caucho.jsp", "true");
631
632     LineMap lineMap = null;
633     WriteStream os = path.openWrite();
634     try {
635       if (encoding != null) {
636         os.setEncoding(encoding);
637         if (mimeType == null)
638           mimeType = "text/html";
639       
640         os.print("<%@ page contentType=\"" + mimeType + "; charset=" +
641                  encoding + "\" %>");
642       }
643       else if (mimeType != null)
644         os.print("<%@ page contentType=\"" + mimeType + "\" %>");
645     
646       lineMap = writeJspDoc(os, doc, transformer, req, res);
647     } finally {
648       os.close();
649     }
650
651     StylesheetImpl ss = null;
652     if (stylesheet instanceof StylesheetImpl)
653       ss = (StylesheetImpl) stylesheet;
654
655     try {
656       path.setUserPath(_sourcePath.getPath());
657       
658       boolean cacheable = true; // jspDoc.isCacheable();
659
ArrayList JavaDoc<PersistentDependency> depends =
660         new ArrayList JavaDoc<PersistentDependency>();
661
662       ArrayList JavaDoc<Depend> styleDepends = null;
663       if (ss != null)
664         styleDepends = (ArrayList JavaDoc) ss.getProperty(StylesheetImpl.DEPENDS);
665       for (int i = 0; styleDepends != null && i < styleDepends.size(); i++) {
666         Depend depend = styleDepends.get(i);
667
668         Depend jspDepend = new Depend(depend.getPath(),
669                                       depend.getLastModified(),
670                                       depend.getLength());
671         jspDepend.setRequireSource(true);
672
673         if (! depends.contains(jspDepend))
674           depends.add(jspDepend);
675       }
676
677       // Fill the page dependency information from the document into
678
// the jsp page.
679
ArrayList JavaDoc<Path> docDepends;
680       docDepends = (ArrayList JavaDoc) doc.getProperty(CauchoDocument.DEPENDS);
681       for (int i = 0; docDepends != null && i < docDepends.size(); i++) {
682         Path depend = docDepends.get(i);
683
684         Depend jspDepend = new Depend(depend);
685         if (! depends.contains(jspDepend))
686           depends.add(jspDepend);
687       }
688
689       // stylesheet cache dependencies are normal dependencies for JSP
690
ArrayList JavaDoc<Path> cacheDepends = null;
691       TransformerImpl xform = null;
692       if (transformer instanceof TransformerImpl)
693         xform = (TransformerImpl) transformer;
694       if (xform != null)
695         cacheDepends = (ArrayList JavaDoc) xform.getProperty(TransformerImpl.CACHE_DEPENDS);
696       for (int i = 0; cacheDepends != null && i < cacheDepends.size(); i++) {
697         Path depend = cacheDepends.get(i);
698         Depend jspDepend = new Depend(depend);
699         if (! depends.contains(jspDepend))
700           depends.add(jspDepend);
701       }
702
703       Page page = _jspManager.createGeneratedPage(path, _uri, className, depends);
704       
705       return page;
706     } catch (IOException JavaDoc e) {
707       throw e;
708     } catch (ServletException JavaDoc e) {
709       throw e;
710     } catch (Exception JavaDoc e) {
711       throw new QJspException(e);
712     }
713   }
714
715   /**
716    * Transform XTP page with the stylesheet to JSP source.
717    *
718    * @param os the output stream to the generated JSP.
719    * @param doc the parsed XTP file.
720    * @param transformed the XSL stylesheet with parameters applied.
721    * @param req the servlet request.
722    * @param res the servlet response.
723    *
724    * @return the line map from the JSP to the original source.
725    */

726   private LineMap writeJspDoc(WriteStream os,
727                               Document doc,
728                               javax.xml.transform.Transformer JavaDoc transformer,
729                               CauchoRequest req,
730                               CauchoResponse res)
731     throws IOException JavaDoc, ServletException JavaDoc
732   {
733     PageContext JavaDoc pageContext;
734
735     JspFactory JavaDoc factory = JspFactory.getDefaultFactory();
736
737     TransformerImpl xform = null;
738     if (transformer instanceof TransformerImpl)
739       xform = (TransformerImpl) transformer;
740     String JavaDoc errorPage = null;
741     if (xform != null)
742       errorPage = (String JavaDoc) xform.getProperty("caucho.error.page");
743     pageContext = factory.getPageContext(this,
744                      req, res,
745                                          errorPage,
746                      false,
747                      8192, // bufferSize,
748
false); // autoFlush);
749

750     try {
751       if (xform != null) {
752         xform.setProperty("caucho.page.context", pageContext);
753         xform.setProperty("caucho.pwd", Vfs.lookup());
754       }
755
756       DOMSource JavaDoc source = new DOMSource JavaDoc(doc);
757       StreamResult JavaDoc result = new StreamResult JavaDoc(os);
758
759       xform.setFeature(TransformerImpl.GENERATE_LOCATION, true);
760       transformer.transform(source, result);
761
762       if (xform != null)
763         return (LineMap) xform.getProperty(TransformerImpl.LINE_MAP);
764       else
765         return null;
766     } catch (Exception JavaDoc e) {
767       pageContext.handlePageException(e);
768     } finally {
769       factory.releasePageContext(pageContext);
770     }
771
772     return null;
773   }
774
775   /**
776    * Returns the stylesheet specified by the page.
777    *
778    * The syntax is:
779    * <pre>
780    * &lt;?xml-stylesheet HREF='...' media='...'?>
781    * </pre>
782    *
783    * @param doc the XTP document
784    * @param media the http request media
785    *
786    * @return the href of the xml-stylesheet processing-instruction or
787    * "default.xsl" if none is found.
788    */

789   private String JavaDoc getStylesheetHref(Document doc, String JavaDoc media)
790     throws XPathException
791   {
792     Iterator JavaDoc iter = XPath.select("//processing-instruction('xml-stylesheet')",
793                  doc);
794     while (iter.hasNext()) {
795       ProcessingInstruction JavaDoc pi = (ProcessingInstruction JavaDoc) iter.next();
796       String JavaDoc value = pi.getNodeValue();
797       String JavaDoc piMedia = XmlUtil.getPIAttribute(value, "media");
798       
799       if (piMedia == null || piMedia.equals(media))
800     return XmlUtil.getPIAttribute(value, "href");
801     }
802
803     return "default.xsl"; // xslManager.getDefaultStylesheet();
804
}
805
806   /**
807    * Returns true if the document varies according to the "media".
808    * (Currently unused.)
809    */

810   private boolean varyMedia(Document doc)
811     throws XPathException
812   {
813     Iterator JavaDoc iter = XPath.select("//processing-instruction('xml-stylesheet')",
814                  doc);
815     while (iter.hasNext()) {
816       ProcessingInstruction JavaDoc pi = (ProcessingInstruction JavaDoc) iter.next();
817       String JavaDoc value = pi.getNodeValue();
818       String JavaDoc piMedia = XmlUtil.getPIAttribute(value, "media");
819       
820       if (piMedia != null)
821     return true;
822     }
823
824     return false;
825   }
826
827   public boolean disableLog()
828   {
829     return true;
830   }
831
832   /**
833    * Returns a printable version of the page object
834    */

835   public String JavaDoc toString()
836   {
837     return "XtpPage[" + _uri + "]";
838   }
839 }
840
Popular Tags