如果引用或轉貼,麻煩註明出處與本網誌連結,否則視為侵權。

2005年7月29日

程式設計功力提升的方法與Joel on Software網站

作者 : Fred (Hainchu-Taiwan) 日期: 2005/7/29


每天沒日沒夜的寫程式, 這樣過了幾年, 程式設計的功力, 真正就會自然提升嗎?
我想這是很困難的, 如同每天造橋鋪路, 過了幾年就可以蓋大樓了嗎? 砌磚久了就可以變成建築師了嗎?

我想提升程式功力, 不外乎幾個方向 :


1.實作中學習, 解決實作過程中的任何問題, 但是成功的完成每個專案, 不表示您的程式品質就好
 

2.深入的程式技巧學習, 例如Design Patterns, Programming styles, Refactoring Technology等等, 多看書, 多練習, 將這些東西真正變成您程式設計的習慣
 

3.縱向的學習, 程式設計的上下游的東西, 如系統分析, 架構設計, 細部設計, 資料模型, 系統測試, 軟體品質衡量, 軟體專案管理, 等等, 為什麼要了解這些東西, 例如: 架構設計, 架構的選擇將影響程式設計很大, 軟體品質的程式再用性,可擴充性, 可移植性, 甚至使用者要求的系統效能需求, 都可能牽涉到非常複雜的程式設計技術與技巧. 如果能夠提升縱向的視野, 當然有助能力的提升

另外推薦Joel on Software網站, 好好看看, 有助程式設計素養的提升

內容有:
程式師的使用介面設計手冊
讓錯的程式看得出錯
無痛錯誤追蹤
無痛功能規格
約耳測試: 邁向高品質的12個步驟
無痛軟體時程
軟體人員面試教戰守則

2005年7月25日

SAP Web Dynpro 專案開發程序

