<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>SVG Essentials/Serving SVG Files - Revision history</title>
		<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;action=history</link>
		<description>Revision history for this page on the wiki</description>
		<language>en</language>
		<generator>MediaWiki 1.11.0</generator>
		<lastBuildDate>Wed, 22 May 2013 00:42:28 GMT</lastBuildDate>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=7379&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 13:40, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 13:40:50 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=6044&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 12:51, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 12:51:41 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=3718&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 23:40, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 23:40:41 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=3717&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 23:33, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 23:33:32 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=3259&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:52, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:52:50 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=3258&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:38, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:38:57 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=2673&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:22, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:22:10 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=2672&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:21, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 11:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 11:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-1. Screenshot of web page'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-1. Screenshot of web page'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_13_tt315&lt;/del&gt;.png|Screenshot of web page]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_13_tt315&lt;/ins&gt;.png|Screenshot of web page]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 19:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 19:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-2. Screenshot of resulting graphic'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-2. Screenshot of resulting graphic'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_13_tt316&lt;/del&gt;.png|Screenshot of resulting graphic]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_13_tt316&lt;/ins&gt;.png|Screenshot of resulting graphic]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 238:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 238:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-3. Information flow of Transform servlet'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-3. Information flow of Transform servlet'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_13_tt318&lt;/del&gt;.png|Information flow of Transform servlet]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_13_tt318&lt;/ins&gt;.png|Information flow of Transform servlet]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 616:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 616:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-4. Screenshot of error image'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 13-4. Screenshot of error image'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_13_tt327&lt;/del&gt;.png|Screenshot of error image]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_13_tt327&lt;/ins&gt;.png|Screenshot of error image]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wikicontent:diff:version:1.11a:oldid:2427:newid:2672 --&gt;
