国产亚洲成av人片在线观看,亚洲伊人久久大香线蕉苏妲己,亚洲国产一区在线http://www.tkk7.com/steeven/zh-cnFri, 09 May 2025 22:13:52 GMTFri, 09 May 2025 22:13:52 GMT60搬家通知. 現已喬遷至JavaEye, Fanfou, thankshttp://www.tkk7.com/steeven/archive/2009/05/09/269825.htmlsteevensteevenSat, 09 May 2009 14:13:00 GMThttp://www.tkk7.com/steeven/archive/2009/05/09/269825.htmlhttp://www.tkk7.com/steeven/comments/269825.htmlhttp://www.tkk7.com/steeven/archive/2009/05/09/269825.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/269825.htmlhttp://www.tkk7.com/steeven/services/trackbacks/269825.htmlSorry, I have already moved to JavaEye and Fanfou, please update if you have questions.

steeven 2009-05-09 22:13 發表評論
]]>
吹一吹偶的新作品:skype remote desktophttp://www.tkk7.com/steeven/archive/2006/12/06/85926.htmlsteevensteevenWed, 06 Dec 2006 12:18:00 GMThttp://www.tkk7.com/steeven/archive/2006/12/06/85926.htmlhttp://www.tkk7.com/steeven/comments/85926.htmlhttp://www.tkk7.com/steeven/archive/2006/12/06/85926.html#Feedback6http://www.tkk7.com/steeven/comments/commentRss/85926.htmlhttp://www.tkk7.com/steeven/services/trackbacks/85926.html
自己拿來skype4java看了一下,感覺很好用。里面提供了一個application機制,類似socket,又強于socket。為什么說強呢?因為是基于skype, 穿透防火墻啦。
windows自帶的遠程桌面很好用,在速度上,比以前基于位圖傳送的netmeeting/pcanywhere之類的都要強。
linux下面的遠程桌面做的比較好的是nx系列。但是這些遠程桌面的致命問題就是網關、防火墻問題。
就是說你要在家訪問公司電腦,基本上要在防火墻上鑿洞,或者借助于vpn,softether之類的東東。

skype的application利用skype自身的通訊機制,屏蔽了這些問題,當然,你的應用也必須依賴skype了。

java做遠程桌面要能截屏、控制鼠標鍵盤,所幸有java.awt.Robot, 原來這個東西是為了做自動化測試,剛好。
剩下就是穿數據的問題。屏幕圖片,如果是bmp,比較碩大,即使是上網等文本界面,壓縮下來也要幾十k, 如果網絡帶寬不夠的話,比如公司有幾個下載愛好者,會比較慘。所以呢,決定傳差異,緩存前面的屏幕,看看如果差別不大,就只傳變化的部分。這樣數據量就比較小。但是呢,壓縮圖片的時候就不能采用有損壓縮啦,否則屏幕會變得越來越怪異。。。

比較遺憾的是沒能象windows自帶的rdp那樣攔截繪圖操作,在點陣圖的方案上效率還是比較低的。希望有高手指點!

skype4java是個日本人寫的,幾個聽了我介紹的朋友都有這疑問:日本人寫的?
呵呵,如果你能寫出更好的,咱就不用它。那個日本作者還不錯,上班比較忙,還是答應抽空fix幾個bug,感謝中~

體驗一下吧:skypeRDP

steeven 2006-12-06 20:18 發表評論
]]>
GWT開發中的幾個問題http://www.tkk7.com/steeven/archive/2006/07/14/58239.htmlsteevensteevenFri, 14 Jul 2006 10:10:00 GMThttp://www.tkk7.com/steeven/archive/2006/07/14/58239.htmlhttp://www.tkk7.com/steeven/comments/58239.htmlhttp://www.tkk7.com/steeven/archive/2006/07/14/58239.html#Feedback6http://www.tkk7.com/steeven/comments/commentRss/58239.htmlhttp://www.tkk7.com/steeven/services/trackbacks/58239.html適用版本GWT 1.0.21。
由于目前google web toolkit還沒有正式release, 所以問題多多。記錄一下碰到的問題:

1. Shell調試模式和實際編譯結果有差異。
shell中報告的異常在運行中只是一些凌亂的腳本錯誤,或者干脆沒有響應。
shell中通過的程序在實際運行時還會有錯誤。
2. 避免錯誤的方法是捕獲異常,
在onModuleLoad方法中try catch
或者GWT.setUnCaughtExceptionHandler()//全局異常捕獲
3. LOG, 利用GWT.log(). shell模式下會輸出到控制臺。
4. 遠程調用屬于異步。同步遠程調用可以自己包裝ClientCallback,在一個結束后調用另外一個.
5. RPC調用中Set傳遞有bug, 暫時用List
6. Eclipse直接運行Compiler/Shell, 加入gwt-dev-windows.jar。
main: com.google.gwt.dev.GWTCompiler/GWTShell
arguments: -out ${project_loc}\WebContent real/Index.html
classpath->UserEnties->advanced->add folder->選擇項目的src目錄,要在第一位。
7. Tomcat5問題多多, 用tomcat4.
8. gwt-user中非法包含javax.servlet, tomcat認為其無效。直接放到tomcat/common/lib中。或者在jar中去掉。
9. Exception.getStackTrace() 在Shell模式下有效, GWT.isScript()可以判斷
10. 靜態中文在html中亂碼,要在html header中加入<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />



steeven 2006-07-14 18:10 發表評論
]]>
開發過程中的雞生蛋蛋生雞的問題http://www.tkk7.com/steeven/archive/2006/07/02/56191.htmlsteevensteevenSun, 02 Jul 2006 12:28:00 GMThttp://www.tkk7.com/steeven/archive/2006/07/02/56191.htmlhttp://www.tkk7.com/steeven/comments/56191.htmlhttp://www.tkk7.com/steeven/archive/2006/07/02/56191.html#Feedback2http://www.tkk7.com/steeven/comments/commentRss/56191.htmlhttp://www.tkk7.com/steeven/services/trackbacks/56191.html雞,構造的時候要帶入蛋.
蛋,構造的時候要帶入雞.

編譯沒問題,初始化數據的時候問題出來了.
new 雞(new 蛋(???)) //蛋是誰下的?
作為一個正統的進化論學生,解決如下:構造原始雞類,雞開始是不下蛋的,把雞的構造函數改成空的,這時候初始化一條原始雞的數據沒問題.然后進化出來蛋,雞下的,類不用改,把蛋的數據初始化好.這時候雞進化,由蛋孵出來,構造方法要帶蛋進來,初始化一只新雞,刪除原始雞數據.

OK,問題解決了嗎?這樣程序每次初始化數據的時候要改造雞類,好像不大容易啊....

那上帝造物學說怎樣解決問題呢?:
雞1 = new 雞(null);
蛋1 = new 蛋(null);
雞1.set蛋(蛋1);
蛋1.set雞(雞1);
save(雞1,蛋1);
雞和蛋同時出來了.上帝造物法勝利

是不是我的類設計有問題,怎么會碰到雞生蛋蛋孵雞這種郁悶的問題呢?

steeven 2006-07-02 20:28 發表評論
]]>
db4o,沒有主鍵?http://www.tkk7.com/steeven/archive/2006/06/19/53836.htmlsteevensteevenMon, 19 Jun 2006 10:15:00 GMThttp://www.tkk7.com/steeven/archive/2006/06/19/53836.htmlhttp://www.tkk7.com/steeven/comments/53836.htmlhttp://www.tkk7.com/steeven/archive/2006/06/19/53836.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/53836.htmlhttp://www.tkk7.com/steeven/services/trackbacks/53836.htmldb4o目前還沒有unique index/primary key機制。(5.4)

???? public ? static ? void ?main(String[]?args)? {
????????ObjectContainer?db?
= ?Db4o.openFile( " test.yap " );
????????db.set(
new ?User( " abc " , 234 ));
????????db.set(
new ?User( " abc " , 234 ));
????????ObjectSet
< User > ?list? = ?db.query(User. class );
????????System.out.println(list);
????????db.close();?
// halt?without?this?line?in?5.2
????}

上面的例子會存儲兩個同樣的User對象。
僅有的ID是一個存儲文件中的ID, 經過碎片整理之后會發生變化,顯然不適用。
要實現一個auto_increament的主鍵恐怕要自行實現。或者用已有的UUID實現。

可能db4o太年輕的關系,目前還沒有支援這些功能。建議用@Annotation來實現。并且控制存儲。
@ID
@Unique
@Index
在EJB3里面已經有現成的定義可以參考。

