<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 193,  comments - 520,  trackbacks - 0
     
    開發我們的例子程序
    jackrabbit已經配置好了,現在讓我們來創建我們的示例程序。這個例子程序將調用JCR-170 API。很顯然,我們需要做兩件事情:一個是作為后臺的對數據進行增刪改查(持久層),另一個是開發相對應的UI界面(WEB 層)。首先,讓我們定義一個DAO接口。這個接口BlogEntryDAO.java 如下:
    public?interface?BlogEntryDAO?{
    ????
    public?void?insertBlogEntry(BlogEntryDTO?blogEntryDTO)
    ????????
    throws?BlogApplicationException;
    ????
    public?void?updateBlogEntry(BlogEntryDTO?blogEntryDTO)
    ????????
    throws?BlogApplicationException;
    ????
    public?ArrayList?getBlogList()
    ????????
    throws?BlogApplicationException;
    ????
    public?BlogEntryDTO?getBlogEntry(String?blogTitle)
    ????????
    throws?BlogApplicationException;
    ????
    public?void?removeBlogEntry(String?blogTitle)
    ????????
    throws?BlogApplicationException;
    ????
    public?ArrayList?searchBlogList(String?userName)
    ????????
    throws?BlogApplicationException;
    ????
    public?void?attachFileToBlogEntry(String?blogTitle,?InputStream?uploadInputStream)
    ????????
    throws?BlogApplicationException;
    ????
    public?InputStream?getAttachedFile(String?blogTitle)
    ????????
    throws?BlogApplicationException;
    }

    正如你看到的,這個接口提供了增刪改查的方法,同時還提供了兩個方法來處理附件。接下來,我們需要一個DTO對象用來在兩個層之間傳遞數據。
    public?class?BlogEntryDTO?{

    ????
    private?String?userName;
    ????
    private?String?title;
    ????
    private?String?blogContent;
    ????
    private?Calendar?creationTime;

    ????
    //Getter?and?setter?methods?for?each?of?these?properties????????
    }

    這里我們將僅僅討論持久層。

    連接jackrabbit
    現在,第一件事情是開發一個組件,獲得一個到jackrabbit內容倉庫的連接。為了簡單,我們將在程序啟動的時候獲得這個連接,然后在程序停止的時候釋放這個連接。這里我們使用了Struts ,所以我們需要開發一個PlugIn 類。如下:
    public?class?JackrabbitPlugin?implements?PlugIn{
    ????
    public?static?Session?session;
    ????
    public?void?destroy()?{
    ????????session.logout();
    ????}
    ????
    public?void?init(ActionServlet?actionServlet,?ModuleConfig?moduleConfig)?
    ????
    throws?ServletException?{
    ????????
    try?{
    ????????????System.setProperty(
    "org.apache.jackrabbit.repository.home",
    ????????????????
    "c:/temp/Blogging");
    ????????????Repository?repository?
    =?new?TransientRepository();
    ????????????session?
    =?repository.login(new?SimpleCredentials("username",
    ????????????????????
    "password".toCharArray()));
    ????????}?
    catch?(LoginException?e)?{
    ????????????
    throw?new?ServletException(e);
    ????????}?
    catch?(IOException?e)?{
    ????????????
    throw?new?ServletException(e);
    ????????}?
    catch?(RepositoryException?e)?{
    ????????????
    throw?new?ServletException(e);????????????
    ????????}
    ????}
    ????
    public?static?Session?getSession()?{
    ????????
    return?session;
    ????}
    }

    init()方法將會在程序啟動的時候調用,destroy()將會在程序停止的時候調用。我們在init()方法里獲得了到jackrabbit內容倉庫的連接。看看代碼,我們做的第一件事是設定了org.apache.jackrabbit.repository.home這個系統屬性,在上篇文章里提到,這個屬性是用來指向我們的內容倉庫主目錄。這里我們設定它為c:/temp/blogging。接下來,我們創建了TransientRepository的一個實例。這是jackrabbit提供的類,它提供了一個到內容倉庫的代理。它在第一個session 打開的時候自動啟動內容倉庫,在最后一個session 關閉的時候自動關閉內容倉庫。
    一旦我們獲得了一個內容倉庫對象,我們就可以調用它的login() 方法來打開一個連接。login() 方法需要一個Credential 對象作為參數。如果Credential 對象是NULL,jackrabbit會認為其他的機制做了這個驗證(比如JAAS)。login() 方法還可以傳入一個workspace名字作為參數,如果不傳入這個參數,jackrabbit會返回一個session對象指向默認的workspace。注意workspace和session是一對一的,即一個session僅對應一個workspace。(注:如果不傳入Credential對象,返回的session對workspace是只讀的)

    增加內容
    連接已經建立起來了,下面讓我們實現BlogEntryDAO這個接口。第一個我們想實現的方法是插入數據 insertBlogEntry()
    public?void?insertBlogEntry(BlogEntryDTO?blogEntryDTO)
    ????????????
    throws?BlogApplicationException?{
    ????????Session?session?
    =?JackrabbitPlugin.getSession();
    ????????Node?rootNode?
    =?session.getRootNode();
    ????????Node?blogEntry?
    =?rootNode.addNode("blogEntry");
    ????????blogEntry.setProperty(
    "title",?blogEntryDTO.getTitle());
    ????????blogEntry.setProperty(
    "blogContent",?blogEntryDTO.getBlogContent());
    ????????blogEntry.setProperty(
    "creationTime",?blogEntryDTO.getCreationTime());
    ????????blogEntry.setProperty(
    "userName",?blogEntryDTO.getUserName());????????????
    ????????session.save();
    }

    首先獲得session 對象,即到內容倉庫特定workspace的連接。然后,我們在這個session 對象上調用getRootNode() 方法,獲得這個workspace的根節點,這個根節點的路徑是("/").一旦我們獲得這個根節點,我們就可以通過addNode()方法在這個根節點下增加新的子節點。新節點的名字是blogEntry. 通過setProperty() 方法我們把數據存儲到節點的property里。正如我們先前說明的,真實的數據是存儲在property元素里,property元素是葉子。
    注意session.save() 這行代碼。這個方法是必須調用的,這個方法調用之前,任何 Node,Property的改變都被保存在這個session的一個臨時區域里,其他的和該session連接到相同workspace的session都看不到這些改變。當這個方法被調用并被成功執行后,這些Node,Property的改變才會被持久化到這個session關聯的workspace里,同時所有與這個workspace關聯的session才可見這些變化。相對應的,Session.refresh(false)將會丟棄所有這些改變。item.save()和Item.refresh(false)作用相似,只是影響范圍限定在單個Item上(注意,包括它的子節點)
    posted @ 2007-01-25 23:12 ronghao 閱讀(3831) | 評論 (0)編輯 收藏
    內容倉庫模型
    JSR-170 是這樣定義內容倉庫的,內容倉庫由一組 workspace(工作空間)組成,這些workspace通常應該包含相似的內容。一個內容倉庫有一個到多個 workspace。每個workspace都是一個樹狀結構,都有一個唯一的樹根節點(root node)。樹上的item(元素)或者是個node(節點)或者是個property(屬性)。每個node都可以有零個到多個子節點和零個到多個子屬性。只有根節點沒有父節點,其余所有的節點都有一個父節點。property 也必須有一個父節點,但它沒有子節點或是子屬性,property 是葉子元素。property是真正存儲數據的元素。

    下圖描述了一個blog應用程序的內容倉庫模型。每個root node(根節點)的子節點都代表了一個blog實體。與這個blog實體有關的數據都存儲在 bolgEntry 節點的屬性里,其中一個 blogAttachment property 存儲了一個二進制圖片文件。
    repositorymodel3.gif
    根據內容倉庫實現的功能,JSR-170定義了三種級別:
    Level 1:定義了一個只讀的內容倉庫。功能包括讀取內容,將內容導出為XML和查找內容。
    Level 2:定義了可寫的內容倉庫。Level 2是Level 1的擴展,新增的功能包括往內容倉庫里寫入內容,和從XML導入數據到倉庫。
    Advanced options:定義實現五種附加功能,版本控制、JTA、SQL查詢、清晰的內容鎖定和監視。

    什么是Apache JackRabbit?
    Apache JackRabbit是一個開放源碼的JSR-170 實現,實現了Level 2,但它還有許多擴展的功能。詳細可以去它的官方網站。

    下面我們決定用Apache JackRabbit來作為我們示例程序的內容倉庫。

    如何配置Apache JackRabbit
    JackRabbit需要兩個參數來配置一個內容倉庫實例。
    1.內容倉庫主目錄:這個文件目錄下通常包含了所有的內容,搜索索引,內部配置文件和其他持久化信息。它的結構看起來會像下面這個樣子:
    ???c:/temp
    ????????
    |
    ????????
    |--Blogging
    ????????????????
    |
    ????????????????
    |-repository
    ????????????????
    |???????|
    ????????????????
    |???????|-index
    ????????????????
    |???????|-meta
    ????????????????
    |???????|-namespaces
    ????????????????
    |???????|-nodetypes?????????????
    ????????????????
    |
    ????????????????
    |-version
    ????????????????
    |
    ????????????????
    |-workspace
    ????????????????????????
    |
    ????????????????????????
    |--default

    ? 在上面的情況下,內容倉庫主目錄是c:/temp/Blogging.
    2.內容倉庫配置文件:一個典型的配置文件如下:
    <Repository>
    ?
    <FileSystem?class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
    ??
    <param?name="path"?value="${rep.home}/repository"/>
    ?
    </FileSystem>
    ?
    <Security?appName="Jackrabbit">
    ??
    <AccessManager?class="org.apache.jackrabbit.core.security.SimpleAccessManager"/>
    ??
    <LoginModule?class="org.apache.jackrabbit.core.security.SimpleLoginModule">
    ????
    <param?name="anonymousId"?value="anonymous"/>
    ??
    </LoginModule>
    ?
    </Security>
    ?
    <Workspaces?rootPath="${rep.home}/workspaces"?defaultWorkspace="default"/>
    ?
    <Workspace?name="${wsp.name}">
    ??
    <FileSystem?class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
    ???
    <param?name="path"?value="${wsp.home}"/>
    ??
    </FileSystem>
    ??
    <PersistenceManager?
    ????????
    class="org.apache.jackrabbit.core.state.db.DerbyPersistenceManager">
    ???
    <param?name="url"?value="jdbc:derby:${wsp.home}/db;create=true"/>
    ???
    <param?name="schemaObjectPrefix"?value="${wsp.name}_"/>
    ??
    </PersistenceManager>
    ??
    <SearchIndex?class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
    ???
    <param?name="path"?value="${wsp.home}/index"/>
    ??
    </SearchIndex>
    ?
    </Workspace>
    ?
    <Versioning?rootPath="${rep.home}/version">
    ??
    <FileSystem?class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
    ???
    <param?name="path"?value="${rep.home}/version"?/>
    ??
    </FileSystem>
    ??
    <PersistenceManager?
    ????????
    class="org.apache.jackrabbit.core.state.db.DerbyPersistenceManager">
    ???
    <param?name="url"?value="jdbc:derby:${rep.home}/version/db;create=true"/>
    ???
    <param?name="schemaObjectPrefix"?value="version_"/>
    ??
    </PersistenceManager>
    ??
    </Versioning>
    ??
    <SearchIndex?class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
    ???
    <param?name="path"?value="${rep.home}/repository/index"/>
    ??
    </SearchIndex>
    </Repository>

    ?
    ? 在這個配置文件里,<Repository>元素是根元素,它包含了下面這些元素:
    ? a,<FileSystem>: 該元素配置了內容倉庫的全局數據存儲位置,這些全局數據包括已注冊的命名空間,定制的節點類型等等。??? ??? JackRabbit 提供了幾種選擇,一種是像上面例子里配置的存儲在本地文件里,LocalFileSystem. 如果你想把它們存儲在數據庫里,你可以使用 DbFileSystem.
    ? b,<Security>:內容倉庫的安全配置,它有兩個子元素:<AccessManager>和<LoginModule>。<AccessManager>配置的類用來判斷用戶有沒有權限來對特定數據執行特定的操作。
    ? c,<Workspaces>:這個元素的配置對所有的workspace都通用。它的rootPath 屬性是所有workspace文件夾的根目錄,在我們的例子里它是c:/temp/Blogging/Workspace;defaultWorkspace 屬性則包含了workspace的默認名。
    ? d,<Workspace>:這個元素是所有workspace的默認配置模板。去每個workspace文件夾下你都會發現一個workspace.xml文件,這個文件和這個元素的配置一模一樣。三個子元素:<FileSystem>,和這個workspace相關數據的存儲位置;<PersistenceManager> ,這個workspace內容節點存儲策略;<SearchIndex>,可選,全文檢索。
    ? e,<Versioning>:配置一個版本相關的對象。其實JackRabbit也是把它作為節點來處理的。

    這兩個參數可以通過兩種方式設置,一種是在倉庫實例創建時直接傳到Jackrabbit里去,一種是間接的通過設置JNDI object factory。
    你可以設置org.apache.jackrabbit.repository.home 這個系統屬性的值來指定你的內容倉庫主目錄;也可以設置
    org.apache.jackrabbit.repository.conf 這個系統屬性的值來指定你的內容倉庫配置文件repository.xml。如果你不設定這兩個
    參數,Jackrabbit會把當前目錄作為內容倉庫主目錄,同時,它有一個默認的內容倉庫配置文件。
    posted @ 2007-01-23 23:57 ronghao 閱讀(6817) | 評論 (25)編輯 收藏
    原文地址:http://www.onjava.com/pub/a/onjava/2006/10/04/what-is-java-content-repository.html?page=4
    JSR-170把自己定義為一個能與內容倉庫互相訪問的,獨立的,標準的方式。同時它也對內容倉庫做出了自己的定義,它認為內容倉庫是一個高級的信息管理系統,該系統是是傳統的數據倉庫的擴展,它提供了諸如版本控制、全文檢索,訪問控制,內容分類、訪問控制、內容事件監視等內容服務。

    Java Content Repository? API(JSR-170)試圖建立一套標準的API去訪問內容倉庫。如果你對內容管理系統(CMS)不熟悉的話,你一定會對內容倉庫是什么感到疑惑。你可以這樣去理解,把內容倉庫理解為一個用來存儲文本和二進制數據(圖片,word文檔,PDF等等)的數據存儲應用程序。一個顯著的特點是你不用關心你真正的數據到底存儲在什么地方,是關系數據庫?是文件系統?還是XML?不僅僅是數據的存儲和讀取,大多數的內容倉庫還提供了更加高級的功能,例如訪問控制,查找,版本控制,鎖定內容等等。

    一段時間以來市場上出現了各個廠家開發的不同的CMS系統,這些系統都建立在他們各自的內容倉庫之上。
    問題出現了,每個CMS開發商都提供了他們自己的API來訪問內容倉庫。這對應用程序的開發者帶來了困擾,因為他們要學習不同的開發商提供的API,同時,他們的代碼也與這些特定的API產生了綁定。

    JSR-170正是為解決這一問題而出現的,它提供了一套標準的API來訪問任何數據倉庫。通過JSR-170,你開發代碼只需要引用 javax.jcr.* 這些類和接口。它適用于任何兼容JSR-170規范的內容倉庫。

    我們將通過一個例子來逐步了解JSR-170。

    為什么需要 Java Content Repository API

    隨著各個廠家各自的內容倉庫實現數量的增長,人們越來越需要一組通用的編程接口來使用這些內容倉庫,這就是JSR-170所要做的東西。它提供一組通用的編程接口來連接內容倉庫。你可以把JSR-170理解為和JDBC類似的API,這樣你可以不依賴任何具體的內容倉庫實現來開發你的程序。你可以直接使用支持JSR-170的內容倉庫;或者如果一些廠家的內容倉庫不支持JSR-170則可以通過這些廠家提供的JSR-170驅動來完成從JSR-170與廠家特定的內容倉庫的轉換。

    下面這張圖描述了使用JSR-170開發的應用系統的結構。在該系統運行的時候,它可以操作內容倉庫1,2,3中的任意一個。在這些內容倉庫當中,只有2是直接支持JSR-170的,剩下的兩個都需要JSR-170驅動來和應用系統交互。注意:你的應用系統完全不用關心你的數據是如何存儲的。1可能使用了關系數據庫來存儲,而2使用了文件系統,至于上,它甚至更前衛的使用了XML。

    repositorymodel1.gif

    JSR-170 API對不同的人員提供了不同的好處。

    ●對于開發者無需了解廠家的倉庫特定的API,只要兼容JSR-170就可以通過JSR-170訪問其倉庫。
    ●對于使用CMS的公司則無需花費資金用于在不同種類CMS的內容倉庫之間進行轉換。
    ●對于CMS廠家,無需自己開發內容倉庫,而專注于開發CMS應用。
    posted @ 2007-01-23 15:13 ronghao 閱讀(5113) | 評論 (3)編輯 收藏
    2006年馬上就要過去,在06年的最后一天總結一下自己一年來的生活工作,自己覺得還是挺有意義的,盡管上學時最煩的就是各種各樣的總結了。
    工作技術上:
    1、可以比較熟練的使用webwork、spring和hibernate.這是和05年做的對比,05年做的東西完全是jsp+servlet+jdbc.盡管自己那時也用過,但那還限于demo。
    2、對一個不算復雜的WEB項目有比較清晰的開發思路/架構。三層、封裝、抽象、領域對象。
    3、有過一次和最終用戶打交道的經歷,有了一些經驗。
    4、負責開發了公司產品的權限系統。對ACL、RBAC都有了談不上深入的理解。最后的實現是基于?acegi的擴展。包括數據范圍權限、單條數據權限都實現了控制。只是對所謂的大集中模式下的權限沒有一個很好的解決方法,也是一個遺憾。
    5、初步的學習了ajax。05年自己對javascript還是很不屑的,也僅僅把它用于表單的驗證。今年買了本權威指南,也算是瀏覽過一遍。在開發中用到了prototype.js,dwr,觀念發生了很大的變化。寫了個outlookbar.js以及把xloadtree進行了很多的擴展。最后還模仿了google的日程表也做了個日程表,比較丑,css還得加強。
    6、基于jackrabbit實現了產品的CMS。對jsr170有了理解。一度想數據倉庫可否替代數據庫在一定應用中。
    7、有了一些工作流理論和實踐。
    生活中:
    1、世界觀發生了一點變化。什么是民主,什么是人權,什么叫自由,你真的經過你自己的思考了嗎?
    2、關注了一些以前沒有關注的聲音。知道了一句話叫用腳投票。
    3、關注了高房價、人民幣升值、股票、基金。了解了一些財政金融方面知識,對自己每月把工資存入?銀行產生了懷疑。
    4、給自己配了臺臺式機,然后又給老婆買了臺筆記本。
    展望:
    1、年底開始注意敏捷開發,明年能不能敏捷到我們團隊?
    2、很顯然,ajax剛剛會用的階段,上升到模式?我們的頁面能不能xhtml規范?
    3、OSGI應用到我們的產品中?
    4、具有架構的能力?
    5、明年我能買的起房嗎?
    呵呵,不管怎樣,希望明年會更好。
    posted @ 2006-12-31 16:22 ronghao 閱讀(944) | 評論 (1)編輯 收藏
    似乎到了年末,心情也跟著莫名的煩躁起來了。CMS基本算是開發完畢,現在主要是改改產品的BUG。BUG單總是那么長,讓人打不起精神。產品的發布已經幾次延期,看不到海的對岸。其實還有好多的問題要去解決。想著對acegi 的ACL進行進一步的擴展,CMS的頁面模板要實現可視化的編輯,對頁面的javascript進行重新整理,把頁面由table換成div...確實還有很多的工作。沒有覺得充實而是雜亂沒有條理。
    也許也和生活有關。
    浮躁的年末的一個傍晚,我坐在那里,看著外邊的天慢慢黑透...
    posted @ 2006-12-29 18:30 ronghao 閱讀(442) | 評論 (0)編輯 收藏
    僅列出標題
    共39頁: First 上一頁 26 27 28 29 30 31 32 33 34 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    關注工作流和企業業務流程改進。現就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

    常用鏈接

    留言簿(38)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲成av人片不卡无码| 亚洲欧洲中文日韩av乱码| 亚洲AV天天做在线观看| 国产久爱免费精品视频| 亚洲精品一级无码中文字幕| 麻豆va在线精品免费播放| 国产成人免费a在线资源| 男性gay黄免费网站| 亚洲人AV永久一区二区三区久久| 人妻无码中文字幕免费视频蜜桃| 亚洲女人被黑人巨大进入| japanese色国产在线看免费| 日韩亚洲一区二区三区| 久久久久免费看成人影片| 亚洲一区二区三区在线网站| 日产乱码一卡二卡三免费| 一级毛片无遮挡免费全部| 国产AV无码专区亚洲精品| 99精品视频在线观看免费播放| 亚洲欧洲国产经精品香蕉网| 久久精品女人天堂AV免费观看| 亚洲AV无码成人精品区日韩| 亚洲国产成人爱av在线播放| 免费看搞黄视频网站| 亚洲制服丝袜第一页| 免费成人午夜视频| 高清一区二区三区免费视频| 国产精品亚洲片在线va| 亚洲av片一区二区三区| 久久w5ww成w人免费| 亚洲人成电影网站免费| 亚洲色婷婷六月亚洲婷婷6月| 1000部羞羞禁止免费观看视频| 亚洲欧美成aⅴ人在线观看| 激情97综合亚洲色婷婷五| 18pao国产成视频永久免费| 理论秋霞在线看免费| 中文字幕亚洲精品资源网| 免费一区二区视频| 久久99国产综合精品免费| 免费国产a理论片|