Top > OOoPython > java_to_python

java to python Edit

OOoに含まれるメソッドは数多く全体を把握することは困難です。 いきおい実際にマクロを書くときはUsers' manualやDevelopers' manualの 例を頼ることになります。

ここではjavaでかかれたマクロ(マクロではないようなのですが)を、 pythonに書き写すやり方を紹介します。

developers' manual Edit

この文書はOOoにかかわる人間が何らかの仕方で読まねばならない 文書です。

これは全体で1000ページにも及ぶのでなかなか読破することは困難なのですが、 実際にマクロを書くことが目的なら読まなくても良い部分も多いです。

とくにadvanced UNO と書かれているあたりは難しいのでとりあえず 読みとばしましょう。

examples written in java Edit

developers' manual に書かれている例題はほぼ例外無く javaでかかれています。 また、OOo独特のイディオムのような所もあるのでこれを pythonに移植するのは工夫が必要です。

幸いにも移植した結果はjavaで書かれた例よりも簡潔に なることが多いので、少し安心です。

先ず1つ例をあげます。先にjavaのコードを見て下さい。 この例はDevelopers' manual のchartの章に書かれていた コードです。

//The sample program for inserting chart document.
...final String msChartClassID = "12dcae26-281f-416f-a234-c3086127382e";
com.sun.star.frame.XModel aDrawDoc;
// get a draw document into aDrawDoc
// ...
// this will become the resulting chart
XChartDocument aChartDoc;

com.sun.star.drawing.XDrawPagesSupplier aSupplier =
(com.sun.star.drawing.XDrawPagesSupplier)
UnoRuntime.queryInterface (com.sun.star.drawing.XDrawPagesSupplier.class,aDrawDoc);

com.sun.star.drawing.XShapes aPage = null;

aPage = (com.sun.star.drawing.XShapes) 
aSupplier.getDrawPages ().getByIndex (0);

XMultiServiceFactory aFact = (XMultiServiceFactory)
UnoRuntime.queryInterface (XMultiServiceFactory.class, aDrawDoc);

com.sun.star.drawing.XShape aShape = (com.sun.star.drawing.XShape)
UnoRuntime.queryInterface (com.sun.star.drawing.XShape.class,
aFact.createInstance("com.sun.star.drawing.OLE2Shape"));

aPage.add (aShape);

aShape.setPosition (new com.sun.star.awt.Point (1000, 1000));

aShape.setSize (new com.sun.star.awt.Size (15000, 9271));

XPropertySet aShapeProp =
(XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, aShape);

aShapeProp.setPropertyValue ("CLSID", msChartClassID);

aChartDoc = (XChartDocument)
UnoRuntime.queryInterface (XChartDocument.class, aShapeProp.getPropertyValue ("Model"));

// let aChartDoc be a valid XChartDocument
// get the factory that can create diagrams

XDiagram aDiagram = aFact.createInstance ("com.sun.star.chart.XYDiagram");

aChartDoc.setDiagram (aDiagram);

難しいですね。このコードはドローの文書をうけとってその文書に XYdiagram(2次元プロットです。どうでもいいのですが...。) を挿入するというコードです。実際にはコメントがいろいろ入っていて もうすこし読み易くなっております。 また、drawが開いていなかった、などのいろいろな例外処理に 関するコードもあったのですが、ここでは簡単のためとりのぞいています。

The sample code written in python Edit

では次に、同じ内容をpythonで書いてみます。

from com.sun.star.awt import Point~
from com.sun.star.awt import Size

import sys

def aaa(): 
    """Let OOo have a draw page be active.
    Then this macro inserts a line diagram in that page."""
    
    try:
	 msChartClassID = "12dcae26-281f-416f-a234-c3086127382e"
	 draw = XSCRIPTCONTEXT.getDocument()
	 a_page = draw.getDrawPages().getByIndex(0)
	 shape = draw.createInstance("com.sun.star.drawing.OLE2Shape")
	 a_page.add(shape)
	 shape.setPosition(Point(1000,1000))
	 shape.setSize(Size(15000,9217))
	 shape.setPropertyValue("CLSID", msChartClassID)
	 aChartDoc = shape.getPropertyValue("Model")
	 aDiagram = aChartDoc.createInstance("com.sun.star.chart.LineDiagram")
	 aChartDoc.setDiagram(aDiagram)
    except:
	 print sys.exc_info()

