什么是JAVA內(nèi)容倉(cāng)庫(kù)(Java Content Repository)(3)
開(kāi)發(fā)我們的例子程序
jackrabbit已經(jīng)配置好了,現(xiàn)在讓我們來(lái)創(chuàng)建我們的示例程序。這個(gè)例子程序?qū)⒄{(diào)用JCR-170 API。很顯然,我們需要做兩件事情:一個(gè)是作為后臺(tái)的對(duì)數(shù)據(jù)進(jìn)行增刪改查(持久層),另一個(gè)是開(kāi)發(fā)相對(duì)應(yīng)的UI界面(WEB 層)。首先,讓我們定義一個(gè)DAO接口。這個(gè)接口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;
}
????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;
}
正如你看到的,這個(gè)接口提供了增刪改查的方法,同時(shí)還提供了兩個(gè)方法來(lái)處理附件。接下來(lái),我們需要一個(gè)DTO對(duì)象用來(lái)在兩個(gè)層之間傳遞數(shù)據(jù)。
public?class?BlogEntryDTO?{
????private?String?userName;
????private?String?title;
????private?String?blogContent;
????private?Calendar?creationTime;
????//Getter?and?setter?methods?for?each?of?these?properties????????
}
????private?String?userName;
????private?String?title;
????private?String?blogContent;
????private?Calendar?creationTime;
????//Getter?and?setter?methods?for?each?of?these?properties????????
}
這里我們將僅僅討論持久層。
連接jackrabbit
現(xiàn)在,第一件事情是開(kāi)發(fā)一個(gè)組件,獲得一個(gè)到j(luò)ackrabbit內(nèi)容倉(cāng)庫(kù)的連接。為了簡(jiǎn)單,我們將在程序啟動(dòng)的時(shí)候獲得這個(gè)連接,然后在程序停止的時(shí)候釋放這個(gè)連接。這里我們使用了Struts ,所以我們需要開(kāi)發(fā)一個(gè)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;
????}
}
????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()方法將會(huì)在程序啟動(dòng)的時(shí)候調(diào)用,destroy()將會(huì)在程序停止的時(shí)候調(diào)用。我們?cè)趇nit()方法里獲得了到j(luò)ackrabbit內(nèi)容倉(cāng)庫(kù)的連接。看看代碼,我們做的第一件事是設(shè)定了org.apache.jackrabbit.repository.home這個(gè)系統(tǒng)屬性,在上篇文章里提到,這個(gè)屬性是用來(lái)指向我們的內(nèi)容倉(cāng)庫(kù)主目錄。這里我們?cè)O(shè)定它為c:/temp/blogging。接下來(lái),我們創(chuàng)建了TransientRepository的一個(gè)實(shí)例。這是jackrabbit提供的類,它提供了一個(gè)到內(nèi)容倉(cāng)庫(kù)的代理。它在第一個(gè)session 打開(kāi)的時(shí)候自動(dòng)啟動(dòng)內(nèi)容倉(cāng)庫(kù),在最后一個(gè)session 關(guān)閉的時(shí)候自動(dòng)關(guān)閉內(nèi)容倉(cāng)庫(kù)。
一旦我們獲得了一個(gè)內(nèi)容倉(cāng)庫(kù)對(duì)象,我們就可以調(diào)用它的login() 方法來(lái)打開(kāi)一個(gè)連接。login() 方法需要一個(gè)Credential 對(duì)象作為參數(shù)。如果Credential 對(duì)象是NULL,jackrabbit會(huì)認(rèn)為其他的機(jī)制做了這個(gè)驗(yàn)證(比如JAAS)。login() 方法還可以傳入一個(gè)workspace名字作為參數(shù),如果不傳入這個(gè)參數(shù),jackrabbit會(huì)返回一個(gè)session對(duì)象指向默認(rèn)的workspace。注意workspace和session是一對(duì)一的,即一個(gè)session僅對(duì)應(yīng)一個(gè)workspace。(注:如果不傳入Credential對(duì)象,返回的session對(duì)workspace是只讀的)
增加內(nèi)容
連接已經(jīng)建立起來(lái)了,下面讓我們實(shí)現(xiàn)BlogEntryDAO這個(gè)接口。第一個(gè)我們想實(shí)現(xiàn)的方法是插入數(shù)據(jù) 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();
}
????????????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 對(duì)象,即到內(nèi)容倉(cāng)庫(kù)特定workspace的連接。然后,我們?cè)谶@個(gè)session 對(duì)象上調(diào)用getRootNode() 方法,獲得這個(gè)workspace的根節(jié)點(diǎn),這個(gè)根節(jié)點(diǎn)的路徑是("/").一旦我們獲得這個(gè)根節(jié)點(diǎn),我們就可以通過(guò)addNode()方法在這個(gè)根節(jié)點(diǎn)下增加新的子節(jié)點(diǎn)。新節(jié)點(diǎn)的名字是blogEntry. 通過(guò)setProperty() 方法我們把數(shù)據(jù)存儲(chǔ)到節(jié)點(diǎn)的property里。正如我們先前說(shuō)明的,真實(shí)的數(shù)據(jù)是存儲(chǔ)在property元素里,property元素是葉子。
注意session.save() 這行代碼。這個(gè)方法是必須調(diào)用的,這個(gè)方法調(diào)用之前,任何 Node,Property的改變都被保存在這個(gè)session的一個(gè)臨時(shí)區(qū)域里,其他的和該session連接到相同workspace的session都看不到這些改變。當(dāng)這個(gè)方法被調(diào)用并被成功執(zhí)行后,這些Node,Property的改變才會(huì)被持久化到這個(gè)session關(guān)聯(lián)的workspace里,同時(shí)所有與這個(gè)workspace關(guān)聯(lián)的session才可見(jiàn)這些變化。相對(duì)應(yīng)的,Session.refresh(false)將會(huì)丟棄所有這些改變。item.save()和Item.refresh(false)作用相似,只是影響范圍限定在單個(gè)Item上(注意,包括它的子節(jié)點(diǎn))
posted on 2007-03-19 01:04 Ecko 閱讀(306) 評(píng)論(0) 編輯 收藏