﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-junhong-随笔分类-java技术</title><link>http://www.blogjava.net/junhong/category/8231.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 22 Mar 2007 18:43:22 GMT</lastBuildDate><pubDate>Thu, 22 Mar 2007 18:43:22 GMT</pubDate><ttl>60</ttl><item><title>Thinking in java review 2</title><link>http://www.blogjava.net/junhong/archive/2006/06/28/55575.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Wed, 28 Jun 2006 09:46:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/06/28/55575.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/55575.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/06/28/55575.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/55575.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/55575.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1.     								The only place a label is useful in Java is right before an iteration								statement. And that means right before—it does no good to put any other								statement bet...&nbsp;&nbsp;<a href='http://www.blogjava.net/junhong/archive/2006/06/28/55575.html'>阅读全文</a><img src ="http://www.blogjava.net/junhong/aggbug/55575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-06-28 17:46 <a href="http://www.blogjava.net/junhong/archive/2006/06/28/55575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Thinking in java review</title><link>http://www.blogjava.net/junhong/archive/2006/06/27/55384.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Tue, 27 Jun 2006 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/06/27/55384.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/55384.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/06/27/55384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/55384.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/55384.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">1、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">Java<span style="">  </span></span>
				<span style="font-family: 宋体;">中所有的</span>
				<span lang="EN-US">member function </span>
				<span style="font-family: 宋体;">都是动态绑定</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">2、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">Java </span>
				<span style="font-family: 宋体;">中所有的对象都是通过</span>
				<span lang="EN-US">new </span>
				<span style="font-family: 宋体;">来动态产生</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">3、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span style="font-family: 宋体;">所有的容器</span>
				<span lang="EN-US">(collection)</span>
				<span style="font-family: 宋体;">和</span>
				<span lang="EN-US">Object array(</span>
				<span style="font-family: 宋体;">对象数组</span>
				<span lang="EN-US"> e.g String []str=new String[10]) </span>
				<span style="font-family: 宋体;">内都包含都是对象的</span>
				<span lang="EN-US">reference</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">4、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span style="font-family: 宋体;">在</span>
				<span lang="EN-US">java</span>
				<span style="font-family: 宋体;">中，</span>
				<span lang="EN-US">java</span>
				<span style="font-family: 宋体;">编译器有责任产生“将</span>
				<span lang="EN-US">stack </span>
				<span style="font-family: 宋体;">指针前后移动“的程序代码，所以</span>
				<span style="font-family: 宋体;">它必须能够完全掌握它所编译的的程序中“存在</span>
				<span lang="EN-US">stack </span>
				<span style="font-family: 宋体;">里头的所有数据的实际大小和存活时间“，</span>
				<span style="font-family: 宋体;">如此一来便会限制程序的弹性。</span>
				<span style="font-family: 宋体;">由于这个限制，尽管我们可以将对象的</span>
				<span lang="EN-US">reference </span>
				<span style="font-family: 宋体;">存储与</span>
				<span lang="EN-US">stack</span>
				<span style="font-family: 宋体;">内，但却不能将一般的</span>
				<span lang="EN-US">java</span>
				<span style="font-family: 宋体;">对象放在</span>
				<span lang="EN-US">stack</span>
				<span style="font-family: 宋体;">中</span>
				<span lang="EN-US">
						<br />
				</span>
				<span style="font-family: 宋体;">特例：（</span>
				<span lang="EN-US">primitive
types</span>
				<span style="font-family: 宋体;">）</span>
				<span lang="EN-US">
						<br />
				</span>
				<span style="font-family: 宋体;">基本型别会经常被使用，如果使用</span>
				<span lang="EN-US">new </span>
				<span style="font-family: 宋体;">来产生此类极小，极简单的变量，会因“</span>
				<span lang="EN-US">new </span>
				<span style="font-family: 宋体;">将对象置于</span>
				<span lang="EN-US">heap</span>
				<span style="font-family: 宋体;">之上“</span>
				<span style="font-family: 宋体;">而效率不好。因此对于此类变量</span>
				<span lang="EN-US">java </span>
				<span style="font-family: 宋体;">采取</span>
				<span lang="EN-US">c/c++</span>
				<span style="font-family: 宋体;">的方式，也就是不用</span>
				<span lang="EN-US">new </span>
				<span style="font-family: 宋体;">分配器空间，而是产生一种所谓的</span>
				<span lang="EN-US">”automatic </span>
				<span style="font-family: 宋体;">“变量，存于</span>
				<span lang="EN-US"> static</span>
				<span style="font-family: 宋体;">中</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">5、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span style="font-family: 宋体;">当你产生某个存储对象的数组，真正产生的是个存储</span>
				<span lang="EN-US">reference </span>
				<span style="font-family: 宋体;">的数组。此数组建立之后，其中的每一个</span>
				<span lang="EN-US">reference</span>
				<span style="font-family: 宋体;">都会被自动设为某个特殊的值</span>
				<span lang="EN-US">null,</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">6、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">{ String s=new String(“ddd”);}
s</span>
				<span style="font-family: 宋体;">这个</span>
				<span lang="EN-US">reference </span>
				<span style="font-family: 宋体;">会在生存空间之外消失无踪，但是，</span>
				<span lang="EN-US">s</span>
				<span style="font-family: 宋体;">先前所指的那个</span>
				<span lang="EN-US">String</span>
				<span style="font-family: 宋体;">对象仍然会继续占用内存</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">7、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">Class </span>
				<span style="font-family: 宋体;">内的基本型别变量都有初值，但是在函数内的</span>
				<span lang="EN-US">local variable</span>
				<span style="font-family: 宋体;">是没有初值的</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">8、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">Java </span>
				<span style="font-family: 宋体;">中，所有传递的对象的场合，传递的都是对象的</span>
				<span lang="EN-US">reference.</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">9、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">Return </span>
				<span style="font-family: 宋体;">；</span>
				<span style="font-family: 宋体;">说明这个函数运行结束，返回到其调用函数。</span>
				<span lang="EN-US">Return 2</span>
				<span style="font-family: 宋体;">：返回一个数</span>
				<span lang="EN-US">2 </span>
				<span style="font-family: 宋体;">给调用者，同时结束本函数的运行。</span>
		</p>
		<p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">10、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">             
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">Class </span>
				<span style="font-family: 宋体;">内的</span>
				<span lang="EN-US"> non-static data(state) </span>
				<span style="font-family: 宋体;">和</span>
				<span lang="EN-US">method , </span>
				<span style="font-family: 宋体;">都是和特定的对象绑定的，一般情况下，你的产生某个对象，再通过该对象取用其数据和函数。所以</span>
				<span lang="EN-US">non-static </span>
				<span style="font-family: 宋体;">数据</span>
				<span lang="EN-US">/</span>
				<span style="font-family: 宋体;">函数必须知道他们隶属于哪一个对象，才有办法运行</span>
				<span lang="EN-US">.static </span>
				<span style="font-family: 宋体;">函数内不能使用</span>
				<span lang="EN-US">non-static </span>
				<span style="font-family: 宋体;">数据和函数</span>
		</p>
		<p class="MsoNormal" style="margin-left: 9pt; text-indent: -9pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">11、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">             
</span></span>
				</span>
				<!--[endif]-->
				<span lang="EN-US">(object1= = object2 ) </span>
				<span style="font-family: 宋体;">两个对象的</span>
				<span lang="EN-US">reference </span>
				<span style="font-family: 宋体;">的</span>
				<span lang="EN-US">= = </span>
				<span style="font-family: 宋体;">比较得是两个对象的内存的地址。所以我们不能使用</span>
				<span lang="EN-US">= = </span>
				<span style="font-family: 宋体;">来测试两个对象的内容是否相等。如果想测试对象的内容是否相等，应该使用</span>
				<span lang="EN-US">equal(),</span>
				<span style="font-family: 宋体;">任何一个对象都拥有这个函数。不过你自己的</span>
				<span lang="EN-US">class</span>
				<span style="font-family: 宋体;">需要</span>
				<span lang="EN-US">override</span>
				<span style="font-family: 宋体;">这个函数，否则默认的</span>
				<span lang="EN-US">equal()</span>
				<span style="font-family: 宋体;">函数是还是比较的两个对象的内存地址。</span>
				<span lang="EN-US">
						<br />
Java</span>
				<span style="font-family: 宋体;">标准程序库中的大多数</span>
				<span lang="EN-US">class</span>
				<span style="font-family: 宋体;">都</span>
				<span lang="EN-US">override </span>
				<span style="font-family: 宋体;">了</span>
				<span lang="EN-US">equal(),</span>
				<span style="font-family: 宋体;">所以他们都会比较对象的内容是否相等。</span>
		</p>
		<p class="MsoNormal" style="margin-left: 9pt; text-indent: -9pt;">
				<!--[if !supportLists]-->
				<span style="" lang="EN-US">
						<span style="">12、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">             
</span></span>
				</span>
				<!--[endif]-->
				<span style="font-family: 宋体;">位运算符都是作用于基本正数类型。该运算符主要是针对硬件编程使用（我们用得不多，）</span>
		</p>
		<p class="MsoNormal" style="margin-left: 9pt; text-indent: -9pt;">
				<span style="font-family: 宋体;">待续<br /></span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p><img src ="http://www.blogjava.net/junhong/aggbug/55384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-06-27 17:40 <a href="http://www.blogjava.net/junhong/archive/2006/06/27/55384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于输入框中显示双引号和单引号</title><link>http://www.blogjava.net/junhong/archive/2006/04/19/42026.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Wed, 19 Apr 2006 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/04/19/42026.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/42026.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/04/19/42026.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/42026.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/42026.html</trackback:ping><description><![CDATA[<table align="center" border="0" cellpadding="0" cellspacing="0" width="98%">
				<tbody>
						<tr>
								<td height="20">
										<br />
								</td>
						</tr>
						<tr>
								<td bgcolor="#e8e8e8" height="30">
										<div align="center">
												<font color="#ff0000" size="4">
														<strong>关于输入框中显示双引号和单引号</strong>
												</font>
										</div>
								</td>
						</tr>
						<tr>
								<td>
										<!--内容开始-->
              

		关于输入框中显示双引号和单引号