steeven 2006-06-19 18:15 發表評論
]]>
YY一下未來的用戶界面http://www.tkk7.com/steeven/archive/2006/06/18/53657.htmlsteevensteevenSun, 18 Jun 2006 14:57:00 GMThttp://www.tkk7.com/steeven/archive/2006/06/18/53657.htmlhttp://www.tkk7.com/steeven/comments/53657.htmlhttp://www.tkk7.com/steeven/archive/2006/06/18/53657.html#Feedback3http://www.tkk7.com/steeven/comments/commentRss/53657.htmlhttp://www.tkk7.com/steeven/services/trackbacks/53657.html
微軟這回蓄勢待發xaml有多強大呢?3d(感覺不夠純粹)/強大的數據綁定/動畫/多媒體支持...
這里可怕的不僅僅是框架,還有配套的GUI開發工具.有趣的是Interactive Designer據說就是用wpf開發的.
xaml只是個xml描述文件,里面可以包含代碼,編譯成UI界面.所有的界面內容也可以由程序動態運行.
這樣未來運行在browser里面的UI不是復雜的ajax,是和后臺一致的托管代碼.

Java怎樣應對呢?Java+Flash? 開發bs都困難重重.除非Flash能放棄as,直接同java結合,或者兩個公司合作開發一個新框架.這個新框架應該是什么樣子呢?完全的3D視角,時間軸控制...重演c#后來居上的歷史.

Java在Sun的手里一直半死不活,真希望能趕快被google并購,或者sun主動把java捐贈出來.

如果沒有"意外",在wpf正式發行以后,桌面應用將逐步過渡到wpf開發.HTML由于其跨平臺,可能會平分秋色.

面對wpf,如何反抗?java.net是太監,在.net陣營里面連二奶都不算,等于投降.
利用xaml? xaml被編譯加載,其執行框架還是.net,機會似乎不大.在瀏覽器上可能會有類似lasszlo的組合.

作為Java愛好者,祈禱奇跡發生吧,還好在Java世界中奇跡是家常便飯 :)

steeven 2006-06-18 22:57 發表評論
]]>
監聽Swing窗口的鍵盤鼠標事件http://www.tkk7.com/steeven/archive/2006/06/13/52504.htmlsteevensteevenTue, 13 Jun 2006 08:52:00 GMThttp://www.tkk7.com/steeven/archive/2006/06/13/52504.htmlhttp://www.tkk7.com/steeven/comments/52504.htmlhttp://www.tkk7.com/steeven/archive/2006/06/13/52504.html#Feedback2http://www.tkk7.com/steeven/comments/commentRss/52504.htmlhttp://www.tkk7.com/steeven/services/trackbacks/52504.html一般Apply按鈕應該在用戶有輸入時有效,輸入沒有變化時無效。
為了達到這個效果,一般界面上每個輸入控件要監聽,并且和以前的值做比較,實現起來相當麻煩。

因為我們已有的界面是基于數據綁定,綁定到一個克隆的對象上。這樣判斷有沒有變化就很簡單,updateInput之后,比較兩個對象是否一致即可。

什么時候去判斷呢?在用戶輸入之后:捕捉鍵盤、鼠標事件。

攔截鍵盤鼠標事件目前找到兩種方法:
1. Toolkit.getDefaultToolkit().addAWTEventListener(listener,eventMask);
這個方法注冊全局的監聽機制,無論哪個窗口。里面注冊為weakHashmap,應該不用考慮垃圾回收問題。因為是全局的,不建議采用。
2. 攔截每個component自己的事件。
正常來說,如果在textbox里面打字,事件不會交給window處理。enableInputMethods(true)可以幫忙。
enable以后調用getInputContext(),取得InputContext處理。
注意,InputContext的dispatchEvent(AWTEvent)會接到各種消息,感興趣的getID()有以下三個:
???MouseEvent.MOUSE_CLICKED
???MouseEvent.MOUSE_WHEEL
???KeyEvent.KEY_TYPED



steeven 2006-06-13 16:52 發表評論
]]>
CSDN Java沙龍上海活動http://www.tkk7.com/steeven/archive/2006/06/07/51224.htmlsteevensteevenWed, 07 Jun 2006 15:44:00 GMThttp://www.tkk7.com/steeven/archive/2006/06/07/51224.htmlhttp://www.tkk7.com/steeven/comments/51224.htmlhttp://www.tkk7.com/steeven/archive/2006/06/07/51224.html#Feedback4http://www.tkk7.com/steeven/comments/commentRss/51224.htmlhttp://www.tkk7.com/steeven/services/trackbacks/51224.html
零星記了一些筆記,對我這個ajax門外漢來說收獲還是很大。主講是ajaxcn.org的兩位高手。robbin的Rubby講座因為時間關系要改期。

1. JS2的一些新特性:class/extend/interface/package/import/塊作用域/操作符函數. 明年底會有browser開始支持。
//干脆把java直接搬到browser里面算了。
//以后是不是弄個標準接口允許加載不同語言的腳本引擎?大家就不用受js的鳥氣了。
2. 推薦的ajax框架:Dojo/DWR/Prototype/GWT/YUI
//排名有先后
3. 新技術:
canvas 畫圖,已有多數瀏覽器支持。據說有人用它實現了3D游戲
SVG 基于xml的矢量圖。據說和canvas都支持3d繪圖。
E4X: xml的包裝, firefox支持
4. 技術和需求水漲船高 //我們不會失業了
5. HiJax:
用傳統方式快速開發。在傳統網頁基礎上hack成ajax應用。
對禁用js的瀏覽器表現為傳統網頁。
前期開發和后期改造獨立性很強。
//后期要改造為完美的ajax,對server端要做些小的改動來適應。
6. 推薦用FireFox調試AJAX, 插件三劍客:
firebug/web develope tool/temper data分別用來調試腳本,觀察頁面dom,監聽通信。
//js調試的日子好過多了,但不要忘記總體效率。。。

回來路上和一位tx聊起來ajax在企業中的地位好像不高,他對敏捷開發很有好感,對辦公室環境的要求很有趣。
本次活動的主要心得是:自助餐很好吃,以后有活動還要去吃 :)

steeven 2006-06-07 23:44 發表評論
]]>
GWT做的guess numberhttp://www.tkk7.com/steeven/archive/2006/06/02/49941.htmlsteevensteevenFri, 02 Jun 2006 07:23:00 GMThttp://www.tkk7.com/steeven/archive/2006/06/02/49941.htmlhttp://www.tkk7.com/steeven/comments/49941.htmlhttp://www.tkk7.com/steeven/archive/2006/06/02/49941.html#Feedback13http://www.tkk7.com/steeven/comments/commentRss/49941.htmlhttp://www.tkk7.com/steeven/services/trackbacks/49941.html
anyway, 對于大多數邏輯都在客戶端的應用,gwt可以大展身手。比如小游戲~

guess number demo看這里:http://steeven.googlepages.com/MyApp.html
完全在瀏覽器上運行的玩意,沒有寫一句js,感覺還是很爽的~

代碼如下:
package?org.steeven.gwt.test.client;

import?com.google.gwt.core.client.EntryPoint;
import?com.google.gwt.user.client.Random;
import?com.google.gwt.user.client.ui.Button;
import?com.google.gwt.user.client.ui.ClickListener;
import?com.google.gwt.user.client.ui.DialogBox;
import?com.google.gwt.user.client.ui.Grid;
import?com.google.gwt.user.client.ui.HasHorizontalAlignment;
import?com.google.gwt.user.client.ui.RootPanel;
import?com.google.gwt.user.client.ui.TextBox;
import?com.google.gwt.user.client.ui.VerticalPanel;
import?com.google.gwt.user.client.ui.Widget;

/**
?*?
@author?steeven@gmail.com
?
*/

