逝者如斯夫

          靜而思之
          數據加載中……

          yum install yum-downloadonly

           

          yum install yum-downloadonly

          yum install xxx--downloadonly --downloaddir=/home/dev

          posted @ 2008-12-31 15:06 ideame 閱讀(854) | 評論 (0)編輯 收藏

          Linux下常用配置文件及常用命令介紹

          /etc/sysconfig/network
          包括主機基本網絡信息,用于系統啟動#該文件用來指定服務器上的網絡配置信息

          NETWORK = yes/no??????????????????????網絡是否被配置
          FORWARD_IPV4
          = yes/no    ?是否開啟IP轉發功能
          HOSTNAME
          = <hostname>??????????<hostname>表示服務器的主機名
          GAREWAY
          = <address>????????????????<address>表示網絡網關的IP地址
          GAREWAYDEV
          = <device>???????????<device>表示網關的設備名,如:eth0

          ####示例:

          1?#該文件用來指定服務器上的網絡配置信息
          2?NETWORK=yes/no??????????????????????網絡是否被配置
          3?FORWARD_IPV4=yes/no    ?是否開啟IP轉發功能
          4?HOSTNAME=<hostname>??????????<hostname>表示服務器的主機名
          5?GAREWAY=<address>????????????????<address>表示網絡網關的IP地址
          6?GAREWAYDEV=<device>???????????<device>表示網關的設備名,如:eth0

          /etc/sysconfig/network-script/
          此目錄下是系統啟動最初始化網絡的信息
          系統網絡設備的配置文件保存在/etc/sysconfig/network-scripts目錄下,ifcfg-eth0包含第一塊網卡的配置信息,ifcfg-eth1包含第二塊網卡的配置信息。在啟動時,系統通過讀取這個配置文件決定某個網卡是否啟動和如何配置。/etc/sysconfig /network-scripts/ifcfg-eth0文件示例:

          DEVICE? = ?eth0
          IPADDR?
          = ? 192.168.0.2
          NETMASK?
          = ? 255.255.255.0
          BROADCAST?
          = ? 192.168.0.255
          ONBOOT?
          = ?yes
          BOOTPROTO?
          = ?none
          GATEWAY=?
          192.168.0.1

          若希望手工修改網絡地址或增加新的網絡連接,可以通過修改對應的文件ifcfg-<interface-name>或創建新的文件來實現。

          DEVICE = <name>??????????????????<name>表示物理設備的名字
          IPADDR
          = <address>??????????????<address>表示賦給該網卡的IP地址
          NETMASK
          = <mask>??????????????<mask>表示子網掩碼
          BROADCAST
          = <address> ???<address>表示廣播地址
          ONBOOT
          = yes/no??????????????????啟動時是否激活該卡
          BOOTPROTO
          = none???????????????none:無須啟動協議
          ???????????????????????????????????????????????????bootp:使用bootp協議
          ???????????????????????????????????????????????????dhcp:使用dhcp協議
          GATEWAY
          = <address>??????????<address>表示默認網關
          MACADDR
          = <MAC-address><MAC-address>表示指定一個MAC地址
          USERCTL
          = yes/no???????????????????是否允許非root用戶控制該設備

          /etc/xinetd.conf?定義了由超級進程XINETD啟動的網絡服務

          /etc/protocols?設定了主機使用的協議以及各個協議的協議號
          /etc/services?設定了主機的不同端口的網絡服務?/etc/resolv.conf文件

          文件/etc/resolv.conf配置DNS客戶端,它包含了DNS服務器地址和域名搜索配置,每一行應包含一個關鍵字和一個或多個的由空格隔開的參數。例子文件:

          search?winxp.com
          nameserver?
          192.168.0.1
          nameserver?
          192.168.0.2
          search?winxp.com:表示當提供了一個不包括完全域名的主機名時,在該主機名后添加wuxp.com的后綴;
          nameserver:表示解析域名時使用該地址指定的主機為域名服務器。
          其中域名服務器是按照文件中出現的順序來查詢的。因此,應該首先給出最可靠的服務器。目前,至多支持三個名字服務器。?

          /etc/hosts文件
          當機器啟動時,在可以查詢DNS以前,機器需要查詢一些主機名到IP地址的匹配。這些匹配信息存放在/etc/hosts文件中。在沒有域名服務器情況下,系統上的所有網絡程序都通過查詢該文件來解析對應于某個主機名的IP地址。
          下面是一個/etc/hosts文件的示例:
          127.0.0.1? Localhost server.winxp.com
          192.168.0.3? station1.winxp.com

          #### 使用ifconfig命令配置并查看網絡接口情況

          #配置eth0的IP,同時激活設備
          ifconfig?eth0?
          192.168.168.119 ?netmask? 255.255.255.0 ?up
          //配置eth0別名設備?eth0:
          1 ?的IP,并添加路由
          ifconfig?eth0:
          1 ? 192.168.168.110
          route?add?–host?
          192.168.168.110 ?dev?eth0: 1
          //激活(禁用)設備
          ifconfig?eth0:
          1 ?up(down)
          //查看所有(指定)網絡接口配置
          ifconfig?(eth0)

          #### 使用route 命令配置路由表

          #添加到主機路由
          route?add?–host?
          192.168.168.110 ?dev?eth0: 1
          route?add?–host?
          192.168.168.119 ?gw? 192.168.168.1
          #添加到網絡的路由
          route?add?–net?IP?netmask?MASK?eth0
          route?add?–net?IP?netmask?MASK?gw?${IP}
          route?add?–net?IP/
          24 ?eth1
          #添加默認網關
          route?add?default?gw?${IP}
          #刪除路由
          route?del?–host?
          192.168.168.110 ?dev?eth0: 1

          ####常用命令

          traceroute? [ URL ]
          ping?
          [ URL ]
          #顯示網絡接口狀態信息
          netstat?–I
          #顯示所有監控的服務器的Socket和正在使用Socket的程序信息
          netstat?–lpe
          #顯示內核路由表信息
          netstat?–r
          netstat?–nr
          #顯示TCP/UDP傳輸協議的連接狀態
          netstat?–t
          netstat?–u
          #更改主機名
          hostname?myhost

          #查詢系統支持的字符集
          locale -a
          #設置系統字符集(在 /etc/sysconfig/i18n文件中)
          export LANG=zh_CN.GBK / LANG=en_US.UTF-8

          #查看ARP緩存
          arp
          #添加
          arp?–s?IP?MAC
          #刪除
          arp?–d?IP

          #### 運行級別與網絡服務

          #查看當前運行級別
          runlevel
          #運行級別的切換
          init
          telinit?

          posted @ 2008-12-15 20:21 ideame 閱讀(482) | 評論 (0)編輯 收藏

          查看Linux下系統占用的資源情況

          top

          1.作用
          top命令用來顯示執行中的程序進程,使用權限是所有用戶。

          2.格式
          top [-] [d delay] [q] [c] [S] [s] [i] [n]

          3.主要參數
          d:指定更新的間隔,以秒計算。
          q:沒有任何延遲的更新。如果使用者有超級用戶,則top命令將會以最高的優先序執行。
          c:顯示進程完整的路徑與名稱。
          S:累積模式,會將己完成或消失的子行程的CPU時間累積起來。
          s:安全模式。
          i:不顯示任何閑置(Idle)或無用(Zombie)的行程。
          n:顯示更新的次數,完成后將會退出top。

          image

          圖1 top命令的顯示

          在圖1中,第一行表示的項目依次為當前時間、系統啟動時間、當前系統登錄用戶數目、平均負載。第二行顯示的是所有啟動的進程、目前運行的、掛起(Sleeping)的和無用(Zombie)的進程。第三行顯示的是目前CPU的使用情況,包括系統占用的比例、用戶使用比例、閑置(Idle)比例。第四行顯示物理內存的使用情況,包括總的可以使用的內存、已用內存、空閑內存、緩沖區占用的內存。第五行顯示交換分區使用情況,包括總的交換分區、使用的、空閑的和用于高速緩存的大小。第六行顯示的項目最多,下面列出了詳細解釋。
          PID(Process ID):進程標示號。
          USER:進程所有者的用戶名。
          PR:進程的優先級別。
          NI:進程的優先級別數值。
          VIRT:進程占用的虛擬內存值。
          RES:進程占用的物理內存值。
          SHR:進程使用的共享內存值。
          S:進程的狀態,其中S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值是負數。
          %CPU:該進程占用的CPU使用率。
          %MEM:該進程占用的物理內存和總內存的百分比。
          TIME+:該進程啟動后占用的總的CPU時間。
          Command:進程啟動的啟動命令名稱,如果這一行顯示不下,進程會有一個完整的命令行。
          top命令使用過程中,還可以使用一些交互的命令來完成其它參數的功能。這些命令是通過快捷鍵啟動的。
          <空格>:立刻刷新。
          P:根據CPU使用大小進行排序。
          T:根據時間、累計時間排序。
          q:退出top命令。
          m:切換顯示內存信息。
          t:切換顯示進程和CPU狀態信息。
          c:切換顯示命令名稱和完整命令行。
          M:根據使用內存大小進行排序。
          W:將當前設置寫入~/.toprc文件中。這是寫top配置文件的推薦方法。

          可以看到,top命令是一個功能十分強大的監控系統的工具,對于系統管理員而言尤其重要。但是,它的缺點是會消耗很多系統資源。

          更多的請看:http://www.QQread.com/windows/2003/index.Html

          free

          1.作用
          free命令用來顯示內存的使用情況,使用權限是所有用戶。

          2.格式
          free [-b-k-m] [-o] [-s delay] [-t] [-V]

          3.主要參數
          -b -k -m:分別以字節(KB、MB)為單位顯示內存使用情況。
          -s delay:顯示每隔多少秒數來顯示一次內存使用情況。
          -t:顯示內存總和列。
          -o:不顯示緩沖區調節列。

          4.應用實例
          free命令是用來查看內存使用情況的主要命令。和top命令相比,它的優點是使用簡單,并且只占用很少的系統資源。通過-S參數可以使用free命令不間斷地監視有多少內存在使用,這樣可以把它當作一個方便實時監控器。
          #free -b -s5

          使用這個命令后終端會連續不斷地報告內存使用情況(以字節為單位),每5秒更新一次。

          ?image

          更多的請看:http://www.qqread.com/windows/2003/index.html

          uptime 命令

          我曾經看到資料上講,load avarage <3 系統良好,大于5 則有嚴重的性能問題。注意,這個值還應當除以CPU數目。
          如果load avarage=8 ,CPU=3,8/3=2.666,2.66這個值表示系統狀態良好
          大于5也不一定是嚴重性能問題,有可能是的確主機提供的服務超過了他能夠提供的能力,需要擴容了。要具體看看。

          image

          posted @ 2008-12-15 09:53 ideame 閱讀(517) | 評論 (0)編輯 收藏

          HTML Response ContentType 大全

          ".*"="application/octet-stream"
          ".001"="application/x-001"
          ".301"="application/x-301"
          ".323"="text/h323"
          ".906"="application/x-906"
          ".907"="drawing/907"
          ".a11"="application/x-a11"
          ".acp"="audio/x-mei-aac"
          ".ai"="application/postscript"
          ".aif"="audio/aiff"
          ".aifc"="audio/aiff"
          ".aiff"="audio/aiff"
          ".anv"="application/x-anv"
          ".asa"="text/asa"
          ".asf"="video/x-ms-asf"
          ".asp"="text/asp"
          ".asx"="video/x-ms-asf"
          ".au"="audio/basic"
          ".avi"="video/avi"
          ".awf"="application/vnd.adobe.workflow"
          ".biz"="text/xml"
          ".bmp"="application/x-bmp"
          ".bot"="application/x-bot"
          ".c4t"="application/x-c4t"
          ".c90"="application/x-c90"
          ".cal"="application/x-cals"
          ".cat"="application/vnd.ms-pki.seccat"
          ".cdf"="application/x-netcdf"
          ".cdr"="application/x-cdr"
          ".cel"="application/x-cel"
          ".cer"="application/x-x509-ca-cert"
          ".cg4"="application/x-g4"
          ".cgm"="application/x-cgm"
          ".cit"="application/x-cit"
          ".class"="java/*"
          ".cml"="text/xml"
          ".cmp"="application/x-cmp"
          ".cmx"="application/x-cmx"
          ".cot"="application/x-cot"
          ".crl"="application/pkix-crl"
          ".crt"="application/x-x509-ca-cert"
          ".csi"="application/x-csi"
          ".css"="text/css"
          ".cut"="application/x-cut"
          ".dbf"="application/x-dbf"
          ".dbm"="application/x-dbm"
          ".dbx"="application/x-dbx"
          ".dcd"="text/xml"
          ".dcx"="application/x-dcx"
          ".der"="application/x-x509-ca-cert"
          ".dgn"="application/x-dgn"
          ".dib"="application/x-dib"
          ".dll"="application/x-msdownload"
          ".doc"="application/msword"
          ".dot"="application/msword"
          ".drw"="application/x-drw"
          ".dtd"="text/xml"
          ".dwf"="Model/vnd.dwf"
          ".dwf"="application/x-dwf"
          ".dwg"="application/x-dwg"
          ".dxb"="application/x-dxb"
          ".dxf"="application/x-dxf"
          ".edn"="application/vnd.adobe.edn"
          ".emf"="application/x-emf"
          ".eml"="message/rfc822"
          ".ent"="text/xml"
          ".epi"="application/x-epi"
          ".eps"="application/x-ps"
          ".eps"="application/postscript"
          ".etd"="application/x-ebx"
          ".exe"="application/x-msdownload"
          ".fax"="image/fax"
          ".fdf"="application/vnd.fdf"
          ".fif"="application/fractals"
          ".fo"="text/xml"
          ".frm"="application/x-frm"
          ".g4"="application/x-g4"
          ".gbr"="application/x-gbr"
          ".gcd"="application/x-gcd"
          ".gif"="image/gif"
          ".gl2"="application/x-gl2"
          ".gp4"="application/x-gp4"
          ".hgl"="application/x-hgl"
          ".hmr"="application/x-hmr"
          ".hpg"="application/x-hpgl"
          ".hpl"="application/x-hpl"
          ".hqx"="application/mac-binhex40"
          ".hrf"="application/x-hrf"
          ".hta"="application/hta"
          ".htc"="text/x-component"
          ".htm"="text/html"
          ".html"="text/html"
          ".htt"="text/webviewhtml"
          ".htx"="text/html"
          ".icb"="application/x-icb"
          ".ico"="image/x-icon"
          ".ico"="application/x-ico"
          ".iff"="application/x-iff"
          ".ig4"="application/x-g4"
          ".igs"="application/x-igs"
          ".iii"="application/x-iphone"
          ".img"="application/x-img"
          ".ins"="application/x-internet-signup"
          ".isp"="application/x-internet-signup"
          ".IVF"="video/x-ivf"
          ".java"="java/*"
          ".jfif"="image/jpeg"
          ".jpe"="image/jpeg"
          ".jpe"="application/x-jpe"
          ".jpeg"="image/jpeg"
          ".jpg"="image/jpeg"
          ".jpg"="application/x-jpg"
          ".js"="application/x-javascript"
          ".jsp"="text/html"
          ".la1"="audio/x-liquid-file"
          ".lar"="application/x-laplayer-reg"
          ".latex"="application/x-latex"
          ".lavs"="audio/x-liquid-secure"
          ".lbm"="application/x-lbm"
          ".lmsff"="audio/x-la-lms"
          ".ls"="application/x-javascript"
          ".ltr"="application/x-ltr"
          ".m1v"="video/x-mpeg"
          ".m2v"="video/x-mpeg"
          ".m3u"="audio/mpegurl"
          ".m4e"="video/mpeg4"
          ".mac"="application/x-mac"
          ".man"="application/x-troff-man"
          ".math"="text/xml"
          ".mdb"="application/msaccess"
          ".mdb"="application/x-mdb"
          ".mfp"="application/x-shockwave-flash"
          ".mht"="message/rfc822"
          ".mhtml"="message/rfc822"
          ".mi"="application/x-mi"
          ".mid"="audio/mid"
          ".midi"="audio/mid"
          ".mil"="application/x-mil"
          ".mml"="text/xml"
          ".mnd"="audio/x-musicnet-download"
          ".mns"="audio/x-musicnet-stream"
          ".mocha"="application/x-javascript"
          ".movie"="video/x-sgi-movie"
          ".mp1"="audio/mp1"
          ".mp2"="audio/mp2"
          ".mp2v"="video/mpeg"
          ".mp3"="audio/mp3"
          ".mp4"="video/mpeg4"
          ".mpa"="video/x-mpg"
          ".mpd"="application/vnd.ms-project"
          ".mpe"="video/x-mpeg"
          ".mpeg"="video/mpg"
          ".mpg"="video/mpg"
          ".mpga"="audio/rn-mpeg"
          ".mpp"="application/vnd.ms-project"
          ".mps"="video/x-mpeg"
          ".mpt"="application/vnd.ms-project"
          ".mpv"="video/mpg"
          ".mpv2"="video/mpeg"
          ".mpw"="application/vnd.ms-project"
          ".mpx"="application/vnd.ms-project"
          ".mtx"="text/xml"
          ".mxp"="application/x-mmxp"
          ".net"="image/pnetvue"
          ".nrf"="application/x-nrf"
          ".nws"="message/rfc822"
          ".odc"="text/x-ms-odc"
          ".out"="application/x-out"
          ".p10"="application/pkcs10"
          ".p12"="application/x-pkcs12"
          ".p7b"="application/x-pkcs7-certificates"
          ".p7c"="application/pkcs7-mime"
          ".p7m"="application/pkcs7-mime"
          ".p7r"="application/x-pkcs7-certreqresp"
          ".p7s"="application/pkcs7-signature"
          ".pc5"="application/x-pc5"
          ".pci"="application/x-pci"
          ".pcl"="application/x-pcl"
          ".pcx"="application/x-pcx"
          ".pdf"="application/pdf"
          ".pdf"="application/pdf"
          ".pdx"="application/vnd.adobe.pdx"
          ".pfx"="application/x-pkcs12"
          ".pgl"="application/x-pgl"
          ".pic"="application/x-pic"
          ".pko"="application/vnd.ms-pki.pko"
          ".pl"="application/x-perl"
          ".plg"="text/html"
          ".pls"="audio/scpls"
          ".plt"="application/x-plt"
          ".png"="image/png"
          ".png"="application/x-png"
          ".pot"="application/vnd.ms-powerpoint"
          ".ppa"="application/vnd.ms-powerpoint"
          ".ppm"="application/x-ppm"
          ".pps"="application/vnd.ms-powerpoint"
          ".ppt"="application/vnd.ms-powerpoint"
          ".ppt"="application/x-ppt"
          ".pr"="application/x-pr"
          ".prf"="application/pics-rules"
          ".prn"="application/x-prn"
          ".prt"="application/x-prt"
          ".ps"="application/x-ps"
          ".ps"="application/postscript"
          ".ptn"="application/x-ptn"
          ".pwz"="application/vnd.ms-powerpoint"
          ".r3t"="text/vnd.rn-realtext3d"
          ".ra"="audio/vnd.rn-realaudio"
          ".ram"="audio/x-pn-realaudio"
          ".ras"="application/x-ras"
          ".rat"="application/rat-file"
          ".rdf"="text/xml"
          ".rec"="application/vnd.rn-recording"
          ".red"="application/x-red"
          ".rgb"="application/x-rgb"
          ".rjs"="application/vnd.rn-realsystem-rjs"
          ".rjt"="application/vnd.rn-realsystem-rjt"
          ".rlc"="application/x-rlc"
          ".rle"="application/x-rle"
          ".rm"="application/vnd.rn-realmedia"
          ".rmf"="application/vnd.adobe.rmf"
          ".rmi"="audio/mid"
          ".rmj"="application/vnd.rn-realsystem-rmj"
          ".rmm"="audio/x-pn-realaudio"
          ".rmp"="application/vnd.rn-rn_music_package"
          ".rms"="application/vnd.rn-realmedia-secure"
          ".rmvb"="application/vnd.rn-realmedia-vbr"
          ".rmx"="application/vnd.rn-realsystem-rmx"
          ".rnx"="application/vnd.rn-realplayer"
          ".rp"="image/vnd.rn-realpix"
          ".rpm"="audio/x-pn-realaudio-plugin"
          ".rsml"="application/vnd.rn-rsml"
          ".rt"="text/vnd.rn-realtext"
          ".rtf"="application/msword"
          ".rtf"="application/x-rtf"
          ".rv"="video/vnd.rn-realvideo"
          ".sam"="application/x-sam"
          ".sat"="application/x-sat"
          ".sdp"="application/sdp"
          ".sdw"="application/x-sdw"
          ".sit"="application/x-stuffit"
          ".slb"="application/x-slb"
          ".sld"="application/x-sld"
          ".slk"="drawing/x-slk"
          ".smi"="application/smil"
          ".smil"="application/smil"
          ".smk"="application/x-smk"
          ".snd"="audio/basic"
          ".sol"="text/plain"
          ".sor"="text/plain"
          ".spc"="application/x-pkcs7-certificates"
          ".spl"="application/futuresplash"
          ".spp"="text/xml"
          ".ssm"="application/streamingmedia"
          ".sst"="application/vnd.ms-pki.certstore"
          ".stl"="application/vnd.ms-pki.stl"
          ".stm"="text/html"
          ".sty"="application/x-sty"
          ".svg"="text/xml"
          ".swf"="application/x-shockwave-flash"
          ".tdf"="application/x-tdf"
          ".tg4"="application/x-tg4"
          ".tga"="application/x-tga"
          ".tif"="image/tiff"
          ".tif"="application/x-tif"
          ".tiff"="image/tiff"
          ".tld"="text/xml"
          ".top"="drawing/x-top"
          ".torrent"="application/x-bittorrent"
          ".tsd"="text/xml"
          ".txt"="text/plain"
          ".uin"="application/x-icq"
          ".uls"="text/iuls"
          ".vcf"="text/x-vcard"
          ".vda"="application/x-vda"
          ".vdx"="application/vnd.visio"
          ".vml"="text/xml"
          ".vpg"="application/x-vpeg005"
          ".vsd"="application/vnd.visio"
          ".vsd"="application/x-vsd"
          ".vss"="application/vnd.visio"
          ".vst"="application/vnd.visio"
          ".vst"="application/x-vst"
          ".vsw"="application/vnd.visio"
          ".vsx"="application/vnd.visio"
          ".vtx"="application/vnd.visio"
          ".vxml"="text/xml"
          ".wav"="audio/wav"
          ".wax"="audio/x-ms-wax"
          ".wb1"="application/x-wb1"
          ".wb2"="application/x-wb2"
          ".wb3"="application/x-wb3"
          ".wbmp"="image/vnd.wap.wbmp"
          ".wiz"="application/msword"
          ".wk3"="application/x-wk3"
          ".wk4"="application/x-wk4"
          ".wkq"="application/x-wkq"
          ".wks"="application/x-wks"
          ".wm"="video/x-ms-wm"
          ".wma"="audio/x-ms-wma"
          ".wmd"="application/x-ms-wmd"
          ".wmf"="application/x-wmf"
          ".wml"="text/vnd.wap.wml"
          ".wmv"="video/x-ms-wmv"
          ".wmx"="video/x-ms-wmx"
          ".wmz"="application/x-ms-wmz"
          ".wp6"="application/x-wp6"
          ".wpd"="application/x-wpd"
          ".wpg"="application/x-wpg"
          ".wpl"="application/vnd.ms-wpl"
          ".wq1"="application/x-wq1"
          ".wr1"="application/x-wr1"
          ".wri"="application/x-wri"
          ".wrk"="application/x-wrk"
          ".ws"="application/x-ws"
          ".ws2"="application/x-ws"
          ".wsc"="text/scriptlet"
          ".wsdl"="text/xml"
          ".wvx"="video/x-ms-wvx"
          ".xdp"="application/vnd.adobe.xdp"
          ".xdr"="text/xml"
          ".xfd"="application/vnd.adobe.xfd"
          ".xfdf"="application/vnd.adobe.xfdf"
          ".xhtml"="text/html"
          ".xls"="application/vnd.ms-excel"
          ".xls"="application/x-xls"
          ".xlw"="application/x-xlw"
          ".xml"="text/xml"
          ".xpl"="audio/scpls"
          ".xq"="text/xml"
          ".xql"="text/xml"
          ".xquery"="text/xml"
          ".xsd"="text/xml"
          ".xsl"="text/xml"
          ".xslt"="text/xml"
          ".xwd"="application/x-xwd"
          ".x_b"="application/x-x_b"
          ".x_t"="application/x-x_t"

          Technorati 標簽:

          posted @ 2008-10-28 14:47 ideame 閱讀(1150) | 評論 (0)編輯 收藏

          Erlang Compileing Paths

          關于設置路徑變量

          1> cd(a).
          C:/Erlang5.6.4/erl5.6.4/usr
          ok


          2> cd("D:/Work/sp/apps").
          D:/Work/sp/apps
          ok

          還可以直接在user.home目錄中建立.erlang文件,在文件中加入自定義搜索路徑:

          io:format( " Custom?search?path?added.~n~n " ).?
          code:add_patha(
          " . "
          ).?
          code:add_pathz(
          " /Erlang5.6.4/erlyweb-0.7.1/ebin "
          ).?
          code:add_pathz(
          " /Yaws-1.77/include " ).

          Technorati 標簽:

          posted @ 2008-10-20 16:31 ideame 閱讀(236) | 評論 (0)編輯 收藏

          IntelliJ IDEA插件開發手冊

        1. Technorati 標簽:

          來自:中國網站資源 作者:lybykw

        2. ? 開發準備


          ?? 在開發前,首先我們要做一些環境準備,這樣你可以快速進入這個場景。首先你要安裝好IntelliJ IDEA,這里我推薦大家使用IntelliJ IDEA 7.0 M2,你可以通過http://www.jetbrains.com/idea下載。IntelliJ IDEA安裝完畢后,你需要安裝一個插件開發包,主要用于IntelliJ IDEA的插件開發。下載地址和IntelliJ IDEA相同。 這個開發包包含以下內容:IntelliJ IDEA的Open API和源碼,以及一些插件的源碼(IntelliJ IDEA的插件源碼都在 http://svn.jetbrains.org/idea/Trunk,這些都是你編寫插件的很好樣例)。當然沒有這個插件開發包你可以開發插件,不過我強烈推薦下載這個開發包。開發部下載完畢后,你需要將其解壓到IntelliJ IDEA的安裝目錄下,這樣IntelliJ IDEA的SDK創建會很簡單。這里要注意一點,插件開發包的版本最好和IntelliJ IDEA的版本相對應。關于IntelliJ IDEA的SDK準備,你可以參考這篇文章:建立IntelliJ IDEA插件開發環境
          ?? 接下來我們啟動IntelliJ IDEA來創建一個IntelliJ IDEA SDK,這是開發插件的基礎。啟動IDEA,打開設置面板,選擇”Project Settings",在彈出的對話框中安裝下圖進行IntelliJ IDEA SDK設置:

          ?

          這里要有一個注意事項:默認的情況下,新創建的SDK并會將idea.jar包含到classpath中,由于IntelliJ IDEA的Open API不能完全滿足你需要的功能,你的插件可能會用到IDEA未公布的API,所以這里建議你檢查一下idea.jar文件是否已經被包含,如果沒有被包含,請加入這個jar文件。
          ??? IntelliJ IDEA的SDK已經被創建了,它是開發插件的基礎包。在這里我相對這些jar文件進行一些描述,已方便我們以后的代碼編寫,畢竟我們代碼是要引用其他的開發包的,如果IDEA已經提供,我們就沒有必要在找第三方的jar包啦。在$IDEA_HOME/lib下有以下文件需要提一下:
          ????? commons-codec-1.3.jar:這個是進行編碼轉換的開發包,是Apache Commons一個比較重要的開發包; http://commons.apache.org/codec
          ????? commons-collections.jar: Java Collection擴展框架,對Collection處理更加方便,也是Apache Commons一個比較重要的開發包;? http://commons.apache.org/collections/
          ????? j2ee.jar和javaee.jar:J2EE開發包,這個不用說啦; http://java.sun.com/javaee/5/docs/api/
          ????? jdom.jar:XML開發包; http://www.jdom.org
          ????? trove4j.jar: java.util.Collections的一個實現,更加快速、輕量; http://trove4j.sourceforge.net/
          ????? velocity.jar: Velocity模板引擎; http://velocity.apache.org
          ????? xmlrpc-2.0.jar: xml-rpc的開發包; http://ws.apache.org/xmlrpc/
          ????? xstream.jar: xml/object映射框架; http://xstream.codehaus.org/
          ?? 了解一下這些開發包,可能對后續的開發有不少的幫助。
          ?? 下面就讓我們開始創建一個項目并進行插件開發。首先我們要創建一個項目,這里個人有一個建議:建立一個空的項目,然后添加多個plugin module,這樣在一個項目中可以包含多個plugin module,主要的好處就是你可以添加一些參考的插件,這對編寫一個新的插件會幫助不少。

          項目創建后,我們需要添加一個plugin module。只需打開"File" -> "Add Module"然后選擇"plugin module"就可以啦,請將module的SDK設置為上面我們創建的IDEA SDK。到這里插件開發的項目就創建完畢啦,你可以開發你的插件啦。

        3. IntelliJ IDEA的IoC介紹


          ??? 當你看到這一章節時,你估計會罵我雞婆。IoC,這個還要你來告訴我,我用SpringFramework已經很久啦。但我還是要說一下。IDEA整個組件結構是基于PicoContainer(http://www.picocontainer.org)的,PicoContainer是一個高效的嵌入式的DI容器。如果你有時間的話,我建議你花5分鐘瀏覽一下PicoContainer,然后回到這篇文檔來。
          ??? PicoContainer是有層次結構的,就是一個container可以包含子container,子容器可以訪問父容器中的組件,而各個子容器直接是獨立的。在IDEA中,主要有三種container:Application, Project和Module,分別包含不同的組件。application container包含多個project container,project container可以包含多個module container,如下圖:

          ??? 這樣各個project container是獨立的,都可以訪問application container中的組件;module container也是獨立的,可以訪問所屬project container和application container中的組件。這個圖是我們后面理解application component, project component, module component和extension point等等的基礎。
          ??? PicoContainer的組件注入主要有兩種方式:構造注入和Setter注入,但是在IDEA中,目前Setter注入還不支持,全部是構造注入,關于構造注入,PicoContainer推薦最好使用一個構造函數,這點也在IDEA中需要明確。如果你的組件需要引用其他的組件或資源,你最好在組件的構造函數中指定,PicoContainer會幫助你完成資源引用和初始化。
          ?? IDEA的這些容器中包含些什么? 當然首先是各種component,還有就是一些服務,容器中不僅僅是component,還有相關為組件服務的資源,在后面我們也會涉及到對容器中服務資源的講述。?
          ?? 如果訪問這些容器中的組件?在IDEA中,訪問application container中的組件可以通過ApplicationManager.getInstance().getComponent(Class T)來進行。通用獲得project對象后,你可以訪問project容器中的組件;獲取module對象后,你可以訪問module容器的組件。有了容器后,如何能獲取指定的組件?有以下幾種方式: 1. 組件ID,組件提供的組件標識符號,可以通過標識符來訪問。如果組件沒有標識符號,我們稱之為匿名組件。 2. 組件的interface類。如果一個組件的是通過interface向外服務的,那么我們可以通過interface來獲取對應的組件。如果 interface的實現為多個組件,就會獲得多個組件。
          ?? 如果讓我的組件被注冊到這些容器中? 在IDEA中,有三種組件: Application Component, Project Component和Module Component。不用的組件需要繼承不同接口,分別為Application Component, ProjectComponent和ModuleComponent,如果你的組件繼承了某一接口,將會自動放置到某一容器中,不需要你手動去注冊。
          ?? 組件既然要交給容器去管理,這就牽涉到生命周期的概念,對于Application Component來說,initComponent負責初始化,disposeComponent負責資源清理。對ProjectComponent來說,除了initComponent和disposeComponent,還增加了projectOpened 和projectClosed,這個意思還比較容易理解,就是一個掛鉤(hook)。組件一旦被激活,就開始發揮它的作用啦。
          ? 組件的行為可能需要設置,如設置不同的參數組件的特性就不一樣。如何給組件設置參數?當然可以讓組件自身去做,去找一個文件,當文件修改后重新加載。在IDEA中,你不需要這么做,你只需讓組件繼承Configurable接口,IDEA會將在設置面板中添加一個設置選項,讓你設置這個組件的參數,當然包括運行期的,這個好像和JMX相像。 :)
          ? 組件的參數設置完畢啦,當容器關閉后,組件帶的這些參數需要保存在一個地方,這樣當容器重新啟動后,組件仍然能向以前一樣工作,不然你又得重新設置一下。同樣的道理,你可以自己設定邏輯,保存到某一個地方,然后在加載起來。如果IDEA提供了一個 JDOMExternalizable接口,只要實現接口并添加少量的代碼,IDEA就會完成component的參數保存和讀取的任務。在最新的 IDEA 7.0中,采取了另外一種保存機制,這個我們會在后面進行說明。
          ?? 講到這里,你可能會問,有沒有一種方面來聲明Component? 這是有的,那就是extension point。extension point是組件的簡化方式,它的主要功能是數據信息擴展,它們不需要繼承component接口,同時也沒有組件標識符號,只需要在 plugin.xml聲明就可以,在聲明的時候你需要指名是何種類型的組件。下面會有更詳細的介紹。
          ? PicoContainer是IDEA基礎,因為我們編寫的組件都是由容器初始化的,而且組件直接的相互依賴也是有容器完成,所有了解一下PicoContainer還是很有必要的,對插件編寫和IDEA的機制都非常有好處。

        4. Extension Points


          ?? 前面講解了一下extions point,這里想再細化一下。Extension point的主要作用是數據信息擴展和事件監聽,也就是一個插件注冊了某一extension point,其他插件可以通過extension point為該插件提供數據信息或觸發事件邏輯,從而達到影響上一插件中的組件的一些行為。最典型的就是gotoSymbolContributor,我們在各個插件中通過gotoSymbolContributor的聲明,提供插件自己的symbol信息給IDEA,這樣在按下 Ctrl+Shift+Alt+N時,插件提供的symbol信息就會被提示出來,當然你可以利用這種機制實現其他功能,監聽也是一種實現。從用戶的角度來看,就是在某些方面,原先的插件功能增加啦。那么如何聲明一個extension point呢。這個很簡單,只要建立一個Java Integerace,然后在plugin.xml進行什么就可以啦,代碼如下:
          ????????? <extensionPoint name="resourceBundleManager" interface="com.intellij.lang.properties.psi.ResourceBundleManager" area="IDEA_PROJECT"/>????
          ?? 前面說過,extension point是組件的簡化方式,這里的area是指組件的類型,如果不指定就是ApplicationComponent,IDEA_PROJECT表示 ProjectComponent,MODULE_PROJECT表示ModuleComponent。聲明完成后,我們需要在插件中訪問 extension point去獲取數據,代碼如下:
          ????????? Object[] extensions = Extensions.getExtensions("plugin_id.testExtPoint");
          ?? 這里字符串中的plugin_id表示plugin的id(在xml文件中),testExtPoint就是extension point的name。還有一種就是提供ExtensionPointName,這個可以參考一下Open API,也非常簡單。這里返回一個數組,因為可能多個其他插件使用該extension point為該插件提供數據。接下來就是在其他插件應用該extension point啦,三個步驟:
          ???? 1 首先依賴該插件:? <depends>reliant_plugin_id</depends>
          ???? 2 創建extension point的interface的實現,java編碼即可
          ???? 3 extension point引用聲明,xmlns的值就是所依賴的plugin的id。代碼如下:
          ???????????? <extensions xmlns="reliant_plugin_id">????
          ??????????????????? <testExtPoint implementation="com.foobar.test.impl.Extender"/>
          ??????????? </extensions>
          ?? 通過這種方式,可以實現插件直接的數據供給,提示原有插件的功能,一個好的插件,如果能定義好一下擴展點,方便其他插件進行擴充,將是非常有益的。
          ?? 事實上IDEA核心就提供了非常多的extension point,這里你可以擴展IDEA的功能。關于這些擴展點的元信息,請參考:$IDEA_HOME/lib/resources.jar文件的/META-INF/plugin.xml文件。

        5. Plugin的結構介紹


          ??? 我們應該進入正題啦。Plugin的主要功能擴展IDE的功能,前面我們講述了IDEA整體結構是基于容器的,那么要擴展IDEA的功能,唯一的方法就是想容器中添加組件,新添加的組件包含自身的一些功能,同時和其他組件進行交互(修改一些參數和特性等),影響其他組件的行為,從而達到功能的擴展目的。那么一個插件中,應該會包含application component, project component和module component。由于還要和用戶進行交換,插件還提供了action,也就是和用戶進行交換的操作,所以插件的主要內容就是component和 action。這里順便還聊一句,component是由容器管理的,那么action可不可以也由容器管理呢?這樣在action中引用 component將更加方便。目前action還不是由容器管理的,這個主要是由歷史原因決定的,不少action的代碼還不能轉移到容器中管理,不過 IDEA正在做一些工作,相信以后action也可以由容器進行管理。
          ?? 下面我們要開始插件編寫啦。首先我們要設定一下插件的基本信息。插件需要有一個唯一標識符,有一個版本號(便于升級)還有就是適用的IDEA版本。這三項應該說是必需的,其他就是插件的額外信息,如描述,changeLog,作者等等,在plugin.xml設定就可以啦。
          ?? 完成設定后,我們就需要向插件中添加內容啦。創建Component和Action非常簡單,只要通過new group就可以創建。圖例如下:

          ?

          這里我們可能還要啰嗦一下,就是關于plugin的目錄結構。插件開發包中有一個plugin structure的html文檔,已經講述的非常清楚,這里只是重復一下。一個plugin通常包含plugin.xml,相關的class和引用的第三方jar文件。如何組織這些文件,我推薦以下的結構:插件目錄下的lib文件夾保存第三方jar文件(如果沒有引用第三方jar,可以沒有該目錄),classes目錄包含插件的代碼,META-INF包含 plugin.xml文件,結構如下:

        6. 使用Maven管理插件項目


          ???? Maven實際上已經成為Java項目管理的規范,當然這里我們也希望IDEA的插件開發也能通過Maven管理起來。Maven并不難,但是針對 IDEA的插件項目主要有以下問題,可能導致管理有一定的難度:1. IDEA并不是都使用Javac進行代碼編譯。如果你使用了IDEA的UI Designer,那么你得使用Javac2才能編譯這些代碼; 2. 開發插件需要的IDEA的jar文件在repo1.maven.org/maven2中沒有,你可能需要自己設定repository的位置;3. IDEA的插件需要裝配,這個可能是一些web項目,jar項目不具有的。基于這些原因,我想給一個相對標準的pom.xml文件和插件項目的目錄結構,目錄結構如下圖:?

          這個目錄和標準Maven項目是一致的,不過有一點就是我們將plugin.xml文件放置在src/main/resources目錄下,最好形成這樣的標準,這對后續的plugin打包分發有幫助。
          ??? 回到pom.xml文件,其實只需注意一下,IDEA插件開發需要的jar包都在 http://mevenide.codehaus.org/m2-repository/, 所以我們需要設置一下項目的repository的位置。由于還使用了codehaus的一些Maven插件,所以還有設置一下plugin repository的為位置。下面就是設置build plugin,能保證插件項目中的代碼能被正確編譯,主要就是IDEA的UI Designer的文件編譯,其他的和標準的Maven編譯選項一致。接下來就是設置dependency,由于插件開發需要的jar包不少都包括在 IDEA SDK(前面我們講述過),所有這些dependency的scope設置為provided即可。如果你引用的是IntelliJ IDEA本身的jar包,那可能還有注意一點:由于IDEA的jar包包括正式版本號和編譯版本號,所以你可能還有給dependency設置 classifier,這個值就是IDEA的編譯版本號,一個典型的dependency聲明如下:
          ?????? <dependency>
          ??????????? <groupId>com.intellij.idea</groupId>
          ??????????? <artifactId>openapi</artifactId>
          ??????????? <version>7.0</version>
          ??????????? <scope>provided</scope>
          ??????????? <classifier>${idea_build_number}</classifier>
          ??????? </dependency>
          ??? 因為牽涉到插件要發布出去,所以我們還是需要設置一下如何將插件打包。在Maven中這稱之為Assembly,是通過Assembly plugin完成。我們只需要創建Assembly的描述文件,然后在設置一下Assembly插件的配置,最后咨詢mvn assembly:assembly就可以啦。一個IDEA插件項目典型的Assembly的描述文件如下所示:
          ??? <?xml version="1.0" encoding="utf-8" ?>
          ??? <assembly? xmlns="http://maven.apache.org/xsd/assembly??????? <id/>
          ??????? <formats>
          ?????????? <format>zip</format>
          ??????? </formats>
          ??????? <includeBaseDirectory>false</includeBaseDirectory>
          ??????? <dependencySets>
          ??????????? <dependencySet>
          ??????????? <outputDirectory>/gmail-plugin/lib</outputDirectory>
          ??????????? <unpack>false</unpack>
          ??????????? <scope>runtime</scope>
          ??????????? <includes>
          ??????????????? <include>org.intellij:gmail-plugin</include>
          ??????????????? <include>net.sf:jgmail</include>
          ??????????????? <include>commons-httpclient:commons-httpclient</include>
          ??????????????? <include>commons-logging:commons-logging</include>
          ??????????? </includes>
          ??????? </dependencySet>
          ???? </dependencySets>
          ? </assembly>????????
          ???? 在Assembly中出現的artifact,如commons-httpclient需要能在pom.xml中解析得到(只要commons- httpclient處于dependency中就可以),這樣我們就可以將IDEA的插件打包成zip文件,這樣就可以發布,現在你只要將登錄到
          http://plugins.intellij.net,然后上傳這個zip文件,你的發布就完成啦。???

        7. IntelliJ IDEA TestCase


          ??? 個人對TDD還是比較推崇的,所以在沒有進行開發前,還是先介紹一下如何進行測試。在com.intellij.testFramework包下包含各種 TestCase,你可以進行相關的單元測試。下面我們先看一下IDEA是如何運行TestCase的。IntelliJ IDEA在運行IDEA的TestCase時,會加載當前編輯的插件,這樣就會模擬出一個IDEA運行的真實環境,這樣你就可以進行各種測試。在實際的開發中,我們經常會PsiFile,VirtualFile等Java類,在plugin的內容組織方面,也主要是Action,Inspection 等,IDEA的test framework都提供了這些TestCase,很方便地測試這些類和組件。IdeaTestCase、LightIdeaTestCase、 PsiTestCase以及InspectionTestCase等都提供很便捷的方式來測試你編寫的代碼。當然IDEA還沒有提供非常全面的測試方案來測試任何代碼,這個可能對TestCase設計編寫要求會比較高,應該絕大多數情況下,你要自己覺得怎樣去編寫Unit Test。對于新的插件開發人員,個人建議還是TestCase加Debug合并使用,畢竟這方面的知識我們還是比較欠缺點。參考一下別人編寫的 TestCase可能會提升我們編寫TestCase的水平。如何使用IDEA test framework提供的TestCase,這個很簡單,只要繼承響應的TestCase,然后編寫代碼就可以啦,沒有任何特殊的要求。不要害怕,編寫幾個TestCase,你就有感覺啦。最后說一句,IDETalk插件的Unit Test寫的不錯,大家可以參考一下,而且IDETalk的作者Kirill Maximov也寫了不是關于IDEA下Unit Test的文章。

        8. 開發場景


          ?? 1 開發一個讀寫文件的Action:
          ????????? IDEA的設計思路是多線程讀單線程寫的模式,而且在AnAction中是不能進行寫操作的,如果你要在Action中進行寫操作,你需要創建一個 Runnable對象,然后交給 ApplicationManager.getApplication().runWriteAction(runnable)去執行。
          ?? 2 Editor Action:
          ????????? editor action主要用于操作當前編輯窗口中的內容,通常需要給editor action設置一個EditorWriteActionHandler來完成對editor的操作。EditorModificationUtil提供了不少方法,可以加快開發。如果向想獲取光標處的PsiElement對象,需要設置PsiFile的 getElementByOffset(offset)來獲取。如果你想進行相關的插入操作,你可能需要創建指定的PsiElement,這個時候 PsiElementFactory可能會幫你不少忙,你可以參考一下PsiElementFactory API,看是否有你需要的東西。
          ? 3 Intention Action:?
          ????????? intention action簡單地說就是意圖操作,IDEA會根據光標所在的位置,進行相關檢查,然后提示可以進行相關的操作。intention action需要繼承IntentionAction類,需要提供family name(ID標識)和description(顯示名稱)。在IntentionAction類中,isAvailable判斷當前Intention Action是否有效,invoke表示你選擇該intention action后執行的動作。PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); 這個語句用來獲取當前光標處的PsiElement。intention action還需要注意的一點,就是我們要在源碼根目錄建立一個intentionDescriptions的目錄,然后在依據family name建立一個子目錄,最后添加三個文件:description.html、before.xxx.templates和 after.xxx.template,xxx可以為某一種類型文件的擴展名。如下圖所示:

          最后,我們需要將這個action進行注冊,action通常要歸屬于某一類別。注冊有兩種方式:代碼和聲明。代碼為:IntentionManager.getInstance().registerIntentionAndMetaData(new FirstIntentionAction(), "category"); 聲明方式需要在plugin.xml中指定,代碼如下:
          ?????? <intentionAction>
          ????????? <className>com.foobar.FirstIntentionAction</className>
          ????????? <category>category</category>
          ?????? </intentionAction>
          ? 4? Inspection action創建
          ?????? inspection action就是代碼審查action,它可以檢查發現代碼潛在的錯誤。如果你留意一下右下角的偵探頭像,他就是代碼審查員,負責調用各種 inspection action,完成對代碼的審查。如果發現潛在的問題,就會給你一個解決方案,你可以選擇該方案進行問題修復。在IDEA設置面板中的“Errors”選項,其實就是inspection action的集合,目前IDEA 7.0大概包含800+個inspection action,審查代碼的各個方面,對代碼質量的提升有很大的幫助。
          ?????? 言歸正傳,如果編寫一個這樣的action。首先我們創建一個新的inspection action,它需要實現LocalInspectionTool類。Inspection action需要提供short name(ID標識),display name(顯示名)和group display name(所在的組名), 這樣inspection action可以更好地顯示。和Intention Action一樣,我們需要在源碼目錄下建立一個inspectionDescription的目錄,然后依據short name創建一個html文檔,將該inspection的功能進行描述。圖例如下:

          ??? LocalInspectionTool默認是檢查Java文件的,如果你想讓LocalInspectionTool審查其他文件,你需要重寫 LocalInspectionTool類的buildVisitor方法,來審查特定的類型的PsiElement,你可以參考一下 LocalInpsectionTool的源碼。前面我們講到inspection action會提供一個解決問題的方案,在IDEA中這叫QuickFix。當我們檢查到一個錯誤時,我們需要創建一個問題描述,如果有必要的話,需要創建一個quick fix來完成問題修復。注冊一個問題,通常提供這四個參數:可能存在錯誤的PsiElement、警告級別、描述和quickfix。這個可以通過 InspectionManager進行審查問題創建。
          ?? 目前,我們的Inspection Action已經完成啦,如何注冊inspection action? 和intention action的注冊一樣,有兩種方式:代碼和extension point。代碼方式:需要創建一個application component,然后繼承InspectionToolProvider,只要實現InspectionToolProvider的 getInspectionClasses()方法即可。 extension point:同intention action不一樣的是,我們要創建一個類,繼承InspectionToolProvider,這個類不必要繼承 ApplicationComponent,然后實現InspectionToolProvider的getInspectionClasses(),最后在plugin.xml文件中進行聲明,如下:
          ?? <inspectionToolProvider implementation="com.intellij.psi.css.CssInspectionsLoader"/>?
          從理論上來說,IDEA是將inspectionToolProvider最為一個application component對待。
          5. Annotator創建
          ???? annotator顧名思義標注,就是給相關的PsiElement加上標識,這個標識涉及到高亮顯示、裝訂欄(裝訂欄添加圖標標識)等等,annotator主要用于標識一些信息。編寫annotator,我們需要創建一個類,繼承Annotator,然后根據psiElement來判斷是否要給element添加標識,主要是和Annotation打交到。最后,我們需要在plugin.xml中進行annotator申明,如下:
          ???????? <annotator language="JAVA" annotatorClass="cn.org.intellij.webx.ScreenAnnotator"/>
          6. 設置組件屬性和狀態保存
          ???? 前面我們講過如何保存組件的狀態,在這里我們講述一下IDEA 7.0中的實現方法,可能有點不一樣。想要設置一個組件的狀態,你需要繼承Configurable,這樣在設置面板中就會出現一個選項,你可以進行相關的操作。接下來我們需要將設置的狀態保存起來,這是我們需要創建另外一個類,專門用于保存設置,我們可以稱之為Settings類,這個Settings 類需要PersistentStateComponent類,負責信息的保存和讀取。信息的讀取是通過一個@State的annotation來設置的。到這里,我們就可以理解啦,一個類用于接收參數設定,一個類用于參數保存和讀取,由于該類包含相關參數,所以它就是一個Service,通常將參數進行封裝,對外提供服務,代碼很簡單。接下來就是在plugin.xml中進行聲明,我們可以參考一下Ruby插件中的例子:
          ??? <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable"/>
          ??? <projectService serviceInterface="org.jetbrains.plugins.ruby.settings.RProjectSettings" serviceImplementation="org.jetbrains.plugins.ruby.settings.RProjectSettings"/>
          下面是@State的描述:
          ??? @State(
          ??? name = YourPluginConfiguration.COMPONENT_NAME,
          ??? storages = {@Storage(id = "your_id", file = "$PROJECT_FILE$")}
          ??? )
          ?? 在這個例子中我們使用了$PROJECT_FILE$宏,你可以根據組件的類型不同設置不同的宏,如下:
          ?? - application-level components (ApplicationComponent): $APP_CONFIG$, $OPTIONS$;
          ?? - project-level components (ProjectComponent): $PROJECT_FILE$, $WORKSPACE_FILE$, $PROJECT_CONFIG_DIR$;
          ?? - module-level components (ModuleComponent): $MODULE_FILE$
          7. gotoClassContributor
          ??? 在IDEA中,我們通常會按下Ctrl+N或Ctrl+All+Shift+N去尋找類或symbol,如果你想擴展各個功能,如在struts中,查找某一個action的聲明,這個時候我們需要擴展這一功能。這個時候我們只需創建一個類,讓其繼承ChooseByNameContributor,實現 ChooseByNameContributor的方法就可以。接下來就是在plugin.xml中進行聲明,可以參考Struts, Ruby的插件:
          ??????? <gotoSymbolContributor implementation="org.jetbrains.plugins.ruby.ruby.gotoByName.RubySymbolContributor"/>

        9. Virtual File, Document 和Psi File


          ???? 在IDEA中,我想對文本的操作可能就是這三個在發揮作用,這三者都可以對文件的內容進行更改。
          ???? Virtual File是IDEA的統一文件系統,就向Java的IO一樣,我們可以稱之為VFS(虛擬文件系統)。有了Virtual File,我們不在需要和傳統的文件打交到,取而代之的是VFS。我們對VFS的各種操作,會映射到傳統的文件系統上。IDEA中的所有和文件相關的操作都是通過Virtual File進行,這些操作和傳統的文件操作差不多,不過更加簡單。
          ???? Document其實就是Virtual File的內容的字符序列,所以對Document的各種操作都是基于普通文本的。Document的可操作的方法并不多,主要是Document是基于字符序列的,操作起來難度有點大。事實上我們對Document的使用也比較少,通常都是一些信息的簡單獲取。
          ???? Psi File這個是結構化的文件內容呈現,這樣我們通過操作結構化的對象,從而達到操作文件內容的目的。這些結構化的對象通常通過一種編程語言來體現,在 IDEA中,就是Java對象,這樣我們操作就更加簡單。這里我不知道這個例子是否合適,JDom是用Java對象來體現xml文檔,這里PsiFile 就是用Java語言來體現各種文件內容。講到這里可能大家還沒有體驗PsiFile的好處,我們舉一個例子來說明。現在有一個Java文件,那么我們就可以構建一個PsiJavaFile對象,通過該對象,我們可以了解該java文件的一些信息,如package 名稱,import語句列表,包含的class。假設我們獲取了PsiJavaFile的一個PsiClass對象,我們就可以了解該Java類的各種信息,如名稱、注釋和包含的函數等等。在這里我們可以更改PsiClass的名稱、注釋等等,這些修改馬上就會反映到文件的內容中。試想一下,如果這一切通過文本分析完成,那將是多么復雜的工作,有了Psi File,這一切就簡單啦,操作對象比操作文件內容要可靠簡單的多。關于PSI,請參考一些IntelliJ IDEA的插件開發文檔,同時我們推薦Psi Viewer這個插件,你可以對IDEA處理內容做更好地理解。如果你想寫出好的插件的話,你需要對PSI有較深的理解,雖然我寫的很少,但是它的重要性卻相當高。

        10. 數據關聯結構


          ?? 其實這節不知道如何寫?章節的名稱也怪怪的。我們都知道IDEA的代碼提示、代碼導航和代碼重構非常強大,這背后的是什么樣的數據結構來支撐這些特性。在 IDEA中,通過一種Reference機制可以將很多的事情關聯起來。回到上一節所說的,在IDEA中,我們對文件的內容操作,通常都是通過 PsiFile完成的。PsiFile中最小的元素就是PsiElement,由于PSI的設計合理,所以可以將PsiElement進行關聯,這樣可以實現很多的特性。舉一個例子來說吧。 <bean id="personManager" class="com.foobar.PersonManagerImpl"/>這是一個簡單xml元素,但是在這個云素中,我們知道class的屬性值(XmlAttributeValue, PsiElemnt的子類)是和Java Class類進行關聯的。如果我們將將XmlAttributeValue和PsiClass(Java類的Psi結構類型)關聯起來,那么我們就可以實現代碼提示,導航和重構(當類名更改會更新xml的屬性值),這個關聯的過程就是Reference的實現。我們通過特定的Reference將這兩者關聯進行實現,然后進行注冊聲明,那么我們這種關聯就建立起來,我們就會體會到其中的便捷。IDEA包含特定的索引結構,你可以想象一下,項目中文件的內容都存在著一定的關聯關系,最后形成一個很大的網來維護這些關聯。在IDEA啟動時,會花不少的時間來建立索引,來形成這些關聯關系,相信大家在打開項目都能體驗到這一點。如果建立這些關聯關系,有很多中實現方式,主要是PsiReference和ReferenceProvidersRegistry。 PsiReference顧名思義就是建立PsiElement直接的關聯,ReferenceProvidersRegistry則完成這些關聯的注冊和管理。關于這些方面的內容寫起來比較瑣碎,如果你實現了某一關聯,代碼提示、導航、重構等都能很好的工作,對你的工作效率提升有很大的幫助。
          ?? 前面介紹了基本原理,下面我們看一下如何實現常用的幾種關聯方式。我們前面講述了PsiReference,但是這里還有一個 PsiReferenceProvider要介紹一下,其實就是對PsiReference的一個封裝,因為 ReferenceProvidersRegistry進行注冊的時候,只接受PsiReferenceProvider。 PsiReferenceProvider很簡單,只需要將指定的PsiReference實例返回即可。 ReferenceProvidersRegistry的對象實例可以通過 ReferenceProvidersRegistry registry = ReferenceProvidersRegistry.getInstance(project); 接下來注冊的代碼可以在project component初始化的時候完成。下面讓我們進行幾個樣例吧:
          ?? 1. xml tag的屬性值和某一PsiElement進行關聯:這種情形很常見,如xmlTag的屬性值和java class關聯,xmlTag的屬性值和java class field關聯等等。如果實現這個關聯呢。首先我們要找到指定的屬性值,通常我們通過三個參數就可以確定: xml的namspace, tag名稱和屬性名,有了這三個值,我們就可以確定該屬性值,下面就是和某一reference provider關聯。代碼如下:
          ????? String[] attributeNames=...;
          ????? String tagName=...;
          ????? NamespaceFilter namespaceFilter=...;
          ????? PsiReferenceProvider referenceProvider=...;?
          ???? registry.registerXmlAttributeValueReferenceProvider(attributeNames, new ScopeFilter(new ParentElementFilter(new AndFilter(new ClassFilter(XmlTag.class), new AndFilter(new OrFilter(new TextFilter(tagName)), namespaceFilter)), 2)), referenceProvider);
          ???? 如果你說,這個xml沒有namespace,你可能需要根據改xml的特征寫一個filter,完成定位的需要。你可以將上述的namespaceFilter替換為你需要的filter即可。
          ?? 2. xml tag的文本值和某一PsiElement關聯: 由于IDEA并沒有提供類似 registerXmlAttributeValueReferenceProvider這樣的函數,這樣xml tag的文本值就沒法通過直接api的方式進行。IDEA提供了這樣的一個方式: registry.registerReferenceProvider(filter, XmlTag.class, psiReferenceProvider); 你只需要設定filter即可。另外你可以通過registry.registerXmlTagReferenceProvider()也可以進行注冊。
          ? 3. 字符串和某一PsiElement關聯:這種情形也很多,如context.getBean(""),和xml中的bean tag關聯,這里的字符串作為函數的參數,有了實際的意義,可能就會和某一個PsiElement關聯。這個關聯注冊很簡單, registry.registerReferenceProvider(filter, PsiLiteralExpression.class, psiReferenceProvider);? PsiLiteralExpression.class是文本的代表。這里要注意的是,一定要設置好filter,否則會很其他的代碼帶來問題。關于字符串和PsiElement關聯還要注意一點就是PsiReference的isSoft一定要設置為false,因為IDEA中字符串的默認提示是 property key,還有是classpath中的路徑,如果isSoft為false,那么其他的提示將不會出現。
          ?? 上面的三個是比較常見的。說到這里,因為是要建立關聯,必定涉及到更加字符串查找指定的PsiElement。在IDEA中我們可以通過 PsiManager,PsiShortNamesCache和PsiSearchHelper能完成不少的工作。如果還有問題的話,請參考 PsiElement和PsiRecursiveElementVisitor完成查找工作。

        11. 基于xml的框架插件開發指南


          ???? 這一章節可以說有實際的意義,畢竟xml在各種框架中的應用還是畢竟廣的(盡管annotation已經替代部分xml的功能)。IntelliJ IDEA提供一個文檔主要介紹在IntelliJ IDEA下如何通過DOM方式進行xml操作(http://www.jetbrains.com/idea/documentation/dom-rp.html),這個章節可以說作為中文說明和補充。我不想就細節和大家溝通,主要說的是一個步驟:
          ??? 1. 創建各種Dom Element及其直接關系,這個在IDEA DOM的文檔中有描述。這里我們說一下,根節點需要繼承CommonDomModelRootElement,普通節點需要繼承 CommonDomModelElement,最好給每一個Dom Element創建對應的實現類,主要是為了擴展。對于實現類,根節點需要實現RootBaseImpl,普通節點實現BaseImpl。
          ??? 2. 首先我們創建一個DOM File Descriptor,進行Dom File注冊,讓IDEA能在某一類型的xml和Dom直接進行映射。DomFileDescription提供一個isMyFile()方法,可以幫助我們確定xml文件是否是Dom要求的。接下來在plugin.xml中進行聲明: <dom.fileDescription implementation="org.intellij.ibatis.IbatisConfigurationFileDescription"/>
          ??? 3. 如果有必要的話,給Dom Element創建各種converter;
          ??? 4. 創建DomModel和DomModelFactory:xml文件是提供基礎信息的基石,如果我們想訪問xml文件中的信息,可以通過統一的接口去訪問,這個就是DomModel和DomModelFactory。DomModel負責和Dom Element之間交互,對外提供服務。而DomModelFactory則創建DomModel,DomModelFacotory能夠處理各種情況,準確構建DomModel;
          ??? 5. 這樣我們就完成XML的基本處理。在實際的開發我們可能要參考這些類: DomManager, DomElement, DomUtil, 這些類都在com.intellij.util.xml包下,建議看一下。
          ??? 6. 總的來說,DOM的操作要比之間操作XmlFile和XmlTag要簡單很多,如果你的插件中牽涉到xml操作,考慮一下IDEA DOM是非常有必要的。

        12. Custom Language Plugin


          ? 寫這節的目的有兩點:1. 開發中可能需要各種語言; 2. IntelliJ IDEA中支持語言注入,你編寫的這一功能可能被應用到各種地方,提升效率。由于Custom Language Plugin牽涉到很多的內容,如果你對這方面感興趣,可以先參考一下 http://www.jetbrains.com/idea/plugins/developing_custom_language_plugins.html,了解一下基本原理和自定義語言插件的功能。這里還要說一下就是關于JFlex,通常你需要了解這個工具,它是詞法分析器,和IDEA能結合的很好,同時 IDEA也提供了JFlex Plugin,你可以進行JFlex相關的試驗。關于這部分內容,在后續我還會更新,主要是想通過一個具體的例子來說明。

        13. 代碼提示相關


          ?? 如果你想在編輯窗口實現代碼提示,通常有三種方式: PsiReference,CompletionData和LookupManager,其中PsiReference,CompletionData是系統直接調用的,而LookupManager需要你手動觸發的。PsiReference前面已經介紹過,就是通過PsiElement之間相互關聯來進行的。CompletionData則是和某一種語言管理起來,在調用代碼提示時會觸發這段代碼,從而達到提示的目的。LookupManager就完全手動編碼方式,就是手動觸發一個代碼提示框,只不過LookupManager幫你做了很多,而不用關心很多的細節。

        14. Inspection Action和Intention Action編寫注意事項


          ?? 在進行Inspection講解之前,讓我看一下Inpsection的結構:


          在此結構中,我們可以看到一個Inspection需要一個Visitor去訪問某一起始點下的各個子PsiElement,在遍歷各個 PsiElement的過程中,當發現問題時注冊問題描述(ProblemDescription),如果該問題有對應的QuickFix,則將該問題描述和QuickFix關聯起來。Inspection的機制如下:
          ?? 1. Inspection Manager調用某一Inspection來審查某一PsiElement
          ?? 2. Inpsection會調用visitor去訪問該PsiElement的各個子PsiElement
          ?? 3. 在訪問各個子PsiElement時,如果發現了問題,這創建對應的問題描述,如果該問題包含對應的QuickFix,則進行關聯
          ?? 4. 當用戶調用quickfix時,觸發quickfix的執行
          在實際的編碼中,我們看一下BaseInspection的結構:

          通常一個Inspection只會關注一種問題,基于這個原則,所有錯誤提示應該是一樣的,所以BaseInspection需要你提供一個統一的問題描述。對應同一個問題的解決方法,當然可能有一種或多種,所以BaseInspection提供了buildFix和BuildFixes,你只需要實現一個即可。最后是Visitor的創建,BaseInspection引入了BaseInspectionVisitor,顧名思義就是專門為 inspection做的的visitor,包含了針對Inspecitond的常用方法。Visitor同時包含ProlemsHolder和 Inspection對象,這樣在發現問題的時候,馬上可以將問題和該inspection對應的解決方法關聯起來。這里還有一個 InspectionGadgetsFix,這個類沒有太多的解釋,主要目的就是去做一些判定,是否可以進行QuickFix操作等。通過這種結構調整,流程和代碼就簡單了很多,你創建Inspection就容易多啦。
          同樣的原理可用在Intention Action上,在Intention Action中,首先通過一個predicate來進行匹配判斷,如果匹配后又專門的處理邏輯進行操作,完成intention action。

        15. FAQ


          Q: 插件中的圖片大小有哪些要求?
          A: 在菜單欄中出現的圖片要是是16x16的png圖片;在設置面板中出現的圖片要求是48x48的png圖片。這些圖片通常都是要求透明的,如果你不知道怎么制作透明的png圖片的話,你可以通過ImageMagick提供的命令行行進行操作: >convert? -transparent white logo.png logo_1.png
          Q: 如何創建Live Template的自定義function?
          A: 在Open API里沒有涉及到這個方面,你需要參考一下Macro和MacroFactory,Macro是自定義函數的接口,MacroFactory完成注冊,你可以參考一下CapitalizeMacro的實現,在Web Service插件中也有例子。
          Q: 如何訪問剪切板?
          A:你可以通過CopyPasteManager進行訪問,下面是一個想剪切板添加內容的例子。
          CopyPasteManager copyPasteManager = CopyPasteManager.getInstance ();
          copyPasteManager.setContents (new StringSelection ("the character string which we would like to copy appointment"));

        16. 參考資源


          ? 這里我不想列出幾篇文檔,這些文檔只能起到掃盲的作用,如果你想開發插件,從掃盲版畢業是遠不夠的。個人的建議,多看別人的插件,多看論壇的帖子,多看API,多實踐。
          ? IntelliJ IDEA官方論壇: http://www.intellij.net/forums
          ? Jira for Open API:http://www.jetbrains.net/jira/secure/IssueNavigator.jspa?reset=true&mode=hide&pid=10132&component=10366
          ? 插件的源碼庫: http://svn.jetbrains.org/idea/Trunk
          ? 現在不少項目都在Google Code上安家啦,你可以去Google Code上搜索關于IDEA的插件,然后了解他人的想法和代碼,對自己的幫助會很大。

        17. posted @ 2008-10-17 17:00 ideame 閱讀(13023) | 評論 (0)編輯 收藏

          PowerCenter 安裝數據庫配置的問題

          安裝了幾次老是啟動有問題:
          The service did not start due to the following error: Unable to connect to the repository isaservice on database jamax.. Check the log for more information.
          node01 node01
          或者
          The service did not start due to the following error: DataBase error: [IBM][CLI Driver][LU62SPM] SQL30070N 不支持 "Unsupported function for SPMDB connect" 命令。 SQLSTATE=58014 sqlstate = 40003 Database driver error... Function Name : Execute SQL Stmt : VALUES CURRENT TIMESTAMP DB2 Fatal Error.. Check the log for more information.
          node01 node01

          日志:
          DOM_10079?Unable?to?start?service?[isaservice]?on?any?node?specified?for?the?service.
          DOM_10055?Unable?to?start?service?process?
          [isaservice]?on?node?[node01].
          SPC_10013?Process?for?service?isaservice?failed?to?start.

          原來懷疑是安裝的問題,后來才發現是因為元數據庫和源數據的連接錯誤地設置成同一個數據庫,造成元數據庫損壞造成的。出錯后試了幾種辦法都不行,只能重新再裝,原來的元數據就沒法用了,這是一個很嚴重的后果!正確的做法應該如下(本機):

          1. 設置元數據倉庫:



          Database URL 格式是HOST_NAME:PORT_NAME,如果用的是默認端口那么只需要填HOST_NAME就可以了。
          Database user ID: 填一個有管理員權限的用戶(sys好像不行,可以用system)
          Database service name: 填全局數據庫名, 對應下面的SERVICE_NAME

          file:tnsnames.ora

          INFORMAT?=
          ??(DESCRIPTION?
          =
          ????(ADDRESS?
          =?(PROTOCOL?=?TCP)(HOST?=?jamax)(PORT?=?1521))
          ????(CONNECT_DATA?
          =
          ??????(SERVER?
          =?DEDICATED)
          ??????(SERVICE_NAME?
          =?informatic.jamax)
          ????)
          ??)

          2. 新建源數據庫的知識庫(Repository )配置。



          這里2的數據庫配置應該是連接源數據庫的,如果設置為1的配置就會出錯。


          posted @ 2008-05-30 16:20 ideame 閱讀(3777) | 評論 (0)編輯 收藏

          DataSourceTransactionManager 的事務和JdbcTemplate的關系

          當使用了DataSourceTransactionManager后,使用同一個DataSource的JdbcTemplate也在事務中了嗎?
          還是使用了從這個dataSourceTransactionManager.getDataSource()的jdbcTemplate才在事務里?不明白。


          ???
          /**
          ?????*?在同一事務中執行,當拋出異常時會自動回滾事務,操作成功后自動提交事務
          ?????
          */
          ????
          public?int[]?batchExc(final?List?lists)?{
          ????????
          //這個txManager是DataSourceTransactionManager
          ????????TransactionTemplate?tt?=?new?TransactionTemplate(txManager);
          ????????
          return?(int[])?tt.execute(
          ????????????????
          new?TransactionCallback()?{
          ????????????????????
          public?Object?doInTransaction(TransactionStatus?status)?{
          ????????????????????????
          if?(!lists.isEmpty())?{
          ????????????????????????????log.info(
          "?===?開始事務?===?");
          ????????????????????????????String[]?sqls?
          =?new?String[lists.size()?-?1];
          ????????????????????????????
          for?(int?i?=?0;?i?<?lists.size();?i++)?{
          ????????????????????????????????sqls[i]?
          =?(String)?lists.get(i);
          ????????????????????????????????log.info(sqls[i]);
          ????????????????????????????}
          ????????????????????????????log.info(
          "?===?結束事務?===?");

          ????????????????????????????
          //這個jdbcTemplate不用設置DataSource就可以實現在事務中
          ????????????????????????????return?jdbcTemplate.getJdbcOperations().batchUpdate(sqls);

          ????????????????????????}?
          else?{
          ????????????????????????????
          return?new?int[0];
          ????????????????????????}
          ????????????????????}
          ????????????????});
          ????}


          繼續跟蹤。。。

          Powered by ScribeFire.

          posted @ 2007-11-29 18:02 ideame 閱讀(6141) | 評論 (0)編輯 收藏

          jre 1.6 的 webstart 自動安裝參考

          ?

          <? xml?version="1.0"?encoding="utf-8" ?>
          < jnlp? codebase ="http://javadl.sun.com/webapps/jawsautodl/AutoDL/j2se" >
          ??
          < information >
          ????
          < title > J2RE?1.6.0?Installer </ title >
          ????
          < vendor > Sun?Microsystems,?Inc. </ vendor >
          ??
          </ information >
          ??
          < security >
          ??????
          < all-permissions />
          ??
          </ security >
          ??
          < resources >
          ????
          < j2se? version ="1.3+" ?href ="http://java.sun.com/products/autodl/j2se" />
          ????
          < jar? href ="javaws-1_0_1-j2re-1_6_0-inst-windows-i586.jar" ?download ="lazy" ?size ="40719" />
          ????
          < jar? href ="javaws-1_0_1-j2re-1_6_0-data-windows-i586.jar" ?download ="lazy" ?size ="12263551" />
          ????
          < property? name ="javaVersion" ???????value ="1.6.0" />
          ????
          < property? name ="platformVersion" ???value ="1.6" />
          ????
          < property? name ="installerLocation" ?value ="javaws-1_0_1-j2re-1_6_0-data-windows-i586.jar" />
          ????
          < property? name ="installerEntry" ????value ="jre.dat" />
          ????
          < property? name ="licenseEntry" ?????????value ="LICENSE" />
          ????
          < property? name ="lib" ???????????????value ="j2re-installer" />
          ????
          < property? name ="msvcrt.versionMS" ??value ="60000" />
          ????
          < property? name ="msvcrt.versionLS" ??value ="20910000" />
          ????
          < property? name ="execString" ????????value ="{0}?{1}" />
          ????
          < property? name ="javaPath" ??????????value ="bin\javaw.exe" />
          ????
          < property? name ="verbose" ???????????value ="true" />
          ????
          < property? name ="hopper" ????????????value ="true" />
          ????
          < property? name ="isWindowsInstall" ??value ="true" />
          ????
          < nativelib? href ="javaws-1_0_1-j2re-1_6_0-native-windows-i586.jar" ?size ="13932" />
          ??
          </ resources >
          ??
          < installer-desc? main-class ="com.sun.webstart.installers.Main" />
          </ jnlp >



          Powered?by?ScribeFire.

          posted @ 2007-11-27 20:15 ideame 閱讀(920) | 評論 (0)編輯 收藏

          關于 PropertyPlaceholderConfigurer

          在Spring中,使用PropertyPlaceholderConfigurer可以在XML配置文件中加入外部屬性文件,例如:

          ????<bean?id="propertyConfigurer"
          ??????????class
          ="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          ????????
          <property?name="location"?value="classpath:config/jdoserver.properties"/>
          ????
          </bean>

          但是好像在屬性文件定義中卻不支持多個屬性文件的定義,比如不能這樣用config/*.properties。

          經過查看源碼,發現可以使用locations屬性定義多個配置文件:
          <property?name="locations">
          ????????????
          <list>
          ????????????????
          <value>classpath:config/maxid.properties</value>
          ????????????????
          <value>classpath:config/jdoserver.properties</value>
          ????????????
          </list>
          </property>

          使用外部屬性后如下:

          ????<bean?id="dataSource"?class="org.springframework.jdbc.datasource.DriverManagerDataSource">
          ????????
          <property?name="driverClassName"?value="${jdbc.agent.driver}"/>
          ????????
          <property?name="url"?value="${jdbc.agent.main.url}"/>
          ????
          </bean>

          上面的例子是采用Spring DriverManagerDataSource包裝VJDBC Connection的用法,沒有提供連接池功能,只能作作簡單的單機連接。

          posted @ 2007-11-27 18:19 ideame 閱讀(1118) | 評論 (0)編輯 收藏

          僅列出標題
          共4頁: 上一頁 1 2 3 4 下一頁 
          主站蜘蛛池模板: 蕉岭县| 东平县| 正镶白旗| 贵溪市| 化德县| 文登市| 泸水县| 库车县| 潮州市| 屏山县| 东丰县| 泰州市| 濮阳市| 庆云县| 闽侯县| 泰来县| 河津市| 保山市| 兴安县| 沂水县| 微博| 九寨沟县| 伊川县| 河北省| 鹤山市| 庆云县| 延安市| 武邑县| 延津县| 团风县| 山西省| 金堂县| 托克托县| 巴东县| 关岭| 嘉荫县| 辽源市| 浦江县| 阳原县| 垣曲县| 宽甸|