<br /><br />前台显示解决办法:
<br />方法一:
<br />单引号&lt;input type="text" value="'"&gt;
<br />双引号&lt;input type="text" value='"'&gt;
<br />方法二:
<br />单引号&lt;input type="text" value="&amp;#39;"&gt;
<br />双引号&lt;input type="text" value="&amp;#34;"&gt;
<br /><br /><br />从后台读取数据前台显示解决办法:
<br />我们从数据库中读取值到前台显示时应该加入转换
<br /><br />JavaScript版本:
<br /><br />&lt;% @Language="JavaScript" %&gt;
<br />&lt;%
<br />function ForamtValue(oStr)
<br />{
<br />    switch(typeof(oStr))
<br />    {
<br />        case "date"     :   
<br />            //直接toString()转换,可以加入丰富的显示方式
<br />            sStr = (new Date(oStr)).toString();
<br />            break;
<br />        default         :
<br />            sStr = String(oStr);
<br />    }
<br />    sStr = sStr.replace(/\"/g,"&amp;#34;"); //输入框中显示双引号问题
<br />    sStr = sStr.replace(/\'/g,"&amp;#39;"); //输入框中显示单引号问题
<br />    return sStr;
<br />}
<br />%&gt;
<br /><br />&lt;%
<br />//测试
<br />var str = "\"灰豆宝宝.net(魔幻季节)\"";
<br />var str = new Date();
<br />%&gt;
<br />&lt;br&gt;
<br />&lt;input type="text" value="&lt;%=str%&gt;" style="width:200px"&gt;[不能正常显示]&lt;br&gt;
<br />&lt;input type="text" value="&lt;%=ForamtValue(str)%&gt;" style="width:200px"&gt;[正常显示]&lt;br&gt;
<br /><br /><br />VBScript版本:
<br /><br />&lt;% @Language="VBScript" %&gt;
<br />&lt;%
<br />function ForamtValue(oStr)
<br />    Select Case VarType(oStr)
<br />        Case "vbDate"     
<br />            '直接toString()转换,可以加入丰富的显示方式
<br />            sStr = CDate(oStr)
<br />        Case Else        
<br />            sStr = CStr(oStr)
<br /> End Select
<br /> sStr = Replace(sStr,"""","&amp;#34;") '输入框中显示双引号问题
<br />    sStr = Replace(sStr,"'","&amp;#39;")  '输入框中显示单引号问题
<br />    ForamtValue = sStr
<br />End Function
<br />%&gt;
<br /><br />&lt;%
<br />'测试
<br />Dim str
<br />str = """'灰豆宝宝.net(魔幻季节)'"""
<br />%&gt;
<br />&lt;br&gt;
<br />&lt;input type="text" value="&lt;%=str%&gt;" style="width:200px"&gt;[不能正常显示]&lt;br&gt;
<br />&lt;input type="text" value="&lt;%=ForamtValue(str)%&gt;" style="width:200px"&gt;[正常显示]&lt;br&gt;
<br /></td>
						</tr>
				</tbody>
		</table><img src ="http://www.blogjava.net/junhong/aggbug/42026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-04-19 23:39 <a href="http://www.blogjava.net/junhong/archive/2006/04/19/42026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>how to use ant to deply your web application</title><link>http://www.blogjava.net/junhong/archive/2006/04/19/42008.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Wed, 19 Apr 2006 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/04/19/42008.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/42008.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/04/19/42008.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/42008.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/42008.html</trackback:ping><description><![CDATA[<font color="#ff0000">
		</font>
		<p>
				<font color="#ff0000">
						<br />First of all, if you develop your application by Eclipse, it means you have had the ant tool and you need not to download the internet.<br /><br /></font>
		</p>
		<h3>
				<font color="#ff0000">
						<a name="projects">
								<font size="4">Projects</font>
						</a>
				</font>
		</h3>
		<p>
				<font color="#ff0000">A <i>project</i> has three attributes:</font>
		</p>
		<p>
		</p>
		<table cellspacing="0" cellpadding="2" border="1">
				<tbody>
						<tr>
								<td valign="top">
										<b>Attribute</b>
								</td>
								<td valign="top">
										<b>Description</b>
								</td>
								<td valign="top" align="middle">
										<b>Required</b>
								</td>
						</tr>
						<tr>
								<td valign="top">name</td>
								<td valign="top">the name of the project.</td>
								<td valign="top" align="middle">No</td>
						</tr>
						<tr>
								<td valign="top">default</td>
								<td valign="top">the default target to use when no target is supplied.</td>
								<td valign="top" align="middle">No; however, <b>since Ant 1.6.0</b>, every project includes an implicit target that contains any and all top-level tasks and/or types. This target will always be executed as part of the project's initialization, even when Ant is run with the <a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/running.html#options"><font color="#0000ff">-projecthelp</font></a> option. </td>
						</tr>
						<tr>
								<td valign="top">basedir</td>
								<td valign="top">the base directory from which all path calculations are done. This attribute might be overridden by setting the "basedir" property beforehand. When this is done, it must be omitted in the project tag. If neither the attribute nor the property have been set, the parent directory of the buildfile will be used.</td>
								<td valign="top" align="middle">No</td>
						</tr>
				</tbody>
		</table>
		<p>
				<font color="#ff0000">
						<font color="#000000">Optionally, a description for the project can be provided as a top-level <code><font face="新宋体">&lt;description&gt;</font></code> element (see the </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/CoreTypes/description.html">
								<font color="#000000">description</font>
						</a>
						<font color="#000000">type).</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Each project defines one or more <i>targets</i>. A target is a set of <i>tasks</i> you want to be executed. When starting Ant, you can select which target(s) you want to have executed. When no target is given, the project's default is used.</font>
				</font>
		</p>
		<h3>
				<font color="#ff0000">
						<a name="targets">
								<font size="4">Targets</font>
						</a>
				</font>
		</h3>
		<p>
				<font color="#ff0000">
						<font color="#000000">A target can depend on other targets. You might have a target for compiling, for example, and a target for creating a distributable. You can only build a distributable when you have compiled first, so the distribute target <i>depends on</i> the compile target. Ant resolves these dependencies.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">It should be noted, however, that Ant's <code><font face="新宋体">depends</font></code> attribute only specifies the <i>order</i> in which targets should be executed - it does not affect whether the target that specifies the dependency(s) gets executed if the dependent target(s) did not (need to) run. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Ant tries to execute the targets in the <code><font face="新宋体">depends</font></code> attribute in the order they appear (from left to right). Keep in mind that it is possible that a target can get executed earlier when an earlier target depends on it:</font>
				</font>
		</p>
		<blockquote>
				<pre>
						<font color="#ff0000">
								<font color="#000000">&lt;target name="A"/&gt;<br />&lt;target name="B" depends="A"/&gt;<br />&lt;target name="C" depends="B"/&gt;<br />&lt;target name="D" depends="C,B,A"/&gt;</font>
						</font>
				</pre>
		</blockquote>
		<p>
				<font color="#ff0000">
						<font color="#000000">Suppose we want to execute target D. From its <code><font face="新宋体">depends</font></code> attribute, you might think that first target C, then B and then A is executed. Wrong! C depends on B, and B depends on A, so first A is executed, then B, then C, and finally D.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">In a chain of dependencies stretching back from a given target such as D above, each target gets executed only once, even when more than one target depends on it. Thus, executing the D target will first result in C being called, which in turn will first call B, which in turn will first call A. After A, then B, then C have executed, execution returns to the dependency list of D, which will <u>not</u> call B and A, since they were already called in process of dependency resolution for C and B respectively as dependencies of D. Had no such dependencies been discovered in processing C and B, B and A would have been executed after C in processing D's dependency list.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">A target also has the ability to perform its execution if (or unless) a property has been set. This allows, for example, better control on the building process depending on the state of the system (java version, OS, command-line property defines, etc.). To make a target <i>sense</i> this property, you should add the <code><font face="新宋体">if</font></code> (or <code><font face="新宋体">unless</font></code>) attribute with the name of the property that the target should react to. <strong>Note:</strong> Ant will only check whether the property has been set, the value doesn't matter. A property set to the empty string is still an existing property. For example:</font>
				</font>
		</p>
		<blockquote>
				<pre>
						<font color="#ff0000">
								<font color="#000000">&lt;target name="build-module-A" if="module-A-present"/&gt;</font>
						</font>
				</pre>
				<pre>
						<font color="#ff0000">
								<font color="#000000">&lt;target name="build-own-fake-module-A" unless="module-A-present"/&gt;</font>
						</font>
				</pre>
		</blockquote>
		<p>
				<font color="#ff0000">
						<font color="#000000">In the first example, if the <code><font face="新宋体">module-A-present</font></code> property is set (to any value), the target will be run. In the second example, if the <code><font face="新宋体">module-A-present</font></code> property is set (again, to any value), the target will not be run. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">If no <code><font face="新宋体">if</font></code> and no <code><font face="新宋体">unless</font></code> attribute is present, the target will always be executed.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">
								<b>Important:</b> the <code><font face="新宋体">if</font></code> and <code><font face="新宋体">unless</font></code> attributes only enable or disable the target to which they are attached. They do not control whether or not targets that a conditional target depends upon get executed. In fact, they do not even get evaluated until the target is about to be executed, and all its predecessors have already run. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">The optional <code><font face="新宋体">description</font></code> attribute can be used to provide a one-line description of this target, which is printed by the <nobr><code><font face="新宋体">-projecthelp</font></code></nobr> command-line option. Targets without such a description are deemed internal and will not be listed, unless either the <nobr><code><font face="新宋体">-verbose</font></code></nobr> or <nobr><code><font face="新宋体">-debug</font></code></nobr> option is used. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">It is a good practice to place your </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/CoreTasks/tstamp.html">
								<font color="#000000">tstamp</font>
						</a>
						<font color="#000000">tasks in a so-called <i>initialization</i> target, on which all other targets depend. Make sure that target is always the first one in the depends list of the other targets. In this manual, most initialization targets have the name <code><font face="新宋体">"init"</font></code>.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">If the depends attribute and the if/unless attribute are set, the depends attribute is executed first.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">A target has the following attributes:</font>
				</font>
		</p>
		<p>
		</p>
		<table cellspacing="0" cellpadding="2" border="1">
				<tbody>
						<tr>
								<td valign="top">
										<b>
												<font color="#000000">Attribute</font>
										</b>
								</td>
								<td valign="top">
										<b>
												<font color="#000000">Description</font>
										</b>
								</td>
								<td valign="top" align="middle">
										<b>
												<font color="#000000">Required</font>
										</b>
								</td>
						</tr>
						<tr>
								<td valign="top">
										<font color="#000000">name</font>
								</td>
								<td valign="top">
										<font color="#000000">the name of the target.</font>
								</td>
								<td valign="top" align="middle">
										<font color="#000000">Yes</font>
								</td>
						</tr>
						<tr>
								<td valign="top">
										<font color="#000000">depends</font>
								</td>
								<td valign="top">
										<font color="#000000">a comma-separated list of names of targets on which this target depends.</font>
								</td>
								<td valign="top" align="middle">
										<font color="#000000">No</font>
								</td>
						</tr>
						<tr>
								<td valign="top">
										<font color="#000000">if</font>
								</td>
								<td valign="top">
										<font color="#000000">the name of the property that must be set in order for this target to execute.</font>
								</td>
								<td valign="top" align="middle">
										<font color="#000000">No</font>
								</td>
						</tr>
						<tr>
								<td valign="top">
										<font color="#000000">unless</font>
								</td>
								<td valign="top">
										<font color="#000000">the name of the property that must not be set in order for this target to execute.</font>
								</td>
								<td valign="top" align="middle">
										<font color="#000000">No</font>
								</td>
						</tr>
						<tr>
								<td valign="top">
										<font color="#000000">description</font>
								</td>
								<td valign="top">
										<font color="#000000">a short description of this target's function.</font>
								</td>
								<td valign="top" align="middle">
										<font color="#000000">No</font>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<font color="#ff0000">
						<font color="#000000">
						</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">A target name can be any alphanumeric string valid in the encoding of the XML file. The empty string "" is in this set, as is comma "," and space " ". Please avoid using these, as they will not be supported in future Ant versions because of all the confusion they cause. IDE support of unusual target names, or any target name containing spaces, varies with the IDE.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Targets beginning with a hyphen such as <code><font face="新宋体">"-restart"</font></code> are valid, and can be used to name targets that should not be called directly from the command line.</font>
				</font>
		</p>
		<h3>
				<font color="#ff0000">
						<a name="tasks">
								<font color="#000000" size="4">Tasks</font>
						</a>
				</font>
		</h3>
		<p>
				<font color="#ff0000">
						<font color="#000000">A task is a piece of code that can be executed.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">A task can have multiple attributes (or arguments, if you prefer). The value of an attribute might contain references to a property. These references will be resolved before the task is executed.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Tasks have a common structure:</font>
				</font>
		</p>
		<blockquote>
				<pre>
						<font color="#ff0000">
								<font color="#000000">&lt;<i>name</i><i>attribute1</i>="<i>value1</i>" <i>attribute2</i>="<i>value2</i>" ... /&gt;</font>
						</font>
				</pre>
		</blockquote>
		<p>
				<font color="#ff0000">
						<font color="#000000">where <i>name</i> is the name of the task, <i>attributeN</i> is the attribute name, and <i>valueN</i> is the value for this attribute.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">There is a set of </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/coretasklist.html" target="navFrame">
								<font color="#000000">built-in tasks</font>
						</a>
						<font color="#000000">, along with a number of </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/optionaltasklist.html" target="navFrame">
								<font color="#000000">optional tasks</font>
						</a>
						<font color="#000000">, but it is also very easy to </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/develop.html#writingowntask">
								<font color="#000000">write your own</font>
						</a>
						<font color="#000000">.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">All tasks share a task name attribute. The value of this attribute will be used in the logging messages generated by Ant.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Tasks can be assigned an <code><font face="新宋体">id</font></code> attribute: </font>
				</font>
		</p>
		<blockquote>
				<pre>
						<font color="#ff0000">
								<font color="#000000">&lt;<i>taskname</i> id="<i>taskID</i>" ... /&gt;</font>
						</font>
				</pre>
		</blockquote>
		<p>
				<font color="#ff0000">
						<font color="#000000">where <i>taskname</i> is the name of the task, and <i>taskID</i> is a unique identifier for this task. You can refer to the corresponding task object in scripts or other tasks via this name. For example, in scripts you could do: </font>
				</font>
		</p>
		<blockquote>
				<pre>
						<font color="#ff0000">
								<font color="#000000">&lt;script ... &gt;<br />  task1.setFoo("bar");<br />&lt;/script&gt;<br /></font>
						</font>
				</pre>
		</blockquote>
		<p>
				<font color="#ff0000">
						<font color="#000000">to set the <code><font face="新宋体">foo</font></code> attribute of this particular task instance. In another task (written in Java), you can access the instance via <code><font face="新宋体">project.getReference("task1")</font></code>. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Note<sup>1</sup>: If "task1" has not been run yet, then it has not been configured (ie., no attributes have been set), and if it is going to be configured later, anything you've done to the instance may be overwritten. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Note<sup>2</sup>: Future versions of Ant will most likely <i>not</i> be backward-compatible with this behaviour, since there will likely be no task instances at all, only proxies. </font>
				</font>
		</p>
		<h3>
				<font color="#ff0000">
						<a name="properties">
								<font color="#000000" size="4">Properties</font>
						</a>
				</font>
		</h3>
		<p>
				<font color="#ff0000">
						<font color="#000000">A project can have a set of properties. These might be set in the buildfile by the </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/CoreTasks/property.html">
								<font color="#000000">property</font>
						</a>
						<font color="#000000">task, or might be set outside Ant. A property has a name and a value; the name is case-sensitive. Properties may be used in the value of task attributes. This is done by placing the property name between "<code><font face="新宋体">${</font></code>" and "<code><font face="新宋体">}</font></code>" in the attribute value. For example, if there is a "builddir" property with the value "build", then this could be used in an attribute like this: <code><font face="新宋体">${builddir}/classes</font></code>. This is resolved at run-time as <code><font face="新宋体">build/classes</font></code>.</font>
				</font>
		</p>
		<h3>
				<font color="#ff0000">
						<a name="built-in-props">
								<font color="#000000" size="4">Built-in Properties</font>
						</a>
				</font>
		</h3>
		<p>
				<font color="#ff0000">
						<font color="#000000">Ant provides access to all system properties as if they had been defined using a <code><font face="新宋体">&lt;property&gt;</font></code> task. For example, <code><font face="新宋体">${os.name}</font></code> expands to the name of the operating system.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">For a list of system properties see </font>
						<a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/System.html#getProperties%28%29">
								<font color="#000000">the Javadoc of System.getProperties</font>
						</a>
						<font color="#000000">. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">In addition, Ant has some built-in properties:</font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000">basedir             the absolute path of the project's basedir (as set<br />                    with the basedir attribute of &lt;project&gt;).<br />ant.file            the absolute path of the buildfile.<br />ant.version         the version of Ant<br />ant.project.name    the name of the project that is currently executing;<br />                    it is set in the name attribute of &lt;project&gt;.<br />ant.java.version    the JVM version Ant detected; currently it can hold<br />                    the values "1.1", "1.2", "1.3", "1.4"  and "1.5".<br /></font>
				</font>
		</pre>
		<font color="#ff0000">
				<a name="example">
						<h3>
								<font color="#000000">Example Buildfile</font>
						</h3>
				</a>
		</font>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;project name="MyProject" default="dist" basedir="."&gt;<br />    &lt;description&gt;<br />        simple example build file<br />    &lt;/description&gt;<br />  &lt;!-- set global properties for this build --&gt;<br />  &lt;property name="src" location="src"/&gt;<br />  &lt;property name="build" location="build"/&gt;<br />  &lt;property name="dist"  location="dist"/&gt;<br /><br />  &lt;target name="init"&gt;<br />    &lt;!-- Create the time stamp --&gt;<br />    &lt;tstamp/&gt;<br />    &lt;!-- Create the build directory structure used by compile --&gt;<br />    &lt;mkdir dir="${build}"/&gt;<br />  &lt;/target&gt;<br /><br />  &lt;target name="compile" depends="init"<br />        description="compile the source " &gt;<br />    &lt;!-- Compile the java code from ${src} into ${build} --&gt;<br />    &lt;javac srcdir="${src}" destdir="${build}"/&gt;<br />  &lt;/target&gt;<br /><br />  &lt;target name="dist" depends="compile"<br />        description="generate the distribution" &gt;<br />    &lt;!-- Create the distribution directory --&gt;<br />    &lt;mkdir dir="${dist}/lib"/&gt;<br /><br />    &lt;!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --&gt;<br />    &lt;jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/&gt;<br />  &lt;/target&gt;<br /><br />  &lt;target name="clean"<br />        description="clean up" &gt;<br />    &lt;!-- Delete the ${build} and ${dist} directory trees --&gt;<br />    &lt;delete dir="${build}"/&gt;<br />    &lt;delete dir="${dist}"/&gt;<br />  &lt;/target&gt;<br />&lt;/project&gt;<br /></font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
						<font color="#000000">Notice that we are declaring properties outside any target. As of Ant 1.6 all tasks can be declared outside targets (earlier version only allowed <tt><font face="新宋体">&lt;property&gt;</font></tt>,<tt><font face="新宋体">&lt;typedef&gt;</font></tt> and <tt><font face="新宋体">&lt;taskdef&gt;</font></tt>). When you do this they are evaluated before any targets are executed. Some tasks will generate build failures if they are used outside of targets as they may cause infinite loops otherwise (<code><font face="新宋体">&lt;antcall&gt;</font></code> for example).</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">We have given some targets descriptions; this causes the <tt><font face="新宋体">projecthelp</font></tt> invocation option to list them as public targets with the descriptions; the other target is internal and not listed. </font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Finally, for this target to work the source in the <tt><font face="新宋体">src</font></tt> subdirectory should be stored in a directory tree which matches the package names. Check the <tt><font face="新宋体">&lt;javac&gt;</font></tt> task for details. </font>
						<a name="filters">
								<h3>
										<font color="#000000">Token Filters</font>
								</h3>
						</a>
				</font>
		</p>
		<p>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">
						</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">A project can have a set of tokens that might be automatically expanded if found when a file is copied, when the filtering-copy behavior is selected in the tasks that support this. These might be set in the buildfile by the </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/CoreTasks/filter.html">
								<font color="#000000">filter</font>
						</a>
						<font color="#000000">task.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Since this can potentially be a very harmful behavior, the tokens in the files <b>must</b> be of the form <code><font face="新宋体">@</font></code><i>token</i><code><font face="新宋体">@</font></code>, where <i>token</i> is the token name that is set in the <code><font face="新宋体">&lt;filter&gt;</font></code> task. This token syntax matches the syntax of other build systems that perform such filtering and remains sufficiently orthogonal to most programming and scripting languages, as well as with documentation systems.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Note: If a token with the format <code><font face="新宋体">@</font></code><i>token</i><code><font face="新宋体">@</font></code> is found in a file, but no filter is associated with that token, no changes take place; therefore, no escaping method is available - but as long as you choose appropriate names for your tokens, this should not cause problems.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">
								<b>Warning:</b> If you copy binary files with filtering turned on, you can corrupt the files. This feature should be used with text files <em>only</em>.</font>
				</font>
		</p>
		<h3>
				<font color="#ff0000">
						<a name="path">
								<font color="#000000" size="4">Path-like Structures</font>
						</a>
				</font>
		</h3>
		<p>
				<font color="#ff0000">
						<font color="#000000">You can specify <code><font face="新宋体">PATH</font></code>- and <code><font face="新宋体">CLASSPATH</font></code>-type references using both "<code><font face="新宋体">:</font></code>" and "<code><font face="新宋体">;</font></code>" as separator characters. Ant will convert the separator to the correct character of the current operating system.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">Wherever path-like values need to be specified, a nested element can be used. This takes the general form of:</font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;classpath&gt;<br />      &lt;pathelement path="${classpath}"/&gt;<br />      &lt;pathelement location="lib/helper.jar"/&gt;<br />    &lt;/classpath&gt;<br /></font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
						<font color="#000000">The <code><font face="新宋体">location</font></code> attribute specifies a single file or directory relative to the project's base directory (or an absolute filename), while the <code><font face="新宋体">path</font></code> attribute accepts colon- or semicolon-separated lists of locations. The <code><font face="新宋体">path</font></code> attribute is intended to be used with predefined paths - in any other case, multiple elements with <code><font face="新宋体">location</font></code> attributes should be preferred.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">As a shortcut, the <code><font face="新宋体">&lt;classpath&gt;</font></code> tag supports <code><font face="新宋体">path</font></code> and <code><font face="新宋体">location</font></code> attributes of its own, so:</font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;classpath&gt;<br />      &lt;pathelement path="${classpath}"/&gt;<br />    &lt;/classpath&gt;<br /></font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
						<font color="#000000">can be abbreviated to:</font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;classpath path="${classpath}"/&gt;<br /></font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
						<font color="#000000">In addition, </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/CoreTypes/dirset.html">
								<font color="#000000">DirSet</font>
						</a>
						<font color="#000000">s, </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/CoreTypes/fileset.html">
								<font color="#000000">FileSet</font>
						</a>
						<font color="#000000">s, and </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/CoreTypes/filelist.html">
								<font color="#000000">FileList</font>
						</a>
						<font color="#000000">s can be specified via nested <code><font face="新宋体">&lt;dirset&gt;</font></code>, <code><font face="新宋体">&lt;fileset&gt;</font></code>, and <code><font face="新宋体">&lt;filelist&gt;</font></code> elements, respectively. <em>Note</em>: The order in which the files building up a FileSet are added to the path-like structure is not defined.</font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;classpath&gt;<br />      &lt;pathelement path="${classpath}"/&gt;<br />      &lt;fileset dir="lib"&gt;<br />        &lt;include name="**/*.jar"/&gt;<br />      &lt;/fileset&gt;<br />      &lt;pathelement location="classes"/&gt;<br />      &lt;dirset dir="${build.dir}"&gt;<br />        &lt;include name="apps/**/classes"/&gt;<br />        &lt;exclude name="apps/**/*Test*"/&gt;<br />      &lt;/dirset&gt;<br />      &lt;filelist refid="third-party_jars"/&gt;<br />    &lt;/classpath&gt;<br /></font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
						<font color="#000000">This builds a path that holds the value of <code><font face="新宋体">${classpath}</font></code>, followed by all jar files in the <code><font face="新宋体">lib</font></code> directory, the <code><font face="新宋体">classes</font></code> directory, all directories named <code><font face="新宋体">classes</font></code> under the <code><font face="新宋体">apps</font></code> subdirectory of <code><font face="新宋体">${build.dir}</font></code>, except those that have the text <code><font face="新宋体">Test</font></code> in their name, and the files specified in the referenced FileList.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">If you want to use the same path-like structure for several tasks, you can define them with a <code><font face="新宋体">&lt;path&gt;</font></code> element at the same level as <i>target</i>s, and reference them via their <i>id</i> attribute - see </font>
						<a href="file:///D:/java/tools/apache-ant-1.6.5-bin/apache-ant-1.6.5/docs/manual/using.html#references">
								<font color="#000000">References</font>
						</a>
						<font color="#000000">for an example.</font>
				</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">A path-like structure can include a reference to another path-like structure via nested <code><font face="新宋体">&lt;path&gt;</font></code> elements:</font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;path id="base.path"&gt;<br />      &lt;pathelement path="${classpath}"/&gt;<br />      &lt;fileset dir="lib"&gt;<br />        &lt;include name="**/*.jar"/&gt;<br />      &lt;/fileset&gt;<br />      &lt;pathelement location="classes"/&gt;<br />    &lt;/path&gt;<br /><br />    &lt;path id="tests.path"&gt;<br />      &lt;path refid="base.path"/&gt;<br />      &lt;pathelement location="testclasses"/&gt;<br />    &lt;/path&gt;</font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
						<font color="#000000">The shortcuts previously mentioned for <code><font face="新宋体">&lt;classpath&gt;</font></code> are also valid for <code><font face="新宋体">&lt;path&gt;</font></code>.For example: </font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000">
								<font color="#ff0000">
								</font> &lt;path id="base.path"&gt;<br />      &lt;pathelement path="${classpath}"/&gt;<br />    &lt;/path&gt;<br /></font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
						<font color="#000000">can be written as: </font>
				</font>
		</p>
		<pre>
				<font color="#ff0000">
						<font color="#000000"> &lt;path id="base.path" path="${classpath}"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">generally, you need not to write your builder.xml file started from scratch. you can just modify the following<br /></font>
						<font color="#000000">
								<font color="#ff0000">
								</font>part to meet your demand.</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;project name="javastep" default="deploy" basedir="."&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ===================== Property Definitions =========================== --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />         All properties should be defined in this section.<br />         Any host-specific properties should be defined<br />         in the build.properties file.</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  In this app, the following properties are defined in build.properties:</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">   o  tomcat.home     - the home directory of your Tomcat installation<br />        o  webapps.home    - the place to copy the war file to deploy it<br />    --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;property file="build.properties" /&gt;<br /> </font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;property name="app.home"          value="." /&gt;<br />  &lt;property name="app.name"          value="javastep" /&gt;<br />  &lt;property name="javadoc.pkg.top"   value="hello" /&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;property name="src.home"          value="${app.home}/src"/&gt;<br />  &lt;property name="lib.home"          value="${app.home}/WebRoot/WEB-INF/lib"/&gt;<br />  <br />  &lt;property name="classes.home"       value="${app.home}/WebRoot/WEB-INF/classes/"/&gt;<br />  &lt;property name="deploy.home"       value="${app.home}/deploy"/&gt;<br />  &lt;property name="doc.home"          value="${app.home}/doc"/&gt;<br />  &lt;property name="web.home"          value="${app.home}/WebRoot"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;property name="build.home"        value="${app.home}/build"/&gt;<br />  &lt;property name="build.classes"     value="${build.home}/WEB-INF/classes"/&gt;<br />  &lt;property name="build.lib"         value="${build.home}/WEB-INF/lib"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ==================== Compilation Classpath =========================== --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />         This section creates the classpath for compilation.<br />    --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;path id="compile.classpath"&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- The object files for this application --&gt;<br />    &lt;pathelement location="${classes.home}"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- The lib files for this application --&gt;<br />    &lt;fileset dir="${lib.home}"&gt;<br />      &lt;include name="*.jar"/&gt;<br />      &lt;include name="*.zip"/&gt;<br />    &lt;/fileset&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- All files/jars that Tomcat makes available --&gt;</font>
				</font>
		</pre>
		<font color="#ff0000">
				<font color="#000000">
				</font>
		</font>
		<pre>
				<font color="#ff0000">
						<font color="#000000">
								<br />  &lt;/path&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">
								<br />&lt;!-- ==================== Build Targets below here========================= --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">
								<br />&lt;!-- ==================== "help" Target =================================== --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />         This is the default ant target executed if no target is specified.<br />         This helps avoid users just typing 'ant' and running a<br />         default target that may not do what they are anticipating...<br />    --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000"> &lt;target name="help" &gt;<br />   &lt;echo message="Please specify a target! [usage: ant &amp;lt;targetname&amp;gt;]" /&gt;<br />   &lt;echo message="Here is a list of possible targets: "/&gt;<br />   &lt;echo message="  clean-all.....Delete build dir, all .class and war files"/&gt;<br />   &lt;echo message="  prepare.......Creates directories if required" /&gt;<br />   &lt;echo message="  compile.......Compiles source files" /&gt;<br />   &lt;echo message="  build.........Build war file from .class and other files"/&gt;<br />   &lt;echo message="  deploy........Copy war file to the webapps directory" /&gt;<br />   &lt;echo message="  javadoc.......Generates javadoc for this application" /&gt;<br /> &lt;/target&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ==================== "clean-all" Target ============================== --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">   &lt;!--<br />          This target should clean up any traces of the application<br />          so that if you run a new build directly after cleaning, all<br />          files will be replaced with what's current in source control<br />   --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000"> &lt;target name="clean-all" &gt;<br />    &lt;delete dir="${build.home}"/&gt;<br />    &lt;delete dir="${classes.home}"/&gt;<br />    &lt;delete dir="${deploy.home}"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- can't delete directory if Tomcat is running --&gt;<br />    &lt;delete dir="${webapps.home}/${app.name}" failonerror="false"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- deleting the deployed .war file is fine even if Tomcat is running --&gt;<br />    &lt;delete dir="${webapps.home}/${app.name}.war" /&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- delete the javadoc --&gt;<br />    &lt;delete dir="${doc.home}"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000"> &lt;/target&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ==================== "prepare" Target ================================ --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />          This target is executed prior to any of the later targets<br />          to make sure the directories exist. It only creates them<br />          if they need to be created....<br />          Other, similar, preparation steps can be placed here.<br />    --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;target name="prepare"&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;echo message="Tomcat Home = ${tomcat.home}" /&gt;<br />    &lt;echo message="webapps Home = ${webapps.home}" /&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;mkdir dir="${classes.home}"/&gt;<br />    &lt;mkdir dir="${deploy.home}"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;mkdir dir="${doc.home}"/&gt;<br />    &lt;mkdir dir="${doc.home}/api"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;mkdir dir="${build.home}"/&gt;<br />    &lt;mkdir dir="${build.home}/WEB-INF" /&gt;<br />    &lt;mkdir dir="${build.home}/WEB-INF/classes" /&gt;<br />    &lt;mkdir dir="${build.home}/WEB-INF/lib" /&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;/target&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ==================== "compile" Target ================================ --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />          This only compiles java files that are newer<br />          than their corresponding .class files.<br />     --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;target name="compile" depends="prepare" &gt;<br />    &lt;javac srcdir="${src.home}" destdir="${classes.home}" debug="yes" &gt;<br />        &lt;classpath refid="compile.classpath"/&gt;<br />    &lt;/javac&gt;<br />  &lt;/target&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ==================== "build" Target ================================== --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />          This target builds the war file for the application<br />          by first building the directory structure of the<br />          application in ${build.home} and then creating the<br />          war file using the ant &lt;war&gt; task<br />     --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;target name="build" &gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- Copy all the webapp content (jsp's, html, tld's, xml, etc. --&gt;<br />    &lt;!-- Note that this also copies the META-INF directory --&gt;<br />    &lt;copy    todir="${build.home}"&gt;<br />      &lt;fileset dir="${web.home}"/&gt;<br />    &lt;/copy&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- Now, copy all the Java class files --&gt;<br />    &lt;copy    todir="${build.home}/WEB-INF/classes"&gt;<br />      &lt;fileset dir="${classes.home}"/&gt;<br />    &lt;/copy&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- Now, copy all the properties files, etc that go on the classpath --&gt;<br />    &lt;copy    todir="${build.home}/WEB-INF/classes"&gt;<br />      &lt;fileset dir="${src.home}"&gt;<br />         &lt;include name="**/*.properties" /&gt;<br />         &lt;include name="**/*.prop" /&gt;<br />      &lt;/fileset&gt;<br />    &lt;/copy&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- Now, copy all the jar files we need --&gt;<br />    &lt;copy    todir="${build.home}/WEB-INF/lib"&gt;<br />      &lt;fileset dir="${lib.home}" /&gt;<br />    &lt;/copy&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- Create the &lt;war&gt; file --&gt;<br />    &lt;jar jarfile="${deploy.home}/${app.name}.war"<br />         basedir="${build.home}"/&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;/target&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ==================== "deploy" Target ================================= --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />         This target simply copies the war file from the deploy<br />         directory into the Tomcat webapp directory.<br />     --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;target name="deploy" depends="build" &gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!-- Copy the contents of the build directory --&gt;<br />    &lt;copy todir="${webapps.home}"  file="${deploy.home}/${app.name}.war" /&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;/target&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">&lt;!-- ==================== "doc" Target ==================================== --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />         This task creates javadoc. It is dependent upon only the<br />         'compile' target so it is not executed in a normal build.<br />         As a result, the target needs to be run on its own.<br />    --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;target name="javadoc" depends="compile"&gt;<br />      &lt;javadoc sourcepath = "${src.home}"<br />                  destdir = "${doc.home}/api"<br />             packagenames = "${javadoc.pkg.top}.*"/&gt;<br />  &lt;/target&gt;<br />  <br />&lt;!-- ==================== "test" Target ================================== --&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">    &lt;!--<br />        This task runs all test cases. It invokes each test case individually.<br />        The "test-all" target is tied back to the "struts-test" target which<br />        actually runs the tests. This allows other test targets to be created<br />        in this section while maintaining the ability to run each test target<br />        individually. All individual test targets should be added to the<br />        "depends" attribute of the "test-all" target to provide a single<br />        target that runs all tests.<br />--&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;target name="test-all" depends="struts-tests" /&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">  &lt;target name="struts-tests" depends="build" &gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">      &lt;junit printsummary="yes" &gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">          &lt;classpath &gt;<br />              &lt;pathelement location="${classes.home}"/&gt;<br />              &lt;pathelement location="${build.home}"/&gt;<br />              &lt;pathelement location="${build.home}/WEB-INF/classes"/&gt;<br />              &lt;path refid="compile.classpath"/&gt;<br />          &lt;/classpath&gt;</font>
				</font>
		</pre>
		<pre>
				<font color="#ff0000">
						<font color="#000000">          &lt;formatter type="plain" /&gt;<br />          &lt;test name="hello.mocktest.TestHelloAction" /&gt;<br />          &lt;test name="hello.mocktest.TestHelloActionMultiple" /&gt;<br />      &lt;/junit&gt;<br />    <br />  &lt;/target&gt;<br />&lt;/project&gt;<br /></font>
				</font>
		</pre>
		<p>
				<font color="#ff0000">
				</font> </p><img src ="http://www.blogjava.net/junhong/aggbug/42008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-04-19 21:41 <a href="http://www.blogjava.net/junhong/archive/2006/04/19/42008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>how to use sitemesh </title><link>http://www.blogjava.net/junhong/archive/2006/04/13/40996.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Thu, 13 Apr 2006 15:41:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/04/13/40996.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/40996.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/04/13/40996.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/40996.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/40996.html</trackback:ping><description><![CDATA[<li>Copy <b><code>sitemesh-2.2.1.jar</code></b> into <b><code>[web-app]/WEB-INF/lib</code></b>. 
</li>
		<li>Create the file <b><code>[web-app]/WEB-INF/decorators.xml</code></b> that contains the following: 
<p></p><blockquote><code>&lt;decorators&gt;<br />&lt;/decorators&gt;</code></blockquote></li>
		<li>(Optional) Create the file <b><code>[web-app]/WEB-INF/sitemesh.xml</code></b> that contains the following: <pre style="BORDER-RIGHT: rgb(153,153,153) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(153,153,153) 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: rgb(153,153,153) 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: rgb(153,153,153) 1px solid">&lt;sitemesh&gt;
    &lt;property name="decorators-file" value="/WEB-INF/decorators.xml" /&gt;
    &lt;excludes file="${decorators-file}" /&gt;

    &lt;page-parsers&gt;
        &lt;parser content-type="text/html"
            class="com.opensymphony.module.sitemesh.parser.FastPageParser" /&gt;
        &lt;parser content-type="text/html;charset=ISO-8859-1"
            class="com.opensymphony.module.sitemesh.parser.FastPageParser" /&gt;
    &lt;/page-parsers&gt;

    &lt;decorator-mappers&gt;
        &lt;mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"&gt;
            &lt;param name="config" value="${decorators-file}" /&gt;
        &lt;/mapper&gt;
    &lt;/decorator-mappers&gt;
&lt;/sitemesh&gt;
</pre></li>
		<li>Add the following to <b><code>[web-app]/WEB-INF/web.xml</code></b> within the <b><code>&lt;web-app&gt;</code></b> tag: 
<p></p><pre style="BORDER-RIGHT: rgb(153,153,153) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(153,153,153) 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: rgb(153,153,153) 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: rgb(153,153,153) 1px solid">&lt;filter&gt;
    &lt;filter-name&gt;<b>sitemesh</b>&lt;/filter-name&gt;
    &lt;filter-class&gt;<b>com.opensymphony.module.sitemesh.filter.PageFilter</b>&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
    &lt;filter-name&gt;sitemesh&lt;/filter-name&gt;
    &lt;url-pattern&gt;<b>/*</b>&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre>Decorators are the pages that "decorate" the original, requested page (the page that is <a href="http://www.opensymphony.com/sitemesh/flow.html">handed to the SiteMesh filter from the web container</a>). Most (HTML) decorators are a combination of: 
<ul><li>meta tags (keywords, description, author)
</li><li>stylesheet (CSS)
</li><li>header
</li><li>navigation
</li><li>footer
</li><li>copyright notice</li></ul>First, define what different navigation/layout schemes you need. For example: Do I need a default decorator (a standard one for all pages)? Do I have a special layout for the index page? Is the header needed for my documentation files? Do I need printable version of my website? 
<h3>Web Application Structure</h3><p>Here is an example structure of a web application. This is not needed for SiteMesh to work.</p><table style="BACKGROUND: rgb(238,238,238) 0% 50%; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellpadding="4" width="80%" align="center"><tbody><tr><td width="15%"><b><code>/decorators</code></b></td><td><p>Directory containing all decorator files (e.g. <code>main.jsp</code>, <code>printable.jsp</code>).</p></td></tr><tr><td width="15%"><b><code>/includes</code></b></td><td><p>Directory containing all files to be included into other files (e.g. <code>header.jsp</code>, <code>footer.jsp</code>, <code>copyright.jsp</code>).</p></td></tr><tr><td width="15%"><b><code>/images</code></b></td><td><p>Directory containing all images (e.g. <code>background.gif</code>, <code>logo.gif</code>).</p></td></tr><tr><td width="15%"><b><code>/styles</code></b></td><td><p>Directory containing all .CSS styles (e.g. <code>ie4.css</code>, <code>ns4.css</code>).</p></td></tr><tr><td width="15%"><b><code>/scripts</code></b></td><td><p>Directory containing all scripts (JavaScript, VBScript files).</p></td></tr></tbody></table><p>Good practices:</p><ul><li>Define a stylesheet to use in the entire application and include it using <a href="http://www.opensymphony.com/sitemesh/style.jsp.txt">this script</a>.
</li><li>Use includes in your decorators (e.g. <code>includes/navigation.jsp</code>, <code>includes/style.jsp</code>).
</li><li>Try not to refer to the absolute root ("<code>/</code>") path. Use <code>&lt;%=request.getContextPath()%&gt;/</code> instead. This will make life easier when moving your web application under another context path.
</li><li>Making your decorators compatible with multiple browsers (IE, Mozilla, Opera, ...) will (probably) make your entire application (all decorated pages) compatible.
</li><li>Be careful when using frames, because decorators may NOT be applied to frames (<a href="http://www.opensymphony.com/sitemesh/api/com/opensymphony/module/sitemesh/mapper/FrameSetDecoratorMapper.html">FrameSetDecoratorMapper</a>).</li></ul><h3>My First Decorator</h3>Basically, all you need to know is what <a href="http://www.opensymphony.com/sitemesh/tags.html">decorator tags</a> you can use. The <a href="http://www.opensymphony.com/sitemesh/tags.html#decorator:title">title</a>, <a href="http://www.opensymphony.com/sitemesh/tags.html#decorator:head">head</a> and <a href="http://www.opensymphony.com/sitemesh/tags.html#decorator:body">body</a> tags are most used.<br />Here is an example of a decorator (save it as /decorators/main.jsp): 
<p><code>1: &lt;%--<br />2: % This is the main decorator for all SOMECOMPANY INTRANET pages.<br />3: % It includes standard caching, style sheet, header, footer and copyright notice.<br />4: --%&gt;<br />5: <b>&lt;%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %&gt;</b><br />6: &lt;%@ include file="<a href="http://www.opensymphony.com/sitemesh/cache.jsp.txt">/includes/cache.jsp</a>" %&gt;<br />7: &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />8: &lt;html&gt;<br />9: &lt;head&gt;<br />10: &lt;title&gt;<b><font color="maroon">&lt;decorator:title default="INTRANET" /&gt;</font></b>&lt;/title&gt;<br />11: <b><font color="maroon">&lt;decorator:head /&gt;</font></b><br />12: <b>&lt;%@ include file="<a href="http://www.opensymphony.com/sitemesh/style.jsp.txt">/includes/style.jsp</a>" %&gt;</b><br />13: &lt;/head&gt;<br />14: &lt;body bgcolor="#FFFFFF" background="&lt;%=request.getContextPath()%&gt;/images/bg.gif"&gt;<br />15: &lt;script type="text/javascript"&gt;window.status = "Loading: <b><font color="maroon">&lt;decorator:title default="INTRANET" /&gt;</font></b>...";&lt;/script&gt;<br />16: &lt;%@ include file="/includes/header.jsp"%&gt;<br />17: &lt;table width="100%" border="0" cellspacing="0" cellpadding="0"&gt;<br />18: &lt;tr&gt;<br />19: &lt;td height="20" nowrap&gt; &lt;/td&gt;<br />20: &lt;/tr&gt;<br />21: &lt;tr&gt;<br />22: &lt;td width="1%" nowrap&gt; &lt;/td&gt;<br />23: &lt;td width="16%" valign="top" nowrap&gt;<br />23: &lt;script type="text/javascript"&gt;window.status = "Loading: Navigation...";&lt;/script&gt;<br />24: &lt;%@ include file="/includes/navigation.jsp" %&gt;<br />25: &lt;/td&gt;<br />26: &lt;td width="2%" nowrap&gt; &lt;/td&gt;<br />27: &lt;td valign="top"&gt;<br />28: &lt;br&gt;<br />29: &lt;script type="text/javascript"&gt;window.status = "Loading: Document body...";&lt;/script&gt;<br />30: &lt;div class="docBody"&gt;<b><font color="maroon">&lt;decorator:body /&gt;</font></b>&lt;/div&gt;<br />31: &lt;/td&gt;<br />32: &lt;td width="1%" nowrap&gt; &lt;/td&gt;<br />33: &lt;/tr&gt;<br />34: &lt;/table&gt;<br />35: &lt;br&gt;<br />36: <b>&lt;%@ include file="/includes/footer.jsp" %&gt;</b><br />37: <b>&lt;%@ include file="/includes/copyright.jsp" %&gt;</b><br />38: &lt;script type="text/javascript"&gt;window.status = "Done";&lt;/script&gt;<br />39: &lt;/body&gt;<br />40: &lt;/html&gt;<br /></code></p><ul><li>Line <strong>1-4</strong>:<br />An explanation of the decorator. This way different people working on the decorator are quickly up to speed.
</li><li>Line <strong>5</strong>:<br />This is needed for the <code>decorator:</code> tags to work (also needed on all pages that work with inline decorators (<a href="http://www.opensymphony.com/sitemesh/tags.html#page:applyDecorator">page:applyDecorator</a>).
</li><li>Line <strong>6</strong>:<br />Sets the necessary response headers to let the browser cache the page. Omit this line if your application is real dynamic (changing data).
</li><li>Line <strong>10</strong>:<br />If the requested page doesn't have a title, the default title is used ("INTRANET").
</li><li>Line <strong>15</strong>:<br />The status bar gets a message when the page is loading.
</li><li>Line <strong>30</strong>:<br />The entire body of the requested page has the <code>docBody</code> class. This way the navigation and body do not have to have the same font.</li></ul><p>Now open <code>WEB-INF/decorators.xml</code> with your favorite editor and let SiteMesh know there is a decorator (with a mapping):</p><pre style="BORDER-RIGHT: rgb(153,153,153) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(153,153,153) 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: rgb(153,153,153) 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: rgb(153,153,153) 1px solid">&lt;decorators defaultdir="/decorators"&gt;
    &lt;decorator name="main" page="<b>main.jsp</b>"&gt;
          &lt;pattern&gt;<b>/*</b>&lt;/pattern&gt;
    &lt;/decorator&gt;
&lt;/decorators&gt;
</pre><p>Now deploy the web application, go to the welcome page, and the main decorator will be applied.</p></li>
		<li>
				<p>When a page has been parsed, it then has to be mapped to a decorator. This mapping is performed by a chain of <a href="http://www.opensymphony.com/sitemesh/api/com/opensymphony/module/sitemesh/DecoratorMapper.html">DecoratorMappers</a> (referred to as mappers from here on).</p>
				<p>For each request, the first mapper in the chain is asked which decorator should be used. It is passed across a reference to the Page object and HttpServletRequest. It returns either a Decorator object, if it knows which decorator to be used, or null. If null is returned, the next mapper in the chain is queried. This whole process is repeated until there are no more mappers in the chain, or one of the mappers returns a valid decorator. If no mappers return a decorator, the page is not decorated at all and served in its original state.</p>
				<p>This way the mappers are chained together and queried is known as the Chain of Responsibility design pattern.</p>
				<p>Examples of mappers:</p>
				<ul>
						<li>Determine decorator based on path of requested page. 
</li>
						<li>Use different decorators based on time, locale or browser. 
</li>
						<li>Use simplified decorators for search-engine robots. 
</li>
						<li>Switch decorators based on a URL parameter, request attribute or meta-tag. 
</li>
						<li>Use custom decorators based on user's saved settings... </li>
				</ul>
				<p>The main implementation of DecoratorMapper is <a href="http://www.opensymphony.com/sitemesh/api/com/opensymphony/module/sitemesh/mapper/ConfigDecoratorMapper.html">ConfigDecoratorMapper</a> which reads the decorators and mappings from <code>/WEB-INF/decorators.xml</code>. The appropriate decorator is then applied depending on the URL pattern.</p>
				<p>DecoratorMappers are simple to write and the distribution includes some samples that demonstrate how to write them and how flexible they can be. These are: </p>
				<table cellspacing="10" border="0">
						<tbody>
								<tr>
										<td valign="top">
												<strong>AgentDecoratorMapper</strong>
										</td>
										<td>Can determine the user-agent (i.e. web-browser) requesting a page, and map to a suitable Decorator.</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>ConfigDecoratorMapper</strong>
										</td>
										<td>Default implementation of DecoratorMapper. Reads decorators and mappings from the <code>config</code> property (default '/WEB- INF/decorators.xml').</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>CookieDecoratorMapper</strong>
										</td>
										<td>Will map a suitable decorator based on a cookie value.</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>EnvEntryDecoratorMapper</strong>
										</td>
										<td>Allows the reference to a web-app environment entry for the decorator name, and falls back to ConfigDecoratorMapper's behavior if no matching environment entry is found.</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>FileDecoratorMapper</strong>
										</td>
										<td>Will treat the name of the decorator as a file-name to use (in the context of the web-app).</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>FrameSetDecoratorMapper</strong>
										</td>
										<td>Will use the specified decorator when the Page is an instance of HTMLPage and isFrameSet() returns true. The name of this decorator should be supplied in the <code>decorator</code> property - if no decorator property is supplied, no decorator is applied to frame based pages.</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>InlineDecoratorMapper</strong>
										</td>
										<td>Used to determine the correct Decorator when using inline decorators.</td>
								</tr>
								<tr>
										<td>
												<strong>LanguageDecoratorMapper</strong>
										</td>
										<td>Can determine the preferred language set in the browser requesting a page, and map to a suitable Decorator (using the "Accept-Language" HTTP header).</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>PageDecoratorMapper</strong>
										</td>
										<td>The actual Page determines the Decorator to be used. 
<p>The 'meta.decorator' and 'decorator' properties of the page are accessed and if any of them contain the name of a valid Decorator, that Decorator shall be applied.</p></td>
								</tr>
								<tr>
										<td valign="top">
												<strong>ParameterDecoratorMapper</strong>
										</td>
										<td>Will choose the decorator based on request parameters. 
<p>The ParameterDecoratorMapper is configured via three properties.</p><p><code>decorator.parameter</code> - the parameter which contains the name of the decorator which will be mapped. The default is "decorator".</p><p>For example if <code>decorator.parameter</code> is "foobar" then myurl.jsp?foobar=mydecorator will map to the decorator named "mydecorator".</p><p>You can also supply an optional 'confirmation parameter'. The decorator will only be mapped if the parameter named <code>parameter.name</code> is in the request URI and the value of that parameter is equal to the <code>parameter.value</code> property.</p><p>For example assuming parameter.name=confirm and parameter.value=true the URI myurl.jsp?decorator=mydecorator&amp;confirm=true will map the decorator mydecorator. where as the URIs myurl.jsp?decorator=mydecorator and myurl.jsp?decorator=mydecorator&amp;confirm=false will not return any decorator.</p></td>
								</tr>
								<tr>
										<td valign="top">
												<strong>SessionDecoratorMapper</strong>
										</td>
										<td>
												<p>Will look at a session attribute to find the name of an appropriate decorator to use. If the session attribute is present, the mapper will not do anything and allow the next mapper in the chain to select a decorator.</p>
												<p>By default, it will look at the 'decorator' session attribute, however this can be overriden by configuring the mapper with a 'decorator.parameter' property.</p>
										</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>PrintableDecoratorMapper</strong>
										</td>
										<td>Will check to see whether 'printable=true' is supplied as a request parameter and if so, use the specified decorator instead. The name of this decorator should be supplied in the <code>decorator</code> property.</td>
								</tr>
								<tr>
										<td valign="top">
												<strong>RobotDecoratorMapper</strong>
										</td>
										<td>Will use the specified decorator when the requester is identified as a robot (also known as spider, crawler, ferret) of a search engine. The name of this decorator should be supplied in the <code>decorator</code> property.</td>
								</tr>
						</tbody>
				</table>
				<p>An example of a custom DecoratorMapper could be one that displays different Decorators based on time (e.g. morning, afternoon, Christmas, etc).</p>
				<h3>Custom mapper configuration</h3>
				<p>To be able to specify which mappers will be applied to a request, create the file <code>[web-app]/WEB-INF/sitemesh.xml</code> that contains the following:</p>
				<pre style="BORDER-RIGHT: rgb(153,153,153) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(153,153,153) 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: rgb(153,153,153) 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: rgb(153,153,153) 1px solid">&lt;sitemesh&gt;
    &lt;property name="decorators-file" value="/WEB-INF/decorators.xml" /&gt;
    &lt;excludes file="${decorators-file}" /&gt;

    &lt;page-parsers&gt;
        &lt;parser content-type="text/html"
            class="com.opensymphony.module.sitemesh.parser.FastPageParser" /&gt;
        &lt;parser content-type="text/html;charset=ISO-8859-1"
            class="com.opensymphony.module.sitemesh.parser.FastPageParser" /&gt;
    &lt;/page-parsers&gt;

    &lt;decorator-mappers&gt;
        &lt;mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"&gt;
            &lt;param name="config" value="${decorators-file}" /&gt;
        &lt;/mapper&gt;
    &lt;/decorator-mappers&gt;
&lt;/sitemesh&gt;
</pre>
				<p>In this example, the only mapper that will be applied is the <code>ConfigDecoratorMapper</code>, and that will only be applied to responses of type <code>text/html</code> or <code>text/html;charset=ISO-8859-1</code>. Responses of any other content type (eg <code>image/gif</code>) will be ignored by Sitemesh. Additionally, any files that match a pattern specified in the <code>excludes</code> file (in this case <code>'/WEB-INF/decorators.xml'</code>) will not be touched by Sitemesh.</p>
				<p>The excludes file points to an XML file that contains an <code>&lt;excludes /&gt;</code> block similar to the following:</p>
				<pre style="BORDER-RIGHT: rgb(153,153,153) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(153,153,153) 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: rgb(153,153,153) 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: rgb(153,153,153) 1px solid">&lt;decorators&gt;
    &lt;excludes&gt;
        &lt;pattern&gt;/plainPage.jsp&lt;/pattern&gt;
        &lt;pattern&gt;/plain/*.jsp&lt;/pattern&gt;
    &lt;/excludes&gt;
&lt;/decorators&gt;
</pre>
				<p>The above example would prevent <code>/plainPage.jsp</code> and any JSP pages in the <code>/plain</code> directory from being decorated. (Note that the pattern matching follows exactly the same rules as the decorator mappings used by the <code>ConfigDecoratorMapper</code>.)</p>
				<p>Typically the <code>&lt;excludes /&gt;</code> block is just added at the start of the <code>decorators.xml</code> file, however this is not a requirement and any other XML file can be specified instead by changing the excludes file specified in <code>sitemesh.xml</code>. This might be useful if for example the <code>ConfigDecoratorMapper</code> is not being used in your deployment.</p>
				<p>Note that preventing pages from being decorated by adding them to the excludes list superceeds, and is a better approach than, the old method of mapping the pages to a non-existent decorator. This is because when pages were mapped to a non-existent decorator they were still buffered internally by Sitemesh. By using the exclude list Sitemesh will not let the request pass straight through to the servlet container without any buffering.</p>
				<h3>Default mapper configuration</h3>
				<p>If <code>sitemesh.xml</code> is not found in the <code>WEB-INF</code> dir, the default mapper configuration will be used. The default mapper configuration is defined in sitemesh-default.xml (packaged inside the jar) and consists of the following mappers:</p>
				<ul>
						<li>PageDecoratorMapper 
</li>
						<li>FrameSetDecoratorMapper 
</li>
						<li>PrintableDecoratorMapper 
</li>
						<li>FileDecoratorMapper 
</li>
						<li>ConfigDecoratorMapper </li>
				</ul>
				<p>By default only content of type <code>text/html</code> will be decorated by Sitemesh.<br /><br /><br /><br />for more detail, please refer to <a href="http://www.opensymphony.com/sitemesh/dm.html">http://www.opensymphony.com/sitemesh/dm.html</a></p>
		</li><img src ="http://www.blogjava.net/junhong/aggbug/40996.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-04-13 23:41 <a href="http://www.blogjava.net/junhong/archive/2006/04/13/40996.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Design Pattern with java (part three)</title><link>http://www.blogjava.net/junhong/archive/2006/04/10/40347.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Mon, 10 Apr 2006 15:51:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/04/10/40347.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/40347.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/04/10/40347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/40347.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/40347.html</trackback:ping><description><![CDATA[<p align="left">Specialized creation<br /></p>
		<hr />
		<ol>
				<li>
						<div align="left">Prototype<br /></div>Objects are created by cloning a prototypical instance. <br /></li>
				<li>Builder<br />The goal of builder is to separate the construction from the “representation,” to allow multiple<br />different representations. The construction process stays the same, but the resulting object<br />has different possible representations. GoF points out that the main difference with Abstract<br />Factory is that a Builder creates the object step-by-step, so the fact that the creation process is<br />spread out in time seems to be important. In addition, it seems that the “director” gets a<br />stream of pieces that it passes to the Builder, and each piece is used to perform one of the<br />steps in the build process.<br />One example given in GoF is that of a text format converter. The incoming format is RTF, and<br />once it is parsed the directives are passed to the text converter, which may be implemented in<br />different ways depending on whether the resulting format is ASCII, TeX, or a “GUI Text<br />Widget.” Although the resulting “object” (the entire converted text file) is created over time, if<br />you consider the conversion of each RTF directive to be an object, this feels to me a little more<br />like Bridge, because the specific types of converters extend the interface of the base class.<br />Also, the general solution to the problem would allow multiple readers on the “front end” and<br />multiple converters on the “back end,” which is a primary characteristic of Bridge.<br />To me, the fact that Builder has multiple steps in creating an object, and those steps are<br />accessed externally to the Builder object, is the essence of what distinguishes it (structurally,<br />anyway) from a regular factory. However, GoF emphasizes that you’re able to create different<br />representations using the same process. They never define exactly what they mean by<br />representation. (Does the “representation” involve an object that is too large? Would the need<br />for Builder vanish if the representation was broken into smaller objects?)<br />The other example in GoF creates a maze object and adds rooms within the maze and doors<br />within the rooms. Thus it is a multistep process, but alas, the different “representations” are<br />the “Standard” and “Complex” mazes – not really different kinds of mazes, but instead<br />different complexity. I think I would have tried to create one maze builder that could handle<br /><br />arbitrarily complex mazes. The final variation of the maze builder is something that doesn’t<br />create mazes at all, but instead counts the rooms in an existing maze.<br />Neither the RTF converter nor the Mazebuilder example makes an overwhelmingly<br />compelling case for Builder. Readers have suggested that the output of the Sax XML parser,<br />and standard compiler parsers, might naturally be fed into a Builder.<br />Here’s an example that may be a little more compelling, or at least give more of an idea of<br />what Builder is trying to do. Media may be constructed into different representations, in this<br />case books, magazines and web sites. The example argues that the steps involved are the<br />same, and so can be abstracted into the director class.<br />//: builder:BuildMedia.java<br />// Example of the Builder pattern<br />package builder;<br />import java.util.*;<br />import junit.framework.*;<br />// Different "representations" of media:<br />class Media extends ArrayList {}<br />class Book extends Media {}<br />class Magazine extends Media {}<br />class WebSite extends Media {}<br />// ... contain different kinds of media items:<br />class MediaItem {<br />private String s;<br />public MediaItem(String s) { this.s = s; }<br />public String toString() { return s; }<br />}<br />class Chapter extends MediaItem {<br />public Chapter(String s) { super(s); }<br />}<br />class Article extends MediaItem {<br />public Article(String s) { super(s); }<br />}<br />class WebItem extends MediaItem {<br />public WebItem(String s) { super(s); }<br />}<br />// ... but use the same basic construction steps:<br />class MediaBuilder {<br />public void buildBase() {}<br />public void addMediaItem(MediaItem item) {}<br />public Media getFinishedMedia() { return null; }<br />}<br />class BookBuilder extends MediaBuilder {<br />private Book b;<br />public void buildBase() {<br />System.out.println("Building book framework");<br />b = new Book();<br />}<br />public void addMediaItem(MediaItem chapter) {<br />System.out.println("Adding chapter " + chapter);<br />b.add(chapter);<br />}<br />public Media getFinishedMedia() { return b; }<br />}<br />class MagazineBuilder extends MediaBuilder {<br /><br />private Magazine m;<br />public void buildBase() {<br />System.out.println("Building magazine framework");<br />m = new Magazine();<br />}<br />public void addMediaItem(MediaItem article) {<br />System.out.println("Adding article " + article);<br />m.add(article);<br />}<br />public Media getFinishedMedia() { return m; }<br />}<br />class WebSiteBuilder extends MediaBuilder {<br />private WebSite w;<br />public void buildBase() {<br />System.out.println("Building web site framework");<br />w = new WebSite();<br />}<br />public void addMediaItem(MediaItem webItem) {<br />System.out.println("Adding web item " + webItem);<br />w.add(webItem);<br />}<br />public Media getFinishedMedia() { return w; }<br />}<br />class MediaDirector { // a.k.a. "Context"<br />private MediaBuilder mb;<br />public MediaDirector(MediaBuilder mb) {<br />this.mb = mb; // Strategy-ish<br />}<br />public Media produceMedia(List input) {<br />mb.buildBase();<br />for(Iterator it = input.iterator(); it.hasNext();)<br />mb.addMediaItem((MediaItem)it.next());<br />return mb.getFinishedMedia();<br />}<br />};<br />public class BuildMedia extends TestCase {<br />private List input = Arrays.asList(new MediaItem[] {<br />new MediaItem("item1"), new MediaItem("item2"),<br />new MediaItem("item3"), new MediaItem("item4"),<br />});<br />public void testBook() {<br />MediaDirector buildBook =<br />new MediaDirector(new BookBuilder());<br />Media book = buildBook.produceMedia(input);<br />String result = "book: " + book;<br />System.out.println(result);<br />assertEquals(result,<br />"book: [item1, item2, item3, item4]");<br />}<br />public void testMagazine() {<br />MediaDirector buildMagazine =<br />new MediaDirector(new MagazineBuilder());<br />Media magazine = buildMagazine.produceMedia(input);<br />String result = "magazine: " + magazine;<br />System.out.println(result);<br />assertEquals(result,<br />"magazine: [item1, item2, item3, item4]");<br />}<br /><br />public void testWebSite() {<br />MediaDirector buildWebSite =<br />new MediaDirector(new WebSiteBuilder());<br />Media webSite = buildWebSite.produceMedia(input);<br />String result = "web site: " + webSite;<br />System.out.println(result);<br />assertEquals(result,<br />"web site: [item1, item2, item3, item4]");<br />}<br />public static void main(String[] args) {<br />junit.textui.TestRunner.run(BuildMedia.class);<br />}<br />} ///:~ </li>
		</ol>
		<p>
		</p>
		<div align="left">
		</div>
		<p align="left">
		</p><img src ="http://www.blogjava.net/junhong/aggbug/40347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-04-10 23:51 <a href="http://www.blogjava.net/junhong/archive/2006/04/10/40347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Design Pattern with java (part two) </title><link>http://www.blogjava.net/junhong/archive/2006/04/10/40343.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Mon, 10 Apr 2006 15:23:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/04/10/40343.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/40343.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/04/10/40343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/40343.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/40343.html</trackback:ping><description><![CDATA[<p align="center">
				<font size="4">Encapsulating creation</font>
		</p>
		<p align="center">
				<font size="5">
						<br />
				</font>
		</p>
		<div align="left">
				<font size="4">Although only the Simple Factory Method is a true singleton, you’ll find that each specify <br /></font>
		</div>
		<div align="left">
				<font size="4">factory class in the more general types of factories will only have a single instance.</font>
				<br />
		</div>
		<ol>
				<li>Simple Factory method<br /><font color="#ff3333">One approach is to make the factory a static method of the base class:<br /></font>//: factory:shapefact1:ShapeFactory1.java<br />// A simple static factory method.<br />package factory.shapefact1;<br />import java.util.*;<br />import junit.framework.*;<br />abstract class Shape {<br />public abstract void draw();<br />public abstract void erase();<br /><font style="BACKGROUND-COLOR: rgb(255,0,0)">public static Shape factory(String type) {<br /></font>if(type.equals("Circle")) return new Circle();<br />if(type.equals("Square")) return new Square();<br />throw new RuntimeException(<br />"Bad shape creation: " + type);<br />}<br />}<br />class Circle extends Shape {Circle() {} // Package-access constructor<br />public void draw() {<br />System.out.println("Circle.draw");<br />}<br />public void erase() {<br />System.out.println("Circle.erase");<br />}<br />}<br />class Square extends Shape {<br />Square() {} // Package-access constructor<br />public void draw() {<br />System.out.println("Square.draw");<br />}<br />public void erase() {<br />System.out.println("Square.erase");<br />}<br />}<br />public class ShapeFactory1 extends TestCase {<br />String shlist[] = { "Circle", "Square",<br />"Square", "Circle", "Circle", "Square" };<br />List shapes = new ArrayList();<br />public void test() {<br />Iterator it = Arrays.asList(shlist).iterator();<br />while(it.hasNext())<br />shapes.add(Shape.factory((String)it.next()));<br />it = shapes.iterator();<br />while(it.hasNext()) {<br />Shape s = (Shape)it.next();<br />s.draw();<br />s.erase();<br />}<br />}<br />public static void main(String args[]) {<br />junit.textui.TestRunner.run(ShapeFactory1.class);<br />}<br />} ///:~<br />To encourage creation to only happen in the factory( ), the constructors for the specific<br />types of Shape are give package access, so factory( ) has access to the constructors but they<br />are not available outside the package. 
</li>
				<li>Polymorphic factories<br />different types of factories can be subclassed from the basic factory,for example<br />interface Shape {<br />void draw();<br />void erase();<br />}<br />abstract class ShapeFactory {<br />protected abstract Shape create();<br />private static Map factories = new HashMap();<br />public static void<br />addFactory(String id, ShapeFactory f) {<br />factories.put(id, f);<br />}<br />// A Template Method:<br />public static final<br />Shape createShape(String id) {<br />if(!factories.containsKey(id)) {<br />try {<br />// Load dynamically<br />Class.forName("factory.shapefact2." + id);<br />} catch(ClassNotFoundException e) {<br />throw new RuntimeException(<br />"Bad shape creation: " + id);<br />}<br />// See if it was put in:<br />if(!factories.containsKey(id))<br />throw new RuntimeException(<br />"Bad shape creation: " + id);<br />}<br />return<br />((ShapeFactory)factories.get(id)).create();<br />}<br />}<br />class Circle implements Shape {<br />private Circle() {}<br />public void draw() {<br />System.out.println("Circle.draw");<br />}<br />public void erase() {<br />System.out.println("Circle.erase");<br />}<br />private static class Factory<br />extends ShapeFactory {<br />protected Shape create() {<br />return new Circle();<br />}<br />}<br />static {<br />ShapeFactory.addFactory(<br />"Circle", new Factory());<br />}<br />}<br />....... 
</li>
				<li>Abstract factories<br />The Abstract Factory pattern looks like the factory objects we’ve seen previously, with not<br />one but several factory methods. Each of the factory methods creates a different kind of<br />object. The idea is that at the point of creation of the factory object, you decide how all the<br />objects created by that factory will be used.<br />As another example suppose you are creating a general-purpose gaming environment and you<br />want to be able to support different types of games<br />interface Obstacle {<br />void action();<br />}<br />interface Player {<br />void interactWith(Obstacle o);<br />}<br />class Kitty implements Player {<br />public void interactWith(Obstacle ob) {<br />System.out.print("Kitty has encountered a ");<br />ob.action();<br />}<br />}<br />class KungFuGuy implements Player {<br />public void interactWith(Obstacle ob) {<br />System.out.print("KungFuGuy now battles a ");<br />ob.action();<br />}<br />}<br />class Puzzle implements Obstacle {<br />public void action() {<br />System.out.println("Puzzle");<br />}<br />}<br />class NastyWeapon implements Obstacle {<br />public void action() {<br />System.out.println("NastyWeapon");<br />}<br />}<br />// The Abstract Factory:<br />interface GameElementFactory {Player makePlayer();<br />Obstacle makeObstacle();<br />}<br />// Concrete factories:<br />class KittiesAndPuzzles<br />implements GameElementFactory {<br />public Player makePlayer() {<br />return new Kitty();<br />}<br />public Obstacle makeObstacle() {<br />return new Puzzle();<br />}<br />}<br />class KillAndDismember<br />implements GameElementFactory {<br />public Player makePlayer() {<br />return new KungFuGuy();<br />}<br />public Obstacle makeObstacle() {<br />return new NastyWeapon();<br />}<br />}<br />class GameEnvironment {<br />private GameElementFactory gef;<br />private Player p;<br />private Obstacle ob;<br />public GameEnvironment(<br />GameElementFactory factory) {<br />gef = factory;<br />p = factory.makePlayer();<br />ob = factory.makeObstacle();<br />}<br />public void play() { p.interactWith(ob); }<br />}<br />public class Games extends TestCase {<br />GameElementFactory<br />kp = new KittiesAndPuzzles(),<br />kd = new KillAndDismember();<br />GameEnvironment<br />g1 = new GameEnvironment(kp),<br />g2 = new GameEnvironment(kd);<br />// These just ensure no exceptions are thrown:<br />public void test1() { g1.play(); }<br />public void test2() { g2.play(); }<br />public static void main(String args[]) {<br />junit.textui.TestRunner.run(Games.class);<br />}<br />} ///:~<br />In this environment, Player objects interact with Obstacle objects, but there are different<br />types of players and obstacles depending on what kind of game you’re playing. You determine<br />the kind of game by choosing a particular GameElementFactory, and then the<br />GameEnvironment controls the setup and play of the game. In this example, the setup and<br />play is very simple, but those activities (the initial conditions and the state change) can<br />determine much of the game’s outcome. Here, GameEnvironment is not designed to be<br />inherited, although it could very possibly make sense to do that. </li>
		</ol>
		<font face="Arial">
		</font><img src ="http://www.blogjava.net/junhong/aggbug/40343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-04-10 23:23 <a href="http://www.blogjava.net/junhong/archive/2006/04/10/40343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Design Pattern with java (part one)</title><link>http://www.blogjava.net/junhong/archive/2006/04/09/40108.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Sun, 09 Apr 2006 09:15:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/04/09/40108.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/40108.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/04/09/40108.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/40108.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/40108.html</trackback:ping><description><![CDATA[<ul>
				<li>Messager <br />The most trivial of these is the messenger, which simply packages information into an object<br />to be passed around, instead of passing all the pieces around separately. Note that without the<br />messenger, the code for translate() would be much more confusing to read: 
</li>
				<li>Collecting Parameter<br />Messenger’s big brother is the collecting parameter, whose job is to capture information from<br />the method to which it is passed. Generally, this is used when the collecting parameter is<br />passed to multiple methods, so it’s like a bee collecting pollen.<br />A container makes an especially useful collecting parameter, since it is already set up to<br />dynamically add objects. 
</li>
				<li>Object quantity:Singleton and object pool<br />Singleton:The key to creating a singleton is to prevent the client programmer from having any way to<br />create an object except the ways you provide. You must make all constructors private, and<br />you must create at least one constructor to prevent the compiler from synthesizing a default<br />constructor for you (which it will create using package access). 
</li>
				<li>Object pool:If this is an issue, you can create a solution involving a check-out<br />and check-in of the shared objects. see the following example<br />//: singleton:PoolManager.java<br />package singleton;<br />import java.util.*;<br />public class PoolManager {<br />private static class PoolItem {<br />boolean inUse = false;<br />Object item;<br />PoolItem(Object item) { this.item = item; }<br />}<br />private ArrayList items = new ArrayList();<br />public void add(Object item) {<br />items.add(new PoolItem(item));<br />}<br />static class EmptyPoolException extends Exception {}<br />public Object get() throws EmptyPoolException {<br />for(int i = 0; i &lt; items.size(); i++) {<br />PoolItem pitem = (PoolItem)items.get(i);<br />if(pitem.inUse == false) {<br />pitem.inUse = true;<br />return pitem.item;<br />}<br />}<br />// Fail early:<br />throw new EmptyPoolException();<br />// return null; // Delayed failure<br />}<br />public void release(Object item) {<br />for(int i = 0; i &lt; items.size(); i++) {<br />PoolItem pitem = (PoolItem)items.get(i);<br />if(item == pitem.item) {<br />pitem.inUse = false;<br />return;<br />}<br />}<br />throw new RuntimeException(item + " not found");<br />}<br />} ///:~<br />//: singleton:ConnectionPoolDemo.java<br />package singleton;<br />import junit.framework.*;<br />interface Connection {<br />Object get();<br />void set(Object x);<br />}<br />class ConnectionImplementation implements Connection {<br />public Object get() { return null; }<br />public void set(Object s) {}<br />}<br />class ConnectionPool { // A singleton<br />private static PoolManager pool = new PoolManager();<br />public static void addConnections(int number) {<br />17 z 157<br />for(int i = 0; i &lt; number; i++)<br />pool.add(new ConnectionImplementation());<br />}<br />public static Connection getConnection()<br />throws PoolManager.EmptyPoolException {<br />return (Connection)pool.get();<br />}<br />public static void releaseConnection(Connection c) {<br />pool.release(c);<br />}<br />}<br />public class ConnectionPoolDemo extends TestCase {<br />static {<br />ConnectionPool.addConnections(5);<br />}<br />public void test() {<br />Connection c = null;<br />try {<br />c = ConnectionPool.getConnection();<br />} catch (PoolManager.EmptyPoolException e) {<br />throw new RuntimeException(e);<br />}<br />c.set(new Object());<br />c.get();<br />ConnectionPool.releaseConnection(c);<br />}<br />public void test2() {<br />Connection c = null;<br />try {<br />c = ConnectionPool.getConnection();<br />} catch (PoolManager.EmptyPoolException e) {<br />throw new RuntimeException(e);<br />}<br />c.set(new Object());<br />c.get();<br />ConnectionPool.releaseConnection(c);<br />}<br />public static void main(String args[]) {<br />junit.textui.TestRunner.run(ConnectionPoolDemo.class);<br />}<br />} ///:~ 
</li>
				<li>Object decoupling:Both Proxy and State provide a surrogate class that you use in your code; the real class that<br />does the work is hidden behind this surrogate class.When you call a method in the surrogate,<br />it simply turns around and calls the method in the implementing class. These two patterns are<br />so similar that the Proxy is simply a special case of State.<br /><br />The basic idea is simple: from a base class, the surrogate is derived along with the class or<br />classes that provide the actual implementation:<br /><img height="181" alt="thinking in patterns with Java.bmp" src="http://www.blogjava.net/images/blogjava_net/junhong/thinking%20in%20patterns%20with%20Java.bmp" width="445" border="0" /><br />When a surrogate object is created, it is given an implementation to which to send all of the<br />method calls.<br />Structurally, the difference between Proxy and State is simple: a Proxy has only one<br />implementation, while State has more than one. The application of the patterns is considered<br />(in Design Patterns) to be distinct: Proxy is used to control access to its implementation,<br />while State allows you to change the implementation dynamically. However, if you expand<br />your notion of “controlling access to implementation” then the two fit neatly together. 
</li>
				<li>State: changing object behavior<br />The State pattern switches from one implementation to another during the lifetime of the<br />surrogate, in order to produce different behavior from the same method call(s). It’s a way to<br />improve the implementation of your code when you seem to be doing a lot of testing inside<br />each of your methods before deciding what to do for that method. For example, the fairy tale<br />of the frog-prince contains an object (the creature) that behaves differently depending on<br />what state it’s in. You could implement this using a boolean that you test: 
</li>
				<li>Factoring commonality<br />Applying the “once and only once” principle produces the most basic<br />pattern of putting code that changes into a method. 
</li>
				<li>Strategy: choosing the algorithm at run-time<br />Strategy also adds a “Context” which can be a surrogate class that controls the selection and<br />use of the particular strategy object—just like State!<br /><img height="181" alt="thinking in patterns with Java.bmp" src="http://www.blogjava.net/images/blogjava_net/junhong/thinking%20in%20patterns%20with%20Java.bmp" width="445" border="0" /></li>
				<li>
				</li>
				<li>Policy: generalized strategy<br />Although GoF says that Policy is just another name for strategy, their use of Strategy<br />implicitly assumes a single method in the strategy object – that you’ve broken out your<br />changing algorithm as a single piece of code.<br />Others[6] use Policy to mean an object that has multiple methods that may vary<br />independently from class to class. This gives more flexibility than being restricted to a single<br />method.<br /><font color="#ff3300">It also seems generally useful to distinguish Strategies with single methods from Policies with<br />multiple methods</font></li>
				<li>
						<font color="#ff3300">Template method<br />An important characteristic of the Template Method is that it is defined in the base class and<br />cannot be changed. It's sometimes a private method but it’s virtually always final. It calls<br />other base-class methods (the ones you override) in order to do its job, but it is usually called<br />only as part of an initialization process (and thus the client programmer isn’t necessarily able<br />to call it directly).<br />E.g<br />abstract class ApplicationFramework {<br />public ApplicationFramework() {<br />templateMethod(); // Dangerous!<br />}<br />abstract void customize1();<br />abstract void customize2();<br />final void templateMethod() {<br />for(int i = 0; i &lt; 5; i++) {<br />customize1();<br />customize2();<br />}<br />}<br />}<br />// Create a new "application":<br />class MyApp extends ApplicationFramework {<br />void customize1() {<br />System.out.print("Hello ");<br />}<br />void customize2() {<br />System.out.println("World!");<br />}<br />}</font>
				</li>
		</ul>
		<font color="#ff3300">
				<p>
						<br />
				</p>
		</font>
		<br />
		<br /><img src ="http://www.blogjava.net/junhong/aggbug/40108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-04-09 17:15 <a href="http://www.blogjava.net/junhong/archive/2006/04/09/40108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>本人写的分页的标签，和.net中的datagrid标签相似，只需要设置几个属性就可以实现分页功能了</title><link>http://www.blogjava.net/junhong/archive/2006/03/07/33960.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Tue, 07 Mar 2006 01:04:00 GMT</pubDate><guid>http://www.blogjava.net/junhong/archive/2006/03/07/33960.html</guid><wfw:comment>http://www.blogjava.net/junhong/comments/33960.html</wfw:comment><comments>http://www.blogjava.net/junhong/archive/2006/03/07/33960.html#Feedback</comments><slash:comments>31</slash:comments><wfw:commentRss>http://www.blogjava.net/junhong/comments/commentRss/33960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junhong/services/trackbacks/33960.html</trackback:ping><description><![CDATA[<img height="20" src="http://www.blogjava.net/Emoticons/QQ/15.gif" width="20" border="0" />本人写的分页的标签，和.net中的datagrid标签相似，只需要设置几个属性就可以实现分页功能了，简单方便，并且效率很高。<br />我写的有两种分页的标签，一种是全部select 出来，然后再分页的，这个系统在第一次访问的时候可能有点慢,但是在随后的访问可是很快的，因为数据已经都缓存以来的，并且是在pageContext中的，所以不会占用很多的资源。第二种是部分select 出来的，效率很高。如果有需要的朋友，请留下Email地址。<br />想要源代码的朋友请和我联系。<br />大家可以把用的情况给我说一下，以便我做出调整。<br /><font color="#ff0000"><br /><b>本程序作了升级，请大家下载下边的这个连接进行下载，以便使用最新的版本。<br />这次升级修复了几个bugs.</b></font><br /><font color="#ff0000"><b><a href="/Files/junhong/splitpage.rar">请下载Splitpage.rar</a></b></font><br /><img style="WIDTH: 404px; HEIGHT: 611px" height="611" alt="testsplitpage.JPG" src="http://www.blogjava.net/images/blogjava_net/junhong/testsplitpage.JPG" width="399" border="0" /><br /><img src ="http://www.blogjava.net/junhong/aggbug/33960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junhong/" target="_blank">junhong</a> 2006-03-07 09:04 <a href="http://www.blogjava.net/junhong/archive/2006/03/07/33960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>