public?class?MyApp?implements?EntryPoint?{

????TextBox?txtCount?
=?new?TextBox();

????
private?Grid?pnlMain;

????
private?Button[]?numbers?=?new?Button[100];

????
private?int?target;

????
private?int?count;

????
private?DialogBox?box;

????
private?Button?btnRetry;

????
private?Button?btnClose;

????
/**
?????*?This?is?the?entry?point?method.
?????
*/

????
public?void?onModuleLoad()?{
????????VerticalPanel?pnlStatus?
=?new?VerticalPanel();
????????pnlStatus.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
????????pnlStatus.setSpacing(
20);

????????txtCount.setEnabled(
false);
????????txtCount.setVisibleLength(
10);
????????pnlStatus.add(txtCount);
????????btnRetry?
=?new?Button();
????????btnRetry.setHTML(
"<img?src=\"replay.gif\"/>?<u>R</u>etry");
????????btnRetry.setAccessKey(
'r');
????????btnRetry.addClickListener(
new?ClickListener()?{
????????????
public?void?onClick(Widget?sender)?{
????????????????doInit();
????????????}

????????}
);
????????pnlStatus.add(btnRetry);

????????Button?btnAbout?
=?new?Button();
????????btnAbout.setHTML(
"<img?src='about.gif'/>?<u>A</u>bout");
????????btnAbout.setAccessKey(
'a');
????????btnAbout.addClickListener(
new?ClickListener()?{
????????????
public?void?onClick(Widget?sender)?{
????????????????doAbout();
????????????}

????????}
);
????????pnlStatus.add(btnAbout);

????????RootPanel.get(
"status").add(pnlStatus);

????????pnlMain?
=?new?Grid(10,?10);
????????RootPanel.get(
"main").add(pnlMain);

????????
for?(int?i?=?0;?i?<?100;?i++)?{
????????????numbers[i]?
=?new?Button();
????????????numbers[i].setText(i?
+?"");
????????????numbers[i].addClickListener(
new?ClickListener()?{
????????????????
public?void?onClick(Widget?sender)?{
????????????????????doGuess(sender);
????????????????}

????????????}
);
????????????pnlMain.setWidget(i?
/?10,?i?%?10,?numbers[i]);
????????}


????????box?
=?new?DialogBox();
????????box.setPopupPosition(
400,?200);
????????btnClose?
=?new?Button("<u>C</u>lose",?new?ClickListener()?{
????????????
public?void?onClick(Widget?sender)?{
????????????????box.hide();
????????????????doInit();
????????????}

????????}
);
????????btnClose.setAccessKey(
'c');
????????box.add(btnClose);
????????doInit();
????}


????
protected?void?doGuess(Widget?sender)?{
????????Button?btn?
=?(Button)?sender;
????????btnRetry.setEnabled(
true);
????????
int?n?=?Integer.parseInt(btn.getText());
????????txtCount.setText(
""?+?(++count));
????????
if?(n?==?target)?{
????????????numbers[n].setEnabled(
false);
????????????btnClose.setFocus(
true);
????????????box.clear();
????????????box
????????????????????.setHTML(
"<center><img?src='win.gif'/><h1>YOU?WIN!!!</h1><br/><br/><br/>");
????????????box.add(btnClose);
????????????box.show();
????????}
?else?{
????????????
if?(n?<?target)
????????????????
for?(int?i?=?0;?i?<=?n;?i++)
????????????????????numbers[i].setEnabled(
false);
????????????
else
????????????????
for?(int?i?=?n;?i?<?100;?i++)
????????????????????numbers[i].setEnabled(
false);
????????}


????}


????
protected?void?doAbout()?{
????????box.clear();
????????box
????????????????.setHTML(
"<img?src='about.gif'/><h1>Guess?Number</h1><h3>Google?web?toolkit?test</h3>");
????????box.add(btnClose);
????????box.show();
????}


????
private?void?doInit()?{
????????btnRetry.setEnabled(
false);
????????target?
=?Random.nextInt(99);
????????count?
=?0;
????????txtCount.setText(
"0");
????????
for?(int?i?=?0;?i?<?100;?i++)?{
????????????numbers[i].setVisible(
true);
????????????numbers[i].setEnabled(
true);
????????}

????}


}


第一次玩gwt, 總共花了3個小時,菜呀

steeven 2006-06-02 15:23 發表評論
]]>
gwt和echo2的對比http://www.tkk7.com/steeven/archive/2006/06/01/49502.htmlsteevensteevenThu, 01 Jun 2006 03:32:00 GMThttp://www.tkk7.com/steeven/archive/2006/06/01/49502.htmlhttp://www.tkk7.com/steeven/comments/49502.htmlhttp://www.tkk7.com/steeven/archive/2006/06/01/49502.html#Feedback3http://www.tkk7.com/steeven/comments/commentRss/49502.htmlhttp://www.tkk7.com/steeven/services/trackbacks/49502.html前面轉貼Liebeck(echo的主要開發者,我的偶像)關于echo2和gwt的對比:http://www.tkk7.com/steeven/archive/2006/06/01/49379.html

今天仔細做了一些筆記,并且加入了一些自己的想法,供選型者參考:

綜合對比:
1. 兩個都是非傳統的b/s框架,都是用AJAX來構造動態網站。編程過程都和SWT/Swing差不多。
2. 區別在于一個運行于客戶端,一個運行于服務器

3. gwt把代碼編譯為html+js, 目前只支持java1.4規范。echo沒這限制。
4. gwt可以運行于任何web server, echo則需要傳統的servlet容器。(意義不大,現在哪有靜態網站啊,后臺交互肯定還是需要的)
5. echo2的客戶端引擎通過ajax提交用戶動作,對用戶界面增量更新。
?
性能:
1. gwt的頁面logic都在瀏覽器上,所以很快。但是如果需要和中間層交互,就會碰到同樣的網絡問題。
2. echo2的代碼跑在server上,所以所有的交互都需要反饋給server。echo2在設計上盡量減少這種交互,比如客戶對文本的修改都是延遲發送到服務器,而服務器只發送頁面的變化部分到瀏覽器。
3. gwt應用被編譯成一個頁面,雖然應用的復雜化,這個編譯結果也隨之變得可怕。。。(個人認為隨著編譯器的發展,不同的頁面可以做到lazy load)
4. echo的js模塊是lazy加載到瀏覽器的,界面上呈現哪些控件才去加載并且緩存對應的js模塊。發送到客戶端的不是邏輯代碼,只有用戶狀態(個人認為echo2現在過于lazy,導致初始化階段多次訪問server加載一些基本的js模塊,應該揉合到一起。另外,因為echo邏輯代碼在服務器上,相對來說可以防止盜版)
?
中間層和數據訪問:
1. 如果要訪問數據,gwt還是要回到傳統的模式,通過rpc訪問servlet。gwt提供把遠程服務透明的包裝起來,中間傳送pojo. 盡管包裝了,中間的安全和和校驗還是必須要開發者考慮。
2. echo支持SOA,但是不必須。大多數情況下安全不是問題,因為數據和邏輯都不會暴露到瀏覽器上。(以前給echo提過建議,瀏覽器用戶很可能去模擬一個被disabled按鈕提交,這種問題現在無需考慮)
?
運行環境:
1. gwt運行在瀏覽器上,并非所有的java類都能編譯成js. gwt現在只支持java.lang/java.util下面的一個子集(版本?1.0.21):27 classes, 11 interfaces, and 18 exception(這讓人想起了j2me開發). 一些現有的類庫就別想了。
?
調試:
1. gwt調試需要一套和運行時完全不同的環境:HOST模式,代碼作為真正的java在運行。(個人認為這里因為是純java調試,比echo的web調試要稍微方便一些。做單元測試也更方便些,但不是對最終browser的測試)
2. echo調試就是傳統的servlet調試。
?
授權:
1. gwt的api是開源的,編譯器和host模式瀏覽器不公開。整體來說:free. (個人認為,如果要擴充gwt可能會遇到麻煩)
2. echo2開源,mozilla public license. free(個人認為:echostudio也free就好了。nextapp畢竟要生存)
?
應用:
1. gwt可以嵌入傳統的靜態html, 也能作為一個完整應用。做大應用要考慮編譯后的重量、本地化、庫支持等問題(關于18n, 可以在gwt支持論壇上搜索i18n,似乎已經有方案)
2. echo2成熟得可以適用各種應用,但是不能作為靜態頁面的一部分使用。(有點吹牛,在大訪問量下,服務器的壓力肯定不會小)
?
?
?
個人結論:
1. 開發方式都很優秀,用純java開發b/s
2. gwt可用于大型網站,把壓力轉嫁給客戶端。
3. echo可用于快速開發復雜的企業應用,把壓力丟給服務器(企業里面最清閑的就是前臺和服務器)

兩個產品都很優秀,GWT是2006年的IT颶風,波及后面幾年。M$的日子要難過了, GOOGLE的確是個令人頭痛的對手。

然而,還有比gwt/echo2更美好的未來嗎?
有!把他們的輸出變成flash,用java開發flash應用。去年探索過一段時間,原型已經出來,因為flash開發調試太ugly, 沒有繼續下去。
另外,微軟的WPF(AVALON)相當值得關注。


steeven 2006-06-01 11:32 發表評論
]]>
轉貼:Comparing the Google Web Toolkit to Echo2 http://www.tkk7.com/steeven/archive/2006/06/01/49379.htmlsteevensteevenWed, 31 May 2006 16:55:00 GMThttp://www.tkk7.com/steeven/archive/2006/06/01/49379.htmlhttp://www.tkk7.com/steeven/comments/49379.htmlhttp://www.tkk7.com/steeven/archive/2006/06/01/49379.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/49379.htmlhttp://www.tkk7.com/steeven/services/trackbacks/49379.html Google Web Toolkit 雖然還是beta版本,和google的其他產品一樣,剛出生就注定不凡,也許將影響后面幾年的b/s開發。

gwt利用了java開發的一切成熟條件,包括Unit test, refactor, IDE(eclipse...),傳統的b/s framework必將受到重創,橫掃過后,JSF/ECHO等Server side framework可能幸存。如果哪天google加上serverside支持(從包命名上看是留有余地的)。。。雖然gwt目前還是小樣一個,但是背后站的是重量級的google,強大的資源和數不完的銀子。。。。

