明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

OpenCms文件導入過程初探

[摘要]在OpenCms的安裝過程中有一個文件導入的過程。由于工作原因,本人對這個導入過程做了點研究。有點收獲寫出來和大家共享。在系統(tǒng)中安裝過程是通過run_import.jsp文件(該文件位于sourcpath1\opencms_src_5.0.1\opencms\web\ocsetup)觸發(fā)的。在該頁...
在OpenCms的安裝過程中有一個文件導入的過程。由于工作原因,本人對這個導入過程做了點研究。有點收獲寫出來和大家共享。

在系統(tǒng)中安裝過程是通過run_import.jsp文件(該文件位于sourcpath1\opencms_src_5.0.1\opencms\web\ocsetup)觸發(fā)的。在該頁中她使用了

<frameset rows="100%,*">

    <frame src="display_import.jsp" name="display">

    <frame src="about:blank" name="data">

</frameset>

這樣的結構來完成導入和顯示的功能?吹絥ame為display很容易猜想他是用來向用戶顯示處理結果的,name 為data 的frame肯定是用來處理文件導入的了。這只是猜想,具體如何還有待證實。下面我們就去看看display_import.jsp這個文件。

在display_import.jsp服務端基本沒有什么處理,客戶端的處理倒是不少。這一句<body <% if(setupOk){ out.print("onload='enable();'");} %>>倒是很重要。我們先來看看enable()這個函數。

/* indicates if the document has been loaded */

function enable()   {

            enabled = true;

            parent.data.location.href="data_import.jsp";

            document.forms[0].info.value = message;

  }

在這個函數中有parent.data.location.href="data_import.jsp";這一句。他把name 為data 的frame的location.href設為"data_import.jsp"。從文件名來看應該是由該文件處理文件的導入工作。到底是不是,我們進去看看。

在data_import.jsp頁面中除了有個com.opencms.boot.CmsSetup的session范圍的JavaBean外還有一個com.opencms.boot.CmsSetupThread的session范圍的JavaBean。那么這個CmsSetupThread到底是什么玩意。去看源碼吧!



package com.opencms.boot;



import java.io.File;

import java.io.IOException;

import java.io.PipedOutputStream;

import java.io.PrintStream;



// CmsSetupThread是一個線程。

public class CmsSetupThread extends Thread {



       public void run() {



        /* save the original out and err stream */

        m_tempOut = System.out;

        m_tempErr = System.err;



        /* redirect the streams */

        System.setOut(new PrintStream(m_pipedOut));

        System.setErr(new PrintStream(m_pipedOut));



        /* start the logging thread */

        m_lt.start();



        /* start importing the workplace */

        CmsMain.startSetup(basePath + "WEB-INF/ocsetup/cmssetup.txt", basePath + "WEB-INF/");



        /* stop the logging thread */

        try {

            sleep(1000);

            m_lt.stopThread();

            m_pipedOut.close();

        }

        catch (InterruptedException e)  {

            m_lt.stopThread();

            e.printStackTrace(m_tempErr);

        }

        catch (IOException e)  {

            m_lt.stopThread();

            e.printStackTrace(m_tempErr);

        }



        /* restore to the old streams */

        System.setOut(m_tempOut);

        System.setErr(m_tempErr);



    }

… …… ……

}

從上面的代碼中的public void run() 方法中可以看出系統(tǒng)的確用該類來處理文件導入的工作。主要分為一下幾個步驟來完成。這里就驗證了我們前面name為display的frame向用戶顯示處理結果的,name 為data 的frame來處理文件導入的猜想。。

1、 備份系統(tǒng)的標準輸出和系統(tǒng)的錯誤輸出

m_tempOut = System.out;

m_tempErr = System.err;

2、 將系統(tǒng)輸出重新定向到一個PipedOutputStream實例(instance)

System.setOut(new PrintStream(m_pipedOut));

System.setErr(new PrintStream(m_pipedOut));

這樣一來說有的系統(tǒng)輸出都會定向到m_pipedOut到這個對象上來了。要顯示處理信息只需要處理是用System.out.println()之類方法打印出來。在前面讀取m_pipedOut就可以了。是不是這樣實現還有待證實。

3、 啟動 CmsSetupLoggingThread  線程;

4、 開始導入工作。有代碼為證

/* start importing the workplace */

CmsMain.startSetup(basePath + "WEB-INF/ocsetup/cmssetup.txt", basePath + "WEB-INF/");

5、 停止CmsSetupLoggingThread 線程。

6、 還原系統(tǒng)的標準輸出和系統(tǒng)的錯誤輸出。

下面就是還不清楚CmsSetupLoggingThread到底是什么玩意。通過查看源碼可以發(fā)現他就是用來收集CmsSetupThread線程的處理信息的。并且就是通過PipedOutputStream來完成這兩個線程的通信。這一點可以從他的構造函數知道。

    public CmsSetupLoggingThread(PipedOutputStream pipedOut)  {

        messages = new Vector();

        m_stopThread = false;

        try {

            m_pipedIn = new PipedInputStream();

            m_pipedIn.connect(pipedOut);

            m_LineReader = new LineNumberReader(new BufferedReader(new InputStreamReader(m_pipedIn)));

        }

        catch (Exception e) {

            messages.addElement(e.toString());

        }

    }



為了方便jsp頁面方便的得到這些信息CmsSetupLoggingThread還特地提供了一個private static Vector messages;和靜態(tài)的getMessages()方法來處理他。這一點在data_import.jsp中的

messages = com.netmarch.infopub.pubServletCon.LogginThread.getMessages();語句可以得到驗證。最后messages通過

<script language="Javascript">

              var output = new Array();

              <%         for(int i = 0; i < (size-offset) ;i++)    {

                                   out.println("output[" + i + "] = \"" + messages.elementAt(i+offset).toString() + "\";");

                            }                   

                     

              %>

              function send()     {

                     parent.display.start(output);

              }

              

       </script>傳到客戶端。完成了處理信息的顯示。

我寫的是我的知道的,我還很菜。歡迎高手指出我的錯誤。我的E-mail是jetgeng@hotmail.com 謝謝。



注 1、cms的源碼在http://www.opencms.org/opencms/en/download/opencms.html處下載。Sourcpath是你下載OpenCms 5.0.1 Source Distribution解壓后的目錄。