贔屓目かも知れないのですが、さっきよりは少し簡単そうです。 ただしこのコードはあらかじめドローが 開いていないと失敗します。

the difference between java and python Edit

1.queryInterface()の存在 Edit

javaのコードでは頻繁に、

com.sun.star.drawing.XDrawPagesSupplier aSupplier =
 (com.sun.star.drawing.XDrawPagesSupplier)
 UnoRuntime.queryInterface (com.sun.star.drawing.XDrawPagesSupplier.class,
			     aDrawDoc);

のようなコードが現われます。 わかりづらいのですが、まず最初の com.sun.star.drawing.XDrawPagesSupplier というのはオブジェクトの型名です。 cを知っている人なら double とかintの類だと思って良いです。 (実際には構造体と思った方がよいので微妙ですが...)

OOo basicでは、こういった型を全てまとめてObject型として まとめています。インタプレタが勝手に解釈してくれるので これはこれで便利なのですが、basicからjavaへの 移行が難しい原因にもなりそうです。

次に難しいのが、UnoRuntime.queryInterface() というメソッドです。 これはjavaの機能と言うより、OOoの機能の一部です。 実は筆者もよく分っていないのですが、"javaは多重継承を サポートしていない"というのがあります。

しかしこれではうまくいかない点があります。 OOoでいうクラスというのはwriter_document とかcalc_documentとか いろいろあるのですが、writer_documentは、できればprintable_class(印刷できる) とかwritable_class(書き込みできる)とかcan_be_saved_class(保存できる)とか いろいろな低レベルの機能を 持ち合わせたものにしたいというのがあります。

このためにOOo言語では"多重継承"、様々なクラスの持つ 様々な機能を全て継承するというアイディアがよく使われます。

残念ながらjavaではそうはいかないので、例であげた一文のように queryInterface()というメソッドが使われます。 これは、"かっこのなかで指定された1つのクラスの機能を,継承するように 言われたインスタンスを用意しなさい"という命令です。 要するにこれを使えば多重継承を言語がサポートしていなくても うまくそれと同じことが出来るわけです。

実際にはpythonは多重継承をサポートしているので queryInterface()というメソッドを使う機会はとりあえずありません。 なのでこの手の文が書いてあったら無視してokです。

OpenOffice.org 2.0 系では Java を使った Scripting において queryInterface メソッドを使用しなくてもよいようになるはずです。

2. import文の違い Edit

javaでは、

aShape.setPosition (new com.sun.star.awt.Point (1000, 1000));
aShape.setSize (new com.sun.star.awt.Size (15000, 9271));

という2文があります。 これはチャート(ではなくて正確にはOLE埋め込みオブジェクトみたいです) の場所と大きさを定める文なのですが

new com.sun.star.awt.Point()

文でいきなりPoint()のインスタンスを1つ作っています。 pythonの場合には、com.sun.starという場所は pythonの一部ではないので、まずimportが必要です。

from com.sun.star.awt import Point
from com.sun.star.awt import Size

shape.setPosition(Point(1000,1000))
shape.setSize(Size(15000,9217))

ただそれだけなのですが、ここで1つ注意が必要です。 jythonを使ったことがある人は、

import java

java.lang.System.out.println("aaa")

というような呼出しの仕方が出来ることを知っているかも知れません。

理由はわからないのですがOOoマクロではこのような呼出しは出来ません。つまり、

import com 

というような呼出しは出来ないようです。

import com

に到った時点でNameErrorがおこります。 きちんと正式な名前を書かないといけません。

同じように(ちがう理由かも知れないのですが)、

from com.sun.star.awt import *

の文もどういうわけかうまくいきません。 とりあえずきちんと名前を指定するようにすれば、 importがきちんと動作します。

summary Edit

とりあえずjavaからpythonへの移行の仕方を書いてみました。 これを使ってどんどんDevelopers' manualの内容を 移植して遊んでみましょう。

参考文献 Edit

Developers' manual

http://api.openoffice.org/DevelopersGuide/DevelopersGuide.html

T.Uesugi wrote that document on mar/12/2005.


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