|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
public interface Context
此介面表示一個命名上下文,它由一組名稱到物件的綁定組成。它包含檢查和更新這些綁定的一些方法。
大多數方法具有重載形式,一種帶有 Name
參數,另一種帶有 String
參數。這些重載的方法是等效的:如果 Name
和 String
參數只是相同名稱的不同表示形式,則相同方法的重載形式的行為也相同。在以下方法描述中,僅完整記錄一種形式。第二種形式將連接到第一種:對兩者應用相同的文檔。
對於支持聯合的系統,Context 方法的 String 名稱參數是復合名稱。是 CompositeName 實例的那些名稱參數被視為復合名稱,而不是 CompositeName 實例的 Name 參數被視為組合名稱(可能是 CompoundName 實例或組合名稱的其他實作)。這允許將 NameParser.parse() 的結果用作 Context 方法的參數。在 JNDI 1.2 之前,所有名稱參數都被視為復合名稱。
此外,對於支持聯合的系統,NamingEnumeration 中所有從 list() 和 listBindings() 返回的名稱都是表示為字元串的復合名稱。有關名稱的字元串語法,請參見 CompositeName。
對於不支持聯合的系統,名稱參數(Name 或 String 形式)和 NamingEnumeration 中返回的名稱可能是其自己的名稱空間中的名稱,而不是復合名稱空間中的名稱,這由服務提供者決定。
lookup
方法傳遞空名稱將返回一個表示相同命名上下文的新 Context 實例。
為了實作共時控制,返回 NamingEnumeration 的 Context 操作在列舉仍在使用中或者仍在遵從該操作產生的所有參考時被認為尚未完成。
JNDI 應用程序需要一種方式來傳達定義存取命名服務和目錄服務的環境的各種首選項和屬性。例如,為了存取服務,某個上下文可能需要安全證書的規約。另一個上下文可能要求提供伺服器的配置資訊。這些被稱為某一上下文的環境。Context 介面提供一些檢索和更新此環境的方法。
該環境在上下文方法從一個上下文到下一個上下文時從父上下文中繼承。對某一上下文環境的更改不會直接影響其他上下文的環境。
當將環境屬性用於有效性和/或驗證有效性時,這些屬性與實作有關。例如,一些與安全有關的屬性被服務提供者用於“登錄”目錄。此登錄過程可能發生在創建上下文時,或者發生在第一次對該上下文調用方法時。無論這在何時或是否發生,此環境屬性都與實作有關。在將環境屬性添加到上下文中或從上下文中移除時,驗證這些更改的有效性也都與實作有關。例如,驗證某些屬性可能發生在進行更改時,或者發生在對上下文執行下一個操作時,抑或根本不驗證。
擁有對某一上下文的參考的任何對象都可以檢查該上下文的環境。敏感資訊(比如明文密碼)不應該存儲在該環境中,除非已知實作能保護這類別資訊。
要簡化設置 JNDI 應用程序所需環境的任務,可以將資源檔案 與應用程序元件和服務提供者一起發佈。JNDI 資源檔案是使用屬性檔案格式的檔案(參見 java.util.Properties
),包括一個鍵/值對列表。鍵是屬性的名稱(例如 "java.naming.factory.object"),而值是使用為該屬性定義的格式的字元串。以下是 JNDI 資源檔案的一個範例:
JNDI 類別資源庫讀取資源檔案,並使屬性值隨意可用。因此應該認為 JNDI 資源檔案是“所有人可讀的”,敏感資訊(比如明文密碼)不應該存儲在那裡。java.naming.factory.object=com.sun.jndi.ldap.AttrsToCorba:com.wiz.from.Person java.naming.factory.state=com.sun.jndi.ldap.CorbaToAttrs:com.wiz.from.Person java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory
有兩種 JNDI 資源檔案:提供者 和應用程序。
[prefix/]jndiprovider.properties其中 prefix 是提供者的上下文實作的套件名稱,其每個句點 (".") 都被轉換成一個斜槓 ("/")。 例如,假設服務提供者定義了一個帶有類別名稱 com.sun.jndi.ldap.LdapCtx 的上下文實作。此提供者的提供者資源被命名為 com/sun/jndi/ldap/jndiprovider.properties。如果該類別不在一個套件中,則資源的名稱就是 jndiprovider.properties。
JNDI 類別資源庫中的某些方法使用指定 JNDI 處理器列表的標準 JNDI 屬性:
ClassLoader.getResources()
)類別路徑中所有名為 jndi.properties 的應用程序資源檔案。此外,如果檔案 java.home/lib/jndi.properties 存在並且是可讀的,則 JNDI 會將其視為一個額外的應用程序資源檔案。(java.home 指示由 java.home 系統屬性命名的目錄。)包含在這些檔案中的所有屬性都被放置在初始上下文環境中。然後此環境由其他上下文繼承。
對於同時出現在多個應用程序資源檔案中的每個屬性,JNDI 使用最先找到的值,或者在少數有意義的情況下串聯所有這些值(細節在下文給出)。例如,如果在三個 jndi.properties 資源檔案中存在 "java.naming.factory.object" 屬性,則物件處理器列表是所有三個檔案中的屬性值的串聯。使用此方案,每個可部署元件都要負責列出它導出的處理器。JNDI 在搜尋處理器類別時自動收集和使用所有這些導出列表。
從 Java 2 Platform 開始可使用應用程序資源檔案,java.home/lib 中的檔案除外,它在較早的 Java 平臺上也可以使用。
如果 JNDI 類別資源庫需要確定某一屬性的值,它將通過按順序合併取自以下兩個源的值來實作這一點:
當服務提供者需要確定某一屬性的值時,它通常將直接從環境中獲取該值。服務提供者可以定義將置於其本身提供者資源檔案中的特定於提供者的屬性。在這種情況下,它應該根據上文所述合併這些值。
這樣,每個服務提供者開發人員便可以指定與該服務提供者一起使用的處理器列表。這可以由應用程序或 applet 的部署者指定的應用程序資源修改,而這些資源又可以由使用者修改。
欄位摘要 | |
---|---|
static String |
APPLET
該常數保存用來指定搜尋其他屬性時將使用的初始上下文建構子的 applet 的環境屬性名稱。 |
static String |
AUTHORITATIVE
該常數保存用來指定所請求服務的權威性的環境屬性名稱。 |
static String |
BATCHSIZE
該常數保存用來指定通過服務協議返回資料時要使用的批處理量 (batch size) 的環境屬性名稱。 |
static String |
DNS_URL
該常數保存用來指定用於 JNDI URL 上下文的 DNS 主機名和域名(例如 "dns://somehost/wiz.com")的環境屬性名稱。 |
static String |
INITIAL_CONTEXT_FACTORY
該常數保存用來指定要使用的初始上下文處理器的環境屬性名稱。 |
static String |
LANGUAGE
該常數保存用來指定用於服務的首選語言的環境屬性名稱。 |
static String |
OBJECT_FACTORIES
該常數保存用來指定要使用的物件處理器列表的環境屬性名稱。 |
static String |
PROVIDER_URL
該常數保存用來指定要使用的服務提供者配置資訊的環境屬性名稱。 |
static String |
REFERRAL
該常數保存用來指定將如何處理服務提供者遇到的參考的環境屬性名稱。 |
static String |
SECURITY_AUTHENTICATION
該常數保存用來指定將使用的安全級別的環境屬性名稱。 |
static String |
SECURITY_CREDENTIALS
該常數保存用來指定用於驗證服務調用者主體證書的環境屬性名稱。 |
static String |
SECURITY_PRINCIPAL
該常數保存用來指定用於驗證服務調用者主體身份的環境屬性名稱。 |
static String |
SECURITY_PROTOCOL
該常數保存用來指定將使用的安全協議的環境屬性名稱。 |
static String |
STATE_FACTORIES
該常數保存用來指定要使用的狀態處理器列表的環境屬性名稱。 |
static String |
URL_PKG_PREFIXES
該常數保存用來指定載入 URL 上下文處理器時要使用的套件前綴列表的環境屬性名稱。 |
方法摘要 | |
---|---|
Object |
addToEnvironment(String propName,
Object propVal)
將一個新環境屬性添加到此上下文的環境中。 |
void |
bind(Name name,
Object obj)
將名稱綁定到物件。 |
void |
bind(String name,
Object obj)
將名稱綁定到物件。 |
void |
close()
關閉此上下文。 |
Name |
composeName(Name name,
Name prefix)
將此上下文的名稱與相對於此上下文的名稱組合。 |
String |
composeName(String name,
String prefix)
將此上下文的名稱與相對於此上下文的名稱組合。 |
Context |
createSubcontext(Name name)
創建並綁定一個新上下文。 |
Context |
createSubcontext(String name)
創建並綁定一個新上下文。 |
void |
destroySubcontext(Name name)
銷毀指定上下文,並將它從名稱空間中移除。 |
void |
destroySubcontext(String name)
銷毀指定上下文,並將它從名稱空間中移除。 |
Hashtable<?,?> |
getEnvironment()
檢索對此上下文有效的環境。 |
String |
getNameInNamespace()
在此上下文自己的名稱空間中檢索其完全名稱。 |
NameParser |
getNameParser(Name name)
檢索與指定上下文關聯的解析器。 |
NameParser |
getNameParser(String name)
檢索與指定上下文關聯的解析器。 |
NamingEnumeration<NameClassPair> |
list(Name name)
列舉綁定在指定上下文中的名稱,以及綁定到這些名稱的物件的類別名稱。 |
NamingEnumeration<NameClassPair> |
list(String name)
列舉綁定在指定上下文中的名稱,以及綁定到這些名稱的物件的類別名稱。 |
NamingEnumeration<Binding> |
listBindings(Name name)
列舉綁定在指定上下文中的名稱,以及綁定到這些名稱的物件。 |
NamingEnumeration<Binding> |
listBindings(String name)
列舉綁定在指定上下文中的名稱,以及綁定到這些名稱的物件。 |
Object |
lookup(Name name)
檢索指定的物件。 |
Object |
lookup(String name)
檢索指定的物件。 |
Object |
lookupLink(Name name)
按照除名稱的最終原子元件以外的連接檢索指定物件。 |
Object |
lookupLink(String name)
按照除名稱的最終原子元件以外的連接檢索指定物件。 |
void |
rebind(Name name,
Object obj)
將名稱綁定到物件,覆寫任何現有綁定。 |
void |
rebind(String name,
Object obj)
將名稱綁定到物件,覆寫所有現有綁定。 |
Object |
removeFromEnvironment(String propName)
從此上下文的環境中移除一個環境屬性。 |
void |
rename(Name oldName,
Name newName)
將一個新名稱綁定到已經被綁定到某一舊名稱的物件上,並取消對舊名稱的綁定。 |
void |
rename(String oldName,
String newName)
將一個新名稱綁定到已經被綁定到某一舊名稱的物件上,並取消對舊名稱的綁定。 |
void |
unbind(Name name)
取消對指定物件的綁定。 |
void |
unbind(String name)
取消對指定物件的綁定。 |
欄位詳細資訊 |
---|
static final String INITIAL_CONTEXT_FACTORY
此常數的值是 "java.naming.factory.initial"。
InitialContext
,
InitialDirContext
,
NamingManager.getInitialContext(java.util.Hashtable, ?>)
,
InitialContextFactory
,
NoInitialContextException
,
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
APPLET
,
常數欄位值static final String OBJECT_FACTORIES
此常數的值是 "java.naming.factory.object"。
NamingManager.getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable, ?>)
,
ObjectFactory
,
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
APPLET
,
常數欄位值static final String STATE_FACTORIES
此常數的值是 "java.naming.factory.state"。
NamingManager.getStateToBind(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable, ?>)
,
StateFactory
,
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
APPLET
,
常數欄位值static final String URL_PKG_PREFIXES
此常數的值是 "java.naming.factory.url.pkgs"。
NamingManager.getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable, ?>)
,
NamingManager.getURLContext(java.lang.String, java.util.Hashtable, ?>)
,
ObjectFactory
,
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
APPLET
,
常數欄位值static final String PROVIDER_URL
此常數的值是 "java.naming.provider.url"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
APPLET
,
常數欄位值static final String DNS_URL
此常數的值是 "java.naming.dns.url"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String AUTHORITATIVE
此常數的值是 "java.naming.authoritative"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String BATCHSIZE
此常數的值是 "java.naming.batchsize"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String REFERRAL
此常數的值是 "java.naming.referral"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String SECURITY_PROTOCOL
此常數的值是 "java.naming.security.protocol"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String SECURITY_AUTHENTICATION
此常數的值是 "java.naming.security.authentication"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String SECURITY_PRINCIPAL
此常數的值是 "java.naming.security.principal"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String SECURITY_CREDENTIALS
此常數的值是 "java.naming.security.credentials"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String LANGUAGE
此常數的值是 "java.naming.language"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
常數欄位值static final String APPLET
此常數的值是 "java.naming.applet"。
addToEnvironment(String, Object)
,
removeFromEnvironment(String)
,
InitialContext
,
常數欄位值方法詳細資訊 |
---|
Object lookup(Name name) throws NamingException
name
- 要查詢的物件的名稱
NamingException
- 如果遇到命名異常lookup(String)
,
lookupLink(Name)
Object lookup(String name) throws NamingException
lookup(Name)
。
name
- 要查詢的物件的名稱
NamingException
- 如果遇到命名異常void bind(Name name, Object obj) throws NamingException
name
- 要綁定的名稱,不可以為空obj
- 要綁定的物件,可能為 null
NameAlreadyBoundException
- 如果已經綁定了 name
InvalidAttributesException
- 如果物件不支持所有強制屬性
NamingException
- 如果遇到命名異常bind(String, Object)
,
rebind(Name, Object)
,
DirContext.bind(Name, Object, javax.naming.directory.Attributes)
void bind(String name, Object obj) throws NamingException
bind(Name, Object)
。
name
- 要綁定的名稱,不可以為空obj
- 要綁定的物件,可能為 null
NameAlreadyBoundException
- 如果已經綁定了 name
InvalidAttributesException
- 如果物件不支持所有強制屬性
NamingException
- 如果遇到命名異常void rebind(Name name, Object obj) throws NamingException
如果該物件是一個 DirContext,則使用該物件的屬性替換與該名稱關聯的所有現有屬性。否則,與該名稱關聯的所有現有屬性保持不變。
name
- 要綁定的名稱,不可以為空obj
- 要綁定的物件,可能為 null
InvalidAttributesException
- 如果物件不支持所有強制屬性
NamingException
- 如果遇到命名異常rebind(String, Object)
,
bind(Name, Object)
,
DirContext.rebind(Name, Object, javax.naming.directory.Attributes)
,
DirContext
void rebind(String name, Object obj) throws NamingException
rebind(Name, Object)
。
name
- 要綁定的名稱,不可以為空obj
- 要綁定的物件,可能為 null
InvalidAttributesException
- 如果物件不支持所有強制屬性
NamingException
- 如果遇到命名異常void unbind(Name name) throws NamingException
name
的最終原子名稱,目標上下文由 name
的最終原子部分以外的所有名稱指定。
此方法是冪等的 (idempotent)。即使最終原子名稱沒有綁定在目標上下文中,該操作也能成功,但如果不存在任何中間上下文,則將拋出 NameNotFoundException。
所有與該名稱關聯的屬性都被移除。不更改中間上下文。
name
- 要取消綁定的名稱,不能為空
NameNotFoundException
- 如果不存在中間上下文
NamingException
- 如果遇到命名異常unbind(String)
void unbind(String name) throws NamingException
unbind(Name)
。
name
- 要取消綁定的名稱,不能為空
NameNotFoundException
- 如果不存在中間上下文
NamingException
- 如果遇到命名異常void rename(Name oldName, Name newName) throws NamingException
oldName
- 現有綁定的名稱,不能為空newName
- 新綁定的名稱,不能為空
NameAlreadyBoundException
- 如果已經綁定了 newName
NamingException
- 如果遇到命名異常rename(String, String)
,
bind(Name, Object)
,
rebind(Name, Object)
void rename(String oldName, String newName) throws NamingException
rename(Name, Name)
。
oldName
- 現有綁定的名稱,不能為空newName
- 新綁定的名稱,不能為空
NameAlreadyBoundException
- 如果已經綁定了 newName
NamingException
- 如果遇到命名異常NamingEnumeration<NameClassPair> list(Name name) throws NamingException
如果將某一綁定添加到此上下文,或者從此上下文中移除某個綁定,則對以前返回的列舉的影響是不確定的。
name
- 要列出的上下文的名稱
NamingException
- 如果遇到命名異常list(String)
,
listBindings(Name)
,
NameClassPair
NamingEnumeration<NameClassPair> list(String name) throws NamingException
list(Name)
。
name
- 要列出的上下文的名稱
NamingException
- 如果遇到命名異常NamingEnumeration<Binding> listBindings(Name name) throws NamingException
如果將某一綁定添加到此上下文,或者從此上下文中移除某個綁定,則對以前返回的列舉的影響是不確定的。
name
- 要列出的上下文的名稱
NamingException
- 如果遇到命名異常listBindings(String)
,
list(Name)
,
Binding
NamingEnumeration<Binding> listBindings(String name) throws NamingException
listBindings(Name)
。
name
- 要列出的上下文的名稱
NamingException
- 如果遇到命名異常void destroySubcontext(Name name) throws NamingException
此方法是冪等的。即使最終原子名稱沒有綁定在目標上下文中,該操作也能成功,但如果不存在任何中間上下文,則將拋出 NameNotFoundException。
在聯合命名系統中,取自某一命名系統的上下文可以綁定到另一個命名系統中的名稱上。隨後可以使用復合名稱在外部上下文 (foreign context) 中查詢和執行操作。不過,試圖使用此復合名稱銷毀上下文將失敗並拋出 NotContextException,因為外部上下文不是綁定該復合名稱的上下文的子上下文。改為使用 unbind() 移除外部上下文的綁定。銷毀外部上下文需要對取自該外部上下文的“本機”命名系統的上下文執行 destroySubcontext()。
name
- 要銷毀的上下文的名稱,不能為空
NameNotFoundException
- 如果不存在中間上下文
NotContextException
- 如果該名稱被綁定,但它沒有指定一個上下文,或者它沒有指定適當型別的上下文
ContextNotEmptyException
- 如果指定的上下文不為空
NamingException
- 如果遇到命名異常destroySubcontext(String)
void destroySubcontext(String name) throws NamingException
destroySubcontext(Name)
。
name
- 要銷毀的上下文的名稱,不能為空
NameNotFoundException
- 如果不存在中間上下文
NotContextException
- 如果該名稱被綁定,但它沒有指定一個上下文,或者它沒有指定適當型別的上下文
ContextNotEmptyException
- 如果指定的上下文不為空
NamingException
- 如果遇到命名異常Context createSubcontext(Name name) throws NamingException
name
- 要創建的上下文的名稱,不能為空
NameAlreadyBoundException
- 如果已經綁定了 name
InvalidAttributesException
- 如果創建子上下文需要指定強制屬性
NamingException
- 如果遇到命名異常createSubcontext(String)
,
DirContext.createSubcontext(javax.naming.Name, javax.naming.directory.Attributes)
Context createSubcontext(String name) throws NamingException
createSubcontext(Name)
。
name
- 要創建的上下文的名稱,不能為空
NameAlreadyBoundException
- 如果已經綁定了 name
InvalidAttributesException
- 如果創建子上下文需要指定強制屬性
NamingException
- 如果遇到命名異常Object lookupLink(Name name) throws NamingException
name
- 要查詢的物件的名稱
NamingException
- 如果遇到命名異常lookupLink(String)
Object lookupLink(String name) throws NamingException
lookupLink(Name)
。
name
- 要查詢的物件的名稱
NamingException
- 如果遇到命名異常NameParser getNameParser(Name name) throws NamingException
name
- 從中獲得解析器的上下文的名稱
NamingException
- 如果遇到命名異常getNameParser(String)
,
CompoundName
NameParser getNameParser(String name) throws NamingException
getNameParser(Name)
。
name
- 從中獲得解析器的上下文的名稱
NamingException
- 如果遇到命名異常Name composeName(Name name, Name prefix) throws NamingException
name
)以及此上下文相對於其一個祖先的名稱(prefix
)的情況下,此方法使用適合所涉及命名系統的語法返回這兩個名稱的組合。也就是說,如果 name
指定一個相對於此上下文的物件,則結果是同一個物件的名稱,但該名稱相對於祖先上下文。所有名稱都不能為 null。
例如,如果此上下文被命名為 "wiz.com",該名稱相對於初始上下文,則
composeName("east", "wiz.com")可能返回
"east.wiz.com"
。如果將此上下文命名為 "org/research",則
composeName("user/jane", "org/research")可能返回
"org/research/user/jane"
,而
composeName("user/jane", "research")返回
"research/user/jane"
。
name
- 相對於此上下文的名稱prefix
- 此上下文相對於其一個祖先的名稱
prefix
和 name
的組合
NamingException
- 如果遇到命名異常composeName(String, String)
String composeName(String name, String prefix) throws NamingException
composeName(Name, Name)
。
name
- 相對於此上下文的名稱prefix
- 此上下文相對於其一個祖先的名稱
prefix
和 name
的組合
NamingException
- 如果遇到命名異常Object addToEnvironment(String propName, Object propVal) throws NamingException
propName
- 要添加的環境屬性的名稱,不能為 nullpropVal
- 要添加的屬性的值,不能為 null
NamingException
- 如果遇到命名異常getEnvironment()
,
removeFromEnvironment(String)
Object removeFromEnvironment(String propName) throws NamingException
propName
- 要移除的環境屬性的名稱,不能為 null
NamingException
- 如果遇到命名異常getEnvironment()
,
addToEnvironment(String, Object)
Hashtable<?,?> getEnvironment() throws NamingException
調用者不應對返回的物件進行任何更改:因為這些更改對於上下文的影響是不確定的。可以使用 addToEnvironment() 和 removeFromEnvironment() 更改此上下文的環境。
NamingException
- 如果遇到命名異常addToEnvironment(String, Object)
,
removeFromEnvironment(String)
void close() throws NamingException
此方法是冪等的:對已經關閉的上下文調用此方法無效。對已關閉的上下文調用其他任何方法都是不允許的,這會導致不確定的行為。
NamingException
- 如果遇到命名異常String getNameInNamespace() throws NamingException
許多命名服務都有一個“完全名稱”的概念,用於其各自的名稱空間中的物件。例如,LDAP 項有一個獨特的名稱,而 DNS 記錄有一個完全限定名。此方法允許客戶端應用程序檢索此名稱。此方法返回的字元串不是一個 JNDI 復合名稱,不應將它直接傳遞給上下文方法。在沒有完全名稱概念的命名系統中,將拋出 OperationNotSupportedException。
OperationNotSupportedException
- 如果命名系統沒有完全名稱的概念
NamingException
- 如果遇到命名異常
|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only。