看到這玩意首先想到的是echo2, 客戶端技術都是ajax, 編碼都是java. 不同的是gwt發行時編譯成HTML+JS,Echo2則是完全的服務器端生成+更新。gwt跟server端交互依靠類似于ws的service把前后臺完全區分開。

在echo的論壇里面已經有人在討論這玩意了,并且八卦了一下gwt的前身似乎是Morfik的一部分(待證實)
從原理上,echo的開發者作出了對比,這個網站似乎被封鎖,這里轉貼一下:


===============================
http://echotwo.blogspot.com/?作者tod liebeck

Comparing the Google Web Toolkit to Echo2
The Google Web Toolkit (GWT) is being compared to Echo2 quite frequently. Some of these comparisons have been fairly accurate, while others contain bits of misinformation. This article, written by the lead developer of Echo2, discusses the similarities and differences between these two frameworks.

Overview

The Google Web Toolkit and Echo2 definitely make for an interesting comparison. Both of these frameworks take a non-traditional approach toward web application development, even considering the latest crop of "AJAX-based frameworks" available today.

The most obvious similarity between GWT and Echo2 is that they both enable the developer to create dynamic, AJAX-driven web user interfaces using only Java. In both projects, UIs are developed in a fashion similar to SWT or Swing: by assembling hierarchies of components and registering event handlers. Neither project requires the developer to work with HTML, JavaScript, or XML.

The most obvious difference between GWT and Echo2 is that all of your GWT code is executed on the client, whereas your Echo2 code is executed on the server. There are advantages and disadvantages to both of these approaches, which will be highlighted throughout the article.

GWT's defining attribute is the Java-to-JavaScript compiler. This compiler allows you to develop the web interface to your application in Java, then compile it to JavaScript. GWT limits the developer to a subset of the Java 1.4 libraries. GWT applications can be served by any web server, such as Apache, without the need for server-side processing.

Echo2 applications are compiled to Java byte code and run on a Java server. Their Java code is executed by Echo2's "Web Application Container" layer, which sits atop a Java Servlet. On the web browser, the Echo2 "Client Engine" communicates user input to the Web Application Container via AJAX requests, with the server responding with directives to perform incremental updates to the state of the client web browser.

User Interface Performance

With GWT, all of your user interface code exists on the client browser. In operations that do not require server communication--that is, that do not require retrieving data from the middle tier--this configuration results in response times that are not dependent on the server. When data must be retrieved from the application's middle tier or business logic layer, the response time is subject to the same criteria as any other AJAX application, i.e., network latency, bandwidth, and server performance.

Echo2 application code is run on the server, so for each user interaction that requires a call to the middle tier or immediate execution of the application's Java code, an AJAX connection is made to the server. Echo2 components are designed to minimize the client/server communication as much as is possible, limiting it to times when the server must be notified immediately of events. For example, simple events such as user input to a TextField component will not result in server contact. The server's response is the minimum set of instructions to incrementally update the client to reflect the new screen state.

GWT applications are served to the client as a single HTML/JavaScript file, containing the entirety of the user interface. The size of this file will be proportional to the size of your user interface code and the toolkit libraries used by your application.

Echo2 JavaScript modules are lazy-loaded to the client, and thereafter cached. A module will be retrieved when a component first appears on-screen that requires it. Application code is never sent to the client, only the state of the user interface.

Middle Tier / Data Retrieval

To access business data or perform a business process, a GWT user interface makes a remote procedure call (RPC) from the browser to a Servlet. GWT provides a mechanism to make the RPC invocation transparent to the developer, allowing the developer to build the application with "Plain Old Java Objects" (POJOs). However, any application that provides an RPC capability is a distributed application -- even when the RPC is accomplished transparently to the developer. Distributed applications in businesses and enterprises usually have security considerations and the remote objects serving the GWT clients must be designed with a focus on security to deflect attacks from imitated or hostile client applications.

Echo2 applications support, but do not require, the use of distributed application logic or a Service Oriented Architecture (SOA). Alternatively, Echo2 applications can be built to run entirely within a single JVM instance, backed by a POJO-based middle tier. This allows Echo2 developers to build applications without the security concerns of distributed application logic -- and leverage the many strong frameworks built around POJO development such as the Spring Framework and Hibernate. Echo2 accomplishes this by keeping the state of a user's web interface on the server so that no remote objects need to be exposed.

Run-time Environment

GWT has some limitations due to the fact that applications are run on the client browser. First, GWT applications are limited to using a subset of the core Java class libraries, consisting of 27 classes, 11 interfaces, and 18 exception types found in the java.util and java.lang packages (as of GWT 1.0.21). This limitation prevents GWT applications from linking to most existing Java libraries. Additionally, all Java code must be compliant with the Java 1.4 specification; 1.5 is not supported. Localization-related portions of the Java API are not provided.

Debugging

GWT provides an alternate deployment environment for applications to facilitate debugging. The environment, called "Hosted Mode", allows a GWT application to be run as Java byte code in a local JVM, to which an IDE's debugger can be connected. In this mode, the application's user interface is displayed in a special web browser (a Mozilla/Firefox derivative).

Echo2 applications may be debugged in the conventional manner, by connecting an IDE's debugger to a JVM running a Servlet container.

Licensing

The primary component of GWT, the Java-to-JavaScript cross-compiler, is proprietary, binary-only software. The Java API libraries are open source software, distributed under the Apache License. The API libraries have essentially no value without the proprietary compiler. The (non-critical) hosted-mode browser is also under the proprietary license. GWT is provided free of charge.

Echo2 is open source software, licensed under the Mozilla Public License, and provided free of charge.

Applicability

GWT can be used as a means of creating AJAX components to embed in traditional web applications (or even in static web pages) as well as for creating complete application user interfaces. There are some issues to using it for the creation of large applications, where downloading an entire application to a client web browser in one shot would not be practical. The lack of localization and full Java API support also presents a problem for larger solutions.

Echo2 is practical for creating web applications of any size. It is however not intended to scale downward to function as a platform for simply creating AJAX components in traditional web frameworks (or static web sites).

More Information

Google Web Toolkit:
Home Page, Example Applications, Getting Started Guide, Developer Guide

Echo2:
Home Page, Example Applications, Tutorial
posted by Tod Liebeck at 5:13 AM | 0 comments??

======================================
畢竟gwt還是小baby, 以后怎么發展還難說,現在下結論太早。這兩天試用一下,有空從細節上對比一下。



steeven 2006-06-01 00:55 發表評論
]]>
EMF之ResourceSet探索(4)http://www.tkk7.com/steeven/archive/2006/05/26/48271.htmlsteevensteevenFri, 26 May 2006 02:22:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/26/48271.htmlhttp://www.tkk7.com/steeven/comments/48271.htmlhttp://www.tkk7.com/steeven/archive/2006/05/26/48271.html#Feedback1http://www.tkk7.com/steeven/comments/commentRss/48271.htmlhttp://www.tkk7.com/steeven/services/trackbacks/48271.html測試一下getResource(URI,boolean):

????????System.out.println(EcorePackage.eINSTANCE.eResource());? // 1
????????System.out.println(XMLTypePackage.eINSTANCE.eResource());? // 2

????????ResourceSet?rs?
= ? new ?ResourceSetImpl();
????????rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put(
????????????????Resource.Factory.Registry.DEFAULT_EXTENSION,
????????????????
new ?XMIResourceFactoryImpl());
????????String?uri?
= ? " http://abc.eg/asdf " ;
// ????????System.out.println(rs.createResource(URI.createURI(uri)));? // ?如果創建過臨時的,得到這個
// ????????System.out.println(rs.createResource(URI.createURI(uri)));? // ?如果創建過多個臨時的,返回第一個,這個忽略
????????rs.getPackageRegistry().put(uri,?EcorePackage.eINSTANCE);? // 得到結果同1,如果上面取消注釋,本地創建的優先

????????System.out.println(rs.getResource(URI.createURI(uri),?
false ));? // 同1


createResource每次創建新的,getResource則是唯一實例的。

每個生成的XxxPackage.eINSTANCE會自行創建自己的Resource。如果在插件中修改了EcorePackge.eInstance.eResource(),會不會天下大亂呢?

==================
eclispe編輯器右邊的Mark Occurrence很方便,但是家里電腦上的這個黃色小標記很不清楚。前幾天調整了老半天,修改配色方案,換顯示器驅動,調整顯示器對比度、亮度都收效不大。昨天偶然把XP的桌面風格換回傳統模式,搞定了。

ecore.ecore這個問題很有意思,以前看過schema.xsd,就是自己定義自己。據說JDK也是用java開發編譯出來的。。。
先有雞還是現有蛋呢?