Fred Wang(http://fredwang.blogspot.com) 2005/07/25

SAP Web Dynpro是一套快速建構的Java Web Application Framework, 在SAP Netweaver Developer Studio的開發環境中提供特有Component-Based的MVC架構 。

不過,網路上鮮少文獻或討論有關使用Web Dynpro開發Web Application完整的軟體工程方法或程序。在SAP出版, Chris Whealy, “Inside Web Dynpro for Java”書中, 第27-31頁僅以五頁的篇幅描述這個程序。對於多數開發者而言,一個新的架構,需要更多的時間,更多的學習資訊協助以了解Web Dynpro如何用在真實的應用專案中。下面是筆者近幾個月開發Web Dynpro專案整理的一些心得筆記,希望對準備學習或使用Web Dynpro的人有所幫助。也歡迎先進給予指正。



需求分析

Web Dynpro開發專案的分析階段應該與Web Dynpro的技術無關,建議可採用UML的技術來描述系統需求。

架構設計

架構設計階段則與系統規模,非功能需求如可靠度,可擴充性等有關,例如: 是否使用異質資料庫,是否分散式處理,效能需求的要求如何,是否採用Design Patterns,採用何種Design Patterns,採用哪些基礎性與平台性的APIs, 例如: Logging , Exception Handling, Authentication,

Authorization, Asynchronous Processing, Scheduling, Configuration, Messaging等。 採用哪應用APIs, 例如 : Workflow, Reporting, Content Management, Transaction等。 另外使否使用JDI, 是否整合SAP Portal, 是否與其他Project互相整合等。


細部設計與實作程序

第一 使用者介面設計與系統雛形(Prototyping)

1. 根據Activity Diagram中的畫面建立View : 可以一個畫面建立一個View或多個類似的畫面共用一個View

1.1 View中進行畫面設計, 表格, 欄位, 按鈕等

1.2 建立畫面所需Binding的Context nodes and value attributes,並設定UI elements property的binding關係

1.3 若Context nodes或attributes需要跨Views來使用,則要在Component Controller複製相同的若Context nodes或attributes,並用Data Modeler(Component Diagram)建立Context mapping。

1.4 若是共用的View則應增加一些value attributes並bind到特定UI元件的read-only, enabled, visible等欄位, 來控制這些View在不同的狀況下可否輸入,是否顯示等。

2. 建立View間的Navigation關係 : 建立Window, 在Window Diagram建立View的Inbound plug與Outbound plug及連結關係

2.1 若Inbound Plug與Outbound Plug間要傳遞參數, 則兩者都需建立相同名稱的參數

2.2 找出Trigger Outbound Plug的UI元件,建立Event Handler,並指定Outbound Plug

2.3 要注意,畫面除了有進入的Inbound Plug,也應該要有返回的Outbound Plug,因此也要指定一個UI元件來啟動Outbound Plug

2.4 若View為多個功能畫面共用,則在Inbound Plug Method中根據不同的參數或不同的Inbound plug,設定畫面的read-only, enabled, visible (透過value attributes)

3. 使用者進行介面測試 : 完成上面的程序,畫面的Navigation已接近完成,此時可以與使用者進行介面測試,確認畫面樣式與畫面操作流程是否正確。

3.1 此時可以在Context node的supply function中,設定一些測試資料,以利操作過程中雛型的測試。

3.2 完成上面的程序可以提早在此階段與使用者確定規格,避免在開發的後期才更改規格, 造成專案進度更大的影響。


第二 商業功能設計與單元測試

1. 完成每個商業功能

1.1 畫面顯示前的處理, 在wdDoInit()或onPlugXXX() (Inbound Plug)中的商業處理

1.2 商業功能處理, 每一個會Trigger Event的UI元件,實作這些Event的Event Handler功能

1.3 Context Node的Supply Function,若與Data Model整合可以到後面資料模型設計階段來處理。

2. 這階段,可能有自行開發的程式,採用外界的APIs, 或自訂的公用APIs, 盡量可以讓程式高度模組化,提高程式的可再用性

3. 如果使用者前端設計及商業功能設計為不同開發人員,則負責商業功能設計的開發人員需撰寫單元測試程式進行商業功能的單元測試,一般採用JUnit測試架構。


第三 資料模型設計與整合測試

1. 建立Database Tables

2. Data Model可以用不同的方式實作

2.1 Java Bean : 用EJB or POJOs(DAO design pattern)

2.2 Web Service

2.3 SAP RFC Function

3. 將Data Model Map到View Context Node或Component Controller的Context Node

4. 進行整合測試

4.1 此時的測試就是包含Data Model, Business Function與UI設計的整合測試。

2005年7月14日

應用系統該如何選擇使用哪些J2EE Design Pattern?

應用系統該如何選擇使用哪些J2EE Design Pattern?

Fred Wang(http://fredwang.blogspot.com)

方法如下 :
1.依照樣式(Pattern)的目的加以分類
例如Presentation Tier的樣式可以加以分類如下:
. Intercepting Filter, Front Controller, Context Object and Application Controller: 用來處理需求, 或將需求轉交商業服務來處理。都是處理需求但是實際應用上略有差異。
. View Helper, Composite View : 都是用來將回應或需求處理的結果加以呈現
. Service to Worker, Dispatcher View : 從需求處理, 商業邏輯呼叫及View的呈現的架構

2. 了解每一種樣式要解決的問題與適用範圍
例如Service Activator專門用於非同步服務的呼叫。Session Facade用於使用EJB提供遠端商業服務的狀況。

3. 閱讀每個樣式的描述, 解決方案。特別要了解其Class Diagram and Sequence Diagram。

4. 找出樣式間的關係
例如 : Session Facade, Application Service與Business Objects間的關係, Front Controller, Context Object與Application Controller間的關係。

5. 系統可變因素是甚麼? 在不需重新設計下如何讓系統有更高的可擴充性:
例如 : 設計的樣式是否考慮不同的網路協定, 使用端的環境, 是否支援不同的資料庫。簡單而言, 您的系統可否增加Rich Client, Mobile Client, 是否可以增加另一種資料庫的存取。

6. 與第5點相反的就是訂出什麼狀況會造成系統要重新設計 :
例如 : 商業處理由POJOs提供服務, 增加EJB的遠端商業服務時, 系統是否要重新設計? 增加一種後端系統(Backend)存取需求時,系統是否要重新設計? (只要增加處理的元件而既有的元件仍可再用)

參考 : Craig A. Berry, John Carnell..etc, "J2EE Design Patterns Applied"

2005年7月13日

[推薦文章]e天下: 席捲企業的新勢力!Blog Inc.


根據部落格搜尋引擎Technorati指出,部落格以每天新增2萬3,000個的驚人速度成長,甚至迫使企業必須開始改變遊戲規則。美國《財星》(Fortune)雜誌則將部落格列為2005年度十大趨勢之首。微軟董事長比爾‧蓋茲更指出,部落格是繼e-mail、BBS、即時訊息(如MSN Messenger)之後,第四個改變世界的網路殺手級應用。...

根據美國網路調查機構Perseus估計,全球部落格的數量5年內數量成長超過1,000倍,從2000年的2.95萬個,快速成長到今年第一季的3,160萬個,到今年底,預估全球部落格數量將達到5,340萬個。...
http://www.techvantage.com.tw/content/055/055082.asp

2005年7月12日

J2EE Design Pattern : Service Activator筆記

J2EE Design Pattern : Service Activator筆記

正體中譯與整理 : Fred Wang (http://fredwang.blogspot.com)
內容來源 : "Core J2EE Design Pattern"

這個Pattern用來解決甚麼問題?
- 需要呼叫非同步的服務,如: Mail Service, Order Processing等, 這些服務因為處理時間較長或耗用資源較大等因素, 無法在短時間內完成並提供即時的回應。另外部分Business processing可能跨應用系統, 可能整合企業內外的應用系統, 而這些較長的處理不適合讓客戶端等待商業處理的完成。

重點 :
. 以非同步的方式叫用商業服務, POJOs(Plain Old Java Objexts,傳統Java物件)或EJB元件。
. 整合出版/訂閱及點對點通訊來啟動非同步處理服務。
. 執行的商業工作是由許多的商業工作(business tasks)所組成。

解決方案
- 使用Service Activator來接收非同步需求並呼叫一個或多個商業服務。

Service Activator實作成一個JMS Listener用來監聽並接收JMS訊息。如果你的應用系統使用EJB元件且EJB Container(Web Application Server)支援EJB 2.0以上的版本,則可以使用Message-Drivern bean(MDB)來接收非同步需求,否則就必須自己撰寫Java Message Service(JMS)。

步驟 :
1. 需求端建立並送出一個訊息給Service Activator
2. Service Activator收到此訊息並解析,轉譯這個需求
3. Service Activatorr必須指定正確的商業服務元件並呼叫它來處理這個需求(非同步)
4. 處理完成後, 需求端可能需要接收結果。為了要通知需求端這個處理的結果,Service Activator可以將回應訊息送回給需求端。這個回應訊息可能是告訴需求端處理是否成功並提供結果。也可能有處理失敗的狀況,此時回應訊息就包含造成失敗的細節,這個細節可能指出需求端如何回復,是否要重新送出需求或修正造成錯誤的因素來進行回復處理。

此Pattern參與的成員與責任 :
. Client(需求端) : 需要對商業服務發出非同步處理的需求,可能是各種型態的應用系統元件,如POJO或EJB元件,必須可以建立並發送JMS訊息。

註 : 當舊系統(Legacy System)為需求端時,Java應用系統可以代替舊系統作為訊息的產生器。這個舊系統可能不是用Java,而是與訊息導向的中介軟體(middleware)整合來發送與接收訊息。而Java應用系統中的Service Activator可以接收來自這些舊系統的需求訊息並進行非同步的處理。

. Request : 需求端產生的訊息物件, 透過Message-oriented middleware(MOM)送給Service Activator。必須實作javax.jms.Message interface.訊息型態有TextMessage, ObjectMessage等。

. Service Activator : 實作javax.jms.MessageListener,其中onMessage() method, 在訊息收到後會被啟動。Service Activator用來解析此訊息並決定要完成的事情。通常使用Service Locator找到並建立BusinessService元件。

. BusinessService : 進行同步處理的目標物件滿足需求端的商業需求,通常為Session Facade 或Application Service, 詳細的商業邏輯可能再封裝於商業物件(Business Object)。

. Response : 也是一個訊息物件, 由Service Activator或BusinessService建立並傳送, 這個Response可能是一個確認訊息,讓需求端知道Request已經被收到, Response也可能是非同步處理的結果。

Class Diagram :




參考 :
http://www.corej2eepatterns.com/Patterns2ndEd/ServiceActivator.htm

J2EE Design Pattern : Application Controller筆記

J2EE Design Pattern : Application Controller筆記

正體中譯與整理 : Fred Wang (http://fredwang.blogspot.com)
內容來源 : "Core J2EE Design Pattern"

這個Pattern用來解決甚麼問題?
. 將Action與View的管理集中化與模組化

在展示層中在接收到需求後有兩件主要的工作 :
. 第一, 收到的需求由特定的Action來提供服務, 稱為Action Management
. 第二, 控制權轉交給適當的View, 稱為View Management

這些也可以集中在Front Controller處理, 但是當應用系統及程式複雜時,最好將這些行為移到不同的classes以提高程式的模組化,重用性及擴充性。

重點:
. 重用(reuse)action與view management的程式碼
. 提升需求控管的可擴充性, 例如逐漸將Use case的功能加到應用系統內。
. 提升程式碼的模組化及可維護性, 更容易擴充您的應用系統, 更容易測試你每一部份的需求控管程式, 而這些程式與Web Container是不相關的(與Web Contrainer相關的需求管控在Front Controller完成)。

解決方案 :
- 使用一個Application Controller集中需求處理元件(如Commands與Views)的擷取與呼叫
註 : 真正處理需求及展現結果的元件不是Application Controller, 而是Commands與Views, Application Controller可以視為根據需求找到對應處理的Command(或Action), 並分派給合適的View來處理要呈現的結果。

將這些程式碼從Front Controller分離的好處有 :
1. 從Front Controller中與特定網路協定相關的程式碼分離以提升程式模組化與重用性, 例如特定的application controller元件可以提供給許多的channels(如web application與web service)重複使用來控管需求。這些控管有資料驗證(Validation), error handling, authentication, 存取控制(access control)等。
2. 與Servlet-based Front Controller分離以便於在Web container外進行測試
註 : Application Controller內部會有與Servlet及Web Container有關的API呼叫, 因此, 程式設計師進行這部份功能的單元測試就不一定要與未來執行環境相同(不需用相同的Web Container)

Pattern內的成員及責任
. Client(需求端) : 負責呼叫Application Controller, 通常維Front Controller或Intercepting Filter

. Application Controller : 使用Mapper解決收到的需求及對應的Action及View之間委派(Delegate)或分派(Dispatch)
註 : Delegate與Dispatch不同, Delegate只是將部分工作委派特定對象處理, 但控制權還在本身, 但Dispatch則是將控制權交給分派的對象。

. Mapper : 使用Map來轉譯收到的需求為合適的action和view, 可視為工廠(factory)

. Map : 放置目標資源的參考關係, 可能是Class或registry。
註 : 直接控管方式是直接可從Map中取出參考關係, 而間接控管方式是Map內包含物件, 須透過此物件才可找到目標資源。

以Jakarta Struts為例, Command Factory將request與action對應的關係從struts-config.xml中找出來, 傳回Command Map(ActionMapping)物件。這裡的Command Factory就是Mapper, ActionMappig就是Map。




參考 : http://www.corej2eepatterns.com/Patterns2ndEd/ApplicationController.htm

2005年7月11日

J2EE Design Pattern : Transfer Object筆記

J2EE Design Pattern : Transfer Object筆記

正體中譯與整理 : Fred Wang (http://fredwang.blogspot.com)
內容來源 : "Core J2EE Design Pattern"


這個Pattern用來解決甚麼問題?
跨層(presentation tier, business tier and integration tier)轉送多個資料元素, 並減少遠端呼叫造成網路的負擔。

J2EE應用系統用Session Facade 或Business Objects作為伺服器端商業元件並由其中的一些methods傳資料回需求端。這些商業元件常用如session beans與entity beans等遠端物件來實作。若這些商業元件採用較小的get及set methods,則需求端必需呼叫很多的getter methods才能取得所需的屬性內容值。

因為這些method的呼叫對enterprise bean而言都是遠端呼叫, 因此可能會造成效率上的問題。因為遠端呼叫會造成網路的負擔。即使需求端與EJB container在相同的JVM, OS或相同的實體機器上執行效能都會受影響。因此使用許多的遠端getter method的呼叫, 每次只傳回一點點資料, 這種方式非常沒有效率。

因此即使不是存取遠端元件,仍然需要存取封裝在不同層內的資料元件, 如商業層的Business Objects, 整合層的Data Access Objects, 仍需要以較大顆粒(傳遞物件)介面來傳送及與接收資料。

重點 :
. 需求端要存取其他層的元件來擷取或更新資料
. 要減少網路上遠端的需求次數。
. 要避免存取頻繁的應用系統造成高的網路流量使網路效能下降。

解決方案
- 使用Transfer Object來攜帶跨層間傳遞的多個資料元素。

Transfer Object用來讓跨層間的資料最佳化,Transfer Object將需求與回應間的傳送與接收的所有元素包含在單一個資料結構內。

Transfer Object以傳值的方式被傳送到需求端, 因此需求端對Transfer Object的所有呼叫, 是針對原始Transfer Object的副本,而非遠端的原始Transfer Object。

步驟 :
1. Component因需求來建立Transfer Object的instance並傳回給需求端
註 : Component可能是展示層的view helper, business delegate或command object; 或商業層的Business Object, Application Service或Service Facade等; 或整合層的Data Access Object。
2. 此時的Transfer Object為序列化的(serialized)並跨網路傳送到需求端, 需求端收到並使用這個Transfer Object的本地副本(local copy)
3. 需求端也可以產生自己的Transfer Object instance送到Component來執行資料更新。

實作上Transfer Object是一個Serializable plan old Java Object(POJO), 包含許多的members(attributes or fields), 且用單一的method call來完成所有資料的傳送。

實作策略 : (待續)

Class Diagram



參考 :
http://www.corej2eepatterns.com/Patterns2ndEd/TransferObject.htm

2005年7月9日

J2EE Design Pattern : Application Service筆記

J2EE Design Pattern : Application Service筆記

正體中譯與整理 : Fred Wang (http://fredwang.blogspot.com)
內容來源 : "Core J2EE Design Pattern"


這個Pattern用來解決甚麼問題?
要集中跨許多商業層元件與服務的商業邏輯提供簡單的介面給需求端。

Service Facade如Session Facade或POJO Facade內含很少甚至沒有商業邏輯,僅用來提供簡單的介面, 當應用系統實作的使用案例(use cases)由許多的商業物件(Business Objects)及商業服務(如Web Services)所完成, 不應該用商業物件來實作這個User Case內的商業物件與服務間的協調工作, 這將增加了商業物件間的耦合性(coupling)。

註 :
1. Session Facade及POJO(Plain Old Java Object) Facade都是一種Service Facade, Session Facade是一種提供遠端商業服務(如Web Services)的介面。POJO Facade提供的近端商業服務的介面, 這些近端商業服務為POJO, 如Business Object(另一種Design Pattern)
2. 簡單的說, Service Facade提供一個Use Case對外的單一服務介面。

重點 :
. 盡量減少Service Facade內的商業邏輯
. 商業邏輯包含在商業物件與服務內
. 在現有的商業層的元件與服務之上提供簡單的介面
. 將使用案例特定的邏輯(控制與協調邏輯)在商業物件外加以封裝

解決方案 :
- 使用一個Application Service集中與彙整商業處理,提供統一的服務層。

Application Service的七項功能 :
1. Application Service 提供一個集中的地方來實作商業邏輯, 這些商業邏輯內含商業物件及服務。也就是說用Application Service將高層次的商業邏輯封裝在一個元件, 而這個元件叫用一些商業物件與服務。

2. 即使你不使用商業物件, Application Service也可以提供集中的商業邏輯實作層。Application service 可以包含程序控制的商業邏輯, 這些商業邏輯用來實作不同的服務(要依序完成)及資料存取物件(Data Access Object)。

3. 在非EJB的應用系統, Application Service提供展示層與商業層物件(如商業物件或服務)間的中介功能以減少兩個層的耦合性(Coupling)。就介面的粗細緻的層次而言Application Service介於Service Facade與Business Object之間。

4. Application Service提供Service Facade基礎架構, 讓Service Facase變得更簡單, 包含更少的程式碼, 因為Service Facade只要將商業處理委派(Delegate)給Application Service就好了。 (Application Service包含商業邏輯而Session Facade不包含商業邏輯)

5. 以Session Facade為例, 當商業邏輯(高層次)變得複雜, 如果將這些邏輯放在特定的Session Facade內, 則這些邏輯將很難被其他的Session Facade叫用, 只能用copy and paste方式重用, 如此一來這些Session Facade將變的難以維護。Application Service就可用來放置這些可重用的邏輯,讓Session Facade變的簡單, 優雅且好維護。

6. Application Service 可用來處理應用系統間的互動, 不同Use Cases間的互動及不同需求端型態的互動。如Use Case特有的處理或特定需求端形態的處理。

7. Application Service也可以用來實作存取外部服務的邏輯, 如eMail system, legacy system或Web Service, 並提供可重用的服務元件。

實作這個Pattern的策略 : <準備中>



參考 : http://www.corej2eepatterns.com/Patterns2ndEd/ApplicationService.htm

2005年7月8日

J2EE Design Pattern : Service to Worker筆記

正體中譯與整理 : Fred Wang (http://fredwang.blogspot.com)
內容來源 : "Core J2EE Design Pattern"


這個Pattern用來解決甚麼問題?
在View顯示前要執行主要的需求控管(request handling)並執行商業邏輯處理。

檢視下面的問題,了解在View準備階段的需求處理過程有多少工作要完成:
. 控制邏輯有多複雜?
. 要傳回的內容有多少動態資料?
. 商業邏輯及資料模型有多複雜?

重點 :
. 一個需求透過指定的商業邏輯來取得用來產生回應的資訊(例如資料庫或檔案內的資訊)。
. View的選擇決定於商業服務(邏輯)產生的回應訊息(HTML, JSP等)。
. 可以使用Framework或library, 如Jakarta Struts, JSF等。

解決方案 :
- 用Service to Worker來集中控制與需求控管在控制權交給View前取得展示資料模型(Presentation Model 例如儲存在Session內的資料), View 就是基於這個展示模型來產生動態的回應。

註 : Service to Worker與Dispatcher View為兩個最常使用的方法。Service to Worker是以控制器(application controller)為中心的架構,Dispatcher View是以View為中心的架構, 它的商業處理是到View的處理時才被執行(例如在JSP中的scriptlet or tag library)

Service to Worker pattern 由許多的patterns所組成,包含Front Controller, Application Controller與 View Helper

步驟 :
1.Front Controller接收需求(request), 並處理與網路協定相關的元素(如HttpServletRequest..)然後產生Context Object, 交給Application Controller, 並委派Application Controller進行Action與View的管理。

2.Application Controller扮演Command Handler將request中的邏輯名稱(例如http://some.server.com/Controller?action=login中的"login")找到對應的Command(例如LoginCmd), 並呼叫(invoke)這個Command

3.特定Command用來呼叫特定的商業服務來產生展示資料模型。

4.然後Application Controller再將控制權轉交給特定的View

5.這個View透過View Helper將展示資料模型內的資料轉換成View所需的內容。這個View也可能是個合成的View(Composite View)

在此要注意的是, 商業邏輯在控制權轉交給View前就完成了, 而Dispatch View則在制權轉交給View之後才執行這些商業邏輯。

實作這個Pattern的策略 :
1. Front Controller有Servlet Front Strategy與JSP Front Controller兩種, 前者較好。(在Front Controller的筆記中介紹)
2. View Helper有Template-Based View Strategy, Controller-Based View Strategy, JavaBean Helper Strategy, Custom Tag Helper四種策略 (在View Helper的筆記中介紹)
3. Dispatcher in Controller Strategy : 就是將控制權轉交給View的派送程式放在Front Controller內, 這也是在Front Controller的筆記中介紹。



參考 : http://www.corej2eepatterns.com/Patterns2ndEd/ServiceToWorker.htm

2005年7月5日

透過Jakarta Beanutils將ResultSet轉成ArrayList

有關Jakarta Commons的Beanutils請見http://jakarta.apache.org/commons/beanutils

將ResultSet轉成ArrayList的範例程式 :
import java.sql.*;
import java.util.*;
import org.apache.commons.beanutils.*;

public class DynaBeanArrayList {
public DynaBeanArrayList() {
}
public ArrayList getArrayList(ResultSet rs) throws Exception{
ArrayList results = new ArrayList(); // To hold copied list
try{
ResultSetDynaClass rsdc = new ResultSetDynaClass(rs);
BasicDynaClass bdc = new BasicDynaClass("DynaBeanTemplate", BasicDynaBean.class, rsdc.getDynaProperties());
Iterator rows = rsdc.iterator();
while (rows.hasNext()) {
DynaBean oldRow = (DynaBean) rows.next();
DynaBean newRow = bdc.newInstance();
PropertyUtils.copyProperties(newRow, oldRow);
results.add(newRow);
}
return results;
}
catch(Exception e){
return null;
}
}
}