&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:21:01 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Serving_SVG_Files&amp;diff=2427&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{SVG Essentials/TOC}}&lt;br /&gt;
In most of the preceding chapters, we have presented a general view of SVG and have tried to be application-agnostic. The techniques you've seen can be applied to diagrams destined for print, for conversion of legacy data to a more transportable format, and, of course, for web graphics. In this chapter, we will consider the problem of accessing data in XML format, transforming it to SVG, and then sending it to a client on the Web.&lt;br /&gt;
&lt;br /&gt;
== Serving Web Files -- The Task at Hand ==&lt;br /&gt;
&lt;br /&gt;
We will present a list of airports on a web page, and let the users select one whose weather report they wish to see. The request will be sent to a Java servlet, which will retrieve the information in Weather Observation Markup Format (OMF) and send back a web page containing a graphic presentation of the data. Though SVG is the most compact representation — and this is a book about SVG, after all — some users may not have an SVG plugin for their browsers. Thus, we will offer them a choice of receiving the graphic in SVG or in one of two rasterized formats: PNG (Portable Network Graphics) or JPG. We offer JPG for users with older browsers that don't support PNG. The web page is shown in [[SVG Essentials/Serving SVG Files#svgess-CHP-13-FIG-1|Figure 13-1]].&lt;br /&gt;
&lt;br /&gt;
This example uses a servlet without explaining the servlet mechanism in any great detail. You can find that information in ''Java Servlet Programming'' by Jason Hunter and William Crawford, published by O'Reilly &amp;amp; Associates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-13-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 13-1. Screenshot of web page'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_13_tt315.png|Screenshot of web page]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting graphic will be a modified form of the graphic presented in [[SVG Essentials/Generating SVG|Chapter 12]], in [[SVG Essentials/Generating SVG#Using XSLT to Convert XML Data to SVG|Section 12.3]], showing the city name, time, temperature, wind speed and direction, and visibility. The most important modification is that the graphic will show the local time, rather than Greenwich Mean Time, which is the format for the original data. [[SVG Essentials/Serving SVG Files#svgess-CHP-13-FIG-2|Figure 13-2]] shows one such result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-13-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 13-2. Screenshot of resulting graphic'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_13_tt316.png|Screenshot of resulting graphic]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Partitioning the Task ==&lt;br /&gt;
&lt;br /&gt;
Our task can be broken down into three major subtasks: creating the web page, writing the servlet itself, and constructing the XSLT file that the servlet will use.&lt;br /&gt;
&lt;br /&gt;
=== The Request Web Page ===&lt;br /&gt;
&lt;br /&gt;
[[SVG Essentials/Serving SVG Files#svgess-CHP-13-EX-1|Example 13-1]] is a listing of the HTML for the web page. The &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt; of each select menu option consists of the four-letter station ID, city name, and time zone, separated by vertical bars. The time zone is chosen from the list provided by Java's &amp;lt;tt&amp;gt;java.util.TimeZone.getAvailableIDs()&amp;lt;/tt&amp;gt; function. The &amp;lt;tt&amp;gt;action&amp;lt;/tt&amp;gt; attribute points to the servlet running on &amp;lt;tt&amp;gt;localhost&amp;lt;/tt&amp;gt;; you will change this depending on the server, server software, and servlet container you're using.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-13-EX-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 13-1. HTML form for requesting OMF information'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;OMF to SVG&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;OMF Graphic Display&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;get&amp;quot;&lt;br /&gt;
 action=&amp;quot;http://localhost:8080/omf_j/servlet/Weather&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
See weather for:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select name=&amp;quot;call_id&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;----|-----|----&amp;quot;&amp;gt;Choose an airport&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;SABE|Buenos Aires, Argentina|America/Buenos_Aires&amp;quot;&amp;gt;&lt;br /&gt;
    Buenos Aires, Argentina&lt;br /&gt;
&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;KORD|Chicago/O'Hare|America/Chicago&amp;quot;&amp;gt;&lt;br /&gt;
    Chicago/O'Hare&lt;br /&gt;
&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;!-- etc. --&amp;gt;&lt;br /&gt;
&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;KSJC|San Jose|America/Los_Angeles&amp;quot;&amp;gt;&lt;br /&gt;
    San Jose, California&lt;br /&gt;
&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;RKSS|Seoul/Kimp'o|Asia/Seoul&amp;quot;&amp;gt;&lt;br /&gt;
    Seoul/Kimp'o&lt;br /&gt;
&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;YSSY|Sydney, Australia|Australia/Sydney&amp;quot;&amp;gt;&lt;br /&gt;
    Sydney, Australia&lt;br /&gt;
&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Format: &lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;imgtype&amp;quot; value=&amp;quot;SVG&amp;quot;&lt;br /&gt;
    checked=&amp;quot;checked&amp;quot; /&amp;gt; SVG &lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;imgtype&amp;quot; value=&amp;quot;JPG&amp;quot; /&amp;gt; JPG &lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;imgtype&amp;quot; value=&amp;quot;PNG&amp;quot; /&amp;gt; PNG &lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Show Weather Graphic&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Weather Servlet ===&lt;br /&gt;
&lt;br /&gt;
Let us now turn our attention to the Java servlet, &amp;lt;tt&amp;gt;Weather&amp;lt;/tt&amp;gt;, that creates the web page on which the image will appear. This servlet merely creates HTML; it doesn't create the image itself. Instead, it will create an &amp;lt;tt&amp;gt;&amp;lt;embed&amp;gt;&amp;lt;/tt&amp;gt; tag (or &amp;lt;tt&amp;gt;&amp;lt;img&amp;gt;&amp;lt;/tt&amp;gt; tag) whose &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; attribute will be a reference to the &amp;lt;tt&amp;gt;Transform&amp;lt;/tt&amp;gt; servlet that does the actual transformation. There are two reasons to do this: First, most applications create a web page with an image rather than returning an image alone. Second, returning only an image causes caching problems with some browsers; returning a web page doesn't. The source code for the servlet is listed in [[SVG Essentials/Serving SVG Files#svgess-CHP-13-EX-2|Example 13-2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-13-EX-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 13-2. Weather.java, a servlet for creating a web page'''&lt;br /&gt;
&lt;br /&gt;
 import java.io.*;&lt;br /&gt;
 import java.text.*;&lt;br /&gt;
 import java.util.*;&lt;br /&gt;
 &lt;br /&gt;
 import java.net.URLEncoder;     '''[1]'''&lt;br /&gt;
 import javax.servlet.*;&lt;br /&gt;
 import javax.servlet.http.*;&lt;br /&gt;
 &lt;br /&gt;
 public class Weather extends HttpServlet {&lt;br /&gt;
 &lt;br /&gt;
     ResourceBundle rb =     '''[2]'''&lt;br /&gt;
         ResourceBundle.getBundle(&amp;quot;TransformFileStrings&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     public void doPost(HttpServletRequest request,&lt;br /&gt;
         HttpServletResponse response)&lt;br /&gt;
         throws ServletException, IOException&lt;br /&gt;
     {&lt;br /&gt;
 &lt;br /&gt;
         PrintWriter out = response.getWriter();&lt;br /&gt;
             &lt;br /&gt;
         try&lt;br /&gt;
         {&lt;br /&gt;
             response.setContentType(&amp;quot;text/html&amp;quot;);     '''[3]'''&lt;br /&gt;
             response.setHeader(&amp;quot;Cache-Control&amp;quot;,&lt;br /&gt;
                 &amp;quot;no-cache, no-store, must-revalidate&amp;quot;);&lt;br /&gt;
             response.setHeader(&amp;quot;Cache-Control&amp;quot;,&lt;br /&gt;
                 &amp;quot;post-check=0, pre-check=0&amp;quot;);&lt;br /&gt;
             String agent = &lt;br /&gt;
                 request.getHeader(&amp;quot;User-Agent&amp;quot;).toLowerCase();&lt;br /&gt;
         &lt;br /&gt;
             // netscape chokes on Pragma no-cache so only&lt;br /&gt;
             // send it to explorer&lt;br /&gt;
             if (agent.indexOf(&amp;quot;explorer&amp;quot;) &amp;gt; -1){&lt;br /&gt;
               response.setHeader(&amp;quot;Pragma&amp;quot;, &amp;quot;no-cache&amp;quot;);&lt;br /&gt;
             }&lt;br /&gt;
             response.setHeader(&amp;quot;Expires&amp;quot;,&lt;br /&gt;
                 &amp;quot;Thu, 01 Dec 1994 16:00:00 GMT&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
             String params = request.getParameter( &amp;quot;call_id&amp;quot; );     '''[4]'''&lt;br /&gt;
             String referer = request.getHeader( &amp;quot;Referer&amp;quot; );&lt;br /&gt;
 &lt;br /&gt;
             /* if no airport chosen, return to caller */&lt;br /&gt;
             if ( params.startsWith(&amp;quot;----&amp;quot;) &amp;amp;&amp;amp; (referer != null) )&lt;br /&gt;
             {&lt;br /&gt;
                 response.setStatus( response.SC_MOVED_TEMPORARILY );&lt;br /&gt;
                 response.setHeader( &amp;quot;Location&amp;quot;, referer );&lt;br /&gt;
                 return;&lt;br /&gt;
             }&lt;br /&gt;
             &lt;br /&gt;
             StringTokenizer info = new StringTokenizer( params, &amp;quot;|&amp;quot; );      '''[5]'''&lt;br /&gt;
             info.nextToken();   /* we don't need the station ID */&lt;br /&gt;
             String cityName = info.nextToken();&lt;br /&gt;
             &lt;br /&gt;
             String imgType = request.getParameter( &amp;quot;imgtype&amp;quot; );&lt;br /&gt;
             &lt;br /&gt;
             String transformURL = rb.getString( &amp;quot;transformURL&amp;quot; );&lt;br /&gt;
 &lt;br /&gt;
             out.println(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;quot; +&lt;br /&gt;
                 cityName + &amp;quot;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;);&lt;br /&gt;
             out.println(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
             if (referer != null)        '''[6]'''&lt;br /&gt;
             {&lt;br /&gt;
                 out.println(&amp;quot;&amp;amp;lt;p&amp;gt;&amp;lt;a href=\&amp;quot;&amp;quot; +&lt;br /&gt;
                     request.getHeader(&amp;quot;Referer&amp;quot;) +&lt;br /&gt;
                     &amp;quot;\&amp;quot;&amp;gt;Back&amp;lt;/a&amp;gt;&amp;amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;
             }&lt;br /&gt;
             &lt;br /&gt;
             /* &lt;br /&gt;
              * Construct parameters to pass to Transform servlet.&lt;br /&gt;
              * The servlet request.getParameter function decoded&lt;br /&gt;
              * the information, so we must re-encode it.&lt;br /&gt;
             */&lt;br /&gt;
             params = &amp;quot;call_id=&amp;quot; + java.net.URLEncoder.encode(params) +&lt;br /&gt;
                 &amp;quot;&amp;amp;imgtype=&amp;quot; + imgType;&lt;br /&gt;
 &lt;br /&gt;
             if (imgType.equals(&amp;quot;SVG&amp;quot;))      '''[7]'''&lt;br /&gt;
             {&lt;br /&gt;
                 out.println(&amp;quot;&amp;amp;lt;p&amp;gt;&amp;lt;embed width=\&amp;quot;350\&amp;quot; height=\&amp;quot;200\&amp;quot; &amp;quot; +&lt;br /&gt;
                     &amp;quot;type=\&amp;quot;image/svg+xml\&amp;quot; &amp;quot;);&lt;br /&gt;
                 out.println(&lt;br /&gt;
                     &amp;quot;src=\&amp;quot;&amp;quot; + transformURL +&lt;br /&gt;
                     &amp;quot;?&amp;quot; + params +&lt;br /&gt;
                     &amp;quot;\&amp;quot; /&amp;gt;&amp;amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;
             }&lt;br /&gt;
             else&lt;br /&gt;
             {&lt;br /&gt;
                 out.println(&amp;quot;&amp;amp;lt;p&amp;gt;&amp;lt;img width=\&amp;quot;350\&amp;quot; height=\&amp;quot;200\&amp;quot; &amp;quot;);&lt;br /&gt;
                 out.println(&lt;br /&gt;
                     &amp;quot;src=\&amp;quot;&amp;quot; + transformURL +&lt;br /&gt;
                     &amp;quot;?&amp;quot; + params +&lt;br /&gt;
                     &amp;quot;\&amp;quot; /&amp;gt;&amp;amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;
             }&lt;br /&gt;
             out.println(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         catch (Exception e)&lt;br /&gt;
         {&lt;br /&gt;
             out.println(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Error&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;quot;);&lt;br /&gt;
             out.println(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;);&lt;br /&gt;
             out.println(&amp;quot;&amp;amp;lt;p&amp;gt;Unable to extract information.&amp;amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;
             out.println(&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     public void doGet(HttpServletRequest request,     '''[8]'''&lt;br /&gt;
                       HttpServletResponse response)&lt;br /&gt;
         throws IOException, ServletException&lt;br /&gt;
     {&lt;br /&gt;
         doPost( request, response );&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[1]'''&amp;lt;/tt&amp;gt; Include all the connectivity and servlet routines.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[2]'''&amp;lt;/tt&amp;gt; For ease of modification, all the file names and URL names for both servlets are stored in a resource file, which looks like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
pathName=file:///home/httpd/html/omf_j/&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#   for Weather servlet&lt;br /&gt;
#&lt;br /&gt;
transformURL=http://localhost:8080/omf_j/servlet/Transform&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#   for Transform servlet&lt;br /&gt;
#&lt;br /&gt;
xslFileName=omf.xsl&lt;br /&gt;
svgErrFile=/home/httpd/html/omf_j/err.svg&lt;br /&gt;
imgErrFile=/home/httpd/html/omf_j/err.jpg&lt;br /&gt;
omfSource=http://&amp;lt;/nowiki&amp;gt;''url.of.omf.org''/get-obs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[3]'''&amp;lt;/tt&amp;gt; The servlet sets the content type for a web page (&amp;lt;tt&amp;gt;text/html&amp;lt;/tt&amp;gt;) and emits an inordinate amount of information to make sure the page doesn't get cached.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[4]'''&amp;lt;/tt&amp;gt; Retrieve the weather station call letters (&amp;lt;tt&amp;gt;call_id&amp;lt;/tt&amp;gt;) and the URL of the web page from which we were called (the &amp;lt;tt&amp;gt;referer&amp;lt;/tt&amp;gt;). The referrer, whose keyword was misspelled when the API was created, will be null if the user typed the URL in the browser's location bar rather than calling the servlet from an actual web page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[5]'''&amp;lt;/tt&amp;gt; Split out the city name from the &amp;lt;tt&amp;gt;call_id&amp;lt;/tt&amp;gt; parameter for use in the &amp;lt;tt&amp;gt;&amp;lt;title&amp;gt;&amp;lt;/tt&amp;gt; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[6]'''&amp;lt;/tt&amp;gt; If there was a referring page, create a link back to that page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[7]'''&amp;lt;/tt&amp;gt; Create the appropriate &amp;lt;tt&amp;gt;&amp;lt;object&amp;gt;&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;&amp;lt;img&amp;gt;&amp;lt;/tt&amp;gt; tag. Note that the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; attribute is a URL that will call the &amp;lt;tt&amp;gt;Transform&amp;lt;/tt&amp;gt; servlet, passing on to it all the parameters that we received in this servlet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[8]'''&amp;lt;/tt&amp;gt; If this servlet is called from a &amp;lt;tt&amp;gt;GET&amp;lt;/tt&amp;gt; request, handle it exactly the same as a &amp;lt;tt&amp;gt;POST&amp;lt;/tt&amp;gt; request.&lt;br /&gt;
&lt;br /&gt;
=== The Transform Servlet ===&lt;br /&gt;
&lt;br /&gt;
When the &amp;lt;tt&amp;gt;Weather&amp;lt;/tt&amp;gt; servlet is invoked, it will create a web page, one of whose tags will in turn invoke the &amp;lt;tt&amp;gt;Transform&amp;lt;/tt&amp;gt; servlet. This servlet has to retrieve the XML, transform it to SVG, possibly convert it to JPG or PNG format, and send it to the client, as shown in [[SVG Essentials/Serving SVG Files#svgess-CHP-13-FIG-3|Figure 13-3]]. We want a cross-platform, open source solution, so we will use Apache's Xalan processor for XSLT, and the Apache Batik project's transcoder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-13-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 13-3. Information flow of Transform servlet'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_13_tt318.png|Information flow of Transform servlet]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The servlet begins by importing a significant number of classes:&lt;br /&gt;
&lt;br /&gt;
 import java.io.*;&lt;br /&gt;
 import java.text.*;&lt;br /&gt;
 import java.util.*;&lt;br /&gt;
 &lt;br /&gt;
 import java.net.URL;&lt;br /&gt;
 import java.net.URLConnection;&lt;br /&gt;
 import java.net.URLEncoder;&lt;br /&gt;
 import java.net.URLDecoder;&lt;br /&gt;
 &lt;br /&gt;
 import javax.servlet.*;&lt;br /&gt;
 import javax.servlet.http.*;&lt;br /&gt;
 import javax.xml.transform.*;&lt;br /&gt;
 import javax.xml.transform.stream.StreamSource;&lt;br /&gt;
 import javax.xml.transform.stream.StreamResult;&lt;br /&gt;
 &lt;br /&gt;
 import org.apache.batik.transcoder.image.JPEGTranscoder;&lt;br /&gt;
 import org.apache.batik.transcoder.image.PNGTranscoder;&lt;br /&gt;
 import org.apache.batik.transcoder.TranscoderInput;&lt;br /&gt;
 import org.apache.batik.transcoder.TranscoderOutput;&lt;br /&gt;
 &lt;br /&gt;
 import org.xml.sax.helpers.XMLReaderFactory;&lt;br /&gt;
 &lt;br /&gt;
 import org.apache.xalan.templates.OutputProperties;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt; function will read the XSL transformation file, compile it, and store the result in the class variable &amp;lt;tt&amp;gt;xslTemplate&amp;lt;/tt&amp;gt;. This function is called only once, and the variable will persist throughout the servlet's lifetime. This means we don't have to re-parse the XSL file every time the servlet is called.&lt;br /&gt;
&lt;br /&gt;
 public class Transform extends HttpServlet {&lt;br /&gt;
 &lt;br /&gt;
     ResourceBundle rb =&lt;br /&gt;
         ResourceBundle.getBundle(&amp;quot;TransformFileStrings&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     private Templates xslTemplate;&lt;br /&gt;
 &lt;br /&gt;
     public void init(ServletConfig config) throws ServletException&lt;br /&gt;
     {&lt;br /&gt;
         String path;&lt;br /&gt;
         String title;&lt;br /&gt;
         &lt;br /&gt;
         path = rb.getString(&amp;quot;pathName&amp;quot;);&lt;br /&gt;
         title = rb.getString( &amp;quot;xslFileName&amp;quot; );&lt;br /&gt;
         super.init(config);&lt;br /&gt;
         try&lt;br /&gt;
         {&lt;br /&gt;
             //for storing a compiled and resuseable style sheet&lt;br /&gt;
             TransformerFactory factory =&lt;br /&gt;
                 TransformerFactory.newInstance();&lt;br /&gt;
             xslTemplate =&lt;br /&gt;
                 factory.newTemplates(new StreamSource(path + title));&lt;br /&gt;
         }&lt;br /&gt;
         catch (Exception ex)&lt;br /&gt;
         {&lt;br /&gt;
             xslTemplate = null;&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
This is followed by the main routine, &amp;lt;tt&amp;gt;doPost&amp;lt;/tt&amp;gt;. Of particular interest is the code in boldface, which passes the time zone string as a parameter to the XSLT file.&lt;br /&gt;
&lt;br /&gt;
 public void doPost(HttpServletRequest request,&lt;br /&gt;
     HttpServletResponse response)&lt;br /&gt;
     throws ServletException, IOException&lt;br /&gt;
 {&lt;br /&gt;
     StreamSource    xmlInput;&lt;br /&gt;
     StreamResult    svgOutput;&lt;br /&gt;
     StringWriter    svgWriter;&lt;br /&gt;
     String          svgString;&lt;br /&gt;
     String          stationID = &amp;quot;&amp;quot;;&lt;br /&gt;
     String          cityName = &amp;quot;&amp;quot;;&lt;br /&gt;
     String          timeZoneString =&amp;quot;&amp;quot;;&lt;br /&gt;
     String          retrievedXML = &amp;quot;&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
     /* If init failed, exit immediately */&lt;br /&gt;
     if (xslTemplate == null)&lt;br /&gt;
     {&lt;br /&gt;
         errorExit( request, response, &amp;quot;No template&amp;quot; );&lt;br /&gt;
         return;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     try&lt;br /&gt;
     {&lt;br /&gt;
         /* Split out information from the parameter */&lt;br /&gt;
         String temp;&lt;br /&gt;
         temp = request.getParameter( &amp;quot;call_id&amp;quot; );&lt;br /&gt;
         StringTokenizer info = new StringTokenizer( temp, &amp;quot;|&amp;quot; );&lt;br /&gt;
         stationID = info.nextToken();&lt;br /&gt;
         cityName = info.nextToken();&lt;br /&gt;
         timeZoneString = info.nextToken();&lt;br /&gt;
     }&lt;br /&gt;
     catch (Exception e)&lt;br /&gt;
     {&lt;br /&gt;
         errorExit( request, response, &amp;quot;Can't split parameters&amp;quot; );&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
      * The OMF source that we are using returns&lt;br /&gt;
      * an SVG document beginning with a &amp;lt;!DOCTYPE if there&lt;br /&gt;
      * is no error, or an HTML form document if it got&lt;br /&gt;
      * invalid input.&lt;br /&gt;
      */&lt;br /&gt;
     retrievedXML = getOMFReports( request, cityName, stationID );&lt;br /&gt;
     if (retrievedXML != null &amp;amp;&amp;amp;&lt;br /&gt;
      retrievedXML.startsWith(&amp;quot;&amp;lt;!DOC&amp;quot;))&lt;br /&gt;
     {&lt;br /&gt;
         try&lt;br /&gt;
         {&lt;br /&gt;
             xmlInput = new StreamSource(&lt;br /&gt;
                 new StringReader( retrievedXML )&lt;br /&gt;
             );&lt;br /&gt;
             &lt;br /&gt;
             /*&lt;br /&gt;
              * Create an XSLT Transformer based on our template,&lt;br /&gt;
              * make it output UTF, and pass it the time zone&lt;br /&gt;
              */&lt;br /&gt;
             Transformer transformer = xslTemplate.newTransformer();&lt;br /&gt;
             transformer.setOutputProperty(&amp;quot;encoding&amp;quot;, &amp;quot;UTF-8&amp;quot;);&lt;br /&gt;
             '''transformer.setParameter(&amp;quot;timeZone&amp;quot;, timeZoneString);'''&lt;br /&gt;
             &lt;br /&gt;
             /*&lt;br /&gt;
              * Transform the XML to SVG as one long&lt;br /&gt;
              * string.&lt;br /&gt;
              */&lt;br /&gt;
             svgWriter = new StringWriter( 2048 ); &lt;br /&gt;
             svgOutput = new StreamResult( svgWriter );&lt;br /&gt;
             transformer.transform(&lt;br /&gt;
                 xmlInput,&lt;br /&gt;
                 svgOutput&lt;br /&gt;
             );&lt;br /&gt;
 &lt;br /&gt;
             svgString = svgWriter.toString();&lt;br /&gt;
 &lt;br /&gt;
             /*&lt;br /&gt;
              * Send back the appropriate output given the&lt;br /&gt;
              * image type that the user requested.&lt;br /&gt;
              */&lt;br /&gt;
             if ( request.getParameter(&amp;quot;imgtype&amp;quot;).equals(&amp;quot;JPG&amp;quot;) )&lt;br /&gt;
             {&lt;br /&gt;
                 emitJPG( request, response, svgString );&lt;br /&gt;
             }&lt;br /&gt;
             else if (request.getParameter(&amp;quot;imgtype&amp;quot;).equals(&amp;quot;PNG&amp;quot;))&lt;br /&gt;
             {&lt;br /&gt;
                 emitPNG( request, response, svgString );&lt;br /&gt;
             }&lt;br /&gt;
             else&lt;br /&gt;
             {&lt;br /&gt;
                 emitSVG( request, response, svgString );&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
         catch (Exception e)&lt;br /&gt;
         {&lt;br /&gt;
             errorExit( request, response, e.getMessage() );&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
     else&lt;br /&gt;
     {&lt;br /&gt;
         errorExit( request, response, retrievedXML );&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * Treat get and post equivalently.&lt;br /&gt;
  */&lt;br /&gt;
 public void doGet(HttpServletRequest request,&lt;br /&gt;
                   HttpServletResponse response)&lt;br /&gt;
     throws IOException, ServletException&lt;br /&gt;
 {&lt;br /&gt;
     doPost( request, response );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Here's the routine that accesses the OMF source. The particular source we're using will only accept &amp;lt;tt&amp;gt;POST&amp;lt;/tt&amp;gt; requests; this code shows you how to do them. The OMF source we used while developing this chapter returns an XML file starting with a &amp;lt;tt&amp;gt;&amp;lt;!DOCTYPE ... &amp;gt;&amp;lt;/tt&amp;gt; if the input data is valid; otherwise it returns an HTML page with an error message.&lt;br /&gt;
&lt;br /&gt;
 private String getOMFReports( HttpServletRequest request,&lt;br /&gt;
     String cityName, String stationID )&lt;br /&gt;
 {&lt;br /&gt;
     URL url;&lt;br /&gt;
     URLConnection urlConn;&lt;br /&gt;
 &lt;br /&gt;
     DataOutputStream output;&lt;br /&gt;
     DataInputStream input;&lt;br /&gt;
 &lt;br /&gt;
     String  retrievedReport = null;&lt;br /&gt;
 &lt;br /&gt;
     try&lt;br /&gt;
     {&lt;br /&gt;
         /*&lt;br /&gt;
          * Open a URL connection to the OMF source URL&lt;br /&gt;
          */&lt;br /&gt;
         url = new URL( rb.getString(&amp;quot;omfSource&amp;quot;) );&lt;br /&gt;
         urlConn = url.openConnection();&lt;br /&gt;
 &lt;br /&gt;
         /*&lt;br /&gt;
          * We need to both send (output)&lt;br /&gt;
          * and receive (input) data&lt;br /&gt;
          * with this connection&lt;br /&gt;
          */&lt;br /&gt;
         urlConn.setDoOutput (true);&lt;br /&gt;
         urlConn.setDoInput (true);&lt;br /&gt;
  &lt;br /&gt;
         // Don't use any cached values&lt;br /&gt;
         urlConn.setUseCaches (false);&lt;br /&gt;
 &lt;br /&gt;
         // Specify the content type.&lt;br /&gt;
         urlConn.setRequestProperty(&amp;quot;Content-Type&amp;quot;,&lt;br /&gt;
             &amp;quot;application/x-www-form-urlencoded&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
         /*&lt;br /&gt;
          * No user interaction such as authentication&lt;br /&gt;
          * dialogs is needed here.&lt;br /&gt;
          */&lt;br /&gt;
         urlConn.setAllowUserInteraction(false);&lt;br /&gt;
 &lt;br /&gt;
         /*&lt;br /&gt;
          * Write the POST data; this OMF source&lt;br /&gt;
          * is ordinarily called from an HTML form;&lt;br /&gt;
          * we are filling in the call_id field and&lt;br /&gt;
          * faking the &amp;quot;Retrieve&amp;quot; submit button&lt;br /&gt;
          */&lt;br /&gt;
         output = new DataOutputStream (urlConn.getOutputStream ());&lt;br /&gt;
         String content = &amp;quot;do-retrieve=Retrieve&amp;amp;call_id=&amp;quot; +&lt;br /&gt;
             URLEncoder.encode( stationID );&lt;br /&gt;
         output.writeBytes (content);&lt;br /&gt;
         output.flush ();&lt;br /&gt;
         output.close ();&lt;br /&gt;
 &lt;br /&gt;
         /*&lt;br /&gt;
          * Get response data, appending it to a&lt;br /&gt;
          * string buffer.&lt;br /&gt;
          */&lt;br /&gt;
         input = new DataInputStream(urlConn.getInputStream ());&lt;br /&gt;
 &lt;br /&gt;
         StringBuffer strBuf = new StringBuffer(2048);&lt;br /&gt;
         String str;&lt;br /&gt;
         while (null != ((str = input.readLine())))&lt;br /&gt;
         {&lt;br /&gt;
             strBuf.append(str);&lt;br /&gt;
             strBuf.append(&amp;quot;\n&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
          *  If the result begins with &amp;lt;!DOCTYPE, it's good;&lt;br /&gt;
          *  otherwise, it's not.&lt;br /&gt;
          */&lt;br /&gt;
         retrievedReport = strBuf.toString();&lt;br /&gt;
         if (!retrievedReport.startsWith(&amp;quot;&amp;lt;!DOCTYPE&amp;quot;))&lt;br /&gt;
         {&lt;br /&gt;
             retrievedReport = &amp;quot;No reports available for &amp;quot; +&lt;br /&gt;
                 cityName + &amp;quot;.&amp;quot;;&lt;br /&gt;
         }&lt;br /&gt;
         input.close( );&lt;br /&gt;
     }&lt;br /&gt;
     catch (Exception e)&lt;br /&gt;
     {&lt;br /&gt;
         /*&lt;br /&gt;
          * We can get an exception when the connection&lt;br /&gt;
          * hits end of file; this test makes sure we&lt;br /&gt;
          * only report true errors.&lt;br /&gt;
          */&lt;br /&gt;
         if (e.getMessage() != null)&lt;br /&gt;
         {&lt;br /&gt;
             retrievedReport = null;&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
     return retrievedReport;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The following routine is a utility routine for sending header information back to the caller.&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Send back a header of the given contentType;&lt;br /&gt;
  * add lots of checks to avoid caching.&lt;br /&gt;
  */&lt;br /&gt;
 public void headerInfo( HttpServletRequest request,&lt;br /&gt;
     HttpServletResponse response, String contentType)&lt;br /&gt;
 {&lt;br /&gt;
     response.setContentType( contentType );&lt;br /&gt;
     response.setHeader(&amp;quot;Cache-Control&amp;quot;,&lt;br /&gt;
         &amp;quot;no-cache, no-store, must-revalidate&amp;quot;);&lt;br /&gt;
     response.setHeader(&amp;quot;Cache-Control&amp;quot;,&lt;br /&gt;
         &amp;quot;post-check=0, pre-check=0&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
      * Netscape has problems with Pragma: no-cache,&lt;br /&gt;
      * so only send it to Explorer.&lt;br /&gt;
      */&lt;br /&gt;
     String agent = request.getHeader(&amp;quot;User-Agent&amp;quot;).toLowerCase();&lt;br /&gt;
     if (agent.indexOf(&amp;quot;explorer&amp;quot;) &amp;gt; -1){&lt;br /&gt;
         response.setHeader(&amp;quot;Pragma&amp;quot;, &amp;quot;no-cache&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
     response.setHeader(&amp;quot;Expires&amp;quot;, &amp;quot;Thu, 01 Dec 1994 16:00:00 GMT&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Sending the SVG is trivial; it's already ready and waiting in a string.&lt;br /&gt;
&lt;br /&gt;
 public void emitSVG (  HttpServletRequest request,&lt;br /&gt;
     HttpServletResponse response, String svgString )&lt;br /&gt;
 {&lt;br /&gt;
     headerInfo( request, response, &amp;quot;image/svg+xml&amp;quot;);&lt;br /&gt;
     try {&lt;br /&gt;
 &lt;br /&gt;
         response.getWriter().write( svgString );&lt;br /&gt;
         response.getWriter().flush();&lt;br /&gt;
     }&lt;br /&gt;
     catch (Exception e)&lt;br /&gt;
     {&lt;br /&gt;
         e.printStackTrace();&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Sending back the JPG and PNG requires one extra step: invoking the appropriate Batik transcoder to convert the SVG into an array of bytes, which we send directly to the response's output stream. &amp;lt;tt&amp;gt;response.getWriter()&amp;lt;/tt&amp;gt; is used for text; &amp;lt;tt&amp;gt;response.getOutputStream()&amp;lt;/tt&amp;gt; is used for binary data.&lt;br /&gt;
&lt;br /&gt;
 public void emitJPG( HttpServletRequest request,&lt;br /&gt;
     HttpServletResponse response, String svgString )&lt;br /&gt;
 {&lt;br /&gt;
     headerInfo( request, response, &amp;quot;image/jpeg&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     JPEGTranscoder t = new JPEGTranscoder();&lt;br /&gt;
     t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,&lt;br /&gt;
                          new Float(.8));&lt;br /&gt;
 &lt;br /&gt;
     TranscoderInput input =&lt;br /&gt;
         new TranscoderInput( new StringReader(svgString) );&lt;br /&gt;
     try {&lt;br /&gt;
         TranscoderOutput output =&lt;br /&gt;
             new TranscoderOutput(response.getOutputStream());&lt;br /&gt;
         t.transcode(input, output);&lt;br /&gt;
         response.getOutputStream().close();&lt;br /&gt;
     }&lt;br /&gt;
     catch (Exception e)&lt;br /&gt;
     {&lt;br /&gt;
         e.printStackTrace();&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 public void emitPNG ( HttpServletRequest request,&lt;br /&gt;
     HttpServletResponse response, String svgString )&lt;br /&gt;
 {&lt;br /&gt;
     headerInfo( request, response, &amp;quot;image/png&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     PNGTranscoder t = new PNGTranscoder();&lt;br /&gt;
 &lt;br /&gt;
     TranscoderInput input =&lt;br /&gt;
         new TranscoderInput( new StringReader(svgString) );&lt;br /&gt;
     try {&lt;br /&gt;
         TranscoderOutput output =&lt;br /&gt;
             new TranscoderOutput(response.getOutputStream());&lt;br /&gt;
         t.transcode(input, output);&lt;br /&gt;
         response.getOutputStream().close();&lt;br /&gt;
     }&lt;br /&gt;
     catch (Exception e)&lt;br /&gt;
     {&lt;br /&gt;
         e.printStackTrace();&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We are now left with one interesting problem — handling errors. In the &amp;lt;tt&amp;gt;Weather&amp;lt;/tt&amp;gt; servlet, we were creating an HTML page, so the error trapping simply generated a different HTML page with the error message on it. In this case, though, the servlet is expecting image data, and sending back HTML text won't do. The client wants image data, so that's what we'll give it. If the user requested an SVG graphic, we'll send back the following &amp;quot;error image&amp;quot; from a text file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE svg PUBLIC &amp;quot;-//W3C//DTD SVG 1.0//EN&amp;quot;&lt;br /&gt;
    &amp;quot;http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;svg viewBox=&amp;quot;0 0 350 200&amp;quot; height=&amp;quot;200&amp;quot; width=&amp;quot;350&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;rect x=&amp;quot;1&amp;quot; y=&amp;quot;1&amp;quot; width=&amp;quot;348&amp;quot; height=&amp;quot;198&amp;quot;&lt;br /&gt;
        style=&amp;quot;fill: none; stroke: black;&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;text x=&amp;quot;175&amp;quot; y=&amp;quot;112&amp;quot;&lt;br /&gt;
        style=&amp;quot;font-size: 18pt; text-anchor: middle;&amp;quot;&amp;gt;&lt;br /&gt;
    Unable to retrieve data.&lt;br /&gt;
    &amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;/svg&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the user requested a JPG or PNG image, we'll send back a JPG version of the error image, shown at half size in [[SVG Essentials/Serving SVG Files#svgess-CHP-13-FIG-4|Figure 13-4]]. We send back a JPG image because that format is supported by even the oldest browsers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-13-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 13-4. Screenshot of error image'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_13_tt327.png|Screenshot of error image]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here's the code. Again, the SVG, being text, is sent to &amp;lt;tt&amp;gt;response.getWriter()&amp;lt;/tt&amp;gt;, and the JPG, being binary, is sent to &amp;lt;tt&amp;gt;response.getOutputStream()&amp;lt;/tt&amp;gt;. If there's any error during ''this'' process, we log the error and let the bits fall where they may.&lt;br /&gt;
&lt;br /&gt;
 public void errorExit( HttpServletRequest request,&lt;br /&gt;
     HttpServletResponse response, String msg )&lt;br /&gt;
 {&lt;br /&gt;
     try {&lt;br /&gt;
         if (request.getParameter( &amp;quot;imgtype&amp;quot; ).equals( &amp;quot;SVG&amp;quot; ))&lt;br /&gt;
         {&lt;br /&gt;
             response.setContentType(&amp;quot;image/svg+xml&amp;quot;);&lt;br /&gt;
             String title = rb.getString( &amp;quot;svgErrFile&amp;quot; );&lt;br /&gt;
             BufferedReader input =&lt;br /&gt;
                 new BufferedReader(new FileReader(title));&lt;br /&gt;
             String str;&lt;br /&gt;
             while (null != ((str = input.readLine())))&lt;br /&gt;
             {&lt;br /&gt;
                 response.getWriter().write( str );&lt;br /&gt;
             }&lt;br /&gt;
             input.close();&lt;br /&gt;
             response.getWriter().close();&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
             response.setContentType(&amp;quot;image/jpeg&amp;quot;);&lt;br /&gt;
             String title = rb.getString( &amp;quot;imgErrFile&amp;quot; );&lt;br /&gt;
             byte [] buffer = new byte[8192];&lt;br /&gt;
 &lt;br /&gt;
             FileInputStream input =&lt;br /&gt;
                 new FileInputStream( title );&lt;br /&gt;
             while (input.read( buffer ) &amp;gt;= 0)&lt;br /&gt;
             {&lt;br /&gt;
                 response.getOutputStream().write( buffer );&lt;br /&gt;
             }&lt;br /&gt;
             input.close();&lt;br /&gt;
             response.getOutputStream().close();&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
     catch (Exception e)&lt;br /&gt;
     {&lt;br /&gt;
         if (e.getMessage() != null)&lt;br /&gt;
         {&lt;br /&gt;
             log( &amp;quot;Cannot output error image&amp;quot; );&lt;br /&gt;
             log( e.getMessage() );&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== The XSLT File ===&lt;br /&gt;
&lt;br /&gt;
The XSLT file used to transform the OMF records to SVG has one major enhancement; it must receive the parameter that was passed to it in the &amp;lt;tt&amp;gt;doPost&amp;lt;/tt&amp;gt; method. Note that we give a default value of &amp;lt;tt&amp;gt;UTC&amp;lt;/tt&amp;gt; so that the result will show up in Greenwich Mean Time if no parameter is passed to the XSLT file.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;xsl:param name=&amp;quot;timeZone&amp;quot; select=&amp;quot;UTC&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The XSLT extensions we wrote in [[SVG Essentials/Generating SVG|Chapter 12]] in [[SVG Essentials/Generating SVG#Extending XSLT in Java|Section 12.3.4]] must also be modified to use the time zone parameter when returning the date and time. These extensions are in the ''XSLTUtils.java'' file, which will be compiled and stored in a file named ''XSLTUtils.jar'' (rather than ''TimeUtils.class'' as in the original example).&lt;br /&gt;
&lt;br /&gt;
 import java.util.Calendar;&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.TimeZone;&lt;br /&gt;
 import java.text.DateFormat;&lt;br /&gt;
 &lt;br /&gt;
 public class XSLTUtils&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
     public static String getDate(String timeStampString,&lt;br /&gt;
         String timeZoneString)&lt;br /&gt;
     {&lt;br /&gt;
         DateFormat d = DateFormat.getDateInstance();&lt;br /&gt;
         d.setTimeZone( TimeZone.getTimeZone( timeZoneString ));&lt;br /&gt;
         long milliseconds = Long.parseLong( timeStampString ) * 1000;&lt;br /&gt;
         return &lt;br /&gt;
             d.format(new Date(milliseconds));&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     public static Double getHour(String timeStampString,&lt;br /&gt;
         String timeZoneString)&lt;br /&gt;
     {&lt;br /&gt;
         long milliseconds = Long.parseLong( timeStampString ) * 1000;&lt;br /&gt;
         Calendar c = Calendar.getInstance(&lt;br /&gt;
             TimeZone.getTimeZone( timeZoneString ));&lt;br /&gt;
         c.setTime( new Date( milliseconds ) );&lt;br /&gt;
         return new Double( c.get( Calendar.HOUR_OF_DAY ) );&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     public static Double getMinute(String timeStampString,&lt;br /&gt;
         String timeZoneString)&lt;br /&gt;
     {&lt;br /&gt;
         long milliseconds = Long.parseLong( timeStampString ) * 1000;&lt;br /&gt;
         Calendar c = Calendar.getInstance(&lt;br /&gt;
             TimeZone.getTimeZone( timeZoneString ));&lt;br /&gt;
         c.setTime( new Date( milliseconds ) );&lt;br /&gt;
         return new Double( c.get( Calendar.MINUTE ) );&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The XSLT can then call upon these functions when drawing the clock and date.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;text font-size=&amp;quot;10pt&amp;quot; x=&amp;quot;345&amp;quot; y=&amp;quot;20&amp;quot; text-anchor=&amp;quot;end&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;xsl:value-of select=&amp;quot;java:XSLTUtils.getDate( $tstamp, $timeZone )&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/text&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;xsl:call-template name=&amp;quot;draw-time-and-clock&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;xsl:with-param name=&amp;quot;hour&amp;quot;&lt;br /&gt;
         select=&amp;quot;java:XSLTUtils.getHour( $tstamp, $timeZone )&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;xsl:with-param name=&amp;quot;minute&amp;quot;&lt;br /&gt;
         select=&amp;quot;java:XSLTUtils.getMinute( $tstamp, $timeZone )&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the Server ==&lt;br /&gt;
&lt;br /&gt;
We chose the Tomcat servlet container implementation from the Apache Software Foundation, found at ''http://jakarta.apache.org/index.html'', to run these servlets. As with all the other software mentioned in this appendix, it is cross-platform and open source. It can run as a standalone server, serving web pages, servlets, and JavaServer Pages. It can also be used in conjunction with the Apache web server, Microsoft's Internet Information Server (IIS), Microsoft's Personal Web Server, or Netscape's Netscape Enterprise Server.&amp;lt;ref&amp;gt;This isn't the only choice available. You can also use a Java-based delivery framework such as Cocoon, available from the Apache Software Foundation at ''http://xml.apache.org/cocoon/'', or the Perl-based AxKit system, available at ''http://217.158.50.178''.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We did our testing with Tomcat running in standalone mode on a Linux system. We changed the ''tomcat.sh'' shell script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;We explicitly set the &amp;lt;tt&amp;gt;JAVA_HOME&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;TOMCAT_HOME&amp;lt;/tt&amp;gt; variables:&lt;br /&gt;
&lt;br /&gt;
 JAVA_HOME=/usr/local/j2sdk1.3.0&lt;br /&gt;
 TOMCAT_HOME=/usr/local/jakarta-tomcat&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;To run our servlets, Tomcat's classpath needs access to Xalan and Xerces for the XSLT transformations, and it also needs access to the Batik .jar files. The normal Tomcat classpath setup is also in ''conf/tomcat.sh''. It saves your current &amp;lt;tt&amp;gt;CLASSPATH&amp;lt;/tt&amp;gt;, creates a new one with the paths that it wants, and then re-appends the classpath that you had specified. We modified that code to create a new classpath and entirely ignore the old one, which had some duplications and many unnecessary paths. Our changes are shown in boldface.&lt;br /&gt;
&lt;br /&gt;
 oldCP=$CLASSPATH&lt;br /&gt;
 unset CLASSPATH&lt;br /&gt;
 &lt;br /&gt;
 '''#'''&lt;br /&gt;
 '''# The latest versions of Xalan and Xerces which we'''&lt;br /&gt;
 '''# want to use must come first!'''&lt;br /&gt;
 '''#'''&lt;br /&gt;
 '''CLASSPATH=/usr/local/xmljar/xalan.jar:/usr/local/xmljar/xerces.jar'''&lt;br /&gt;
 '''CLASSPATH=${CLASSPATH}:/usr/local/xmljar/bsf.jar'''&lt;br /&gt;
 '''CLASSPATH=${CLASSPATH}:/usr/local/xmljar/XSLTUtils.jar'''&lt;br /&gt;
 &lt;br /&gt;
 '''#'''&lt;br /&gt;
 '''# Add all the .jar files in the Batik library'''&lt;br /&gt;
 '''# to the classpath'''&lt;br /&gt;
 '''#'''&lt;br /&gt;
 '''for i in /usr/local/batik/lib/* ; do'''&lt;br /&gt;
 '''  CLASSPATH=${CLASSPATH}:$i'''&lt;br /&gt;
 '''done'''&lt;br /&gt;
 &lt;br /&gt;
 '''#'''&lt;br /&gt;
 '''# Add all the .jar files in Tomcat's library directory'''&lt;br /&gt;
 '''# to the classpath. The &amp;quot;else&amp;quot; branch will never be'''&lt;br /&gt;
 '''# taken, but it's needed in Tomcat's code, so we decided'''&lt;br /&gt;
 '''# to leave it intact here'''&lt;br /&gt;
 '''#'''&lt;br /&gt;
 for i in ${TOMCAT_HOME}/lib/* ; do&lt;br /&gt;
   if [ &amp;quot;$CLASSPATH&amp;quot; != &amp;quot;&amp;quot; ]; then&lt;br /&gt;
     CLASSPATH=${CLASSPATH}:$i&lt;br /&gt;
   else&lt;br /&gt;
     CLASSPATH=$i&lt;br /&gt;
   fi&lt;br /&gt;
 done&lt;br /&gt;
 &lt;br /&gt;
 if [ -f ${JAVA_HOME}/lib/tools.jar ] ; then&lt;br /&gt;
    # We are probably in a JDK1.2 environment&lt;br /&gt;
    CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Backdoor classpath setting for development purposes when all classes&lt;br /&gt;
 # are compiled into a /classes dir and are not yet jarred.&lt;br /&gt;
 if [ -d ${TOMCAT_HOME}/classes ]; then&lt;br /&gt;
     CLASSPATH=${TOMCAT_HOME}/classes:${CLASSPATH}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 '''#  Ignore old classpath altogether'''&lt;br /&gt;
 '''#'''&lt;br /&gt;
 '''#if [ &amp;quot;$oldCP&amp;quot; != &amp;quot;&amp;quot; ]; then'''&lt;br /&gt;
 '''#    CLASSPATH=${CLASSPATH}:${oldCP}'''&lt;br /&gt;
 '''#fi'''&lt;br /&gt;
                &lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;We added a new context to the ''conf/server.xml'' so we could put our files in a directory other than the ''webapps/examples'' directory. We set &amp;lt;tt&amp;gt;reloadable&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; because we were doing a lot of recompiling and testing. In a production environment you would probably want to set this to &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt; to avoid the overhead of checking for updates every time a request comes to the server.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Context path=&amp;quot;/omf_j&amp;quot; &lt;br /&gt;
          docBase=&amp;quot;/home/httpd/html/omf_j&amp;quot; &lt;br /&gt;
          crossContext=&amp;quot;false&amp;quot;&lt;br /&gt;
          debug=&amp;quot;0&amp;quot; &lt;br /&gt;
          reloadable=&amp;quot;true&amp;quot; &amp;gt; &lt;br /&gt;
 &amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</description>
			<pubDate>Tue, 04 Mar 2008 22:37:00 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Serving_SVG_Files</comments>		</item>
	</channel>
</rss>