steeven 2006-05-26 10:22 發表評論
]]>
EMF之ResourceSet探索(3) http://www.tkk7.com/steeven/archive/2006/05/26/48249.htmlsteevensteevenThu, 25 May 2006 17:23:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/26/48249.htmlhttp://www.tkk7.com/steeven/comments/48249.htmlhttp://www.tkk7.com/steeven/archive/2006/05/26/48249.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/48249.htmlhttp://www.tkk7.com/steeven/services/trackbacks/48249.html在RS中同一URI可以createResource多個Resource,List方式存放。還存在另外一種Map存放方式, getResource(URI,boolean loadOnDemand)就是通過這種方式存取,如果不存在的話創建。這兩個方法看起來有些沖突。似乎用于不同場合。

再來看看怎樣通過URL存取EObject:
RS整個相當于一個DataBase, Resource相當于表,存放的是EObject, 每個EObject可以看成對象或者XML。
表用URI來區分,URI中的Segment用來定位EObject。URI的例子參見探索(1)
getEObject(URL, boolean loadOnDemand)很簡單,getResource找到對應的Resource,在里面根據Segment查找,就是那個#///@xxx.n格式的東西,注意,還有ID方式。

getPackageRegistry()用來返回RS的URL->Package注冊表,它也是個本地的注冊表,代理了全局的EPackage.Registry.INSTANCE。這個注冊表用于取得EPackage(類型信息)和EFactory(創建實例)


Resource就不說了,主要load,save, 一些具體子類,比如XmlResourceImpl可以直接使用,指定Encoding之類。

看看ResourceSet對EMF了解了很多~



steeven 2006-05-26 01:23 發表評論
]]>
EMF之ResourceSet探索(2) http://www.tkk7.com/steeven/archive/2006/05/26/48242.htmlsteevensteevenThu, 25 May 2006 16:02:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/26/48242.htmlhttp://www.tkk7.com/steeven/comments/48242.htmlhttp://www.tkk7.com/steeven/archive/2006/05/26/48242.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/48242.htmlhttp://www.tkk7.com/steeven/services/trackbacks/48242.html1. getResourceFactoryRegistry()
??public?Resource.Factory.Registry?getResourceFactoryRegistry()
??
{
????
if?(resourceFactoryRegistry?==?null)
????
{//可以自行Set一個注冊表實現,沒有的話用系統缺省注冊表
??????resourceFactoryRegistry?=
????????
new?ResourceFactoryRegistryImpl()
????????
{
??????????
public?Resource.Factory?delegatedGetFactory(URI?uri)
??????????
{
????????????
return?Resource.Factory.Registry.INSTANCE.getFactory(uri);
??????????}

????????}
;?//代理系統注冊表,注意這個應該是正宗的。
????}

????
return?resourceFactoryRegistry;
??}

所以自己new 出來的ResourceSet可以向注冊表中任意添加工廠實現。
2. 調用注冊表的getFactory(URI), 實現如下:
?public?Resource.Factory?getFactory(URI?uri)
??
{
????String?protocol?
=?uri.scheme();
????Object?resourceFactory?
=??protocolToFactoryMap.get(protocol);?//先根據protocol查找
????if?(resourceFactory?==?null)
????
{
??????String?extension?
=?uri.fileExtension();
??????resourceFactory?
=?extensionToFactoryMap.get(extension);?//找不到再根據擴展名查找
??????if?(resourceFactory?==?null)
??????
{
????????resourceFactory?
=?extensionToFactoryMap.get("*");?//嘗試查找缺省擴展
????????if?(resourceFactory?==?null)
????????
{
??????????resourceFactory?
=?delegatedGetFactory(uri);?//自行實現可以擴展此方法解析。
????????}

??????}

????}


????
//Descriptor可以用于編程使用
????return?
??????resourceFactory?
instanceof?Resource.Factory.Descriptor??
????????((Resource.Factory.Descriptor)resourceFactory).createFactory()?:
????????(Resource.Factory)resourceFactory;
??}

查找一個工廠居然這么復雜!正因為這么復雜,才能支持platform/file/fttp等眾多千奇百怪的URI
不同類型的工廠加工出不同類型的Resource, 才會輸出為XSD/XML/XMI/....

如果直接操作系統注冊表要小心。EMF中定義了幾個擴展點,可以實現類似目的。
已知的ResourceFactory實現有:XSD/ECore/EMOF/XML/XMI,XSD的輸出方法的介紹可以參考Eclipse Development using the Graphical Editing Framework and the Eclipse Modeling Framework電子書。





steeven 2006-05-26 00:02 發表評論
]]>
EMF之ResourceSet探索(1)http://www.tkk7.com/steeven/archive/2006/05/25/48229.htmlsteevensteevenThu, 25 May 2006 14:40:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/25/48229.htmlhttp://www.tkk7.com/steeven/comments/48229.htmlhttp://www.tkk7.com/steeven/archive/2006/05/25/48229.html#Feedback1http://www.tkk7.com/steeven/comments/commentRss/48229.htmlhttp://www.tkk7.com/steeven/services/trackbacks/48229.html先看看現象,以EMF例子Library.ecore為例, 測試代碼如下:
public?class?Test?{
????
public?static?void?main(String[]?args)?throws?IOException?{
????????ResourceSet?rs?
=?new?ResourceSetImpl();
????????rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put(
????????????????Resource.Factory.Registry.DEFAULT_EXTENSION,
????????????????
new?XMIResourceFactoryImpl()); //outside eclipse
????????Resource?resource?
=?rs.createResource(URI
????????????????.createURI(EXTLibraryPackage.eNS_URI));
????????
//step?a
????????Library?library?=?EXTLibraryFactory.eINSTANCE.createLibrary();
????????library.setName(
"some?lib");
????????resource.getContents().add(library);
????????
//step?b
//????????Book?book?=?EXTLibraryFactory.eINSTANCE.createBook();
//????????book.setTitle("some?book");
//????????Employee?employee?=?EXTLibraryFactory.eINSTANCE.createEmployee();
//????????employee.setFirstName("some?one");
????????
//step?c
//????????library.getBooks().add(book);
//????????library.getEmployees().add(employee);
????????
//step?d
//????????resource.getContents().add(book);
????
//????????System.out.println(EcoreUtil.getURI(employee));
//????????System.out.println(EcoreUtil.getURI(book));
????????resource.save(System.out,?null);
????}

}


步驟 輸出
a ----------------
<?xml version="1.0" encoding="ASCII"?>
<extlib:Library xmi:version="2.0" xmlns:xmi="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0" name="some lib"/>
b?#//
#//
<?xml version="1.0" encoding="ASCII"?>
<extlib:Library xmi:version="2.0" xmlns:xmi="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0" name="some lib"/>
c http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0#//@employees.0
#//
<?xml version="1.0" encoding="ASCII"?>
<extlib:Library xmi:version="2.0" xmlns:xmi="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0" name="some lib">
? <employees firstName="some one"/>
</extlib:Library>
d http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0#/0/@employees.0
http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0#/1
<?xml version="1.0" encoding="ASCII"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0">
? <extlib:Library name="some lib">
??? <employees firstName="some one"/>
? </extlib:Library>
? <extlib:Book title="some book"/>
</xmi:XMI>

可以看到,沒有加入lib的時候,employee/book實例的URI都是#//, employee加入以后有了#//@employees.0, book依舊。
在book加入resource以后有了#/1的URI, employee/book在containment定義分別是true,false,所以employee加入lib以后就隨lib加入resource(實例容器)。book則要單獨加入。

另外一個有趣的現象是Resource可以容納多個實例,在step d可以看到輸出的根節點由lib變成匿名容器。

如果lib不加入resource又如何呢?
步驟 輸出
a ----------------
b?#//
#//
c #///@employees.0
#//
d ----------------
沒加入resource之前,URI是未知的,知道的只是相對父節點的相對segment.



steeven 2006-05-25 22:40 發表評論
]]>
Annotation Wizard for EMF插件http://www.tkk7.com/steeven/archive/2006/05/24/47883.htmlsteevensteevenWed, 24 May 2006 12:14:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/24/47883.htmlhttp://www.tkk7.com/steeven/comments/47883.htmlhttp://www.tkk7.com/steeven/archive/2006/05/24/47883.html#Feedback3http://www.tkk7.com/steeven/comments/commentRss/47883.htmlhttp://www.tkk7.com/steeven/services/trackbacks/47883.html手寫指定Source,指定每個Key/Value很容易出錯。
這個插件通過向導選擇source, 通過PropertySheet編寫Key/Value。并且根據Ecore的定義實現校驗。

Step1:


Step 2:
AllDataTypes組合了該URL下面所有的EDataType


Step3: 編輯屬性。注意source的變化:
如果選擇的AllDataTypes,就是Ecore的URI
如果選擇某個EClass, 后面會加上#EClassName


Step4: 如果選擇AllDataTypes,自動選擇所有EdataTypes。


Step5: 工作結果



請注意Source的生成規則!

適用版本:eclipse3.2rc3
下載地址: http://www.tkk7.com/Files/steeven/org.steeven.eclipse.emf.annotation.wizard.zip (含源碼)

