Top > OOoBasic > Generic > Extensions

*拡張機能用 API [#c8ef8818]

拡張機能で利用する API

#contents
**XPackageManager [#u280c438]
パッケージのインストールやインストール済みのパッケージの操作を行う API です。

以下のようにして "user" もしくは "shared" コンテキストを指定して取得します。

 Function GetPackageManager( sContext As String )
   oPMF = GetDefaultContext().getByName( _
     "/singletons/com.sun.star.deployment.thePackageManagerFactory" )
   GetPackageManager = oPMF.getPackageManager(sContext)
 End Function


 Sub pm2
   oPM = GetPackageManager("user")
   oAC = oPM.createAbortChannel()
   oPackages = oPM.getDeployedPackages(oAC,Null)
 End Sub

3.3 からは上記のものが deprecated になったため次のサービスを利用します。
 oEM = com.sun.star.deployment.ExtensionManager.get()
**パッケージディレクトリ [#h4a877d9]
拡張機能パッケージはたとえば user コンテキストの場合は OpenOffice.org/user/uno_packages/cache/uno_packages 以下にインストールされます。このとき、パッケージごとにディレクトリが作成されて配置されます。(このディレクトリ名は com.sun.star.io.TempFile などのサービスが作成したもの)

このディレクトリ名がランダムに決定されるため、以前はパッケージのディレクトリに依存したコードを書かないように、とされていました。
2.3 から新しい API として com.sun.star.deployment.PackageInformationProvider single ton が実装され、com.sun.star.deployment.XPackageInformationProvider インターフェースからパッケージのディレクトリ URL を取得できるようになりました。

***PackageInformationProvider [#r7749358]
この API を利用するには、パッケージの description.xml ファイルに identifier を設定する必要があります。

以下のような形で利用します。

 Sub GetPackageLocation()
   oPIP = GetDefaultContext().getByName( _
     "/singletons/com.sun.star.deployment.PackageInformationProvider")
   Inputbox ,, oPIP.getPackageLocation("mytools.mri")
 End Sub
結果 file:///C:/Users/huga/AppData/Roaming/OpenOffice.org2/user/uno_packages/
cache/uno_packages/2A00.tmp_/MRI.oxt

Py-UNO で行う場合。

#code(python){{
def get_extension_dirurl(ctx,extid=EXTENSION_ID):
	"""Get extension directory url from the extension id."""
	pip_name = "/singletons/com.sun.star.deployment.PackageInformationProvider"
	if ctx.hasByName(pip_name):
		pip = ctx.getByName(pip_name)
		return pip.getPackageLocation(extid)
	return ""
}}

BeanShell

 import com.sun.star.container.XNameAccess;
 import com.sun.star.deployment.XPackageInformationProvider;
 
 // get PackageInformationProvider from ComponentContext
 XNameAccess xNameAccess = (XNameAccess) UnoRuntime.queryInterface(
 	XNameAccess.class, xComponentContext );
 
 Object oPIP = xNameAccess.getByName( 
      "/singletons/com.sun.star.deployment.PackageInformationProvider" );
 XPackageInformationProvider xPIP = (XPackageInformationProvider) UnoRuntime.queryInterface(
 	XPackageInformationProvider.class, oPIP);
 // get the url of the directory extension installed
 String sPackageURL = xPIP.getPackageLocation( "mytools.mri" );


***2.2 以前との共有 [#g8537d54]
2.3 以降では前述の PackageInformationProvider が利用できます。しかし、パッケージのバージョン依存性がこれのみの場合には 2.2 以前でも利用したくなります。

拡張機能 ID は 2.0.4 からサポートされているため、それを利用すればパッケージの位置を知ることができます。

コンテキストから PackageInformationProvider が見つかると (2.3 以降) それを利用し、それ以外の時には thePackageManagerFactory からインストールされているパッケージを調べてディレクトリを取得します。

  sPkgLocation = ""
  sPkgId = "mytools.Honyonyo"
  sPIPName = "/singletons/com.sun.star.deployment.PackageInformationProvider" '2.3
  sPMFName = "/singletons/com.sun.star.deployment.thePackageManagerFactory"
  
  If oContext.hasByName(sPIPName) Then ' 2.3
    oPkgIP = oContext.getByName(sPIPName)
    sPkgLocation = oPkgIP.getPackageLocation(sPkgId)
  
  ElseIf oContext.hasByName(sPMFName) Then
    oPkgMgr = oContext.getByName(sPMFName).getPackageManager("user")
    oPackages = oPkgMgr.getDeployedPackages(oPkgMgr.createAbortChannel(),Null)
    For i = 0 To UBound(oPackages)
      If oPackages(i).getIdentifier().Value = sPkgId Then
        sPkgLocation = oPackages(i).getURL()
        oExpander = oContext.getByName( _
            "/singletons/com.sun.star.util.theMacroExpander")
        sPkgLocation = Mid(oExpander.expandMacros(sPkgLocation),21)
      End If
    Next i
  End If
thePackageManagerFactory から取得したパッケージから取得できるパッケージのディレクトリ URI は vnd.sun.star.expand: ... のような形式になっているため、theMacroExpander で URL に変換しています。

** 拡張機能パッケージ内 URI [#r9ef96b1]
3.3 から拡張機能パッケージへのプロトコルが利用できます。拡張機能パッケージコンテントプロバイダを通過する場合に利用できます。

URI の形式は次のようになります。利用には拡張機能 ID が必要です。
 vnd.sun.star.extension://EXTENSION_ID/to_file

以下のものでは動作が確認できました。
- css.ucb.SimpleFileAccess
- css.graphic.GraphicProvider
- css.awt.DialogProvider

SimpleFileAccess が内部で該当する ucb のプロバイダを利用しているため、各種サービスが内部で SimpleFileAccess を利用していればこの形式の URI を利用できるはずです。

  dp = CreateUnoService("com.sun.star.awt.DialogProvider")
  dlg = dp.createDialog( _
      "vnd.sun.star.extension://mytools.mri/dialogs/Config.xdl")
  dlg.execute()

** パッケージのインストール [#pd02ea22]
拡張機能パッケージを API 経由でインストールできます。しかし、インストールしますか?のダイアログの OK ボタンを自動的に押すような処理が必要なため、普通は利用しないべきです。

#code(python){{
    class ProgressHandler(unohelper.Base, XProgressHandler):
        def push(self, status): pass
        def update(self, status): pass
        def pop(self): pass
    
    class Interactionhalder(unohelper.Base, XInteractionHandler):
        def __init__(self, act):
            self.act = act
        
        def handle(self, request):
            message = request.getRequest()
            if not isinstance(message, str):
                message = message.Message
            try:
                n = self.act.query(message)
                if n == 1:
                    type_name = "com.sun.star.task.XInteractionApprove"
                else:
                    type_name = "com.sun.star.task.XInteractionAbort"
                for continuation in request.getContinuations():
                    if continuation.queryInterface(uno.getTypeByName(type_name)):
                        continuation.select()
            except Exception as e:
                print(e)
    
    def query(self, message, buttons=2):
        return show_message(self.ctx, self.pages[6].getPeer(), 
            message, "", "querybox", buttons)
    
    class CommandEnv(unohelper.Base, XCommandEnvironment):
        def __init__(self, act):
            self.act = act
        
        def getInteractionHandler(self):
            return self.act.__class__.Interactionhalder(self.act)
        
        def getProgressHandler(self):
            return self.act.__class__.ProgressHandler()

    def install(self, command_env):
        if not self.file_exists(self.package_url):
            raise Exception("Extension package lost.")
        manager = self.ctx.getByName(
            "/singletons/com.sun.star.deployment.ExtensionManager")
        ac = manager.createAbortChannel()
        try:
            package = manager.addExtension(
                self.package_url, 
                (), 
                "user", 
                ac, 
                command_env
            )
        except Exception as e:
            print(e)
            return False
        return True
}}

このコードではメッセージボックスでユーザーに選択させていますが、css.task.XInteractionApprove を選択して select メソッドを呼ぶと、ユーザーの操作なしでインストールできます。
勝手にパッケージをインストールされると困るものもあるので、ユーザーの承諾を得るようにしてください。


Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes