- java.lang.Object
-
- java.security.AccessController
-
public final class AccessController extends Object
AccessControllerクラスは、アクセス制御の操作と決定に使用されます。
具体的には、AccessControllerクラスを次の3つの目的で使用します。
- 現在有効なセキュリティ・ポリシーに基づいて、重要なシステム・リソースへのアクセスが許可されるか、拒否されるかを決定する。
- コードを「特権」が与えられたものとしてマークし、以降のアクセスの決定に影響を与える。
- アクセス制御が保存したコンテキストに関して用意される別のコンテキストから決定できるように、現在の呼出し側コンテキストの「スナップショット」を取得する。
checkPermission
メソッドは、指定されたアクセス権によって示されるアクセス要求が許可されるか、拒否されるかを決定します。 呼出しの例を次に示します。 この例では、checkPermission
は、/tempディレクトリのtestFileというファイルへの読込み権を許可するかどうかを決定します。FilePermission perm = new FilePermission("/temp/testFile", "read"); AccessController.checkPermission(perm);
要求されたアクセス権が許可される場合、
checkPermission
は何もしないで復帰します。 アクセスが拒否される場合には、AccessControlExceptionがスローされます。 AccessControlExceptionは、要求されたアクセス権が不正な型であったり、無効な値を含んでいたりした場合にもスローされる可能性があります。 可能な場合には、そうした情報が提供されます。 現在のスレッドが呼出し元1、呼出し元2、呼出し元mの順でm個の呼出し元をトラバースしたとします。 次に、呼出し元mはcheckPermission
メソッドを呼び出しました。 このとき、checkPermission
メソッドは次のアルゴリズムに基づいて、アクセスが許可されるか拒否されるかを決定します。for (int i = m; i > 0; i--) { if (caller i's domain does not have the permission) throw AccessControlException else if (caller i is marked as privileged) { if (a context was specified in the call to doPrivileged) context.checkPermission(permission) if (limited permissions were specified in the call to doPrivileged) { for (each limited permission) { if (the limited permission implies the requested permission) return; } } else return; } } // Next, check the context inherited when the thread was created. // Whenever a new thread is created, the AccessControlContext at // that time is stored and associated with the new thread, as the // "inherited" context. inheritedContext.checkPermission(permission);
呼出し側は、特権コードとしてマークできます(
doPrivileged
および次の説明を参照)。 アクセス制御を決定する場合、checkPermission
メソッドは、コンテキスト引数のないdoPrivileged
の呼出しによって特権コードとしてマークされた呼出し側に届いたときに、検査を中止します(コンテキスト引数については、次の説明を参照)。 その呼出し元のドメインが指定されたアクセス権を持っていて、少なくとも1つのアクセス権制限引数(あれば)に要求されたアクセス権が含まれている場合、checkPermission
はそれ以上のチェックを行わずに正常復帰し、要求されたアクセスが許可されていることを示します。 そのドメインが指定されたアクセス権を持たない場合は、通常は例外が発行されます。 呼出し元のドメインが指定されたアクセス権を持っているが、doPrivileged
の呼出し時に指定されたアクセス権制限引数にそれが含まれていない場合は、呼出し元が存在しなくなるか、別のdoPrivileged
呼出しが要求されたアクセス権と一致して正常に復帰するまで、アクセス権のチェックが続行されます。次に、特権機能の通常の使い方を説明します。 「特権付き」ブロックからの戻り値が必要ない場合は、次のようにします。
somemethod() { ...normal code here... AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { // privileged code goes here, for example: System.loadLibrary("awt"); return null; // nothing to return } }); ...normal code here... }
PrivilegedActionは、
run
という名前の単一のメソッドを持つインタフェースです。 上記の例は、そのインタフェースの実装の作成方法を示しています。つまり、run
メソッドの具象実装が提供されます。doPrivileged
への呼出し時に、PrivilegedActionの実装のインスタンスが渡されます。doPrivileged
メソッドは、特権を有効にしたあとで、PrivilegedActionの実装からrun
メソッドを呼び出し、run
メソッドの戻り値をdoPrivileged
の戻り値として返します。上の例では戻り値は無視されています。次に、値を返す必要がある場合の例を示します。
somemethod() { ...normal code here... String user = AccessController.doPrivileged( new PrivilegedAction<String>() { public String run() { return System.getProperty("user.name"); } }); ...normal code here... }
run
メソッドで実行したアクションが「チェック」例外(メソッドのthrows
節に表示されている例外)をスローする可能性がある場合には、PrivilegedAction
インタフェースの代わりにPrivilegedExceptionAction
インタフェースを使用する必要があります。somemethod() throws FileNotFoundException { ...normal code here... try { FileInputStream fis = AccessController.doPrivileged( new PrivilegedExceptionAction<FileInputStream>() { public FileInputStream run() throws FileNotFoundException { return new FileInputStream("someFile"); } }); } catch (PrivilegedActionException e) { // e.getException() should be an instance of FileNotFoundException, // as only "checked" exceptions will be "wrapped" in a // PrivilegedActionException. throw (FileNotFoundException) e.getException(); } ...normal code here... }
特権構造の使用には細心の注意を払って、特権コード・セクションをできるだけ小さくしてください。
Permission
引数を渡して「特権」のスコープをさらに制限できます(次を参照)。checkPermission
は、常に現在実行しているスレッドのコンテキスト内でセキュリティ・チェックを行います。 しかし実際には、指定されたコンテキスト内で行うセキュリティ・チェックを、別のコンテキスト内から(たとえば、ワーカー・スレッド内から)行わなければならない場合もあります。 この状況に対応するために、getContext
メソッドとAccessControlContextクラスが提供されています。getContext
メソッドは、現在の呼出しコンテキストをAccessControlContextオブジェクトに格納して返します。 呼出しの例を次に示します。AccessControlContext acc = AccessController.getContext()
AccessControlContext自体が
checkPermission
メソッドを持っており、このメソッドを使って、現在の実行スレッドのコンテキストではなくカプセル化しているコンテキストに基づいてアクセスの判断を行います。 したがって、別のコンテキスト内のコードは、以前に保存したAccessControlContextオブジェクトを呼び出すことができます。 呼出しの例を次に示します。acc.checkPermission(permission)
また、コンテキストをどのアクセス権で検査するかが、事前には不明な場合があります。 これらのケースでは、コンテキストを取るdoPrivilegedメソッドを使用できます。 追加の
Permission
パラメータを渡すことによって、特権コードのスコープを制限することもできます。somemethod() { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { // Code goes here. Any permission checks within this // run method will require that the intersection of the // caller's protection domain and the snapshot's // context have the desired permission. If a requested // permission is not implied by the limiting FilePermission // argument then checking of the thread continues beyond the // caller of doPrivileged. } }, acc, new FilePermission("/temp/*", read)); ...normal code here... }
AllPermission
のインスタンスのPermission
制限引数を渡すことは、Permission
制限引数なしで同等のdoPrivileged
を呼び出すことと同じです。 長さゼロのPermission
の配列を渡すと、コードの特権が無効になるため、そのdoPrivileged
メソッドの呼出し元を超えて常にチェックが続行されます。- 導入されたバージョン:
- 1.2
- 関連項目:
AccessControlContext
-
-
メソッドのサマリー
修飾子と型 メソッド 説明 static void
checkPermission(Permission perm)
現在のAccessControlContextとセキュリティ・ポリシーに基づいて、指定されたアクセス権によって示されるアクセス要求が許可されるか拒否されるかを決定します。static <T> T
doPrivileged(PrivilegedAction<T> action)
有効になった特権を使って、指定されたPrivilegedAction
を実行します。static <T> T
doPrivileged(PrivilegedAction<T> action, AccessControlContext context)
指定されたAccessControlContext
によって有効になり、かつ制限される特権を使って、指定されたPrivilegedAction
を実行します。static <T> T
doPrivileged(PrivilegedAction<T> action, AccessControlContext context, Permission... perms)
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedAction
を実行します。static <T> T
doPrivileged(PrivilegedExceptionAction<T> action)
有効になった特権を使って、指定されたPrivilegedExceptionAction
を実行します。static <T> T
doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context)
指定されたAccessControlContext
によって有効になり、かつ制限される特権を使って、指定されたPrivilegedExceptionAction
を実行します。static <T> T
doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms)
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionAction
を実行します。static <T> T
doPrivilegedWithCombiner(PrivilegedAction<T> action)
有効になった特権を使って、指定されたPrivilegedAction
を実行します。static <T> T
doPrivilegedWithCombiner(PrivilegedAction<T> action, AccessControlContext context, Permission... perms)
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedAction
を実行します。static <T> T
doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
有効になった特権を使って、指定されたPrivilegedExceptionAction
を実行します。static <T> T
doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms)
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionAction
を実行します。static AccessControlContext
getContext()
このメソッドは、現在のスレッドの継承されたAccessControlContextと制限された特権スコープを含む、現在の呼出し側コンテキストの「スナップショット」を取得し、それをAccessControlContextオブジェクトに配置します。
-
-
-
メソッドの詳細
-
doPrivileged
public static <T> T doPrivileged(PrivilegedAction<T> action)
有効になった特権を使って、指定されたPrivilegedAction
を実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの
run
メソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。アクションの実行中、現在のAccessControlContextに関連付けられているDomainCombinerは無視されます。
- 型パラメータ:
T
- PrivilegedActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。- 戻り値:
- アクションの
run
メソッドによって返される値。 - 例外:
NullPointerException
- アクションが次の場合:null
- 関連項目:
doPrivileged(PrivilegedAction,AccessControlContext)
,doPrivileged(PrivilegedExceptionAction)
,doPrivilegedWithCombiner(PrivilegedAction)
,DomainCombiner
-
doPrivilegedWithCombiner
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action)
有効になった特権を使って、指定されたPrivilegedAction
を実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの
run
メソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。
- 型パラメータ:
T
- PrivilegedActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。- 戻り値:
- アクションの
run
メソッドによって返される値。 - 例外:
NullPointerException
- アクションが次の場合:null
- 導入されたバージョン:
- 1.6
- 関連項目:
doPrivileged(PrivilegedAction)
,DomainCombiner
-
doPrivileged
public static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context)
指定されたAccessControlContext
によって有効になり、かつ制限される特権を使って、指定されたPrivilegedAction
を実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContext
によって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの
run
メソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された
AccessControlContext
がシステム・コードによって作成されず、呼出し元のProtectionDomain
にcreateAccessControlContextSecurityPermission
が付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
T
- PrivilegedActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。context
- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストがnull
の場合、追加の制限は適用されない。- 戻り値:
- アクションの
run
メソッドによって返される値。 - 例外:
NullPointerException
- アクションが次の場合:null
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedExceptionAction,AccessControlContext)
-
doPrivileged
public static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context, Permission... perms)
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedAction
を実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContext
によって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの
run
メソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された
AccessControlContext
がシステム・コードによって作成されず、呼出し元のProtectionDomain
にcreateAccessControlContextSecurityPermission
が付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
T
- PrivilegedActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。context
- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストがnull
の場合、追加の制限は適用されない。perms
- 呼出し元の特権のスコープを制限するPermission
引数。 引数の数は変動する。- 戻り値:
- アクションの
run
メソッドによって返される値。 - 例外:
NullPointerException
- action、permsまたはpermsのいずれかの要素がnull
である場合- 導入されたバージョン:
- 1.8
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedExceptionAction,AccessControlContext)
-
doPrivilegedWithCombiner
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action, AccessControlContext context, Permission... perms)
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedAction
を実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContext
によって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの
run
メソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。
セキュリティ・マネージャがインストールされ、指定された
AccessControlContext
がシステム・コードによって作成されず、呼出し元のProtectionDomain
にcreateAccessControlContextSecurityPermission
が付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
T
- PrivilegedActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。context
- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストがnull
の場合、追加の制限は適用されない。perms
- 呼出し元の特権のスコープを制限するPermission
引数。 引数の数は変動する。- 戻り値:
- アクションの
run
メソッドによって返される値。 - 例外:
NullPointerException
- action、permsまたはpermsのいずれかの要素がnull
である場合- 導入されたバージョン:
- 1.8
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedExceptionAction,AccessControlContext)
,DomainCombiner
-
doPrivileged
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws PrivilegedActionException
有効になった特権を使って、指定されたPrivilegedExceptionAction
を実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの
run
メソッドがチェック例外をスローすると、例外はこのメソッドを使って送られます。アクションの実行中、現在のAccessControlContextに関連付けられているDomainCombinerは無視されます。
- 型パラメータ:
T
- PrivilegedExceptionActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション- 戻り値:
- アクションの
run
メソッドによって返される値 - 例外:
PrivilegedActionException
- 指定されたアクションのrun
メソッドがチェック例外をスローした場合NullPointerException
- アクションが次の場合:null
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedExceptionAction,AccessControlContext)
,doPrivilegedWithCombiner(PrivilegedExceptionAction)
,DomainCombiner
-
doPrivilegedWithCombiner
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action) throws PrivilegedActionException
有効になった特権を使って、指定されたPrivilegedExceptionAction
を実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの
run
メソッドがチェック例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。
- 型パラメータ:
T
- PrivilegedExceptionActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。- 戻り値:
- アクションの
run
メソッドによって返される値 - 例外:
PrivilegedActionException
- 指定されたアクションのrun
メソッドがチェック例外をスローした場合NullPointerException
- アクションが次の場合:null
- 導入されたバージョン:
- 1.6
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedExceptionAction,AccessControlContext)
,DomainCombiner
-
doPrivileged
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context) throws PrivilegedActionException
指定されたAccessControlContext
によって有効になり、かつ制限される特権を使って、指定されたPrivilegedExceptionAction
を実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContext
によって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの
run
メソッドがチェック例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された
AccessControlContext
がシステム・コードによって作成されず、呼出し元のProtectionDomain
にcreateAccessControlContextSecurityPermission
が付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
T
- PrivilegedExceptionActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクションcontext
- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストがnull
の場合、追加の制限は適用されない。- 戻り値:
- アクションの
run
メソッドによって返される値 - 例外:
PrivilegedActionException
- 指定されたアクションのrun
メソッドがチェック例外をスローした場合NullPointerException
- アクションが次の場合:null
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedAction,AccessControlContext)
-
doPrivileged
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms) throws PrivilegedActionException
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionAction
を実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContext
によって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの
run
メソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された
AccessControlContext
がシステム・コードによって作成されず、呼出し元のProtectionDomain
にcreateAccessControlContextSecurityPermission
が付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
T
- PrivilegedExceptionActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。context
- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストがnull
の場合、追加の制限は適用されない。perms
- 呼出し元の特権のスコープを制限するPermission
引数。 引数の数は変動する。- 戻り値:
- アクションの
run
メソッドによって返される値。 - 例外:
PrivilegedActionException
- 指定されたアクションのrun
メソッドがチェック例外をスローした場合NullPointerException
- action、permsまたはpermsのいずれかの要素がnull
である場合- 導入されたバージョン:
- 1.8
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedAction,AccessControlContext)
-
doPrivilegedWithCombiner
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms) throws PrivilegedActionException
指定されたAccessControlContext
によって許可および制限される特権と、指定されたPermission
引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionAction
を実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContext
によって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの
run
メソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。
セキュリティ・マネージャがインストールされ、指定された
AccessControlContext
がシステム・コードによって作成されず、呼出し元のProtectionDomain
にcreateAccessControlContextSecurityPermission
が付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
T
- PrivilegedExceptionActionのrun
メソッドによって返される値の型。- パラメータ:
action
- 実行されるアクション。context
- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストがnull
の場合、追加の制限は適用されない。perms
- 呼出し元の特権のスコープを制限するPermission
引数。 引数の数は変動する。- 戻り値:
- アクションの
run
メソッドによって返される値。 - 例外:
PrivilegedActionException
- 指定されたアクションのrun
メソッドがチェック例外をスローした場合NullPointerException
- action、permsまたはpermsのいずれかの要素がnull
である場合- 導入されたバージョン:
- 1.8
- 関連項目:
doPrivileged(PrivilegedAction)
,doPrivileged(PrivilegedAction,AccessControlContext)
,DomainCombiner
-
getContext
public static AccessControlContext getContext()
このメソッドは、現在のスレッドの継承されたAccessControlContextと制限された特権スコープを含む、現在の呼出し側コンテキストの「スナップショット」を取得し、それをAccessControlContextオブジェクトに配置します。 このコンテキストは、あとで別のスレッドなどで検査される場合があります。- 戻り値:
- 現在のコンテキストに基づくAccessControlContext
- 関連項目:
AccessControlContext
-
checkPermission
public static void checkPermission(Permission perm) throws AccessControlException
現在のAccessControlContextとセキュリティ・ポリシーに基づいて、指定されたアクセス権によって示されるアクセス要求が許可されるか拒否されるかを決定します。 このメソッドは、アクセス要求が許可される場合には何もしないで復帰し、そうでない場合にはAccessControlExceptionをスローします。 AccessControlExceptionのgetPermissionメソッドは、perm
Permissionオブジェクト・インスタンスを返します。- パラメータ:
perm
- 要求されたアクセス権。- 例外:
AccessControlException
- 現在のセキュリティ・ポリシーに基づいて、指定されたアクセス権が許可されない場合。NullPointerException
- 指定されたアクセス権がnull
であり、そのアクセス権が現在有効なセキュリティ・ポリシーに基づいてチェックされた場合。
-
-