steeven 2006-05-24 20:14 發表評論
]]>
EMF驗證擴展:自定義驗證規則http://www.tkk7.com/steeven/archive/2006/05/19/47107.htmlsteevensteevenFri, 19 May 2006 11:03:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/19/47107.htmlhttp://www.tkk7.com/steeven/comments/47107.htmlhttp://www.tkk7.com/steeven/archive/2006/05/19/47107.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/47107.htmlhttp://www.tkk7.com/steeven/services/trackbacks/47107.html因為比較少,所以這里總結一下。

驗證的定義有兩種方式:
1. 生成驗證方法框架,代碼自己實現。參見EMF Overview:
? 添加Annotatio, Source=http://www.eclipse.org/emf/2002/Ecore, 然后添加DetailsEntry:key=constraints, Value=validateXxx
? EDataType,EClass支持,屬性不支持。
2. 定義類似Schema的Facet,自動生成對應的驗證代碼,用于驗證簡單數據類型:
? 添加Annotatio, Source=http:///org/eclipse/emf/ecore/util/ExtendedMetaData, 然后添加DetailsEntry:key=maxLength, Value=2
? 支持的facet參見ExtendedMetaData。
? 僅EDataType支持,屬性不支持。

示例Ecore:

新生成SqlmodelValidator.java, 代碼如下:

可見Table_ValidateC, MyLabel_ValidateA,MyLabel_validateB都自動生成,修改里面的if(false)為需要的業務判斷邏輯。
validateMyLabel_MaxLength()方法是根據ExtendedMetaData自動生成的,無需修改。

總結:
1. EMF驗證利用了Annotation擴展,這種機制很靈活,但是給用戶帶來不便。
2. Attribute屬性不能生成驗證規則(eclipse3.2rc3),可以定義為單獨的EDataType,然后引用之。
3. Constraints+Facet+本身的結構驗證可以構成很強的驗證規則,并且屬于Model層,數據本身即可驗證自身。
4. EObjectValidator.DynamicEDataTypeValidator似乎可用于動態驗證,有知道用法的朋友給講解一下~



steeven 2006-05-19 19:03 發表評論
]]>
編程使用SDO[EMF兄弟篇]http://www.tkk7.com/steeven/archive/2006/05/15/46266.htmlsteevensteevenMon, 15 May 2006 11:00:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/15/46266.htmlhttp://www.tkk7.com/steeven/comments/46266.htmlhttp://www.tkk7.com/steeven/archive/2006/05/15/46266.html#Feedback5http://www.tkk7.com/steeven/comments/commentRss/46266.htmlhttp://www.tkk7.com/steeven/services/trackbacks/46266.html主要特點:(個人理解)
可驗證
強類型
可取出完整數據和差異。

生成SDO代碼和EMF大同小異,主要是在my.genmodel的第一個節點的右鍵菜單中選擇:Set SDO defaults.

體驗:
1. 生成Editor后,執行生成的Editor Plugin
2. 新建Example EMF Model Creation Wizards->Data Graph Model
3. 在Changes節點上Start Loggin, 然后編輯數據即可看到自動生成的差異。

網上手工操作SDO的示例代碼比較少,這里簡單demo如下:
import?java.util.Iterator;

import?org.eclipse.emf.ecore.EObject;
import?org.eclipse.emf.ecore.sdo.EDataGraph;
import?org.eclipse.emf.ecore.sdo.SDOFactory;
import?org.steeven.family.FamilyFactory;
import?org.steeven.family.個人;
import?org.steeven.family.家庭;

import?commonj.sdo.ChangeSummary;
import?commonj.sdo.DataGraph;
import?commonj.sdo.DataObject;

public?class?Server?{

????
public?static?void?main(String[]?args)?{
????????
//?client?side
????????EDataGraph?graph?=?loadGraph();
????????graph.getChangeSummary().beginLogging(); // important!
????????家庭?family?
=?(家庭)?graph.getRootObject();
????????family.setTitle(
"my?family");
????????個人?baby?
=?FamilyFactory.INSTANCE.create個人();
????????baby.set姓名(
"sophie");
????????family.get兔崽子().add(baby);
????????graph.getChangeSummary().endLogging();
????????saveGraph(graph);
????????update(graph);
????}


????
//server?side
????public?static?EDataGraph?loadGraph()?{
????????家庭?family?
=?FamilyFactory.INSTANCE.create家庭();?//?or?load?from
????????
//?database
????????EDataGraph?graph?=?SDOFactory.eINSTANCE.createEDataGraph();
????????graph.setERootObject((EObject)?family);
????????
return?graph;
????}


????
//server?side?full?save
????public?static?void?saveGraph(EDataGraph?graph)?{
????????System.out.println(graph.getRootObject());
????}


????
//server?side?update?changed?objects
????public?static?void?update(DataGraph?dataGraph)?{
????????ChangeSummary?changeSummary?
=?dataGraph.getChangeSummary();
????????
for?(Iterator?it?=?changeSummary.getChangedDataObjects().iterator();?it
????????????????.hasNext();)?
{
????????????DataObject?changedObject?
=?(DataObject)?it.next();
????????????System.out.println(
"Update?for?"?+?changedObject);
????????????
for?(Iterator?settingIt?=?changeSummary.getOldValues(changedObject)
????????????????????.iterator();?settingIt.hasNext();)?
{
????????????????ChangeSummary.Setting?changeSetting?
=?(ChangeSummary.Setting)?settingIt
????????????????????????.next();
????????????????System.out.println(
"?(changed?"
????????????????????????
+?changeSetting.getProperty().getName()?+?"?from?\""
????????????????????????+?changeSetting.getValue()?+?"\"?to?\""
????????????????????????
+?changedObject.get(changeSetting.getProperty())
????????????????????????
+?"\")");
????????????}

????????}

????}

}

輸出:
org.steeven.family.impl.家庭Impl@9664a1?(title:?my?family)
Update?for?org.steeven.family.impl.個人Impl@1729854?(姓名:?sophie,?性別:?男)
Update?for?org.steeven.family.impl.家庭Impl@9664a1?(title:?my?family)
?(changed?title?from?"null"?to?"my?family")
?(changed?兔崽子?from?"[]"?to?"[org.steeven.family.impl.個人Impl@1729854?(姓名:?sophie,?性別:?男)]")

SDO生成的代碼似乎更加純凈一點,沒有很多的eXxxx()方法(有需要的也可以取到)。
據說log的開銷比較大,不建議對大量數據使用。

steeven 2006-05-15 19:00 發表評論
]]>
EMF編程使用http://www.tkk7.com/steeven/archive/2006/05/14/46129.htmlsteevensteevenSun, 14 May 2006 13:27:00 GMThttp://www.tkk7.com/steeven/archive/2006/05/14/46129.htmlhttp://www.tkk7.com/steeven/comments/46129.htmlhttp://www.tkk7.com/steeven/archive/2006/05/14/46129.html#Feedback3http://www.tkk7.com/steeven/comments/commentRss/46129.htmlhttp://www.tkk7.com/steeven/services/trackbacks/46129.html看到eclipse3.2里面的GMF, 覺得比較有趣,底層還是用到了EMF. 花了兩天時間仔細研究了以下EMF,的確是個好東西.

EMF根據ecore建模(可以和schema的xsd相互轉換)生成強類型的EMF代碼. 這個強類型更強的地方是可以取得meta信息,從而可以用于校驗和界面輔助信息的生成.類似于動態bean,屬性也可以根據名稱動態取得.

以前考慮過用xsd描述界面, 但是數據載體只能是xml, 即使利用apache的schema編譯工具生成強類型的類,后臺代碼也是xml. 不利于持久化. emf在代碼生成引擎比較智能,可以標記出用戶代碼和自動生成代碼.不會有生成覆蓋問題.

這里做個簡單示例:
1. Ecore:
可以新建Ecore, 建立好以后用GMF可視化編輯(Eclipse3.2RC2)

2. 生成Model:
點擊my.ecore文件,菜單:File->New->Other->Eclipse Modeling Framework->EMF Model
3. 打開生成的my.genmodel, 選擇樹頂點的:Generate Model Code
生成的代碼里面會有一個編譯錯誤. 是中文編程的問題, 中文沒有大小寫(先天不足啊),結果性別這個成員變量和性別類名混淆,出錯.在錯誤代碼前面加上包全名即可.
4. 利用生成的代碼構建一個家庭,輸出xml并且校驗之:

import ?java.io.IOException;
import ?java.util.Iterator;

import ?org.eclipse.emf.common.util.Diagnostic;
import ?org.eclipse.emf.common.util.URI;
import ?org.eclipse.emf.ecore.EObject;
import ?org.eclipse.emf.ecore.resource.Resource;
import ?org.eclipse.emf.ecore.util.Diagnostician;
import ?org.eclipse.emf.ecore.xmi.XMLResource;
import ?org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import ?org.steeven.family.FamilyFactory;
import ?org.steeven.family.人物;
import ?org.steeven.family.家庭;
import ?org.steeven.family.性別;

