hk2000c技術(shù)專欄

          技術(shù)源于哲學(xué),哲學(xué)來源于生活 關(guān)心生活,關(guān)注健康,關(guān)心他人

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            111 隨筆 :: 1 文章 :: 28 評(píng)論 :: 0 Trackbacks

          #

          Liferay 二次開發(fā)太困難,花了N*N個(gè)小時(shí),除了搭建了一套可以調(diào)試部署的環(huán)境之外,部署了幾個(gè)示例實(shí)例之外,幾乎毫無建樹。
          liferay代碼可讀性是我見過最差的,乍看覺得可能是反編譯的代碼?;柽^去,我要罵娘了。什么編碼規(guī)范!嘔了?。?!
          網(wǎng)上support 的效率非常低,幾乎沒人幫忙,遇到問題簡(jiǎn)直就是災(zāi)難。繼續(xù)下去的信心簡(jiǎn)直快要破滅了。

          Jetspeed 2 就比較好了 , 源代碼,文檔,二次開發(fā)比較容易。
          而且國內(nèi)弄得人也多,可以相互交流支持,不像liferay 一條小道走不到底的感覺。

          不過Liferay 還是比較好的一個(gè)項(xiàng)目,速度比jetspeed2 不知道快多少,而且擁有很多很實(shí)用的portlet .
          但愿 Jetspeed2 會(huì)做得更好。畢竟開源需要眾人去做,才會(huì)有生命力。

          posted @ 2006-08-08 23:05 hk2000c 閱讀(3125) | 評(píng)論 (6)編輯 收藏

          準(zhǔn)備每個(gè)知識(shí)點(diǎn)的幾個(gè)例子,梳理一下自己的知識(shí)樹結(jié)構(gòu),避免時(shí)間長了,技術(shù)生疏

          暫時(shí)需要整理的知識(shí)點(diǎn)例子有

          tag

          jms

          oscache

          hiberante

          spring

          SWF spring web flow

          struts tiles

          axis webservice

          準(zhǔn)備閱讀相關(guān)的JSR標(biāo)準(zhǔn)
          編寫一個(gè)Axis的例子


          pdf liberay

          nutch search

          SSO


          posted @ 2006-08-08 15:25 hk2000c 閱讀(332) | 評(píng)論 (0)編輯 收藏

          Portlet 形態(tài)

          Portlet 的形態(tài)直白的說,就是 portlet 功能的表現(xiàn)形式。通常, portlet 根據(jù)他們自己功能的不同,執(zhí)行不同的任務(wù)以及生成不同的內(nèi)容。 Portlet 形態(tài)直接預(yù)示著他們擔(dān)任什么樣的功能并且將會(huì)顯示什么樣的內(nèi)容。當(dāng) portlet 被調(diào)用的時(shí)候, portlet 容器會(huì)為其提供的一個(gè)的當(dāng)前 portal 形態(tài)。 Portlet 可以很方便的在處理一個(gè) action 請(qǐng)求的時(shí)候改變它的形態(tài)。

          ?????? Portal 規(guī)范定義了 3 個(gè) portlet 形態(tài)。他們分別是 VIEW , EDIT 以及 HELP 。 PortletMode 類定義了這些形態(tài)的常量。

          ?????? Portal 形態(tài)還用于對(duì)用戶的權(quán)限功能控制,比方說一個(gè)未認(rèn)證用戶只能察看 portlet VIEW 以及 HELP 形態(tài),而認(rèn)證用戶則能訪問 portlet EDIT 形態(tài)。

          ?

          8.1 Portlet VIEW 形態(tài)

          ?????? Portlet VIEW 形態(tài)的主要功能是通過生成標(biāo)記語言來顯示 portlet 的當(dāng)前狀態(tài)。比方說,一個(gè) portlet VIEW 形態(tài)可能包含一到兩個(gè)頁面,用戶可以瀏覽或者做某些操作。它也可能僅僅是一張靜態(tài)頁面而不做任何事情。

          ?????? 開發(fā)者可以簡(jiǎn)單的通過重載 GenericPortlet doView() 方法來獲得這項(xiàng)功能

          ?????? Portlet 必須支持 VIEW 形態(tài)

          ?

          8.2 EDIT 形態(tài)

          ?????? EDIT 形態(tài)下面, portlet 應(yīng)該提供相關(guān)的內(nèi)容以及邏輯給用戶,以便能夠讓用戶可以自定義 portlet 行為。一個(gè) EDIT 形態(tài)的 portlet 應(yīng)該有 1 到多個(gè)窗口,這樣用戶就能從這些窗口進(jìn)入他們自己自定義的數(shù)據(jù)了。

          ?????? 通常, EDIT 形態(tài)的 portlet 會(huì)設(shè)置或者更新 Portlet 參數(shù)。參考 portlet 參數(shù)一節(jié)獲得更多的細(xì)節(jié)。

          開發(fā)者可以簡(jiǎn)單的通過重載 GenericPortlet doEdit() 方法來獲得這項(xiàng)功能

          Portlet 不必支持 EDIT 形態(tài)

          8.3 HELP 形態(tài)

          ?????? help 形態(tài)下面, portlet 應(yīng)該提供 portlet 本身的相關(guān)幫助信息。一個(gè) portlet 的幫助信息可以是介紹 portlet 的完整幫助或者是內(nèi)容相關(guān)的幫助文本。

          開發(fā)者可以簡(jiǎn)單的通過重載 GenericPortlet doHelp() 方法來獲得這項(xiàng)功能

          Portlet 不必支持 HELP 形態(tài)

          8.4 portlet 自定義形態(tài)

          ?????? Portlal 的提供者可以自定義 portlet 形態(tài)用來提供自己指定的功能

          ?????? 要使用自定義 Portlet 形態(tài),首先需要在部署描述器中添加 custom-portlet-mode 元素 ,其次需要在運(yùn)行期找到該形態(tài)的 portal 實(shí)現(xiàn)。如果在運(yùn)行期間找不到該自定義形態(tài)的 portal 實(shí)現(xiàn),這個(gè) portlet 就不應(yīng)該被調(diào)用

          ?????? 打個(gè)比方, portlet 應(yīng)用需要支持 clipsboard 以及 config 形態(tài)的 portlet ,那么部署描述器里面可能這么寫:

          ?

          <portlet-app>

          ...

          <custom-portlet-mode>

          <description>Creates content for Cut and Paste</description>

          <name>clipboard</name>

          </custom-portlet-mode>

          <custom-portlet-mode>

          <description>Provides administration functions</description>

          <name>config</name>

          </custom-portlet-mode>

          ...

          </portlet-app>

          ?

          在《擴(kuò)展 Portlet 形態(tài)》附錄中列出了建議的 portlet 形態(tài)的命名參考以及他們的使用參考。如果 portlet 在部署描述器中定義了一個(gè)自定義的形態(tài),并且 portal 容器實(shí)現(xiàn)了這種形態(tài)的話,那么 Portal 容器可以立即自動(dòng)地映射這種支持形態(tài)。

          ?

          ?

          8.5 GenericPorlet 渲染方法的處理

          ?????? GenericPorlet 通過 render 方法來分發(fā)用戶的請(qǐng)求給 doView , doEdit , doHelp 方法。這個(gè)指定形態(tài)分發(fā)的動(dòng)作在 doDispatch 里面都會(huì)指明。如果 portal 容器提供者需要支持一種新的形態(tài),那么必須重載 doDispatch 方法。

          ?

          8.6???? 定義 portlet 形態(tài)

          ?

          Portlet 通過在它的部署描述器內(nèi)配置 portlet 形態(tài)來獲得它能使用的 portal 容器支持的形態(tài)。每個(gè) Portlet 都必須支持 VIEW 形態(tài),而且 VIEW 形態(tài)無需特別指定。

          下面的例子顯示了一個(gè)配置 Portlet 形態(tài)的樣本:

          ...

          <supports>

          <mime-type>text/html</mime-type>

          <portlet-mode>edit</portlet-mode>

          <portlet-mode>help</portlet-mode>

          ...

          </supports>

          <supports>

          <mime-type>text/vnd.wap.wml</mime-type>

          <portlet-mode>help</portlet-mode>

          ...

          </supports>

          ...

          ?

          以上的配置說明了,該 portlet html 標(biāo)記語言下支持 edit ,help 形態(tài),當(dāng)然還支持默認(rèn)的 view 形態(tài)。在 wml 語言環(huán)境下,支持 help 以及 view 形態(tài)。

          ?

          ?

          ?===


          以上是翻譯節(jié)選,以后會(huì)陸續(xù)刊出其它章節(jié)
          歡迎轉(zhuǎn)載共同交流

          ?

          posted @ 2006-07-12 11:01 hk2000c 閱讀(1716) | 評(píng)論 (0)編輯 收藏

          裝載JBoss 應(yīng)用的時(shí)候出現(xiàn)經(jīng)典log錯(cuò)誤 org.apache.commons.logging.LogConfigurationException: Class org.apache. commons.logging.impl.Log4JCategoryLog does not implement Log

          檢查應(yīng)用路徑 %App_path%/WEB-INF/lib ,把下面 log4j.jar以及 commons-logging.jar 均刪除,問題解決

          原理解釋文章在以下位置

          http://www.qos.ch/logging/thinkAgain.jsp

          以前也遇到類似問題

          如果是tomcat 5.x 版本,需要這樣處理

          刪除tomcat/webapps/%apps%/WEB-INF/lib/下面的
          commons-logging-api-1.0.4.jar 包
          然后換成

          log4j.jar以及 commons-logging.jar

          posted @ 2006-04-28 23:21 hk2000c 閱讀(284) | 評(píng)論 (0)編輯 收藏

               摘要: Java Authentication Authorization Service(JAAS,Java驗(yàn)證和授權(quán)API)提供了靈活和可伸縮的機(jī)制來保證客戶端或服務(wù)器端的Java程序。Java早期的安全框架強(qiáng)調(diào)的是通過驗(yàn)證代碼的來源和作者,保護(hù)用戶避免受到下載下來的代碼的攻擊。JAAS強(qiáng)調(diào)的是通過驗(yàn)證誰在運(yùn)行代碼以及他/她的權(quán)限來保護(hù)系統(tǒng)面受用戶的攻擊。它讓你能夠?qū)⒁恍?biāo)準(zhǔn)的安全機(jī)制,例如Solar...  閱讀全文
          posted @ 2006-03-23 08:07 hk2000c 閱讀(6218) | 評(píng)論 (0)編輯 收藏

               摘要: 有一部分xml解析器使用者認(rèn)為 JDOM 很慢,至少比起Dom4j來說效率不快。其實(shí)JDOM和DOM4J一樣,同屬優(yōu)秀的開源XML解析器,?完全不必這樣擔(dān)心。?現(xiàn)在就實(shí)際拿一些實(shí)際使用的例子,作為簡(jiǎn)單的測(cè)試用例,對(duì)JDOM以及DOM4J最基本的文檔解析功能來說明這個(gè)問題。?JDOM測(cè)試用例如下:??? ? public Document getDoc(String filename) throws...  閱讀全文
          posted @ 2005-03-21 05:00 hk2000c 閱讀(873) | 評(píng)論 (0)編輯 收藏

               摘要: Ant 介紹以及基本使用指南 Ant 是著名 Java 開源組織 Apache 的一個(gè)項(xiàng)目,是一個(gè)基于 java 的 build 工具。它可以使你通過 ant 腳本語言,自動(dòng)你...  閱讀全文
          posted @ 2004-12-03 19:21 hk2000c 閱讀(264) | 評(píng)論 (0)編輯 收藏

          克服J2SE 1.3 ~ 1.4不兼容問題
          --從反射API和ANT獲得幫助



          概要
          ??? 如果你要實(shí)現(xiàn)JavaAPI中的一個(gè),那么可能是件比較痛苦的事情。你經(jīng)常會(huì)需要實(shí)現(xiàn)許多交叉依賴的接口。對(duì)新特性的需求促成了升級(jí)現(xiàn)有的JavaAPI,這就造成了提供這些API的供應(yīng)商對(duì)他們的相關(guān)實(shí)現(xiàn)不斷的升級(jí)以維持相關(guān)功能。隨著這些API的升級(jí)更改越來越頻繁,API代碼的不兼容使你不得不分別維護(hù)新舊版本的代碼庫。這直接到導(dǎo)致了你維護(hù)成本和難度的增加。本文演示了解決此問題的技術(shù),揭示了如何僅使用一個(gè)代碼庫編譯不同JavaAPI版本的代碼。



          ??? 現(xiàn)在非常多的API被加入到到Java的標(biāo)準(zhǔn)庫中,比如JDBC。這樣做的好處是,Java可選包在部署時(shí)不必被綁定到相關(guān)的部署應(yīng)用中去。這些API由專門的專業(yè)開發(fā)小組實(shí)現(xiàn),在實(shí)際的使用當(dāng)中這些API變得越來越受歡迎,使用的深度及廣度也在不斷的增加。但是有時(shí)候?qū)σ恍〢PI升級(jí)會(huì)變得使一些類及方法不可用。開發(fā)小組寧愿讓這些API包成為可選組件而不是作為Java標(biāo)準(zhǔn)支持庫的形式來發(fā)布。但是一旦加入標(biāo)準(zhǔn)庫中的API包,就像是和用戶簽定了終生契約,想再成為可選包是不可能的。所以作為用戶的你,可能會(huì)突然發(fā)現(xiàn)你一下子自己的代碼庫變成了不兼容的2個(gè)代碼庫,一個(gè)是使用新API的代碼庫,另一個(gè)是使用舊API的代碼庫。你可能會(huì)以為情況不像你想象的那樣糟糕。我這里舉一個(gè)簡(jiǎn)單的例子。J2SE1.4中由于對(duì)JDBC中的一些API的升級(jí)使的java.sql.Connection 不能同時(shí)被1.3 及 1.4 版本編譯通過。你可能會(huì)遇到我這樣的困境:我可能需要實(shí)現(xiàn)java.sql.Connection這個(gè)接口,但是我的代碼需要同時(shí)通過1.3 及1.4 得編譯。但是我不想同時(shí)維護(hù)2個(gè)版本的代碼庫。所以我開始尋找更好的解決方法。
          ??? 如果你依賴于javac來編譯你的應(yīng)用的話,那么很不幸,Java著名的一次編寫,到處運(yùn)行(WORA)并不包括WOCA(一次編寫,到處編譯^_^;)。
          不過別太沮喪,編碼的反射技巧以及編譯的Ant技巧是你能夠安然過關(guān)。我能夠僅僅使用一組Java文件以及Ant工具,就能使一個(gè)版本同時(shí)編譯
          在1.3 和1.4 版本下面。別急,在我結(jié)識(shí)解決辦法之前,讓我先詳細(xì)的解釋一下問題的描述。

          可憐人的連接池(PS:Poor man's connection pool ,很有意思的一句話)
          ??? 兩年前,我的公司需要一個(gè)連接池,但是又不肯出錢買一個(gè)。當(dāng)時(shí)并沒有什么免費(fèi)的東東可以使用,所以我們自己寫了一個(gè)連接池。為了能更好的跟蹤在整個(gè)應(yīng)用中連接的情況,我們寫了一個(gè)com.icentris.sql.ConnectionWrapper類,它實(shí)現(xiàn)了java.sql.Connection 接口以及其他的一些包裝類(實(shí)現(xiàn)了另外的一些的java.sql 接口)。這些包裝類僅僅是跟蹤我們應(yīng)用中的數(shù)據(jù)庫使用,以及通過方法調(diào)用真正的
          數(shù)據(jù)庫資源。
          ??? 當(dāng)J2SE1.4來的時(shí)候,我們自然而然的想到升級(jí)我們提供給客戶的應(yīng)用,使這些應(yīng)用的性能得到很多提升。當(dāng)然,我們也需要保留1.3版本,因?yàn)橛行┛蛻舾静恍枰?jí)到1.4。我們氣惱的發(fā)現(xiàn),如果我們不修改,我們的ConnectionWrapper 以及其他JDBC封裝類根本通不過J2SE1.4的編譯。
          ??? 為了文章的簡(jiǎn)明,我通過使用ConnectionWrapper 這個(gè)類來演示我對(duì)所有其他不能夠通過J2SE1.4的類所使用的技術(shù)。如果我按照新的API標(biāo)準(zhǔn),那么我不得不添加幾個(gè)方法到ConnectionWrapper中去,接下來2個(gè)大問題擺在了面前:
          1.因?yàn)槲业陌b類需要經(jīng)歷方法調(diào)用,我將不得不調(diào)用在J2SE1.3 sql類中并不存在的方法。
          2.因?yàn)橐恍┬碌姆椒ㄉ婕暗揭恍┬鲁霈F(xiàn)的類,我將不得不在編譯中面對(duì)那些在J2SE1.3中并不存在的類。

          反射提供了援助
          一些代碼可以很方便的解釋第一個(gè)問題。但是我的ConnectionWrapper 封裝了java.sql.Connection , 所有的我的例子
          依賴于在構(gòu)造方法中的變量 realConnection :

          private java.sql.Connection realConnection = null;
          ?
          ? public ConnectionWrapper(java.sql.Connection connection) {
          ??? realConnection = connection;
          ? }

          ??? 為了看清楚我怎么做到解決版本不兼容問題,讓我們仔細(xì)看一下setHoldability(int)(這個(gè)在J2SE1.4被聲明的新方法)
          public void setHoldability(int holdability) throws SQLException {
          ??? realConnection.setHoldability( holdability );
          ? }

          ??? 很不幸,這個(gè)方法在J2SE1.3中顯然通不過編譯,這就陷入了2難的尷尬境地。為了解決這一情況,我假定setHoldability() 將只會(huì)在J2SE1.4
          下面被調(diào)用,所以我使用了反射機(jī)制來調(diào)用該方法。

          public void setHoldability(int holdability) throws SQLException {
          ??? Class[] argTypes = new Class[] { Integer.TYPE };
          ??? Object[] args = new Object[] {new Integer(holdability)};
          ??? callJava14Method("setHoldability", realConnection, argTypes, args);
          ? }

          ? public static Object callJava14Method(String methodName, Object instance,
          ? Class[] argTypes, Object[] args)
          ??? throws SQLException
          ? {
          ??? try {
          ????? Method method = instance.getClass().getMethod(methodName, argTypes);
          ????? return method.invoke(instance, args );
          ??? } catch (NoSuchMethodException e) {
          ????? e.printStackTrace();
          ????? throw new SQLException("Error Invoking method (" + methodName + "): "
          ????? + e);
          ??? } catch (IllegalAccessException e) {
          ????? e.printStackTrace();
          ????? throw new SQLException("Error Invoking method (" + methodName + "): "
          ????? + e);
          ??? } catch (InvocationTargetException e) {
          ????? e.printStackTrace();
          ????? throw new SQLException("Error Invoking method (" + methodName + "): "
          ????? + e);
          ??? }
          ? }

          ??? 現(xiàn)在我有了setHoldability() 方法,因此能順利通過J2SE1.4的編譯。原理是我并不直接調(diào)用J2SE1.3中間java.sql.Connection并不存在的方法,
          而是轉(zhuǎn)為通過讓setHoldability調(diào)用callJava14Method這個(gè)通用方法來調(diào)用,然后在一個(gè)SQLException 里封裝所有的異常。這樣就達(dá)到我預(yù)期的效果。
          現(xiàn)在所有的在J2SE1.4中新方法都工作的很好,在J2SE1.3的老版本下也能順利編譯而且工作正?!,F(xiàn)在我來著手解決第二個(gè)問題。
          就是如何在應(yīng)用中能夠找到一個(gè)方法能夠使用J2SE1.3中并不存在的新的類。

          Ant 是答案
          在J2SE1.4中,java.sql.Connection 依賴于一個(gè)新的類java.sql.Savepoint。因?yàn)檫@個(gè)類在java.sql 包中,所以你不可能把它加入到J2SE1.3中去。Java不允許任何的第三方擴(kuò)展包加入它的核心包(java.* 以及 javax.* )中去。 因此挑戰(zhàn)來了,在J2SE1.4下調(diào)用這個(gè)新的java.sql.Savepoint 類,但同時(shí)需要代碼能夠在J2SE1.3下面得到編譯以及能夠運(yùn)行。很簡(jiǎn)單,不是嗎?所有回答"Yes"的人都會(huì)得到一個(gè)榛仁巧克力餅(PS:哈哈,我回答了,可是沒有:P)。至少現(xiàn)在我找到了答案,使問題變得很簡(jiǎn)單了。
          ? 首先我插入了下面一條有條件的import語句
          // Comment_next_line_to_compile_with_Java_1.3
          ? import java.sql.Savepoint;

          ??? 然后我找到了一個(gè)能夠在J2SE1.3下面注釋掉import的方法。非常簡(jiǎn)單,使用如下Ant 語句就可以了:
          <replace>
          ??? <replacetoken>Comment_next_line_for_Java_1.3&#010;</replacetoken>
          ??? <replacevalue>Comment_next_line_for_Java_1.3&#010;//</replacevalue>
          ? </replace>

          ??? 這個(gè)Ant 的 replace 標(biāo)簽 有好幾個(gè)標(biāo)簽選項(xiàng),在以后我給出的全部例子里有很多。在這里面最重要的是使用<replacevalue>來替換<replacetoken> 。&#010;在XML里面的意思是換行。在J2SE1.4下,沒什么會(huì)發(fā)生, 但是在J2SE1.3下面一個(gè)import聲明被注釋掉了。
          // Comment_next_line_to_compile_with_Java_1.3
          ? //import java.sql.Savepoint;

          ??? 但是我在代碼中Savepoint仍在使用public Savepoint setSavepoint(String name) throws SQLException { . . .}。不過我只在J2SE1.4使用這些方法類,在J2SE1.3中只要能編譯就可以了。我發(fā)現(xiàn)只要我有一個(gè)我自己的Savepoint 類在我的包中,我的代碼就能夠通過編譯,而且不用任何的import包。但是我又要同時(shí)在這條import 語句不被注釋的同時(shí)我自己的Savepoint類被忽略掉。因此我造了一個(gè)空的com.icentris.sql.Savepoint類,這個(gè)可能(除了JavaDoc)是最短的有效類:
          package com.icentris.sql;

          ? /** Dummy class to allow ConnectionWrapper to implement java.sql.Connection
          ?? * and still compile under J2SE 1.3 and J2SE 1.4. When compiled
          ?? * under J2SE 1.3, this class compiles as a placeholder instead of the
          ?? * missing java.sql.Savepoint (not in J2SE 1.3).? When compiled
          ?? * under J2SE 1.4, this class is ignored and ConnectionWrapper uses the
          ?? * java.sql.Savepoint that is new in J2SE 1.4.
          ?? */
          ? public class Savepoint {}

          ??? 在J2SE1.4下我能夠正確的import java.sql.Savepoint類,而在J2SE1.3下面Ant注釋了這條import語句。因此這個(gè)Savepoint就被替換成了我這個(gè)包里面寫的一個(gè)空的Savepoint類。所以我現(xiàn)在就能加入任何引用到Savepoint類的方法,同樣的在這些新方法中使用剛才所說的反射方法。
          // Comment_next_line_to_compile_with_Java_1.3
          ? import java.sql.Savepoint;

          ? . . .
          ??? public Savepoint setSavepoint() throws SQLException {
          ????? Class[] argTypes = new Class[0];
          ????? Object[] args = new Object[0];
          ????? return (Savepoint) callJava14Method("setSavepoint", realConnection,
          ????? argTypes, args);
          ??? }

          ??? public Savepoint setSavepoint(String name) throws SQLException {
          ????? Class[] argTypes = new Class[] { String.class };
          ????? Object[] args = new Object[] { name };
          ????? return (Savepoint) callJava14Method("setSavepoint", realConnection,
          ????? argTypes, args);
          ??? }

          ??? public void rollback(Savepoint savepoint) throws SQLException {
          ????? Class[] argTypes = new Class[] { Savepoint.class };
          ????? Object[] args = new Object[] { savepoint };
          ????? callJava14Method("rollback", realConnection, argTypes, args);
          ??? }

          ??? public void releaseSavepoint(Savepoint savepoint) throws SQLException {
          ????? Class[] argTypes = new Class[] { Savepoint.class };
          ????? Object[] args = new Object[] { savepoint };
          ????? callJava14Method("releaseSavepoint", realConnection, argTypes, args);
          ??? }

          ??? 現(xiàn)在我所要做的就是能夠使Ant 識(shí)別 J2SE1.3版,然后能夠使這條import 語句被注釋掉。
          <target name="compile">
          ??? <antcall target="undoJava13Tweaks" />
          ??? <antcall target="doJava13Tweaks" />
          ??? <javac srcdir="src" destdir="WEB-INF/classes" debug="on">
          ????? <classpath>
          ??????? <fileset dir="WEB-INF/lib">
          ????????? <include name="*.jar"/>
          ??????? </fileset>
          ????? </classpath>
          ??? </javac>
          ??? <antcall target="undoJava13Tweaks" />
          ? </target>

          ? <target description="Find out if we're being compiled on Java 1.3"
          ? name="isJava13">
          ??? <echo message="java.specification.version=[${java.specification.version}]"/>
          ??? <condition property="isJava13">
          ????? <equals arg1="${java.specification.version}" arg2="1.3" />
          ??? </condition>
          ? </target>

          ? <target description="There are a couple tweaks I have to do to compile under Java 1.3"
          ??? name="doJava13Tweaks" depends="isJava13" if="isJava13">
          ??? <echo message="This is Java 1.3, doing Tweaks!" />
          ??? <replace dir="src/com/icentris/" summary="true">
          ????? <include name="sql/ConnectionWrapper.java" />
          ????? <replacetoken>Comment_next_line_for_Java_1.3&#010;</replacetoken>
          ????? <replacevalue>Comment_next_line_for_Java_1.3&#010;//</replacevalue>
          ??? </replace>
          ? </target>

          ? <target description="Let's undo Java 1.3 tweaks" name="undoJava13Tweaks">
          ??? <replace dir="src/com/icentris/" summary="true">
          ????? <include name="sql/ConnectionWrapper.java" />
          ????? <replacetoken>Comment_next_line_for_Java_1.3&#010;//</replacetoken>
          ????? <replacevalue>Comment_next_line_for_Java_1.3&#010;</replacevalue>
          ??? </replace>
          ? </target>

          ??? 注意編譯目標(biāo)在調(diào)用doJava13Tweaks的前后都調(diào)用了undoJava13Tweaks。如果萬一javac編譯失敗的話,我們可以恢復(fù)以前的編譯版本。

          你沒有必要同時(shí)維護(hù)2個(gè)應(yīng)用實(shí)現(xiàn)
          ??? 對(duì)于Java來說,新的API升級(jí)所帶來的新的方法以及新的類/接口并不是新鮮事。一般而言,加入的新方法以及新的類的同時(shí),會(huì)考慮到向上兼容的問題來照顧老API用戶。但是當(dāng)升級(jí)的API屬于Java核心包內(nèi)時(shí),就會(huì)很麻煩。因?yàn)镴ava不允許對(duì)這些核心包的任何的外在更改或者是增加。通常這會(huì)引起針對(duì)不同版本API而維護(hù)不同版本代碼樹的需要。但是,就像上面的例子所演示的那樣,你只要維護(hù)一棵代碼樹就能夠在不同的版本的API下,編譯運(yùn)行。這個(gè)反射的API允許你調(diào)用并不存在的方法,而Ant能通過識(shí)別不同的Java編譯版本而對(duì)相應(yīng)的import包進(jìn)行調(diào)整。雖然上面的所舉的例子僅僅是一個(gè)簡(jiǎn)單的演示,但是在實(shí)際工作當(dāng)中,利用這些簡(jiǎn)單的技術(shù),解決了許多J2SE1.4和J2SE1.3的版本問題。我相信通過這些技術(shù),你可以在頻繁的Java版本升級(jí)中不必為同時(shí)維護(hù)兩棵代碼庫而煩惱。

          ?


          關(guān)于作者:
          Sam Mefford是iCentris的首席架構(gòu)設(shè)計(jì)師。對(duì)于系統(tǒng)的兼容性重視程度,Sam Mefford是放在第一位的。他帶領(lǐng)的團(tuán)隊(duì)致力于使用一個(gè)代碼庫
          向眾多的客戶公司提供應(yīng)用發(fā)布方案。這些部署方案使用的應(yīng)用服務(wù)器有Tomcat,Weblogic, Resin, Orion以及 Websphere;在數(shù)據(jù)庫方面有
          Oracle,PostgreSQL, MySQL,以及 Informix;以及多個(gè)Java運(yùn)行期環(huán)境。

          譯者: SpikeWang (CSDN ID:hk2000c)

          東華大學(xué)計(jì)算機(jī)系畢業(yè),現(xiàn)在同濟(jì)大學(xué)攻讀軟件工程碩士學(xué)位。致力于J2EE方面的企業(yè)級(jí)應(yīng)用開發(fā)以及研究工作。


          About Copyright:
          原文章版權(quán)屬于作者 Sam Mefford
          譯文版權(quán)屬于譯者及原文作者共同所有,歡迎轉(zhuǎn)載,但要注上譯者及原文作者。


          參考資源:
          The API for java.sql.Connection (J2SE 1.3):
          http://java.sun.com/j2se/1.3/docs/api/java/sql/Connection.html

          The API for java.sql.Connection (J2SE 1.4):
          http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Connection.html

          The JDBC API:
          http://java.sun.com/products/jdbc/

          Java Core Reflection參考概要:
          http://java.sun.com/j2se/1.3/docs/guide/reflection/spec/java-reflectionTOC.doc.html

          the Reflection API指南:
          http://java.sun.com/docs/books/tutorial/reflect/

          The Javadoc (java.lang.reflect):
          http://java.sun.com/j2se/1.3/docs/api/java/lang/reflect/package-summary.html

          ?

          ?

          ?

          ?


          posted @ 2003-10-03 22:27 hk2000c 閱讀(159) | 評(píng)論 (0)編輯 收藏

          JDOM 介紹及使用指南

          一、JDOM 簡(jiǎn)介
          JDOM是一個(gè)開源項(xiàng)目,它基于樹型結(jié)構(gòu),利用純JAVA的技術(shù)對(duì)XML文檔實(shí)現(xiàn)解析、生成、序列化以及多種操作。
          JDOM 直接為JAVA編程服務(wù)。它利用更為強(qiáng)有力的JAVA語言的諸多特性(方法重載、集合概念以及映射),把SAX和DOM的功能有效地結(jié)合起來。
          在使用設(shè)計(jì)上盡可能地隱藏原來使用XML過程中的復(fù)雜性。利用JDOM處理XML文檔將是一件輕松、簡(jiǎn)單的事。
          JDOM 在2000年的春天被Brett McLaughlin和Jason Hunter開發(fā)出來,以彌補(bǔ)DOM及SAX在實(shí)際應(yīng)用當(dāng)中的不足之處。
          這些不足之處主要在于SAX沒有文檔修改、隨機(jī)訪問以及輸出的功能,而對(duì)于DOM來說,JAVA程序員在使用時(shí)來用起來總覺得不太方便。
          DOM的缺點(diǎn)主要是來自于由于Dom是一個(gè)接口定義語言(IDL),它的任務(wù)是在不同語言實(shí)現(xiàn)中的一個(gè)最低的通用標(biāo)準(zhǔn),并不是為JAVA特別設(shè)計(jì)的。JDOM的最新版本為JDOM Beta 9。最近JDOM被收錄到JSR-102內(nèi),這標(biāo)志著JDOM成為了JAVA平臺(tái)組成的一部分。


          二、JDOM 包概覽
          JDOM是由以下幾個(gè)包組成的
          org.JDOM
          org.JDOM.input
          org.JDOM.output
          org.JDOM.adapters
          org.JDOM.transform

          三、JDOM 類說明

          org.JDOM
          這個(gè)包里的類是你解析xml文件后所要用到的所有數(shù)據(jù)類型。
          Attribute
          CDATA
          Coment
          DocType
          Document
          Element
          EntityRef
          Namespace
          ProscessingInstruction
          Text

          org.JDOM.transform
          在涉及xslt格式轉(zhuǎn)換時(shí)應(yīng)使用下面的2個(gè)類
          JDOMSource
          JDOMResult

          org.JDOM.input
          輸入類,一般用于文檔的創(chuàng)建工作
          SAXBuilder
          DOMBuilder
          ResultSetBuilder

          org.JDOM.output
          輸出類,用于文檔轉(zhuǎn)換輸出
          XMLOutputter
          SAXOutputter
          DomOutputter
          JTreeOutputter

          使用前注意事項(xiàng):
          1.JDOM對(duì)于JAXP 以及 TRax 的支持
          JDOM 支持JAXP1.1:你可以在程序中使用任何的parser工具類,默認(rèn)情況下是JAXP的parser。
          制定特別的parser可用如下形式
          SAXBuilder parser
          ? = new SAXBuilder("org.apache.crimson.parser.XMLReaderImpl");
          ?Document doc = parser.build("http://www.cafeconleche.org/");
          ?// work with the document...
          JDOM也支持TRaX:XSLT可通過JDOMSource以及JDOMResult類來轉(zhuǎn)換(參見以后章節(jié))
          2.注意在JDOM里文檔(Document)類由org.JDOM.Document 來表示。這要與org.w3c.dom中的Document區(qū)別開,這2種格式如何轉(zhuǎn)換在后面會(huì)說明。
          以下如無特指均指JDOM里的Document。


          四、JDOM主要使用方法
          1.Ducument類
          (1)Document的操作方法:
          Element root = new Element("GREETING");
          Document doc = new Document(root);
          root.setText("Hello JDOM!");
          或者簡(jiǎn)單的使用Document doc = new Document(new Element("GREETING").setText("Hello JDOM!t"));

          這點(diǎn)和DOM不同。Dom則需要更為復(fù)雜的代碼,如下:
          DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
          DocumentBuilder builder =factory.newDocumentBuilder();
          Document doc = builder.newDocument();
          Element root =doc.createElement("root");
          Text text = doc.createText("This is the root");
          root.appendChild(text);
          doc.appendChild(root);


          注意事項(xiàng):JDOM不允許同一個(gè)節(jié)點(diǎn)同時(shí)被2個(gè)或多個(gè)文檔相關(guān)聯(lián),要在第2個(gè)文檔中使用原來老文檔中的節(jié)點(diǎn)的話。首先需要使用detach()把這個(gè)節(jié)點(diǎn)分開來。

          (2)從文件、流、系統(tǒng)ID、URL得到Document對(duì)象:
          DOMBuilder builder = new DOMBuilder();
          Document doc = builder.build(new File("jdom_test.xml"));

          SAXBuilder builder = new SAXBuilder();
          Document doc = builder.build(url);
          在新版本中DOMBuilder 已經(jīng)Deprecated掉 DOMBuilder.builder(url),用SAX效率會(huì)比較快。

          這里舉一個(gè)小例子,為了簡(jiǎn)單起見,使用String對(duì)象直接作為xml數(shù)據(jù)源:

          ?public jdomTest() {
          ??? String textXml = null;
          ??? textXml = "<note>";
          ??? textXml = textXml +
          ??????? "<to>aaa</to><from>bbb</from><heading>ccc</heading><body>ddd</body>";
          ??? textXml = textXml + "</note>";
          ??? SAXBuilder builder = new SAXBuilder();
          ??? Document doc = null;
          ??? Reader in= new StringReader(textXml);
          ??? try {
          ????? doc = builder.build(in);
          ????? Element root = doc.getRootElement();
          ????? List ls = root.getChildren();//注意此處取出的是root節(jié)點(diǎn)下面的一層的Element集合
          ????? for (Iterator iter = ls.iterator(); iter.hasNext(); ) {
          ??????? Element el = (Element) iter.next();
          ??????? if(el.getName().equals("to")){
          ???????? System.out.println(el.getText());
          ??????? }
          ????? }
          ??? }
          ??? catch (IOException ex) {
          ????? ex.printStackTrace();
          ??? }
          ??? catch (JDOMException ex) {
          ????? ex.printStackTrace();
          ??? }
          ? }

          很簡(jiǎn)單把。


          (3)DOM的document和JDOM的Document之間的相互轉(zhuǎn)換使用方法,簡(jiǎn)單!
          DOMBuilder builder = new DOMBuilder();
          org.jdom.Document jdomDocument = builder.build(domDocument);
          // work with the JDOM document…

          DOMOutputter converter = new DOMOutputter();
          org.w3c.dom.Document domDocument = converter.output(jdomDocument);
          // work with the DOM document…

          2.XML文檔輸出
          XMLOutPutter類:
          JDOM的輸出非常靈活,支持很多種io格式以及風(fēng)格的輸出
          Document doc = new Document(...);
          XMLOutputter outp = new XMLOutputter();
          // Raw output
          outp.output(doc, fileOutputStream);
          // Compressed output
          outp.setTextTrim(true);
          outp.output(doc, socket.getOutputStream());
          // Pretty output
          outp.setIndent(" ");
          outp.setNewlines(true);
          outp.output(doc, System.out);
          ......
          詳細(xì)請(qǐng)參閱最新的JDOM API手冊(cè)


          3.Element 類:
          (1)瀏覽Element樹
          //獲得根元素element
          Element root = doc.getRootElement();
          // 獲得所有子元素的一個(gè)list
          List allChildren = root.getChildren();
          // 獲得指定名稱子元素的list
          List namedChildren = root.getChildren("name");
          //獲得指定名稱的第一個(gè)子元素
          Element child = root.getChild("name");
          (這里的List是java.util.List)

          JDOM給了我們很多很靈活的使用方法來管理子元素
          List allChildren = root.getChildren();
          // 刪除第四個(gè)子元素
          allChildren.remove(3);
          // 刪除叫“jack”的子元素
          allChildren.removeAll(root.getChildren("jack"));

          root.removeChildren("jack"); // 便捷寫法
          // 加入
          allChildren.add(new Element("jane"));

          root.addContent(new Element("jane")); // 便捷寫法
          allChildren.add(0, new Element("first"));


          (2)移動(dòng)Elements:
          在JDOM里很簡(jiǎn)單
          Element movable = new Element("movable");
          parent1.addContent(movable); // place
          parent1.removeContent(movable); // remove
          parent2.addContent(movable); // add

          在Dom里
          Element movable = doc1.createElement("movable");
          parent1.appendChild(movable); // place
          parent1.removeChild(movable); // remove
          parent2.appendChild(movable); // 出錯(cuò)!

          補(bǔ)充:
          糾錯(cuò)性
          JDOM的Element構(gòu)造函數(shù)(以及它的其他函數(shù))會(huì)檢查element是否合法。
          而它的add/remove方法會(huì)檢查樹結(jié)構(gòu),檢查內(nèi)容如下:
          1.在任何樹中是否有回環(huán)節(jié)點(diǎn)
          2.是否只有一個(gè)根節(jié)點(diǎn)
          3.是否有一致的命名空間(Namespaces)

          ?

          (3)Element的text內(nèi)容讀取
          <description>
          A cool demo
          </description>

          // The text is directly available
          // Returns "\n A cool demo\n"
          String desc = element.getText();

          // There's a convenient shortcut
          // Returns "A cool demo"
          String desc = element.getTextTrim();

          (4)Elment內(nèi)容修改
          element.setText("A new description");
          3.可正確解釋特殊字符
          element.setText("<xml> content");
          4.CDATA的數(shù)據(jù)寫入、讀出
          element.addContent(new CDATA("<xml> content"));
          String noDifference = element.getText();

          混合內(nèi)容
          element可能包含很多種內(nèi)容,比如說

          <table>
          <!-- Some comment -->
          Some text
          <tr>Some child element</tr>
          </table>

          取table的子元素tr
          String text = table.getTextTrim();
          Element tr = table.getChild("tr");

          也可使用另外一個(gè)比較簡(jiǎn)單的方法
          List mixedCo = table.getContent();
          Iterator itr = mixedCo.iterator();
          while (itr.hasNext()) {
          Object o = i.next();
          if (o instanceof Comment) {
          ...
          }
          // 這里可以寫成Comment, Element, Text, CDATA,ProcessingInstruction, 或者是EntityRef的類型
          }
          // 現(xiàn)在移除Comment,注意這里游標(biāo)應(yīng)為1。這是由于回車鍵也被解析成Text類的緣故,所以Comment項(xiàng)應(yīng)為1。
          mixedCo.remove(1);

          ?

          4.Attribute類
          <table width="100%" border="0"> </table>
          //獲得attribute
          String width = table.getAttributeValue("width");
          int border = table.getAttribute("width").getIntValue();
          //設(shè)置attribute
          table.setAttribute("vspace", "0");
          // 刪除一個(gè)或全部attribute
          table.removeAttribute("vspace");
          table.getAttributes().clear();

          ?

          5.處理指令(Processing Instructions)操作
          一個(gè)Pls的例子
          <?br?>
          <?cocoon-process type="xslt"?>
          ????????? |??????? |
          ????????? |??????? |
          ??????? 目標(biāo)???? 數(shù)據(jù)

          處理目標(biāo)名稱(Target)
          String target = pi.getTarget();
          獲得所有數(shù)據(jù)(data),在目標(biāo)(target)以后的所有數(shù)據(jù)都會(huì)被返回。
          String data = pi.getData();
          獲得指定屬性的數(shù)據(jù)
          String type = pi.getValue("type");
          獲得所有屬性的名稱
          List ls = pi.getNames();

          6.命名空間操作
          <xhtml:html
          ?xmlns:xhtml="http://www.w3.org/1999/xhtml">
          <xhtml:title>Home Page</xhtml:title>
          </xhtml:html>

          Namespace xhtml = Namespace.getNamespace("xhtml", "http://www.w3.org/1999/xhtml");
          List kids = html.getChildren("title", xhtml);
          Element kid = html.getChild("title", xhtml);
          kid.addContent(new Element("table", xhtml));

          7.XSLT格式轉(zhuǎn)換
          使用以下函數(shù)可對(duì)XSLT轉(zhuǎn)換
          最后如果你需要使用w3c的Document則需要轉(zhuǎn)換一下。
          public static Document transform(String stylesheet,Document in)
          ??????????????????????????????????????? throws JDOMException {
          ???? try {
          ?????? Transformer transformer = TransformerFactory.newInstance()
          ???????????????????????????? .newTransformer(new StreamSource(stylesheet));
          ?????? JDOMResult out = new JDOMResult();
          ?????? transformer.transform(new JDOMSource(in), out);
          ?????? return out.getDeocument();
          ???? }
          ???? catch (TransformerException e) {
          ?????? throw new JDOMException("XSLT Trandformation failed", e);
          ???? }
          ?? }

          參考書目:

          1.JDOM官方網(wǎng)站: http://www.jdom.org

          2.<<Processing XML with Java>> Elliotte Rusty Harold 2002

          3.JDOM API Documentation

          4.<<JDOM Makes XML Easy>>Jason Hunter Co-Creator JDOM Project

          5.WSDP Tutorial

          ?

          ?

          ?

          ?

          posted @ 2003-09-27 07:19 hk2000c 閱讀(254) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共11頁: First 上一頁 3 4 5 6 7 8 9 10 11 
          主站蜘蛛池模板: 咸阳市| 新疆| 西乡县| 昭平县| 银川市| 镇远县| 曲阜市| 舒兰市| 辽宁省| 云南省| 精河县| 浮山县| 邯郸市| 新干县| 桐乡市| 巴林左旗| 九台市| 洮南市| 闵行区| 闻喜县| 岳普湖县| 阿瓦提县| 仙桃市| 上蔡县| 云和县| 昔阳县| 罗定市| 象山县| 行唐县| 长汀县| 久治县| 舟山市| 永平县| 江山市| 凌云县| 韩城市| 磴口县| 唐山市| 若羌县| 鸡泽县| 中宁县|