糊言亂語

          志未半斤, 才無八兩. 有苦有樂, 糊涂過活。
          posts - 25, comments - 7, trackbacks - 0, articles - 42
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          2007年8月6日

          image

          posted @ 2008-07-11 11:25 Stanley Sun 閱讀(336) | 評論 (0)編輯 收藏

          眾所周知在計算機中所有的數據都是以二進制的方式存儲的。不管是int,String,float等等不同的數據類型,最終都會保存為01的形式。那么為什么要使用這種方式儲存數據呢?

          因為計算機是一種電子設備,由復雜的電子元器件組合而成,一個電子元器件有帶電和不帶電兩種狀態,通常我們將帶電狀態表示為數值1,不帶電狀態表示為數值0,多個這樣的元器件的組合可以表示更多狀態,也就是可以表示更多的數據,如000表示0,001表示1,010表示2,011表示3,依此類推,111表示 7,一個元器件可表示一位(bit)數據,這種表示數據的方式就叫二進制。
          在實際的電子設備中,我們將8個這樣的元器件形成一個單元,這樣的單元叫一個字節(byte),一個字節能表示多少個數呢?表示數值的范圍是0-255。
          一個字節由8個二進位組成,其中最右邊的一位稱為“最低有效位”或“最低位”,最左邊的一位稱為“最高有效位”或“最高位”。每一個二進位的值是0或1。

          二進制計數的缺點:書寫太長,容易出錯,一般計算機的數據位數都是4的整數倍,所以,在計算機里通常采用16進制計數法。用數字可以表示各種信息,計算機里只有數值,當你在內存中看到一個數值時,這個數值可能代表各種意義,生活中的數值也可以代表其他意義,如1234可以代表密碼,存款額,電報信息,根據上下線索,我們就能夠知道這數值代表的意義

           

          但是在Java中到底是如何去保存數據的呢?下面我就以int數據類型為例說明Java的方式。

          大家都知道在Java中規定1 int = 4 byte, 1 byte = 8 bit。以此推理那么1個int在計算機中就是以4 * 8 = 32位(bit)的方式存儲的。而又由于java中的int是屬于有符號類型(Java中不存在unsigned類型),所以32位的高一位是符號位,由此可以推理出int的儲存大小區間

          Integer.MAX_VALUE = 2147483647(十進制) = 1111111 11111111 11111111 11111111(二進制)
          Integer.MIN_VALUE = -2147483648(十進制) = 10000000 00000000 00000000 00000000(二進制)

          現在我們知道了二進制的概念了,但是其實二進制我想我們想象的那么單純的表示的,他們是不同的表現方式如:原碼,反碼,補碼

        1. 原碼
          將最高位作為符號位(以0代表正,1代表負),其余各位代表數值本身的絕對值(以二進制表示)。
                      為了簡單起見,我們用1個字節來表示一個整數。
                      +7的原碼為: 00000111
                       -7的原碼為: 10000111
        2. 反碼
                一個數如果為正,則它的反碼與原碼相同;一個數如果為負,則符號位為1,其余各位是對原碼取反。
                      為了簡單起見,我們用1個字節來表示一個整數。
                      +7的反碼為: 00000111
                       -7的反碼為: 11111000
        3. 補碼
              利用溢出,我們可以將減法變成加法。
              對于十進制數,如果從9得到結果5,可以用減法:
                   9-4=5
                因為4+6=10,我們將6作為4的補數,將上式的減法改寫為加法:
                   9+6=15
                去掉高位1(也就是減去10),得到結果5。
                對于16進制數,如果從C得到結果5,可以用減法:
                   C-7=5
                因為7+9=16,我們將9作為7的補數,將上式的減法改寫為加法:
                   C+9=15
                去掉高位1(也就是減去16),得到結果5。
                在計算機中,如果我們用1個字節表示一個數,一個字節有8位,超過8位就進1,在內存中情況為:
                     1 00000000
              進位1被丟棄。
              一個數如果為正,則它的原碼、反碼、補碼相同;一個數如果為負,則符號位為1,其余各位是對原碼取反,然后整個數加1。
                      為了簡單起見,我們用1個字節來表示一個整數。
                      +7的補碼為: 00000111
                      -7的補碼為:第一步:11111000 (符號位為,其余各位取反)
                                            第二步:11111001 (整個數加1)
                     +0的補碼:00000000;
                     -0的補碼:11111111;(第一步)
                                    100000000;(第二步)
          已知一個負數的補碼,將其轉換為十進制數,步驟:
                1、先對各位取反;
                2、將其轉換為十進制數;
                3、加上負號,再減去1。
                例如:
                11111010,最高位為1,是負數,先對各位取反得00000101,轉換為十進制數得5,加上負號得-5,再減1得-6。
        4.  

          那么我們就知道了1與-1的二進制形式分別為0000000 00000000 00000000 00000001和11111111 11111111 11111111 11111111(Java中的數據是以補碼的形式儲存的)了。那么現在我們知道了數據是如何儲存的了。那么計算機是如何利用這些數據進行計算的呢?我們知道在計算機的CPU中只有一個加法器,所有的運算都是需要它進行的。所以在計算機里所有的加減乘除都是轉換成加法來進行運算的。那么它們是怎么轉換的呢?下面我們介紹一下二進制的運算操作

        5. 位運算符
          為了方便對二進制位進行操作,Java給我們提供了四個二進制位操作符:
          &          按位與
          |           按位或
          ^          按位異或
          ~          按位取反
        6. 按位
              一個房間里有兩個開關控制房間的燈的明暗。當兩個開關同時處于打開狀態時,燈才能亮。
               開關1                   開關2                         燈的狀態
                 關                         關                              暗
                開                          關                              暗
                關                          開                              暗
                開                          開                              亮
          結論:按位與,只有壹(1)壹(1)為1。
        7. 按位
              一個房間里有兩個開關控制房間的燈的明暗。當任何一個開關處于打開狀態時,燈就能亮。
              開關1                     開關2                     燈的狀態
                 關                         關                              暗
                開                          關                              亮
                關                          開                              亮
                開                          開                              亮
          結論:按位或,只有零(0)零(0)為0。
        8. 按位異或
              一個房間里有兩個開關控制房間的燈的明暗。當兩個開關處于不同狀態時,燈就能亮。
             開關1                    開關2                       燈的狀態
                關                          關                              暗
                開                          關                              亮
                關                          開                              亮
                開                          開                              暗
          結論:按位異或,只有零(0)壹(1)或壹(1)零(0)為1。
        9. 按位取反
          結論:對二進制數按位取反,即0變成1,1變成0。
        10. Java中有三個移位運算符
          左移:<<              (相當于 乘以2)
          帶符號右移:>>     (相當于 除以2)
          無符號右移:>>>
            數            x                   x<<2                 x>>2              x>>>2
          17      00010001    00 01000100      00000100 01     00000100 01
          -17     11101111     11 10111100      11111011 11     00111011 11
        11. posted @ 2008-06-14 15:25 Stanley Sun 閱讀(1073) | 評論 (0)編輯 收藏

          概念:

          1.數字摘要:解決在安全的通信環境下,保證信息的唯一的一種方式。通常使用MD5/SHA-1等算法完成摘要。一般比如大家在網上下載軟件光盤時都會看到一個MD5值就是起到這個數字摘要的作用。在網絡的環境中發送者把消息和數字摘要一同發送給接收者,接收者使用發送者相同的算法對消息加密,看是否與發送者發送過來的數字摘要相同,如果相同就證明消息沒有給篡改過。下面是一個最為簡單的示例:

          import java.security.*;
          public class myDigest {
            public static void main(String[] args)  {
              myDigest my=new myDigest();
              my.testDigest();
            }
            public void testDigest()
            {
             try {
               String myinfo="我的測試信息";
              //java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5");
                java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");
                alga.update(myinfo.getBytes());
                byte[] digesta=alga.digest();
                System.out.println("本信息摘要是:"+byte2hex(digesta));
                //通過某中方式傳給其他人你的信息(myinfo)和摘要(digesta) 對方可以判斷是否更改或傳輸正常
                java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1");
                algb.update(myinfo.getBytes());
                if (algb.isEqual(digesta,algb.digest())) {
                   System.out.println("信息檢查正常");
                 }
                 else
                  {
                    System.out.println("摘要不相同");
                   }
             }
             catch (java.security.NoSuchAlgorithmException ex) {
               System.out.println("非法摘要算法");
             }
            }
            public String byte2hex(byte[] b) //二行制轉字符串
              {
               String hs="";
               String stmp="";
               for (int n=0;n<b.length;n++)
                {
                 stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                 if (stmp.length()==1) hs=hs+"0"+stmp;
                 else hs=hs+stmp;
                 if (n<b.length-1)  hs=hs+":";
                }
               return hs.toUpperCase();
              }
          }
          

          2.電子簽名:對數據信息的發生者身份的認定,它是一種抽象的概念而不是一種具體技術。實現電子簽名的技術手段目前有多種,比如基于公鑰密碼技術的數字簽名;或用一個獨一無二的以生物特征統計學為基礎的識別標識,例如手印、聲音印記或視網膜掃描的識別;手書簽名和圖章的電子圖象的模式識別;表明身份的密碼代號(對稱算法);基于量子力學的計算機等等。


          3.數字簽名:所謂數字簽名就是利用通過某種密碼運算生成的一系列符號及代碼組成電子密碼進行"簽名",來代替書寫簽名或印章,對于這種電子式的簽名在技術上還可進行算法驗證,其驗證的準確度是在物理世界中與手工簽名和圖章的驗證是無法相比的。一般實現數字簽名的方法是通過生成的密鑰對的私鑰對用戶生成的數字消息進行DSA(Digital Signature Algorithm (DSA)是Schnorr和ElGamal簽名算法的變種,被美國NIST作為DSS(DigitalSignature Standard))加密實現的。實現代碼如下:

             */
           import java.security.*;
           import java.security.spec.*;
          public class testdsa {
            public static void main(String[] args) throws java.security.NoSuchAlgorithmException,java.lang.Exception {
                  testdsa my=new testdsa();
                  my.run();
            }
            public void run()
            {
            //數字簽名生成密鑰
            //第一步生成密鑰對,如果已經生成過,本過程就可以跳過,對用戶來講myprikey.dat要保存在本地
            //而mypubkey.dat給發布給其它用戶
             if ((new java.io.File("myprikey.dat")).exists()==false) {
                 if (generatekey()==false) {
                     System.out.println("生成密鑰對敗");
                     return;
                    };
                  }
          //第二步,此用戶
          //從文件中讀入私鑰,對一個字符串進行簽名后保存在一個文件(myinfo.dat)中
          //并且再把myinfo.dat發送出去
          //為了方便數字簽名也放進了myifno.dat文件中,當然也可分別發送
            try {
            java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));
            PrivateKey myprikey=(PrivateKey)in.readObject();
            in.close();
           // java.security.spec.X509EncodedKeySpec pubX509=new java.security.spec.X509EncodedKeySpec(bX509);
           //java.security.spec.X509EncodedKeySpec pubkeyEncode=java.security.spec.X509EncodedKeySpec
            String myinfo="這是我的信息";    //要簽名的信息
            //用私鑰對信息生成數字簽名
            java.security.Signature signet=java.security.Signature.getInstance("DSA");
            signet.initSign(myprikey);
            signet.update(myinfo.getBytes());
            byte[] signed=signet.sign();  //對信息的數字簽名
            System.out.println("signed(簽名內容)="+byte2hex(signed));
           //把信息和數字簽名保存在一個文件中
            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));
            out.writeObject(myinfo);
            out.writeObject(signed);
            out.close();
            System.out.println("簽名并生成文件成功");
            }
            catch (java.lang.Exception e) {
              e.printStackTrace();
              System.out.println("簽名并生成文件失敗");
            };
            //第三步
            //其他人通過公共方式得到此戶的公鑰和文件
            //其他人用此戶的公鑰,對文件進行檢查,如果成功說明是此用戶發布的信息.
            //
            try {
             java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
             PublicKey pubkey=(PublicKey)in.readObject();
             in.close();
             System.out.println(pubkey.getFormat());
             in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
             String info=(String)in.readObject();
             byte[] signed=(byte[])in.readObject();
             in.close();
            java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
            signetcheck.initVerify(pubkey);
            signetcheck.update(info.getBytes());
            if (signetcheck.verify(signed)) {
            System.out.println("info="+info);
             System.out.println("簽名正常");
            }
            else  System.out.println("非簽名正常");
            }
            catch (java.lang.Exception e) {e.printStackTrace();};
            }
            //生成一對文件myprikey.dat和mypubkey.dat---私鑰和公鑰,
            //公鑰要用戶發送(文件,網絡等方法)給其它用戶,私鑰保存在本地
            public boolean generatekey()
            {
              try {
            java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");
           // SecureRandom secrand=new SecureRandom();
           // secrand.setSeed("tttt".getBytes()); //初始化隨機產生器
           // keygen.initialize(576,secrand);     //初始化密鑰生成器
            keygen.initialize(512);
            KeyPair keys=keygen.genKeyPair();
          //  KeyPair keys=keygen.generateKeyPair(); //生成密鑰組
            PublicKey pubkey=keys.getPublic();
            PrivateKey prikey=keys.getPrivate();
            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));
            out.writeObject(prikey);
            out.close();
            System.out.println("寫入對象 prikeys ok");
            out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));
             out.writeObject(pubkey);
             out.close();
             System.out.println("寫入對象 pubkeys ok");
             System.out.println("生成密鑰對成功");
             return true;
            }
            catch (java.lang.Exception e) {
             e.printStackTrace();
             System.out.println("生成密鑰對失敗");
             return false;
             };
            }
            public String byte2hex(byte[] b)
              {
               String hs="";
               String stmp="";
               for (int n=0;n<b.length;n++)
                {
                 stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                 if (stmp.length()==1) hs=hs+"0"+stmp;
                 else hs=hs+stmp;
                 if (n<b.length-1)  hs=hs+":";
                }
               return hs.toUpperCase();
              }
          }    把他的公鑰的信息及簽名發給其它用戶
          


          4.PKI(公鑰基礎設施):

          posted @ 2007-12-05 22:09 Stanley Sun 閱讀(539) | 評論 (1)編輯 收藏

          安裝完成之后打開window->show views-Task Repositories,界面如下圖:


          在空白處右鍵點擊add task repository添加知識庫,如圖:

          選中Jira,下一步:


          server中填寫Jira的地址(http://ycfd.3322.org:88/jira),label隨便填寫,User ID和Password就是你在Jira上注冊的帳號和密碼了,填寫完畢之后點Validate Setting,驗證成功之后點完成即可。

          在添加完repository后,會彈出添加query界面。如圖:

          選擇create query using form后點擊next,進入query設置界面,如圖:


          在project中選中fms后點擊finish。這樣就完成了各項設置
          之后打開tasklist視圖:window->show view->other->mylyn->task list

          點擊OK,后打開task list視圖,如圖:


          在Task List中你可以看到你的項目中的問題和任務等,雙擊Task會顯示該Task的詳細情況:

          在Task List中還能新建Task并提交到Jira,這里就不多說了,大家自己嘗試一下。

          posted @ 2007-12-03 16:38 Stanley Sun 閱讀(1361) | 評論 (0)編輯 收藏

          mylyn是一款開源的基于eclipse開發平臺的任務管理組件,可以制定自己的本地任務及在遠程服務器(其中包括Bugzilla、Trac 和 JIRA等)中的遠程任務。對于我們現在的項目,使用mylyn就可以方便我們直接的瀏覽在JIRA中的任務,而不必經常的登錄JIRA平臺了。提高了大家的工作效率。

          由于mylyn與在我們現在在項目中使用的eclipse開發平臺中springide插件有沖突問題,所以首先大家需要把springide插件從eclipse中卸載。步驟如下:

          1.在eclipse安裝目錄下找到一個名為links的文件夾,在這個文件夾中刪除Springide.link文件。

          2.啟動eclipse,不過與平常不同的是需要在eclipse啟動命令中加入-clean參數。可以直接加入到eclipse快捷方式的目標項中。

          此時eclipse會把springide插件卸載,之后我們就可以安裝mylyn插件了。在開始安裝mylyn之前,大家需要下載附件中的如下三個文件:mylyn-2.1-e3.3.zip,mylyn-2.1-extras.zip,springide_updatesite_2.0.1_v200708152145.zip

          步驟如下:

          1.設置本地插件歸檔:進入help->software updates->find and install菜單后,選擇search for new features to install后點擊next

          進入install界面,如下圖:


          把下載的三個zip歸檔加入后,點擊finish.

          2.在彈出的updates窗口中選中剛才加入的三個歸檔,并把springide->integrations->spring ide ajdt integrations去掉后,如下圖:

          之后進入授權界面,選擇i accept后next,如圖:

          3.在彈出的verification窗口中點擊install all開始安裝,如圖:

          之后提示是否重啟eclipse,點擊是。

          posted @ 2007-12-03 16:38 Stanley Sun 閱讀(5519) | 評論 (0)編輯 收藏

          EJBCA是一個全功能的CA系統軟件,它基于J2EE技術,并提供了一個強大的、高性能并基于組件的CA。EJBCA兼具靈活性和平臺獨立性,能夠獨立使用,也能和任何J2EE應用程序集成。 

          所需軟件:

          1.jdk 1.5 下載地址:http://java.sun.com/

          2.jboss-4.2.0.GA 下載地址:http://www.jboss.com/

          3.jce_policy-1_5_0:下載地址:http://java.sun.com/

          4.apache-ant-1.7.0:http://ant.apache.org/

          5.oracle 10G:

          6.ojdbc14.jar:

          7.ejbca 3.4.5: 下載地址:http://ejbca.sourceforge.net

          安裝步驟:

          1.安裝jdk,jboss,ant,oracle,并把jce,jdbc解壓分別解壓到%JAVA_HOME%\jre\lib\security\與%JBOSS_HOME%\server\default\lib\。

          2.設置環境變量,我的配置為:

          ANT_HOME=C:\tool\ejbca\apache-ant-1.7.0-bin\apache-ant-1.7.0
          EJBCA_HOME=C:\tool\ejbca\ejbca_3_5_2\ejbca_3_5_2
          JBOSS_HOME=C:\tool\ejbca\jboss-4.2.0.GA\jboss-4.2.0.GA
          JAVA_HOME=C:\Program Files\Java\jdk1.6.0_03
          path=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\tool\ejbca\apache-ant-1.7.0-bin\apache-ant-1.7.0\bin;C:\tool\ejbca\jboss-
          4.2.0.GA\jboss-4.2.0.GA\bin;C:\Program Files\Java\jdk1.6.0_03\bin
          classpath=C:\Program Files\Java\jdk1.6.0_03\lib\tools.jar

          3.在數據庫中創建表空間并添加用戶EJBCA,在ORACLE中的代碼為:

            創建表空間:

            CREATE TABLESPACE EJBCA DATAFILE 'EJBCA.dbf' SIZE 100m ;

            創建用戶:

          CREATE user EJBCA   identified by "EJBCA"   default tablespace USERS   temporary tablespace TEMP   profile DEFAULT;
          -- Grant/Revoke role privileges
          grant aq_administrator_role to EJBCA with admin option;
          grant dba to EJBCA with admin option;
          -- Grant/Revoke system privileges
          grant unlimited tablespace to EJBCA with admin option;

          4.刪除所有的ejbca\adminweb中的jsp(%EJBCA_HOME%\src\adminweb*.jsp)中的

          <%@ page pageEncoding="ISO-8859-1"%>

            以解決中文亂碼問題,下一步也是解決此類問題。 

          5.把%EJBCA_HOME%\conf\ejbca.properties.sample改名為ejbca.properties,并在ejbca.properties添加如下一行:

          web.contentencoding=GBK

          6.把%EJBCA_HOME%\conf\database.properties.sample改名為database.properties,并更改相應的數據庫配置。如下是我的配置:

          datasource.jndi-name=EjbcaDS
          datasource.jndi-name-prefix=java:/
          database.name=oracle
          datasource.mapping=Oracle9i
          database.url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL
          database.driver=oracle.jdbc.driver.OracleDriver
          database.username=ejbca
          database.password=ejbca

            注:datasource.mapping需要選擇與oracle實際版本最接近的版本。 

          7.在%EJBCA_HOME%\bin中,通過cmd運行ant bootstrap。

          8.啟動jboss,在%JBOSS_HOME%\bin,通過cmd運行run。

          9.在%EJBCA_HOME%\bin中,通過cmd運行ant install。

          10.關閉jboss,并在在%EJBCA_HOME%\bin中,通過cmd運行ant deploy。

          11.再次啟動jboss,在%JBOSS_HOME%\bin,通過cmd運行run。

          13.導入在%EJBCA_HOME%\p12目錄中superadmin.p12,默認密碼為ejbca。

          注:在第7步時,如出現ANT失敗,可能是由于ejbca的版本問題,推薦使用ejbca3.4.5。

          訪問地址:http://localhost:8080/ejbca/

          posted @ 2007-12-03 16:33 Stanley Sun 閱讀(1610) | 評論 (0)編輯 收藏

          一般在有著1年半以上的程序員基本上都是知道這個厲害的東西的,它對字符串處理的能力可以說是生猛無比。雖然大家都在使用(有時候在開發的Code中,有時候是在我們自己心愛的Editor里),但是我相信大部分人對這里禽獸的了解程度只是停留在會用的層次上。下面我對它進行一下詳細的說明。

          正則表達式的“祖先”可以一直上溯至對人類神經系統如何工作的早期研究。Warren McCulloch 和 Walter Pitts 這兩位神經生理學家研究出一種數學方式來描述這些神經網絡。

          1956 年, 一位叫 Stephen Kleene 的美國數學家在 McCulloch 和 Pitts 早期工作的基礎上,發表了一篇標題為“神經網事件的表示法”的論文,引入了正則表達式的概念。正則表達式就是用來描述他稱為“正則集的代數”的表達式,因此采用“正則表達式”這個術語。

          隨后,發現可以將這一工作應用于使用Ken Thompson 的計算搜索算法的一些早期研究,Ken Thompson是Unix 的主要發明人。正則表達式的第一個實用應用程序就是 Unix 中的qed 編輯器。

          如他們所說,剩下的就是眾所周知的歷史了。從那時起直至現在正則表達式都是基于文本的編輯器和搜索工具中的一個重要部分。

          使用正則表達式
          在典型的搜索和替換操作中,必須提供要查找的確切文字。這種技術對于靜態文本中的簡單搜索和替換任務可能足夠了,但是由于它缺乏靈活性,因此在搜索動態文本時就有困難了,甚至是不可能的。

          使用正則表達式,就可以:

          測試字符串的某個模式。例如,可以對一個輸入字符串進行測試,看在該字符串是否存在一個電話號碼模式或一個信用卡號碼模式。這稱為數據有效性驗證。
          替換文本。可以在文檔中使用一個正則表達式來標識特定文字,然后可以全部將其刪除,或者替換為別的文字。
          根據模式匹配從字符串中提取一個子字符串。可以用來在文本或輸入字段中查找特定文字。
          例如,如果需要搜索整個 web 站點來刪除某些過時的材料并替換某些HTML 格式化標記,則可以使用正則表達式對每個文件進行測試,看在該文件中是否存在所要查找的材料或 HTML 格式化標記。用這個方法,就可以將受影響的文件范圍縮小到包含要刪除或更改的材料的那些文件。然后可以使用正則表達式來刪除過時的材料,最后,可以再次使用正則表達式來查找并替換那些需要替換的標記。

          許多種工具都支持正則表達式(文本編輯器、文字處理軟件、系統工具、數據庫引擎,等等),不過,要想充分挖掘正則表達式的能力,還是應當將它作為編程語言的一部分。例如Java、JScript、Visual Basic、VBScript、JavaScript、ECMAScript、C、C++、C#、elisp、Perl、Python、Tcl、Ruby、PHP、sed和awk。事實上,在一些用上述語言編寫的程序中,正則表達式扮演了極其重要的角色。
          正則表達式能夠得到眾多語言和工具的支持是有原因的:它們極其有用。從較低的層面上來說,正則表達式描述的是一串文本(a chunk of text)的特征。大家可以用它來驗證用戶輸入的數據,或者也可以用它來檢索大量的文本。從較高的層面上來說,正則表達式容許用戶掌控他們自己的數據——控制這些數據,讓它們為自己服務。掌握正則表達式,就是掌握自己的數據。

          可見它的重要性,難怪每款編輯器和編程語言不同程度的實現了它,使得普通用戶和開發人員受益不淺。

          posted @ 2007-11-07 23:02 Stanley Sun 閱讀(429) | 評論 (1)編輯 收藏

           

          treeview 

          在開發B/S程序時,我們經常會使用到一些頁面級的效果控件。比如:樹形目錄,ComboBox和一些其他的控件,由于這些控件的存在使得我們的程序異常的奪目。但是在開發這些控件的時候或多或少的都會比較麻煩。而大部分的程序員是使用發布的一些開源的JS控件來減輕工作量而且也使得自己的程序健壯。下面我介紹一個在開源社區中赫赫有名的樹形控件:TreeView。

          首先介紹一下TreeView,TreeView原名是FolderTree,是一款比較早就出世的樹形JS控件,當時是由個人開發的,之后由公司購買了。但是現在還可以免費使用。

          TreeView 有兩個JS文件和一些資源文件組成。兩個JS文件分別是:主要實現功能的ftiens4.js和實現多瀏覽器支持的ua.js文件。只有我們在開發的頁面中加入如上兩個文件的話就可以開發如上圖所顯示的樹形目錄了。代碼如下:

          <html>

          <head>

          <script type="text/javascript" src="../treeview/ftiens4.js" ></script>

          <script type="text/javascript" src="../treeview/ua.js" ></script>

          <script type="text/javascript">

          //TreeView 環境變量

          BUILDALL = 0 //創建所有的節點對象 0:延時創建 1:立即創建
          GLOBALTARGET = 'R' //節點觸發時的目標 'B':打開新窗口 'R':右邊的Frame 'S':當前Frame 'T':當前瀏覽器窗口
          HIGHLIGHT = 0 //高亮顯示當前選中的節點 0:不高亮顯示 1:高亮顯示
          HIGHLIGHT_BG = 'blue' //高亮顯示的背景顏色
          HIGHLIGHT_COLOR = 'white' //高亮顯示的顏色
          ICONPATH = '' //指定節點的顯示圖標,使用URL方式,而且必須用"/"結尾 如:http://www.x.com/y/
          PRESERVESTATE = 0 //保存TreeView的狀態到Cookie中,當再次顯示的時候會自動的回置狀態 0:不保存 1:保存
          STARTALLOPEN = 0 //默認打開所有節點 0:只打開根節點 1:打開所以節點
          USEFRAMES = 1 //頁面是否使用了Frame,注意:如果未使用Frame一定要設置此參數 0:未使用 1:使用了
          USEICONS = 1 //是否使用圖標 0:不顯示圖標 1:顯示圖標
          USETEXTLINKS = 0 //節點文字是否為鏈接 0:否 1:是
          WRAPTEXT = 0 //節點顯示超出一行時是否折行 0:不折行 1:折行

          foldersTree = gFld("test", "") //創建一個名為"test"的根節點
          foldersTree.treeID = "t1" //設置test節點的唯一編號為"t1"


          aux1 = insFld(foldersTree, gFld("Day of the week", "b.html")) //在根節點中加入一個名為"Day of the week"的子節點,當點擊的時候打開b.html
          aux1.addChildren([["1","1.html"],["2","2.html"],["3","3.html"],["4","4.html"],["5","5.html"]])  //在aux1節點中連續加入1,2,3,4,5節點,并相應的打開1.html,2.html,3.html,4.html,5.html.

          aux2 = insFld(foldersTree, gLnk("R","Day of the week2", "b.html")) //在根節點中加入名為"Day of the week2"的節點,當點擊的時候在右側的frame中打開b.html
          aux3 = insDoc(foldersTree, gLnk("R","<input type=\"checkbox\">Day of the week3", "c.html")) //在根節點中加入名為"Day of the week3"并帶有復選框的節點,當點擊的時候在右側的frame中打開c.html

          </script>

          </head>

          <body>

          <A style="font-size:7pt;text-decoration:none;color:silver" href=" target=_blank>Javascript Tree Menu</A>

          <script type="text/javascript">

                 initializeDocument();//構造TreeView

          </script>

          </body>

          </html>

          TreeView中主要的方法:

          gFld(Title, Link);//創建節點 例:gFld("Test A", "javascript:parent.op()")

          Argument

          Title
          Specifies the text that appears in the folder name. This text can include simple HTML tags, such as enclosing formatting tags (i, b, div, and so on). It can even include an img tag if you want to place a small icon in the node name, such as a "new!" icon for example.

          Link
          Specifies an optional URL. The URL can be a simple file name like demoFramesetRightFrame.html or a string with protocol, domain, path, and file name like
          http://www.treeview.net/treemenu/demopics/beenthere_europe.gif.

           

          gLnk(Target, Title, Link);//創建一個帶有鏈接的節點 例:gLnk("B", "My File", http://www.mysite.com/MyFile.doc)

          Argument

          Target
          Configures the target location for the link. Specify one of the following values:
          "R": Open the document in the right frame (a frame named basefrm)
          "B": Open the document in a new window
          "T": Open the document in the current browser window, replacing the frameset if one exists
          "S": Open the document in the current frame, replacing the tree
          Note: This argument is case sensitive; make sure to use uppercase letters.

          Title
          Specifies the text that appears in the link. This text can include simple HTML tags, such as enclosing formatting tags (i, b, div, and so on). It can even include an img tag if you want to place a small icon in the node name, such as a "new!" icon for example.

          Link
          Specifies the URL of the document. This can be an absolute URL or a relative URL. Do not enter any other information in this string; adding a target parameter or an event handler will not work.

           

          insFld(Parent Folder, Child Folder); //在父節點中插入一個子節點 例:aux1 = insFld(foldersTree, gFld("Europe", "http..."))

          Argument

          Parent Folder
          Specifies the parent folder. That is, this argument specifies the folder node in which you want to place the other folder node.

          Child Folder
          Specifies the child folder. That is, this argument specifies the folder node that you want to place under the parent folder node.

           

          insDoc(Parent Folder, Document Node); //在節點中加入一個Dom對象 例:insDoc(aux2, gLnk("S", "Boston", "..."))

          Argument

          Parent Folder
          Specifies the parent folder. That is, this argument specifies the folder node in which you want to place the document node.

          Document Node
          Specifies the document node. That is, this argument specifies the document node that you want to place in the parent folder node

           

          更多的參考信息到 http://www.treeview.net/tv/instructions.asp

          posted @ 2007-11-07 17:59 Stanley Sun 閱讀(7509) | 評論 (2)編輯 收藏

              在一年以前一個客戶給我推薦一款文件管理軟件,名叫Total Commander,以下簡稱totalcmd,據說在歐美國家相當的流行。當時給這個客戶開發程序是需要打開很多個資源管理器,在這么多的管理器中相互的拷貝文件真是一件非常頭疼的事情。借助totalcmd可以非常好的完成文件的管理,拷貝、刪除,新建,乃至服務的管理等等。值得一提的就是totalcmd可以通過注入插件實現totalcmd本身不可以完成的功能,這也是它很大的一個亮點。

          在使用的一年多的totalcmd后,也有了一些自己的使用習慣和獨愛的插件,我將羅列如下:
          使用習慣:
          1.把F2快捷鍵指定到cm_RenameOnly命令上。
          2.把Ctrl+G快捷鍵指定到cm_FocusCmdLine命令上。
          3.在開始菜單下建立一個功能,實現cm_SwitchHidSys功能,可以顯示隱藏/系統文件。
          4.指定totalcmd只能運行一個實例。
          5.最小化到系統托盤里。
          6.編輯時默認打開的編輯器為ChoiceEditor。這個插件很難找。
          7.把快速查找定義為Letters with search dialog
          8.當改變驅動盤符的時候直接定位的驅動的根目錄下

          獨愛插件:
          1.Choice Editor:默認編輯選擇器。
          2.File Redirector:臨時目錄,這個插件非常有用,強烈推薦。不過安裝的時候需要下載一個msvcr70.dll的文件放到你的c:\windows\system32目錄下。文件的下載地址:http://www.dll-files.com/dllindex/dll-files.shtml?msvcr70
          3.UnInstTC:集成在totalcmd中添加/刪除程序,支持搜索。
          4.Office:可以通過Ctrl+Q快速查看Office系列軟件格式。

          注:本人只是一個totalcmd的愛好者,而不是在此為他去大廣告。

          posted @ 2007-10-31 11:07 Stanley Sun 閱讀(670) | 評論 (0)編輯 收藏

           



                  AutoSuggest是通過AJAX技術實現的一種類似于ComboBox之類的輸入框,當輸入一些提示字符后,AS會自動的把輸入框中的Value通過AJAX發送到Server中,Server自定義的解析發送的數據,然后把返回數據通過XMLJSON方式返回到AS中。AS再根據Server返回的標準格式的數據構建出提示候選框,當用鼠標或鍵盤選中候選項后填充到輸入框中。在寫這篇手冊的時候,AutoSuggest的最新版本是autosuggest_v2.1.3。基本的運行原理如上。

          AutoSuggest的主要的物理文件有:bsn.AutoSuggest_2.1.3.jsautosuggest_inquisitor.css。其他的還有一些圖片資源文件,一個測試html與一個test.php的服務器段頁面。結構如下:
              

          │ .DS_Store

          │ ._.DS_Store

          │ ._bsn.AutoSuggest_2.
          1.3.html

          │ ._test.php

          │ bsn.AutoSuggest_2.
          1.3.html

          │ test.php



          ├─css

          │ │ .DS_Store

          │ │ ._.DS_Store

          │ │ autosuggest_inquisitor.css

          │ │

          │ └─img_inquisitor

          │      │ .DS_Store

          │      │ ._.DS_Store

          │      │ ._as_pointer.gif

          │      │ ._hl_corner_bl.gif

          │      │ ._hl_corner_br.gif

          │      │ ._hl_corner_tl.gif

          │      │ ._hl_corner_tr.gif

          │      │ ._ul_corner_bl.gif

          │      │ ._ul_corner_br.gif

          │      │ ._ul_corner_tl.gif

          │      │ ._ul_corner_tr.gif

          │      │ as_pointer.gif

          │      │ hl_corner_bl.gif

          │      │ hl_corner_br.gif

          │      │ hl_corner_tl.gif

          │      │ hl_corner_tr.gif

          │      │ ul_corner_bl.gif

          │      │ ul_corner_br.gif

          │      │ ul_corner_tl.gif

          │      │ ul_corner_tr.gif

          │      │

          │      └─_source

          │              .DS_Store

          │              ._.DS_Store

          │              ._as_pointer.png

          │              ._li_corner.png

          │              ._ul_corner.png

          │              as_pointer.png

          │              li_corner.png

          │              ul_corner.png



          └─js

                 .DS_Store

                 ._.DS_Store

                 ._bsn.AutoSuggest_2.
          1.3.js

                 bsn.AutoSuggest_2.
          1.3.js

                 bsn.AutoSuggest_2.
          1.3_comp.js


          AutoSuggest是一組JavaScript類庫,其中主要的對象就是bsn.AutoSggest對象,基本的功能都是在這個對象中完成的。首先我們構建一個簡單的示例:
              

          var options_xml = {

                                          script:
          function(input){return"suggestAction!userName.action?signer="+input; }//(1).帶有傳送數據的請求路徑,其中input是輸入框的value。

                                          varname:
          "input"//(2).儲存輸入框value的變量名

                                          delay:
          800//(3).發送請求的延時時間

                                          cache:
          false//(4).是否緩存

                                          noresults:
          "無符合的記錄!",//(5).當沒有符合的查詢結果時的提示信息

                                          timeout:
          10000,//(6).候選框停留時間

                                          callback: 
          function(record){ document.getElementById("temp").value = record.value; } //(7).選擇候選項后的回調函數

          }
          ;

          var as_xml = new bsn.AutoSuggest('signer', options_xml); //(8).創建autosuggest對象,并綁定一個輸入框




          通過這樣簡單的方式我們就可以完成在頁面中的autosuggest編碼了。其中的參數表可以看下表:

          Property

          Type

          Default

          Description

          script

          String / Function

          -

          REQUIRED!
          Either: A string containing the path to the script that returns the results in XML format. (eg, "myscript.php?")
          Or: A function that accepts on attribute, the autosuggest field input as a string, and returns the path to the result script.

          varname

          String

          "input"

          Name of variable passed to script holding current input.

          minchars

          Integer

          1

          Length of input required before AutoSuggest is triggered.

          className

          String

          "autosuggest"

          Value of the class name attribute added to the generated ul.

          delay

          Integer

          500

          Number of milliseconds before an AutoSuggest AJAX request is fired.

          timeout

          Integer

          2500

          Number of milliseconds before an AutoSuggest list closes itself.

          cache

          Boolean

          true

          Whether or not a results list should be cached during typing.

          offsety

          Integer

          -5

          Vertical pixel offset from the text field.

          shownoresults

          Boolean

          true

          Whether to display a message when no results are returned.

          noresults

          String

          No results!

          No results message.

          callback

          Function

          A function taking one argument: an object

          {id:"1", value:"Foobar", info:"Cheshire"}

          json

          Boolean

          false

          Whether or not a results are returned in JSON format. If not, script assumes results are in XML.

          maxentries

          Integer

          25

          The maximum number of entries being returned by the script. (Should correspond to the LIMIT clause in the SQL query.)

          之后我們只要在我的服務器中解析傳入的signer參數返回,如下格式的xml就可以了。當然也可以用JSON方式,不過我在這里就不在演示了。
              

          <results>

                                          
          <rs id="1" info="">Foobar</rs>

                                          
          <rs id="2" info="">Foobarfly</rs>

                                          
          <rs id="3" info="">Foobarnacle</rs>

          </results>


          AutoSuggest是比較方便的一種實現類Google Suggest的解決方式,提供的js文件也是比較精巧的,并提供的一個壓縮后的js腳本文件只有8.33 KB大小。如果要查看其代碼可以找到一個沒有壓縮的原始版本的源代碼,其中的代碼也是比較容易閱讀,更改起來也是比較簡單的。我會在以后寫一篇《AutoSuggest代碼解析》。

          更多信息可查閱 http://www.brandspankingnew.net/archive/2007/02/ajax_auto_suggest_v2.html

          posted @ 2007-10-19 18:17 Stanley Sun 閱讀(2535) | 評論 (2)編輯 收藏

          在一般的項目中,數據庫主鍵不會擁有業務邏輯。但是在一些數據庫設計不是很嚴格的項目中還是會把擁護業務邏輯的字段作為主鍵使用,而且可能回事復合主鍵。 現在在一個項目我就遇到這情況。這個項目的數據訪問框架使用的Hibernate框架,在對復合主鍵的映射是我遇到了一個Hibernate Bug。我使用的數據庫是Oracle 8i。Hibernate Mapping如下:

          <composite-id name="id" class="InfoViewDetaillistId">

                     <key-property

                        name="accountno"

                        column="ACCOUNTNO"

                        type="string"

                     />

                     <key-property

                        name="rlsdepid"

                        column="RLSDEPID"

                        type="string"

                     />

                     <key-property

                        name="sequenceno"

                        column="SEQUENCENO"

                        type="integer"

                     />

                     <key-property

                        name="ondate"

                        column="ONDATE"

                        type="date"

                     />

          </composite-id>

          在這個復合主鍵中包括了四個擁有業務邏輯的字段,分別是帳號,中心號,序號,日期。問題就在Hibernate對日期類型的映射上,如使用上面的配置方法的話Hibernate在啟動的時候就會報錯。具體的解決方法是把
          <key-property

          name="ondate"

          column="ONDATE"

          type="date"

          />

          替換成

          <key-property name="ondate" type="date">

          <column name="ONDATE" not-null="true" sql-type="java.sql.Types.DATE"/>

          </key-property>

          Bug具體的原因我會在一會的文章中解釋。

          posted @ 2007-10-09 12:57 Stanley Sun 閱讀(311) | 評論 (0)編輯 收藏

          十月放假期間早晨本應該在家里舒服的床上呼呼大睡,十月中旬一個項目就要上線,無奈老板讓所有的員工加班,自己卻跑到埃及去度假。十一期間的交通果然是出奇的好,馬路上零星點點的幾個人頭,公交車上一大片一大片的空位子。本應該用兩個多小時路程卻用了不到一個半小時就到了公司,到了公司連在這里住的的小伙還沒有起床。
          無聊的打開筆記本,聽聽音樂,上上網,出奇的悠哉。呵呵,在哪里是在加班啊。跑到tss網站上看看(本人的英語不是很好,天天強迫自己看看英文網站來提高英文水平),無意中發現TSS里有一個地方是專門通過卡通的形式來演繹程序員生活中遇到的趣事。如果你身邊有什么有趣的事情的話,還可以投稿給他們。

          posted @ 2007-10-04 09:27 Stanley Sun 閱讀(179) | 評論 (0)編輯 收藏

          記憶里Java5發布離現在已經有了兩三年了,雖然有不少的貼心的新特性。但是一直無法撼動J2SE 1.4在Java程序員心中的位置。在Java5發布的時候我也看過一些關于新特性的介紹,泛型、枚舉、注釋、foreach等。當時個人感覺其實除了foreach還算有點吸引眼球,其他的特性只是一種過度功能。對于泛型只是在Java編譯器中做的手腳,而在JVM中是不支持的,有點想一個文字游戲。對于枚舉,由于本人對這樣的功能接觸不多,所以就不妄加評價了。注釋出現的目的主要是消除XML災難,但是有無法達到XML不更改Class就可以改變配置。就是憑借的這些想法本人直到Java5發布后的兩三年一直就沒有碰過它,但是在最近的一個新項目中Java5新特性隨處可見,我與其他的Programmer交流了一下發現現在這些新特性同樣出現在他們的項目中。

          何解?難道大家已經不在乎使用的是一個空中樓閣式的特性,只要能夠圓滿的完成項目?可能Java5新特性有著我看不到的優點。

          posted @ 2007-09-26 22:16 Stanley Sun 閱讀(193) | 評論 (0)編輯 收藏

          對于有本一族的現代人來說,本本為我們的工作提供了很大的方便,但是一般家中還是會用一臺臺式電腦為我們服務(更加傾向于服務器的作用)。那么如何方便的鏈接筆記本和家中的臺式機一起上網呢。有的使用路由器的方式,這種方式固然高效但是對于家中沒有路由的朋友來說就比較郁悶了。這里我介紹一種通過普通網線來對連兩臺電腦上網的方法。


          設備:

          1.準備一根于普通網線差不多的雙機互連線,它不同的只是水晶頭接口的排序方法不同,其他的材料都是一樣的。

          2.需要有一臺雙網卡的臺式電腦,我家里的磐正的8RDA3+主板,集成的雙網卡。非常爽。

          方法:

          1. 把臺式電腦的IP更改為192.168.0.1,這樣當筆記本接入的時候,會默認的通過這個IP,去獲取筆記本的IP。

          2. 把臺式電腦的ADSL鏈接共享,連接的通道選擇雙機互連線接入的網卡。點擊ADSL連接-->高級-->Internet連接共享中設置。

          3. 可能需要重啟一下電腦。此時不用設置筆記本的IP地址,一般使用自動獲取就行了。如果自己想設置可以把IP設置成192.168.0.*,網關為192.168.0.1,Dns服務器為192.168.0.1.

          注意:如果筆記本于臺式電腦的IP不是一個網段的話,則無法共享上網。

          現在一切就設置好了,在臺式電腦上打開ADSL連接后,筆記本就可以一起上網了,是不是非常方便。。。

          posted @ 2007-09-25 20:48 Stanley Sun 閱讀(1174) | 評論 (0)編輯 收藏

          1 背景假設

          廈門央瞬公司是一家電子元器件設備供應商,其中有個ARM部門,專門負責ARM芯片的方案設計、銷售,并在北京、上海各設立了一個辦事處。對于工作日志,原先采用郵件方式發給經理,但是這種方式有個缺點,那就是不具備連續性,要看以前的日志必須一封一封郵件去查看,很麻煩。于是就想到利用 Subversion,讓員工在自己電腦上編輯日志,然后利用svn傳送回來,既方便員工自己編寫日志,又方便對日志的歸檔處理,而且提交日志的時候只需要執行一下 svn update 即可,比發送郵件還要簡單的多。

          • svn服務器相關信息

            • 服務器地址: 192.168.0.1
            • 服務器OS: MS Windows 2000 Server Edition 中文版
            • 代碼庫本地目錄: D:\svn\arm
          • arm部門文檔的目錄結構如下:

            arm                 部門名稱
            ├─diary           工作日志目錄
            │  ├─headquarters    總部工作日志目錄
            │  ├─beijing         北京辦日志目錄
            │  └─shanghai        上海辦日志目錄
            ├─ref             公司公共文件參考目錄
            └─temp            臨時文件目錄
            
          • 人員情況

            • morson,公司總經理,其實他不必親自看任何東西,就連部門經理們的每周總結都不一定看。但是為了表示對他的尊敬,以及滿足一下他的權力欲,還是給他開放了"閱讀所有文檔"的權限
            • michael,arm事業部的部門經理,沒事的時候喜歡弄點兒新技術,用svn來管理日志,就是他相處來的主意
            • scofield,北京辦人員,老員工,為人油滑難管
            • lincon,上海辦人員,老員工,大老實人一個
            • linda,總部協調員、秘書,文筆不錯,長得也不錯
            • rory,單片機技術員,技術支持
          • 訪問權限需求分析

            • 允許總經理讀取所有文件
            • 除部門經理外,所有其他人員,均只能看到本辦事處人員工作日志
            • 不允許匿名訪問
            • ref目錄只允許經理和秘書寫,對其他人只讀
            • temp目錄人人都可以寫

          2 建立代碼庫

          在服務器 D:\svn 目錄下,建立 arm 代碼庫,命令如下:

          D:\svn>svnadmin create arm
          

          在客戶機 F:\temp 目錄下,建立好上述目錄結構

          用命令 F:\temp>svnimportarmsvn://192.168.0.1/arm 導入結構

          【注意點:關于導入時候的細微差別】

          3 編輯代碼庫基礎配置文件

          編輯代碼庫 arm\conf\svnserve.conf 文件,如下:

          [general]
          password-db = passwd.conf
          anon-access = none
          auth-access = write
          authz-db = authz.conf
          

          4 管理用戶帳號

          新建代碼庫 arm\conf\passwd.conf 文件,如下:

          [users]
          morson = ShowMeTheMoney
          michael = mysecretpassword
          scofield = hellolittilekiller
          lincon = asyouknows111
          rory = 8809117
          linda = IlikeWorldCup2006
          

          5 建立目錄訪問權限控制文件

          新建代碼庫 arm\conf\authz.conf 文件,內容如下:

          [groups]
          g_vip = morson
          g_manager = michael
          g_beijing = scofield
          g_shanghai = lincon
          g_headquarters = rory, linda
          g_docs = linda
          [arm:/]
          @g_manager = rw
          * = r
          [arm:/diary/headquarters]
          @g_manager = rw
          @g_headquarters = rw
          @g_vip = r
          * =
          [arm:/diary/beijing]
          @g_manager = rw
          @g_beijing = rw
          @g_vip = r
          * =
          [arm:/diary/shanghai]
          @g_manager = rw
          @g_shanghai = rw
          @g_vip = r
          * =
          [arm:/ref]
          @g_manager = rw
          @g_docs = rw
          * = r
          [arm:/temp]
          * = rw
          

          6 測試

          在服務器上,打開一個 DOS Prompt 窗口,輸入如下指令:

          svn co svn://127.0.0.1/arm --no-auth-cache --username rory --password 8809117
          

          我們應該得到如下目錄結構:

          arm
          ├─diary
          │  └─headquarters
          ├─ref
          └─temp
          

          然后修改ref目錄下任意文件并提交,服務器將會報錯"Access deni"

          深入

          本章將詳細介紹前一章所涉及的兩個配置文件, svnserve.conf 和 authz.conf,通過對配置逐行的描述,來闡明其中的一些細節含義。

          這里首先要注意一點,任何配置文件的有效配置行,都不允許存在前置空格,否則程序會無法識別。也就是說,如果你直接從本文的純文本格式中拷貝了相關的配置行過去,需要手動將前置的4個空格全部刪除。當然了,如果你覺得一下子要刪除好多行的同樣數目的前置空格是一件苦差使,那么也許 UltraEdit 的"Column Mode"編輯模式,可以給你很大幫助呢。

          1 svnserve.conf

          arm\conf\svnserve.conf 文件,是 svnserve.exe 這個服務器進程的配置文件,我們逐行解釋如下。

          首先,我們告訴 svnserve.exe,用戶名與密碼放在 passwd.conf 文件下。當然,你可以改成任意的有效文件名,比如默認的就是 passwd:

          password-db = passwd.conf
          

          接下來這兩行的意思,是說只允許經過驗證的用戶,方可訪問代碼庫。那么哪些是"經過驗證的"用戶呢?噢,當然,就是前面說那些在 passwd.conf 文件里面持有用戶名密碼的家伙。這兩行的等號后面,目前只允許 read write none 三種值,你如果想實現一些特殊的值,比如說"read-once"之類的,建議你自己動手改源代碼,反正它也是自由軟件:

          anon-access = none
          auth-access = write
          

          接下來就是最關鍵的一句呢,它告訴 svnserve.exe,項目目錄訪問權限的相關配置是放在 authz.conf 文件里:

          authz-db = authz.conf
          

          當然,svn 1.3.2 引入本功能的時候,系統默認使用 authz 而不是 authz.conf 作為配置文件。不過由于鄙人是處女座的,有著強烈的完美主義情結,看著 svnserve.conf 有后綴而 passwd 和 authz 沒有就是不爽,硬是要改了。

          2 authz.conf 之用戶分組

          arm\conf\authz.conf 文件的配置段,可以分為兩類,``[group]`` 是一類,里面放置著所有用戶分組信息。其余以 [arm:/] 開頭的是另外一類,每一段就是對應著項目的一個目錄,其目錄相關權限,就在此段內設置。

          首先,我們將人員分組管理,以便以后由于人員變動而需要重新設置權限時候,盡量少改動東西。我們一共設置了5個用戶分組,分組名稱統一采用 g_ 前綴,以方便識別。當然了,分組成員之間采用逗號隔開:

          [groups]
          # 任何想要查看所有文檔的非本部門人士
          g_vip = morson
          # 經理
          g_manager = michael
          # 北京辦人員
          g_beijing = scofield
          # 上海辦人員
          g_shanghai = lincon
          # 總部一般員工
          g_headquarters = rory, linda
          # 小秘,撰寫文檔
          g_docs = linda
          

          注意到沒有, linda 這個帳號同時存在"總部"和"文檔員"兩個分組里面,這可不是我老眼昏花寫錯了,是因為 svnserve.exe 允許我這樣設置。它意味著,這個家伙所擁有的權限,將會比他的同事 rory 要多一些,這樣的確很方便。具體多了哪些呢?請往下看!

          3 authz.conf 之項目根目錄

          接著,我們對項目根目錄做了限制,該目錄只允許arm事業部的經理才能修改,其他人都只能眼巴巴的看著:

          [arm:/]
          @g_manager = rw
          * = r
          
          • [arm:/] 表示這個目錄結構的相對根節點,或者說是 arm 項目的根目錄
          • 這里的 @ 表示接下來的是一個組名,不是用戶名。你當然也可以將 @g_manager=rw 這一行替換成 michael=rw ,而表達的意義完全一樣。
          • * 表示"除了上面提到的那些人之外的其余所有人",也就是"除了部門經理外的其他所有人",當然也包括總經理那個怪老頭
          • * = r 則表示"那些人只能讀,不能寫"

          4 authz.conf 之項目子目錄

          然后,我們要給總部人員開放日志目錄的讀寫權限:

          [arm:/diary/headquarters]
          @g_manager = rw
          @g_headquarters = rw
          @g_vip = r
          * =
          
          • 我敢打賭,設計svn的家伙們,大部分都是在 unix/linux 平臺下工作,所以他們總喜歡使用 / 來標識子目錄,而完全忽視在 MS Windows 下是用 \ 來做同樣的事情。所以這兒,為了表示 arm\diary\headquarters 這個目錄,我們必須使用 [arm:/diary/headquarters] 這樣的格式。
          • 這里最后一行的 *= 表示,除了經理、總部人員、特別人士之外,任何人都被禁止訪問本目錄。這一行是否可以省略呢?
          • 之所以這兒需要將 @g_vip=r 一句加上,就是因為存在上述這個解釋。如果說你沒有明確地給總經理授予讀的權力,則他會和其他人一樣,被 * 給排除在外。
          • 如果眾位看官中間,有誰玩過防火墻配置的話,可能會感覺上述的配置很熟悉。不過這里有一點與防火墻配置不一樣,那就是各個配置行之間,沒有 先后順序 一說。也就是說,如果我將本段配置的 *= 這一行挪到最前面,完全不影響整個配置的最終效果。
          • 請注意這兒,我們并沒有給 arm\diary 目錄設置權限,就直接跳到其子目錄下進行設置了。我當然是故意這樣的,因為我想在這兒引入"繼承"的概念。
          • 權限具備繼承性 任何子目錄,均可繼承其父目錄的所有權限,除非它自己被明確設置了其他的權限。也就是說,在 arm 目錄設置權限后, arm\diary 目錄沒有進行設置,就意味著它的權限與 arm 目錄一樣,都是只有經理才有權讀寫,其他人只能干瞪眼。
          • 【 * = 是否可以省略】【用例子引入覆蓋】【單用戶權限的繼承問題】【父目錄權限集成與全面覆蓋問題】

          現在來看看

          好了,我們現在掌握了"繼承"的威力,它讓我們節省了不少敲鍵盤的時間。可是現在又有一個問題了,

          屬性具備覆蓋性質子目錄若設置了屬性,則完全覆蓋父目錄。

          5 authz.conf 的其他注意點

          1. 父目錄的 r 權限,對子目錄 w 權限的影響

          把這個問題專門提出來,是因為在1.3.1及其以前的版本里面,有個bug,即為了子目錄的寫權限,項目首目錄必須具備讀權限。因此現在使用了1.3.2版本,就方便了那些想在一個代碼庫存放多個相互獨立的項目的管理員,來分配權限了。比如說央舜公司建立一個大的代碼庫用于存放所有員工日志,叫做 diary,而arm事業部只是其中一個部門,則可以這樣做:

          [diary:/]
          @g_chief_manager = rw
          [diary:/arm]
          @g_arm_manager = rw
          @g_arm = r
          

          這樣,對于所有arm事業部的人員來說,就可以將 svn://192.168.0.1/diary/arm 這個URL當作根目錄來進行日常操作,而完全不管它其實只是一個子目錄,并且當有少數好奇心比較強的人想試著 checkout 一下 svn://192.168.0.1/diary 的時候,馬上就會得到一個警告"Access deni",哇,太酷了。

          1. 默認權限

          如果說我對某個目錄不設置任何權限,會怎樣?馬上動手做個試驗,將:

          [diary:/]
          @g_chief_manager = rw
          

          改成:

          [diary:/]
          # @g_chief_manager = rw
          

          這樣就相當于什么都沒有設置。在我的 svn 1.3.2 版本上,此時是禁止任何訪問。也就是說,如果你想要讓某人訪問某目錄,你一定要顯式指明這一點。這個策略,看起來與防火墻的策略是一致的。

          1. 只讀權限帶來的一個小副作用

          若設置了:

          [arm:/diary]
          * = r
          

          則svnserve認為,任何人,都不允許改動diary目錄,包括刪除和改名,和新增。

          也就是說,如果你在項目初期創建目錄時候,一不小心寫錯目錄名稱,比如因拼寫錯誤寫成 dairy,以后除非你改動 authz.conf 里面的這行設置,否則無法利用 svn mv 命令將錯誤的目錄更正。

          改進

          1 對中文目錄的支持

          上午上班的時候,Morson 來到 Michael 的桌子前面,說道:"你是否可以將我們的北京辦、上海辦目錄,改成用中文的,看著那些拼音我覺得很難受?" Michael 心想,還好這兩天剛了解了一些與 unicode 編碼相關的知識,于是微笑地回答:"當然可以,你明天下午就可以看到中文目錄名稱了。"

          1. 使用 svn mv 指令,將原來的一些目錄改名并 commit 入代碼庫,改名后的目錄結構如下:

            arm
            ├─工作日志
            │  ├─總部人員
            │  ├─北京辦
            │  └─上海辦
            ├─公司公共文件參考目錄
            └─臨時文件存放處
            
          2. 修改代碼庫的 authz.conf 文件,將相應目錄逐一改名

          3. 使用 UltraEdit 將 authz.conf 文件轉換成不帶 BOM 的 UTF-8 格式

            將配置文件轉換成 UTF-8 格式之后,Subversion 就能夠正確識別中文字符了。但是這里需要注意一點,即必須保證 UTF-8 文件不包含 BOM 。BOM 是 Byte Order Mark 的縮寫,指 UNICODE 文件頭部用于指明高低字節排列順序的幾個字符,通常是 FFFE ,而將之用 UTF-8 編碼之后,就是 EFBBBF 。由于 UTF-8 文件本身不存在字節序問題,所以對 UTF-16 等編碼方式有重大意義的 BOM,對于 UTF-8 來說,只有一個作用--表明這個文件是 UTF-8 格式。由于 BOM 會給文本處理帶來很多難題,所以現在很多軟件都要求使用不帶 BOM 的 UTF-8 文件,特別是一些處理文本的軟件,如 PHP、 UNIX 腳本文件等,svn 也是如此。

          目前常用的一些文本編輯工具中,MS Windows 自帶的"記事本"里面,"另存為"菜單保存出來的 UTF-8 格式文件,會自動帶上 BOM 。新版本 UltraEdit 提供了選項,允許用戶選擇是否需要 BOM,而老版本的不會添加 BOM。請各位查看一下自己常用的編輯器的說明文件,看看它是否支持這個功能。

          利用 UltraEdit ,我們可以將 BOM 去掉。方法是,首先利用"UTF-8 TO ASCII"菜單將文件轉換成本地編碼,通常是GB2312碼,然后再使用"ASCII TO UTF-8(UNICODE Editing)"來轉換到 UTF-8 即可。

          posted @ 2007-09-05 18:15 Stanley Sun 閱讀(145) | 評論 (0)編輯 收藏

          Zoundry Blog Writer是一款非常不錯的離線Blog編輯工具。本人在BlogJava中所以的文章基本上都是用它來編輯的,一下是對BlogJava的設置。

          新建Blog賬戶--> 選擇你的Blog URL-->選擇Blog類型為Custom MetaWeBlog API-->API的URL為http://www.aygfsteel.com:80/你的賬戶/services/metaweblog.aspx

          posted @ 2007-08-12 01:34 Stanley Sun 閱讀(131) | 評論 (0)編輯 收藏

          文件夾,文件,網址可以創建快捷方式,控制面板中的設置也可以創建快捷方式,下面是快捷方式的命令,使用方法:在桌面或文件夾的空白處點右鍵,選擇新建,快捷方式,在"請鍵入項目的位置"輸入下面的命令,然后下一步輸入快捷方式的名稱。這樣就完成了一個控制面板的快捷方式,同樣還可以在開始菜單,運行,中輸入下面的命令來直接打開控制面板中的某個設置。


          控制面板
          模塊: control.exe
          命令: rundll32.exe shell32.dll,Control_RunDLL
          結果: 顯示控制面板窗口。

          輔助選項
          模塊: access.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,5
          結果: 顯示輔助選項/常規。

          命令: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,1
          結果: 顯示輔助選項/鍵盤。

          命令: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,2
          結果: 顯示輔助選項/聲音。

          命令: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,3
          結果: 顯示輔助選項/顯示。

          命令: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,4
          結果: 顯示輔助選項/鼠標。

          添加新硬件
          模塊: sysdm.cpl
          命令:rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl @1

          增加新的打印機
          模塊:shell32.dll
          命令:rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL AddPrinter

          添加/刪除程序
          模塊:appwiz.cpl

          命令:rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,1
          結果:顯示安裝/卸載。

          命令:rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,1
          結果:顯示安裝/卸載。

          命令:rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,2
          結果:顯示Windows 安裝。

          命令:rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,3
          結果:顯示啟動盤。

          復制磁盤
          模塊:diskcopy.dll
          命令:rundll32.exe diskcopy.dll,DiskCopyRunDll

          時間/日期
          模塊: timedate.cpl

          命令: rundll32.exe shell32.dll,Control_RunDLL timedate.cpl,,0
          結果: 顯示設置日期/時間。

          命令: rundll32.exe shell32.dll,Control_RunDLL timedate.cpl,,1
          結果: 顯示設置時間區域。

          撥號連接(DUN)
          模塊: rnaui.dll
          命令: rundll32.exe rnaui.dll,RnaDial 連接_名稱
          結果: 打開指定的撥號連接。
          例子:
          x= Shell("rundll32.exe rnaui.dll,RnaDial " & "連接_名稱", 1)

          顯示器
          模塊: desk.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0
          結果: 背景設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,1
          結果: 屏幕保護設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,2
          結果: 外觀設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3
          結果: 設置窗口。

          操縱桿
          模塊: joy.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL joy.cpl

          郵件/傳真
          模塊: mlcfg32.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL mlcfg32.cpl
          結果: 出現 MS Exchange 屬性設置。

          郵局設置
          模塊: wgpocpl.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL wgpocpl.cpl
          結果: 顯示 MS Postoffice Workgroup Admin 設置。

          主設置
          模塊: main.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL main.cpl @0
          結果: 顯示鼠標屬性。

          命令: rundll32.exe shell32.dll,Control_RunDLL main.cpl @1
          結果: 顯示鍵盤/速度屬性。

          命令: rundll32.exe shell32.dll,Control_RunDLL main.cpl @1,,1
          結果: 顯示鍵盤/語言屬性。

          命令: rundll32.exe shell32.dll,Control_RunDLL main.cpl @1,,2
          結果: 顯示鍵盤/常規屬性。

          命令: rundll32.exe shell32.dll,Control_RunDLL main.cpl @2
          結果: 顯示打印機屬性。

          命令: rundll32.exe shell32.dll,Control_RunDLL main.cpl @3
          結果: 顯示字體屬性。

          命令: rundll32.exe shell32.dll,Control_RunDLL main.cpl @4
          結果: 顯示電源管理屬性。

          增加 Modem
          模塊:modem.cpl
          命令:rundll32.exe shell32.dll,Control_RunDLL modem.cpl,,add

          多媒體
          模塊: mmsys.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0
          結果:聲音。

          命令: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,1
          結果:視頻。

          命令: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,2
          結果:聲音 MIDI。

          命令: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,3
          結果:CD/音樂。

          命令: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,4
          結果:高級。

          命令: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl @1
          結果:聲音。

          網絡
          模塊:netcpl.cpl
          命令:rundll32.exe shell32.dll,Control_RunDLL netcpl.cpl

          打開方式窗口(Open With)
          模塊: shell32.dll
          命令:rundll32.exe shell32.dll,OpenAs_RunDLL pathfilename

          口令
          模塊: password.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL password.cpl

          區域設置
          模塊: intl.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,0
          結果: 區域設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,1
          結果: 數字格式設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,2
          結果: 金額格式設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,3
          結果:時間格式設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,4
          結果: 日期格式設置。

          屏幕保護
          模塊: appwiz.cpl
          命令: rundll32.exe desk.cpl,InstallScreenSaver c:winntsystemFlying Windows.scr
          結果: 安裝屏幕保護并顯示預覽屬性頁。

          系統設置
          模塊: sysdm.cpl
          命令: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,0
          結果: 顯示常規設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,1
          結果: 顯示設備管理設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,2
          結果: 顯示硬件設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,3
          結果: 顯示性能設置。

          IE 設置
          模塊: inetcpl.cpl

          命令: rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,0
          結果: 常規設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,1
          結果: 安全設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,2
          結果: 隱私設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,3
          結果: 內容設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,4
          結果: 連接設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,5
          結果: 程序設置。

          命令: rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,6
          結果: 高級設置。

          posted @ 2007-08-06 11:57 Stanley Sun 閱讀(151) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 桐庐县| 张家界市| 郑州市| 武陟县| 唐山市| 关岭| 章丘市| 静安区| 怀远县| 塔河县| 靖州| 丰顺县| 封丘县| 抚松县| 昌江| 南康市| 班戈县| 社旗县| 昂仁县| 河北区| 开平市| 井陉县| 武宁县| 芦山县| 高邑县| 沁源县| 建平县| 潍坊市| 长葛市| 东方市| 香格里拉县| 文登市| 金门县| 林甸县| 盱眙县| 若羌县| 瓮安县| 龙海市| 张家川| 黔南| 临桂县|