public ? class ?TestMy? {

????
public ? static ? void ?main(String[]?args)? throws ?IOException? {
????????testFamily();
????}


????
private ? static ? void ?testFamily()? throws ?IOException? {
????????家庭?family?
= ?FamilyFactory.eINSTANCE.create家庭();
????????family.setTitle(
" steeven家 " );
????????family.set老公(FamilyFactory.eINSTANCE.create人物());
????????family.get老公().set姓名(
" steeven " );
????????family.set老婆(FamilyFactory.eINSTANCE.create人物());
????????family.get老婆().set姓名(
" stella " );
????????family.get老婆().set性別(性別.女_LITERAL);
????????人物?sophie?
= ?FamilyFactory.eINSTANCE.create人物();
????????sophie.set姓名(
" sophie " );
????????sophie.set性別(性別.女_LITERAL);
????????family.get兔崽子().add(sophie);
????????dump(family);
????????validate(family);
????}


????
private ? static ? void ?validate(EObject?family)? {
????????Diagnostic?diagnostic?
= ?Diagnostician.INSTANCE.validate(family);
????????System.out.println(diagnostic);
????????
for ?(Iterator?it? = ?diagnostic.getChildren().iterator();?it.hasNext();)? {
????????????Diagnostic?diag?
= ?(Diagnostic)?it.next();
????????????System.out.println(diag.getMessage());
????????}

????}


????
private ? static ?Resource?dump(EObject?objs)? throws ?IOException? {
????????
// ?ResourceSet?rs?=?new?ResourceSetImpl();
????????
// ?rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put(
????????
// ?Resource.Factory.Registry.DEFAULT_EXTENSION,
????????
// ?new?XMIResourceFactoryImpl());
????????
// ?Resource?resource?=?rs.createResource(URI
????????
// ?.createFileURI("c:\\temp\\test.xml"));
????????XMLResource?resource? = ? new ?XMLResourceImpl(URI
????????????????.createFileURI(
" c:\\temp\\test.xml " ));
????????resource.setEncoding(
" GBK " );
????????
for ?(EObject?obj?:?objs)
????????????resource.getContents().add(obj);?
// ?目前版本不加入resource驗證會報singling異常
????????resource.save(System.out,? null );
????????
return ?resource;
????}

}

運行結果如下:

<? xml?version="1.0"?encoding="GBK" ?>
< family: 家庭?xmlns:family ="http://org.steeven/family" ?title ="steeven家" ?老公 ="/" ?老婆 ="/" ?兔崽子 ="/" />
Diagnostic?ERROR?
The?feature?'老公'?of?'org.steeven.family.impl.家庭Impl@f6a746{file:/c:/temp/test.xml#/}'?contains?a?dangling?reference?'org.steeven.family.impl.人物Impl@6eb38a{#//}'
The?feature?'老婆'?of?'org.steeven.family.impl.家庭Impl@f6a746{file:/c:/temp/test.xml#/}'?contains?a?dangling?reference?'org.steeven.family.impl.人物Impl@1cd2e5f{#//}'
The?feature?'兔崽子'?of?'org.steeven.family.impl.家庭Impl@f6a746{file:/c:/temp/test.xml#/}'?contains?a?dangling?reference?'org.steeven.family.impl.人物Impl@19f953d{#//}'

可見輸出的xml中沒有包含人物的具體信息. 修改my.ecore中老公/老婆/兔崽子屬性的containment屬性為true,重新生成代碼后運行結果如下:
<?xml?version="1.0"?encoding="GBK"?>
<family:家庭?xmlns:family="http://org.steeven/family"?title="steeven家">
??
<老公?姓名="steeven"/>
??
<老婆?性別="女"?姓名="stella"/>
??
<兔崽子?性別="女"?姓名="sophie"/>
</family:家庭>
Diagnostic?OK


====================
EMF單獨運行成功~

這里ECORE似乎不支持嵌套定義,不像schema那樣一個complexType聲明里面可以定義的很復雜, 也不像Java的內部類. 似乎被作了簡化, 更像關系數據庫表之間的關系.

待求證問題:
1. EMF的校驗信息是否支持國際化.
2. EMF數據的能否更方便的保存到數據.

EMF的靈活和強大已經驗證過, 用于C/S還是B/S應該都不是問題.


steeven 2006-05-14 21:27 發表評論
]]>
Manifest編輯插件 for eclipse3.1/jdk1.5http://www.tkk7.com/steeven/archive/2006/04/07/39863.htmlsteevensteevenFri, 07 Apr 2006 08:24:00 GMThttp://www.tkk7.com/steeven/archive/2006/04/07/39863.htmlhttp://www.tkk7.com/steeven/comments/39863.htmlhttp://www.tkk7.com/steeven/archive/2006/04/07/39863.html#Feedback2http://www.tkk7.com/steeven/comments/commentRss/39863.htmlhttp://www.tkk7.com/steeven/services/trackbacks/39863.html
主要想法是運行程序一句話搞定: java -jar xxx.jar。所有class path在jar里面的manfiest.mf中設定。
當需要引用的jar很多的時候,windows2000有命令行的長度限制,會報錯。

主要功能:
1. new wizard
2. gui editor
3. switch auto-update in project menu

Class-Path in auto-updated manifest.mf file will be auto updated
while increase & full building.

下載:http://www.tkk7.com/Files/steeven/org.steeven.eclipse.manifest_1.0.zip

安裝:eclipse菜單[help]->?Software Updates->?Find and Install ->????Search for new features to install ->???new archieved site

steeven 2006-04-07 16:24 發表評論
]]>
總結一下最近碰到的幾個怪問題http://www.tkk7.com/steeven/archive/2006/04/07/39860.htmlsteevensteevenFri, 07 Apr 2006 08:15:00 GMThttp://www.tkk7.com/steeven/archive/2006/04/07/39860.htmlhttp://www.tkk7.com/steeven/comments/39860.htmlhttp://www.tkk7.com/steeven/archive/2006/04/07/39860.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/39860.htmlhttp://www.tkk7.com/steeven/services/trackbacks/39860.html最近碰到幾個怪問題:
1. 在新裝的XP上Swing界面文字不顯示,加上遠程調試參數就能出來。安裝最新的jre/jdk也沒用。啟動時加上遠程調試參數OK,但不能這樣交付啊。后來給顯卡升級了一下驅動,搞定!真是奇怪
2. xp上跑的很好的批處理在win2k下失敗,%~dps0失敗,這是用來取批處理的短格式當前路徑。google后知道這個參數在xpsp2以前都返回錯誤路徑,我倒。。。 %~dps1, %~dp0都能正常工作,于是乎,寫了兩個批處理,把%dp0(長路徑)傳給另外一個,在那里面用%~dps1取得后設定環境變量,成功~
3.?Java程序安裝成服務以后不能接受其他電腦的訪問,獨立運行的時候沒問題。用超級用戶權限也沒戲。后來拍拍腦袋發現是防火墻的問題,手動啟動服務的時候windows防火墻不提示是否允許訪問網絡,所以缺省就被禁止鳥~。在防火墻中添加例外程序以后OK。所以安裝程序需要聰明一些,自己在注冊表中增加相關設定。



steeven 2006-04-07 16:15 發表評論
]]>
可惡的mainfest.mf解析http://www.tkk7.com/steeven/archive/2006/03/09/34527.htmlsteevensteevenThu, 09 Mar 2006 10:43:00 GMThttp://www.tkk7.com/steeven/archive/2006/03/09/34527.htmlhttp://www.tkk7.com/steeven/comments/34527.htmlhttp://www.tkk7.com/steeven/archive/2006/03/09/34527.html#Feedback0http://www.tkk7.com/steeven/comments/commentRss/34527.htmlhttp://www.tkk7.com/steeven/services/trackbacks/34527.html

steeven 2006-03-09 18:43 發表評論
]]>
Java版2006新春祝福http://www.tkk7.com/steeven/archive/2006/01/12/27697.htmlsteevensteevenThu, 12 Jan 2006 03:33:00 GMThttp://www.tkk7.com/steeven/archive/2006/01/12/27697.htmlhttp://www.tkk7.com/steeven/comments/27697.htmlhttp://www.tkk7.com/steeven/archive/2006/01/12/27697.html#Feedback1http://www.tkk7.com/steeven/comments/commentRss/27697.htmlhttp://www.tkk7.com/steeven/services/trackbacks/27697.html偶msn名字是:Year y2006 = /*happy*/ new Year(2006);
一個朋友受到啟發,給偶寫了一段祝福代碼,稍微改編一下送給大家

for(Blogger blogger :  BlogFarm.getInstance["BlogJava"].getBloggers()){
    blogger.setHealth(
Health.good);
    blogger.getFamily().setHappy(blogger.getFamily().getHappy() 
1);
    blogger.setMoney(blogger.getMoney 
* 10);
}

