Top > OOoPython > java_to_python
*java to python [#p19653cb]

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

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

*developers' manual [#f3a5300f]

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

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

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

*examples written in java [#ba0d33f1]

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 [#v61ce92d]


では次に、同じ内容を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 [#a3af1347]

**1.queryInterface()の存在 [#lf6c865f]

//おそらくオブジェクト指向の書き方のちがいなのですが、
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文の違い [#sddd4ba2]

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ではこのような動作は出来ません。
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 [#ma9bb564]

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

*参考文献 [#if538efe]

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