什麼是JAVA內容倉庫(Java Content Repository)(4完) – JAVA編程語言程序開發技術文章

獲得列表
在上一步中我們已經把數據保存到瞭內容倉庫中,那我們如何確定數據確實保存進去瞭呢?getBlogList() 這個方法將返回根節點下所有名為blogEntry.的子節點。
public ArrayList getBlogList() throws BlogApplicationException {
    Session session = JackrabbitPlugin.getSession();
    ArrayList blogEntryList = new ArrayList();
    Node rootNode = session.getRootNode();
    NodeIterator blogEntryNodeIterator = rootNode.getNodes();


    while (blogEntryNodeIterator.hasNext()) {
        Node blogEntry = blogEntryNodeIterator.nextNode();
        if (blogEntry.getName().equals(“blogEntry”) == false)
            continue;
        String title = blogEntry.getProperty(“title”).getString();
        String blogContent = blogEntry.getProperty(“blogContent”).getString();
        Value creationTimeValue = (Value) blogEntry.getProperty(
                “creationTime”).getValue();
        String userName = blogEntry.getProperty(“userName”).getString();
        BlogEntryDTO blogEntryDTO = new BlogEntryDTO(userName, title,
                blogContent, creationTimeValue.getDate());
        blogEntryList.add(blogEntryDTO);
    }
    return blogEntryList;
}
一旦你獲得瞭根節點這個對象,你就可以通過調用getNodes()這個方法來獲取它所有的子節點。如果這個節點沒有子節點,將返回一個空的NodeIterator 對象。我們可以遍歷這個NodeIterator 對象來獲得名為blogEntry 的節點集合,然後通過getProperty()方法來獲得節點上的屬性,即我們保存的真實數據。getProperty()方法返回Value對象的一個實例。因為存儲數據類型的不同,所以返回的Value對象實例是不同的。根據不同的數據類型,你應該調用特定的方法來獲取數據,比如getString()來獲取字符串,而getDate()獲得一個日期。


查找內容(用XPath的方式)
JSR-170定義瞭兩種方式來查找內容(也可以理解為查找節點)。一種使用XPath語法,另一種使用SQL語法。JSR-170要求Level 1必須實現XPath的方式,而SQL的方式則作為一個可選的功能。


XPath原本是一種設計用來查找XML元素的語言。因為我們的workspace是樹狀的結構,很像XML。所以XPath語法非常適合於在這裡查找內容。下面的代碼演示瞭通過作者名來查找節點。
Session session = JackrabbitPlugin.getSession();
    Workspace workSpace = session.getWorkspace();
    QueryManager queryManager = workSpace.getQueryManager();


    StringBuffer queryStr = new StringBuffer(
            “//blogEntry[@”+PROP_BLOGAUTHOR +”= “);
    queryStr.append(userName);
    queryStr.append(“]”);
    Query query = queryManager.createQuery(queryStr.toString(),
            Query.XPATH);


    QueryResult queryResult = query.execute();


    NodeIterator queryResultNodeIterator = queryResult.getNodes();
    while (queryResultNodeIterator.hasNext()) {


        Node blogEntry = queryResultNodeIterator.nextNode();
        String title = blogEntry.getProperty(PROP_TITLE).getString();
        String blogContent = blogEntry.getProperty(PROP_BLOGCONTENT).getString();
        Value creationTimeValue = (Value) blogEntry.getProperty(
                PROP_CREATIONTIME).getValue();
        BlogEntryDTO blogEntryDTO = new BlogEntryDTO(userName, title,
                blogContent, creationTimeValue.getDate());
        blogEntryList.add(blogEntryDTO);
    }
首先獲得session 對象,通過它獲得它連接的workspace,然後就可以通過workspace獲得這個workspace的QueryManager 。QueryManager 接口定義瞭很多用來查詢的方法。接下來我們要做的是創建一條查詢語句。我們這裡這樣寫”//blogEntry[@blogAuthor=<bloggerName>”。這句話的意思是查找所有名為blogEntry ,含有blogAuthor 屬性且屬性值為<bloggerName>的節點。具體可以看JSR-170規范。


通過queryManagers createQuery()方法創建一個查詢對象,這個方法需要兩個參數,一個是我們的查詢語句,另一個是查詢的方式,這裡使用XPath。獲得這個Query 查詢對象後,調用它的execute() 方法開始執行查詢,返回一個QueryResult 對象。註意,查詢的結果受到當前session的限制,換句話說,就是如果這個session沒有權限查看一個特定的節點,哪怕這個節點滿足我們查詢的條件,在我們的查詢結果裡也是看不到這個節點的。所有的查詢數據來自於該workspace已經持久化的數據,哪些已經改變但還沒有通過session.save()(item.save())持久化到workspace的數據不在查詢之列。獲得QueryResult 對象後,我們就可以通過調用getNodes()方法來獲得符合查詢條件的節點的一個遍歷。


剩下的兩個未實現的方法是updateBlogEntry() 和 removeBlogEntry(),它們實現起來都很簡單。我們把BOLG 標題作為主鍵,通過標題來獲得相關的節點。在updateBlogEntry()方法裡,我們直接設定需要改變的屬性;在 removeBlogEntry()方法裡,我們獲得目標節點後直接在節點上調用remove()方法。最後別忘瞭一定要調用session.save()方法把我們改變的數據持久化。


處理二進制內容
對內容倉庫來說,處理二進制內容是個很基本的要求,比如說圖片。現在我們的示例程序容許給每個BLOG附加一張圖片。下面分別是附加圖片和獲取圖片的方法。
public void attachFileToBlogEntry(String blogTitle,
  InputStream uploadInputStream) throws BlogApplicationException {
    Session session = JackrabbitPlugin.getSession();
    Node blogEntryNode = getBlogEntryNode(blogTitle, session);
    blogEntryNode.setProperty(PROP_ATTACHMENT, uploadInputStream);
    session.save();


}
public InputStream getAttachedFile(String blogTitle) throws BlogApplicationException {
    InputStream attachFileIS = null;
    Node blogEntryNode = getBlogEntryNode(blogTitle);
    Value attachFileValue = (Value) blogEntryNode.getProperty(PROP_ATTACHMENT).getValue();
    attachFileIS = attachFileValue.getStream();
  return attachFileIS;
}
正如你看到的那樣,我們的代碼在處理二進制內容和一般內容間並沒有什麼太大的區別。僅僅一點不同的是你要通過InputStream 對象來保存和獲取二進制數據。在我們的配置文件裡關於persistent manager會有一個externalBLOBs 屬性。把這個屬性設為true, 圖片將會保存在文件裡,相反則會保存在數據庫的blob字段裡。


總結
到這裡,我們對 JSR-170, Jackrabbit以及如何使用 JSR-170 API開發一個簡單的應用程序都有瞭大概的瞭解。我們的討論更多的在於基礎。相信大傢一定會對內容倉庫有個初步的認識

發佈留言