備注:
1.未單元測試
2. 感覺不如c#版新春祝福優雅一些



steeven 2006-01-12 11:33 發表評論
]]>
沒事不要隨便吃螃蟹http://www.tkk7.com/steeven/archive/2006/01/05/26767.htmlsteevensteevenThu, 05 Jan 2006 11:08:00 GMThttp://www.tkk7.com/steeven/archive/2006/01/05/26767.htmlhttp://www.tkk7.com/steeven/comments/26767.htmlhttp://www.tkk7.com/steeven/archive/2006/01/05/26767.html#Feedback1http://www.tkk7.com/steeven/comments/commentRss/26767.htmlhttp://www.tkk7.com/steeven/services/trackbacks/26767.html最近程序除了點小問題,在多次執行某些操作之后屏幕會沒有反應,服務器上很多執行的線程也中止。
這是個很嚴重的問題,只要執行的任務一多,或者服務器開啟事件過長,都會有這個現象。
我們自己寫的服務器,支持服務器命令行指令。在服務器不響應時,命令行可以動作,但是exit命令執行時會掛起

分析過程:
1. debug模式啟動,找到command line線程,手工中斷,發現停留在Object.wait()方法上。
2. 向下看線程堆棧,是apache/common/pool/GenericObjectPool調用,向下是hibernate的ConnectionManager
3. 查看對象池的源碼,是因為池子滿了,因此等待借出對象return. 說明連接打開后沒有釋放。
4. 因為我們代碼中都是調用spring/hibernate的template或者自動事務,不存在手工打開連接,所以懷疑是哪個工具包出了問題。
5. 首先發現dbcp/pool都不是最新的,換上后無效。 hibernate3.1已經最新了。
6. 復制GenericObjectPool,在borrow和return方法中增加log, 打開connection Manager的log, 排除了所以配對的log外,有非connectionManager打開的連接,沒有被歸還。
7. debug發現是自動事務結束后,連接池中_numActive沒有變化,連接沒有關閉,懷疑spring問題,spring1.2.1是正式發行版本。在其網站上發現最新版本是1.2.6,看看新版本的更新說明,搜索到hibernate的修正,有一個正好就是說:修正了針對hibernate3.1的事務管理。
8. 更換為spring 1.2.6后正常,同時在dbcp中加大缺省maxActive數量。缺省為8個。

分析,因為hibernate3.1改變了事務處理方式,老版spring出現連接池泄漏。因為以前一直用的3.1的m版,所以看到正式版出來就直接更新了,沒想到有些比較重大的改變。記得當初更新時hibernate annotation當時就不能用,過了幾天才出來對應的更新版。

結論:單獨的api都是沒有問題的,配合起來很可能出問題。因此升級時應該謹慎,采用穩定版本,避免出現不匹配問題~~

浪費一個下午的時間~



steeven 2006-01-05 19:08 發表評論
]]>
奢談未來的java語言。。。 http://www.tkk7.com/steeven/archive/2005/12/29/25904.htmlsteevensteevenThu, 29 Dec 2005 09:01:00 GMThttp://www.tkk7.com/steeven/archive/2005/12/29/25904.htmlhttp://www.tkk7.com/steeven/comments/25904.htmlhttp://www.tkk7.com/steeven/archive/2005/12/29/25904.html#Feedback5http://www.tkk7.com/steeven/comments/commentRss/25904.htmlhttp://www.tkk7.com/steeven/services/trackbacks/25904.htmlJava是個扶不起的阿斗,sun在贏了微軟的官司以后似乎在忙于分紅,相對于紅紅火火的.net世界,sun幾乎在坐以待斃,浪費無數開源愛好者的感情。
matrix展望2006的java,似乎只能看到開源愛好者的一腔熱血。

未來的java應該是什么樣子呢?下面是我期望: 

    /**
     * 1. 空指針抑制<br>
     * JVM支持的Runtime空指針抑制,根據方法的[Nullable]標記<br>
     * java里面有太多的NullPointer異常,經常需要復雜的檢測,浪費沒必要的代碼。
     
*/

    [Nullable]
    
public void testNullable(A a){
        
return a.b().c.d(); //如果用if else寫需要多少代碼?
    }

    
    
/**
     * 2. 動態屬性支持<br>
     * 類似范型的實現,由編譯器支持即可。<br>
     * 
@param a: A implements DynamicBean,沒有定義c屬性
     
*/

    
public void dynamicProperty(A a){
        
assert a != null;
        a.b.c 
= "abc"//等效于a.getProperty("b").setProperty("c","abc");
        ResultSet rs; //for database:
        String name = rs.name; //if ResultSet defined getStringProperty(): String name = rs.getStringProperty("a");
        Element order; //for xml, element auto-created in getProperty() method.
        order.address.phone = "1234"//order.getProperty("address").setProperty("phone","1234");
    }

    
    
    
/**
     * 3. 動態方法支持<br>
     * 由編譯器支持即可。<br>
     * 
@param a: A implements DynamicInvoke,沒有定義b()方法
     
*/

    
public void dynamicMethod(A a){
        a.b(
1,"x"); //編譯為a.invoke("b",new Object[]{1,"x"]);
    }

    
    
/**
     * 4. 快速反射<br>
     * 由編譯器支持即可。便于編譯期間錯誤檢查<br>
     * 
@param a: A 定義了b(),c變量
     
*/

    
public void fastReflection(A a){
        Annotation[] mas 
= a.b().class.getAnnotations(); //a.getClass().getMethod("b").getAnnotations();
        Annotation[] mas = a.c.class.getAnnotations(); // a.getClass().getField("c").getAnnotations();
    }

    
    
/**
     * 5. 索引器<br>
     * 類似.net的索引器,語法簡潔。編譯期間支持即可<br>
     * 
@param a: A 實現了List接口,Map接口
     
*/

    
public void indexVisit(A a){
        Element order ; 
//xml element
        Element first = order[0]; //order.get(0);
        Element address = order["address"]; //order.get("address")
    }


    
/**
     * 6. AOP<br>
     * JVM內置支持AOP標記<br>
     * Trace是用戶自行定制的Attribute, Trace.Interceptor指定攔截器 
     
*/

    [Trace]
    [Role(
"admin")][Transactional]
    
public void jvmAOP(A a){
        
    }

    
    
/**
     * 7. 條件編譯<br>
     * 編譯器支持Condition標記,可以用于所有元素,甚至package<br>
     * 用于測試期間、調試期間編譯出不同的結果
     
*/

    
    
/**
     * 8. Schema,DataBase編譯支持<br>
     
*/

    
public static void schemaSupport() {
        [Schema(url
="file://test.xsd")]
        Document doc;
        Element c 
= doc.a.b.c; //根據schema編譯期間檢查
    }

    
    
/**
     * 9. 內置對象數據庫,支持類似記憶的遺忘模式以節省空間
     
*/

    
public void databaseSupport(){
        Database.
default.find("");
    }

    
    
/**
     * 10. 平臺支持<br>
     * 編寫windows的服務,調用windows的注冊表/log/ad/schedule/菜單、工具條、桌面。。。
     
*/

    
public void platformSupport(){
        PlatformRegistry.getString(
".");
    }



希望sun早日把java捐贈到開源社區,象eclipse一樣煥發青春。



steeven 2005-12-29 17:01 發表評論
]]>
主站蜘蛛池模板: 免费人成动漫在线播放r18 | 激情小说亚洲色图| 亚洲av永久综合在线观看尤物| 亚洲av福利无码无一区二区 | 成年女人毛片免费播放人| 国产一卡2卡3卡4卡无卡免费视频| 69视频在线是免费观看| 131美女爱做免费毛片| **一级一级毛片免费观看| 国产成人免费高清激情明星| 成年人视频免费在线观看| 色窝窝免费一区二区三区 | 你是我的城池营垒免费看| 国产一区二区三区免费观看在线| a级毛片高清免费视频| 日本免费一区二区三区四区五六区 | 久久久久国产成人精品亚洲午夜| 亚洲中文字幕无码一区| 亚洲AV无码成人精品区天堂| 18gay台湾男同亚洲男同| 亚洲成av人片不卡无码| 亚洲综合国产成人丁香五月激情 | 日韩亚洲人成在线| 成人亚洲国产精品久久| 九九综合VA免费看| 日本免费电影一区二区| 免费国产作爱视频网站| 国产色婷婷精品免费视频| 亚洲性日韩精品一区二区三区 | 午夜时刻免费入口| 亚洲女同成人AⅤ人片在线观看| 亚洲综合无码AV一区二区| 亚洲天堂男人天堂| 亚洲人成网站在线在线观看| 特级一级毛片免费看| 免费看男人j放进女人j免费看| 99久久99这里只有免费费精品| 国产免费啪嗒啪嗒视频看看| 亚洲精品无码不卡在线播HE| 亚洲国产综合在线| 日亚毛片免费乱码不卡一区|