メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2008年12月31日水曜日

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(10) Capabilities of SheetCell

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Capabilities_of_SheetCell
を読む。

Capabilities of SheetCell
SheetCellというのはOpenOffice.orgにおけるテーブルの基本パーツ。

SheetCellには以下の能力があるそうな。


  1. セルの内容にアクセスできる。

  2. インタフェースであるcom.sun.star.table.XCellはcellにおける式、値を操作できる。

  3. SheetCellはSheetCellRangeの特別なケース。

  4. 一意なセルへのアドレスを提供可能。(com.sun.star.table.CellAddress)

  5. 一時的にロック可能(com.sun.star.document.XActionLockable)


な感じか。





.

2008年12月30日火曜日

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(9) Capabilities of SheetCellRange

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Capabilities_of_SheetCellRange
を読む。

SheetCellRangeの能力
SheetCellRangeは矩形領域をあらわす。

SheetCellRangeは以下の能力がある。
com.sun.star.sheet.XSheetCellRangeで、cell、sub-rangeなcellを提供する。
com.sun.star.table.XColumnRowRangeで、列、行を提供する。
com.sun.star.sheet.XSheetOperationで、計算を提供する。
com.sun.star.table.XAutoFormattableやらcom.sun.star.util.XIndentやらcom.sun.star.sheet.XCellFormatRangesSupplierやらcom.sun.star.sheet.XUniqueCellFormatRangesSupplierやらでフォーマットを提供する。
com.sun.star.sheet.XCellRangeDataでcellやcell-rangeのデータを扱える。
一連のデータをcellやcell-rangeに埋めるにはcom.sun.star.sheet.XCellSeriesを使う。
データベースからのデータのインポートにはcom.sun.star.util.XImportableを使う。
Cellの値を検索したり置き換えたりするのに、com.sun.star.util.XSearchableを使う。
Cellをクエリーするにはcom.sun.star.sheet.XCellRangesQueryを使う。
1つのCellに複数のCellをマージするにはcom.sun.star.util.XMergeableを使う。
ソートしたりフィルターしたりすにはcom.sun.star.util.XSortable,、com.sun.star.sheet.XSheetFilterable,
com.sun.star.sheet.XSheetFilterableEx、などを使う。
セルの一意なアドレスを取得したりするには、com.sun.star.sheet.XCellRangeAddressable:getRangeAddressを使う。これはcom.sun.star.table.CellRangeAddressというstructを返す。
com.sun.star.chart.XChartDataArrayをサポートしているのでSheetCellRangeに基づくチャートを作成できる。


って感じ?
.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(8) Capabilities of Spreadsheet

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Capabilities_of_Spreadsheet
を読む。

スプレッドシートの能力
スプレッドシートはcom.sun.star.sheet.SheetCellRangeを含んだcom.sun.star.sheet.Spreadsheetサービスである。

で、スプレッドシートは、com.sun.star.container.XNamedを使うことで名前によるアクセスが可能。
com.sun.star.sheet.XCellRangeMovementを使うことでcellは挿入可能で、全てのcellは削除可能、移動、コピーも可能。
印刷関連はcom.sun.star.sheet.XPrintAreasやcom.sun.star.sheet.XSheetPageBreakを使えばよいらしい。
チャートも扱えるよ。
com.sun.star.util.XProtectableというのを使えば永久に変更から守ることもできるよ?

.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(7) Spreadsheet Services - Overview

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Spreadsheet_Services_-_Overview
を読む。

スプレッドシートサービス概観
スレッドシートサービスを構成する主要素

  1. com.sun.star.sheet.Spreadsheet
  2. com.sun.star.sheet.SheetCellRange
  3. com.sun.star.sheet.SheetCell
  4. com.sun.star.sheet.SheetCellRanges
  5. com.sun.star.table.TableColumn
  6. com.sun.star.table.TableRow

だそうで。

.



.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(6) Working with Spreadsheet Documents

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Working_With_Spreadsheet_Documents
を読む。

Spreadsheet Document
スプレッドシートドキュメントはcom.sun.star.sheet.SpreadsheetDocumentで表現される。

SpreadsheetDocumentは少なくとも1つの要素を持つSpreadsheetオブジェクトのコレクションからなる。
com.sun.star.sheet.XSpreadsheetDocumentのgetSheets()メソッドを呼べば、
com.sun.star.sheet.XSpreadsheetsを取得できる。

getSheets()メソッドでXSpreadsheetsを取得すれば、3つの異なる方法でシートにアクセスすることを可能にする。

  1. インデックスによる方法
  2. Enumによる方法
  3. 名前による方法

の3つ。


インデックスによる方法
com.sun.star.container.XIndexAccessというインタフェースが提供されているので、
このインタフェースを使用し、シートにアクセスする。

public com.sun.star.sheet.XSpreadsheet getSpreadsheet(
com.sun.star.sheet.XSpreadsheetDocument xDocument, int nIndex) {

// Collection of sheets
com.sun.star.sheet.XSpreadsheets xSheets = xDocument.getSheets();
com.sun.star.sheet.XSpreadsheet xSheet = null;

try {
com.sun.star.container.XIndexAccess xSheetsIA = (com.sun.star.container.XIndexAccess)
UnoRuntime.queryInterface(com.sun.star.container.XIndexAccess.class, xSheets);
xSheet = (com.sun.star.sheet.XSpreadsheet) xSheetsIA.getByIndex(nIndex);
} catch (Exception ex) {
}

return xSheet;
}
 


Enumによる方法
com.sun.star.sheet.SpreadsheetsEnumerationというサービスが提供されているので、
このサービスを使用してシートにアクセスする。

名前による方法
com.sun.star.container.XNameContainerを派生してcom.sun.star.sheet.XSpreadsheetsが提供されているので、XNameContainerのメソッドを使用して、名前による指定でシートにアクセスする。

public com.sun.star.sheet.XSpreadsheet getSpreadsheet(
com.sun.star.sheet.XSpreadsheetDocument xDocument,
String aName) {

// Collection of sheets
com.sun.star.sheet.XSpreadsheets xSheets = xDocument.getSheets();
com.sun.star.sheet.XSpreadsheet xSheet = null;

try {
com.sun.star.container.XNameAccess xSheetsNA = (com.sun.star.container.XNameAccess)
UnoRuntime.queryInterface(com.sun.star.container.XNameAccess.class, xSheets);
xSheet = (com.sun.star.sheet.XSpreadsheet) xSheetsNA.getByName(aName);
} catch (Exception ex) {
}

return xSheet;
}
 



さらに、XSpreadsheetには以下のようなメソッドも存在する。
  1. insertNewByName() - 新しい空のシートを指定した名前で指定した位置に追加する。
  2. moveByName() - シートを指定した名前で指定した位置に移動する。
  3. copyByName() - コピーする。




.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(5) スプレッドシートの保存

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Saving_Spreadsheet_Documents
を読む。


Saving Spreadsheet Documents
ドキュメントは、com.sun.star.frame.XStorableというインタフェースを通して保存することができる。

XStorable.storeAsURL()は、「名前をつけて保存」と似た感じ。
XStorable.storeToUrl()は、現在読み込んでいるドキュメントはそのままで、指定されたURLにコピーとして保存する。


Exporting
他のフォーマットで保存する場合、プロパティFilterNameを指定する。
FilterNameにはフォーマットの名前を指定する。
指定できるフォーマットの名前は、


<OfficePath>/share/config/registry/instance/org/openoffice/Office/TypeDetection.xml
 

に記述されているらしい。
Debian-Etchだと、

/usr/lib/openoffice/share/registry/res/en-US/org/openoffice/TypeDetection/Filter.xcu
 

あたりかな??
MS Excel 2003 XMLで出力したかったら、

XStorable xStorable = (XStorable)UnoRuntime.queryInterface(XStorable.class, xDoc);
PropertyValue[] storeProps = new PropertyValue[1];
storeProps[0] = new PropertyValue();
storeProps[0].Name = "FilterName";
storeProps[0].Value = "MS Excel 2003 XML";
xStorable.storeAsURL(storeUrl, storeProps);
 

などと指定すればよいっぽい。



.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(4) ファイル操作

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Handling_Spreadsheet_Documents_Files
を読む。

Handling Spreadsheet Document Files


Creating and Loading Spreadsheet Documents
loadComponentFromURL()とかで使用するURLには、

  1. file:
  2. http:
  3. ftp:
  4. private:
が使えるらしい。

private:
"factory"を従えて、"private:factory/scalc"と指定できる。
新しいScalcシートを作成する場合にはこれを指定する。

ファイルをロードする場合には、
Windowsなどの場合は、
"file:///c:/MyCalcDocument.ods"
Linuxなどの場合は、
"file:///tmp/MyCalcDocument.ods"
などと指定する。

ロード時に指定できるプロパティはcom.sun.star.document.MediaDescriptorに定義されている。

たとえば、MediaDescriptor.AsTemplateをtrueに指定してロードしたい場合は、
PropertyValue[] loadProps = new PropertyValue[1];
loadProps[0] = new PropertyValue();
loadProps[0].Name = "AsTemplate";
loadProps[0].Value = new Boolean(true);
などとやって、このloadPropsをloadComponentFromURL()に渡してあげればよい。


.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(3) セルをいじってみる

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Example:_Editing_Spreadsheet_Cells
を読む。


XSpreadsheetはcom.sun.star.table.XCellRangeから派生したもの。
なので、
XCellRangeの

  1. getCellByPosition
  2. getCellRangeByPosition
  3. getCellRangeByName
というメソッドを使うことができる。

getCellByPosition
指定された範囲中の1つのcellを返す。

getCellRangeByPosition
指定された範囲中のcellのサブレンジなるものを返す。

getCellRangeByName
指定された範囲中のcellのサブレンジなるものを返す。


だもんで、XSpreadsheet.getCellByPosition(0,0)とやるとExcelで言うところのA1のCellを返す。

getCellByPosition()で返されたCellに対して値をセットしてやると、そのCellの値を書き換えることができる。らしい。


try {
/* シートコレクションにinsert */
xSheets.insertNewByName("うんこ", (short)0);
/* シートコレクションから追加したシートを取り出してみる */
xsheet = (XSpreadsheet)xSheets.getByName("うんこ");
xsheet.getCellByPosition(0,0).setValue(1234);
} catch (Exception ex) {
ex.printStackTrace();
}



さっきのsheet追加のコードにgetCellByPosition().setValue()を加えてみた。
setValueは数値しか渡せない。

文字列をセットしたければ、xsheet.getCellByPosition()で返されるXCellオブジェクトから
queryして、com.sun.star.text.XTextを取り出す必要がある。

コードで書くと、

com.sun.star.table.XCell xCell = xsheet.getCellByPosition(0,0);
com.sun.star.text.XText xCellText = (com.sun.star.text.XText)
UnoRuntime.queryInterface(com.sun.star.text.XText.class, xCell);
com.sun.star.text.XTextCursor xTextCursor = xCellText.createTextCursor();
xCellText.insertString(xTextCursor, "テキストだよー", false);

 

こんな感じ。

.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(2) 新しいシートを追加してみる

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Example:_Adding_a_New_Spreadsheet
を読む。

Example: Adding a New Spreadsheet
やりたいことはSpreadsheetにシートを追加するだけ。
で、その手順は、

  1. com.sun.star.comp.helper.Bootstrap.bootstrap()を使って、リモートのXComponentContextを取得する。
  2. XComponentContext.createInstanceWithContext()を使ってDesktopを取得する。
  3. queryして、DesktopからXComponentLoaderを取り出す
  4. "private:factory/scalc"というURLを指定してscalcのコンポーネントをロード。
  5. queryして、上記で取得したObjectからXSpreadsheetDocumentを取り出す。
  6. XSpreadsheetDocumentからシートのコレクションを取得する。
  7. シートのコレクションに対してinsertNewByName()をコールする。


とやれば新しいシートを追加できるらしい。

で、やってみたソース。

import com.sun.star.beans.PropertyValue;
import com.sun.star.comp.helper.Bootstrap;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.uno.RuntimeException;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;

public class NewSpreadsheet {
public static void main(String[] args) {
try {
/* リモートコンテキストの取得 */
XComponentContext xContext = Bootstrap.bootstrap();

/* リモートサービスマネージャを取得 */
XMultiComponentFactory xServiceManager = xContext.getServiceManager();

/* リモートデスクトップUNOサービスのインスタンスを取得 */
Object desktop = xServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", xContext );

/* queryしてXComponentLoaderを取り出す */
XComponentLoader xComponentLoader =
(XComponentLoader)UnoRuntime.queryInterface(XComponentLoader.class, desktop );

/* スプレッドシートドキュメントのロード */
/* 全てDocumentというもので扱う */
String loadURL = "private:factory/scalc";
PropertyValue[] loadProps = new PropertyValue[0];
XComponent xComp = xComponentLoader.loadComponentFromURL(loadURL, "_blank", 0, loadProps);
XSpreadsheetDocument doc = (XSpreadsheetDocument)UnoRuntime.queryInterface(
com.sun.star.sheet.XSpreadsheetDocument.class, xComp);
/* シートコレクションの取得 */
XSpreadsheets xSheets = doc.getSheets();
XSpreadsheet xsheet = null;
try {
/* シートコレクションにinsert */
xSheets.insertNewByName("うんこ", (short)0);
/* シートコレクションから追加したシートを取り出してみる */
xsheet = (XSpreadsheet)xSheets.getByName("うんこ");
} catch (Exception ex) {
ex.printStackTrace();
}
}
catch (java.lang.Exception e){
e.printStackTrace();
}
finally {
System.exit(0);
}
}
}
 


ほっほー。

・・・保存しないとシートが追加されたかわからん。
.

[work][OpenOffice][SDK][java]Spreadsheet Documents読み中(1)

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Spreadsheet_Documents
を読む。

OpenOffice.orgが扱うtableは3つある。

  1. text table
  2. database table
  3. spreadsheet
だそうで。

text tableはtextコンテンツを扱う。
database tableはデータベースの機能を、
spreadsheetはcellを扱う。

これらの基本的仕様はcom.sun.star.tableで定義される。

で、spreadsheetはcom.sun.star.sheetで定義される。

spreadsheetドキュメントモデルは5つの構造上主要な領域をもつ。
  1. Spreadsheets Container
  2. Service Manager (document internal)
  3. DrawPages
  4. Content Properties
  5. Objects for Styling
の5つらしい。
Spreadsheets ContainerっつーのはSpreadsheetのコア部分をで、
ServiceManagerっつーのは、shape objectsとかtext fieldとかform controlsをSpreadsheetに加えたりする部分。
DrawPageっつーのは、sheetの上に、ページ描画のために設置するもの???
Content Propertiesっつーのは、各名づけられたコンテンツにアクセスできるもの。
Objects for Stylingっつーのはシートのスタイルやフォーマットを扱う??

.



.

[work][OpenOffice][SDK][java] Writing UNO Components読み中(2)

とりあえず、今のところ必要ないので、とばし。

.

[work][OpenOffice][SDK][java] Writing UNO Components読み中(1) Writing UNO Components

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Writing_UNO_Components
を読む。


Writing UNO Components
UNOコンポーネントによってOpenOffice.orgを拡張できる。と。
UNOコンポーネントはUNOによって提供される機能によってOpenOffice.orgの機能にアクセスできまっす。


OpenOffice.orgは多くの拡張のためのエントリーポイントを提供する。

  1. JavaやC++で書かれた任意のオブジェクトはユーザインタフェースから呼ぶことができる。
  2. Calcアドインは、新しい式を作るのに使える
  3. Chartアドインは新しいChartタイプを挿入することができる。
  4. 新しいデータベースドライバはデータアクセスを拡張するためにOpenOffice.orgに追加できる。
  5. 全てのモジュールは取替え可能
  6. 新しいドキュメントタイプをOpenOffice.orgに作ることも追加することも可能。
  7. 開発者は新しいフォーマット作成するのにコンポーネントを通して、OpenOffice.orgのXMLファイルにアクセスすることができる。

で、OpenOffice.org1.1.0から包括的に拡張をサポートしているらしい。

ふーん。
.

2008年12月29日月曜日

[work][OpenOffice][SDK][java] Professional UNO読み中(21) Opening a Connection

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Opening_a_Connection
を読む。

Opening a Connection
前の章で使用したUnoUrlResolver()の下の層は完全な柔軟性を提供する。
UNOにおけるプロセス間通信の接続の確立は、com.sun.star.connection.XConnectionの上に
成り立つ。
XConnectionは双方向通信をカプセル化する。

で、ここには異なるプロセス間通信の仕組みがあるらしい。
仕組みのほとんどは、




ひとつのプロセスがListenし、別のプロセスがそこにアクセスするまで待つ、
 

といった似たパターンに従う。

で、このパターンは、



  1. com.sun.star.connection.Accept


  2. com.sun.star.connection.Connector


のサービスに抽象化されている。

それぞれ、 com.sun.star.connection.XAcceptor、com.sun.star.connection.XConnector
というインタフェースとしてexportされている?


で、そのインタフェース定義。


interface XAcceptor: com::sun::star::uno::XInterface
{
XConnection accept( [in] string sConnectionDescription )
raises( AlreadyAcceptingException,
ConnectionSetupException,
com::sun::star::lang::IllegalArgumentException);

void stopAccepting();
};

interface XConnector: com::sun::star::uno::XInterface
{
XConnection connect( [in] string sConnectionDescription )
raises( NoConnectException,ConnectionSetupException );
};
 


acceptメソッドとconnectメソッドはパラメータに接続文字列を受け取る。
ここで指定する接続文字列は、UNO-URL中の接続文字列部分。
先の"uno:socket,host=localhost,port=2002;urp,Negotiate=0,ForceSynchronous=0;StarOffice.ServiceManager"のうちのunoから;urpまでの文字列。つまり
"uno:socket,host=localhost,port=2002;urp,Negotiate=0,ForceSynchronous=0"
まで。

で、コネクションタイプ部分でDefaultで指定できるものは以下のとおり。

  1. socket

  2. pipe



socketコネクションタイプ
ソケット接続。
指定できるパラメータは以下のとおり。
パラメータ名意味
hostListenまたは接続先のホスト名もしくはIP
portTCP/IPにおけるポート番号
tcpNoDelayソケットオプションのno delay。UNOでは1に設定されるべき。



pipeコネクションタイプ
名前付きパイプによる接続。
指定できるパラメータは以下のとおり。
パラメータ名意味
name名前付きパイプの名前



ConnectorとAcceptorを自分で実装すればコネクションタイプを追加することができる。

どうも、

com.sun.star.connection.Connector.AAA
 

などというコネクターを定義し、実装すると、
UNO-URLは、"uno:AAA;urp"なんてな風に書けるらしい。



.

[work][OpenOffice][SDK][java] Professional UNO読み中(20) Characteristics of the Interprocess Bridge

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Characteristics_of_the_Interprocess_Bridge
を読む。



プロセス間ブリッジの特性。

プロセス間ブリッジはスレッドセーフ。

同期呼び出しと非同期呼び出しがあって、
同期呼び出しは何かしらの応答があるまで待つ。

非同期呼び出しはすぐさま呼び出し元に戻る。

非同期か同期かはIDLに指定される。
IDL中に[oneway]フラグが付いているメソッドは非同期メソッド。


リモートブリッジが非同期に対応していても、デフォルトでは非同期は使えない。
その場合にはすべて同期モードで動作する。

非同期機能を有効にするには、サーバ側、クライアント側の双方の
接続文字列(UNO-URL)のプロトコルタイプのところに以下のパラメータ
を加えなければならない。


Negotiate=0,ForceSynchronous=0
 


まず、サーバ側を有効にする。

$ soffice '-accept=socket,host=0,port=2002;urp,Negotiate=0,ForceSynchronous=0;'
 


次に上記で立ち上げたサーバに接続するクライアント側を有効にする。

"uno:socket,host=localhost,port=2002;urp,Negotiate=0,ForceSynchronous=0;StarOffice.ServiceManager"
 

を接続する際のUNO-URLとして渡してあげる。

な感じ。

.

2008年12月28日日曜日

[work][OpenOffice][SDK][java] Professional UNO読み中(19) Importing a UNO Object

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Importing_a_UNO_Object
を読む。

Importing a UNO Object
もっとも共通のプロセス間通信の使用ケースはexporting serverからUNOオブジェクトの参照をimportすること。
マニュアルのサンプルでは、ComponentContextへの参照を取得している。

で、この参照の正しい方法は、、、


com.sun.star.bridge.UnoUrlResolver
 

というサービスを使う方法。
com.sun.star.bridge.UnoUrlResolverのインタフェースはcom.sun.star.bridge.XUnoUrlResolverに定義されている。

interface XUnoUrlResolver: com::sun::star::uno::XInterface
{
/** resolves an object on the UNO URL */
com::sun::star::uno::XInterface resolve( [in] string sUnoUrl )
raises (com::sun::star::connection::NoConnectException,
com::sun::star::connection::ConnectionSetupException,
com::sun::star::lang::IllegalArgumentException);
};
 

こんな感じで。

で、このresolvメソッドに渡される引数の文字列はUNO URLと呼ばれる文字列を指定する。

UNO-URLのフォーマットは以下のとおり。

Scheme:コネクションタイプ,パラメータ;プロトコルタイプ,パラメータ;Exportされているオブジェクト名
 

Schemeのところには"uno"を指定する。

コネクションタイプのところにはコネクションタイプを指定する(socketとか)
パラメータをつける場合には","(カンマ)で区切り、"="で名前と値のペアを記述できる。

socket,host=localhost,port=1234
 

などと指定できる。パラメータはhostとport。

プロトコルタイプのところにはプロトコルタイプを指定する。(urpとか)
パラメータをつける場合には","(カンマ)で区切り、"="で名前と値のペアで記述できる。

urp
 

などなど。

Exportされているオブジェクト名のところには

StarOffice.ServiceManager
 

などと指定できる。

で、続けて書くと、

uno:socket,host=localhost,port=1234;urp;StarOffice.ServiceManager
 

こんな感じ。これをresolve()に渡してやる。


UnoUrlResolverの制限
  1. どんな場合でもbridgeの終了を検知できない
  2. プロセス間通信の切断ができない。
  3. ローカルで初期化したオブジェクトをリモートプロセスに渡せない



おしまい。
.

[work][OpenOffice][SDK][java] Professional UNO読み中(18) OpenOffice.orgをサーバとして起動

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Starting_OpenOffice.org_in_Listening_Mode
を読む。

やっと来た。
OpenOffice.orgをサーバとして起動しておく、というところ。
正確には「Listenモードで開始」だったみたい。


Starting OpenOffice.org in Listening Mode

デフォルトではセキュリティの観点からListenモードではないとのこと。
現状2とおりの方法がある。

  1. OpenOffice.orgをパラメータをつけてListenモードで起動する方法
  2. OpenOffice.orgの設定ファイルをいじり、-acceptパラメータなしにListenモードで起動する方法

だそうです。

OpenOffice.orgをパラメータをつけてListenモードで起動する方法
以下な感じで起動する。

$ soffice '-accept=socket,host=0,port=2002;urp;'
 

セミコロンが付いているので、shellによってはクォートしないとダメ。

OpenOffice.orgの設定ファイルをいじって、-acceptパラメータなしにListenモードで起動する方法

<OfficePath>/share/registry/data/org/openoffice/Setup.xcu
 

のSetup.xcuという名のファイルをいじるらしい。

で、このファイルの中の、

<prop oor:name="ooSetupConnectionURL"/>
 

というタグを、

<prop oor:name="ooSetupConnectionURL">
<value>
socket,host=localhost,port=2002;urp;StarOffice.ServiceManager
</value>
</prop>
 

といった具合に書き換える。
もし、そういったタグが無ければ

<node oor:name="Office"/>
 

というタグのValue値として付け加えなさい、とのこと。
で、この書き換えはOpenOffice.org全体に影響する。

全体に影響するのがいやなら、ユーザ用の設定を書き換える。

<OfficePath>/user/registry/data/org/openoffice/
 

以下にuser用設定、Setup.xcuを置けばよい。


.

[work][OpenOffice][SDK][java] Professional UNO読み中(17) UNO Interprocess Connections

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/UNO_Interprocess_Connections
を読む。

UNO Interprocess Connections
異なる環境のUNOオブジェクトたちはプロセス間bridgeなるものを経由して接続する。
異なるプロセスに割り当てられているUNOオブジェクトを実行できるらしい。

で、これはメソッド名とか引数をバイトストリームなるものに変換し、
socket接続を通してリモートプロセスに送られる。

で、このドキュメントのほとんどのサンプルではOpenOffice.orgとの通信に
プロセス間bridgeを使うって。

この章では、UNO APIを使ってプロセス間connectionの作成、を扱うらしい。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(16) UNO Concepts

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/UNO_Concepts
を読む。

UNO Concepts


UNOを見ていく準備ができた!って。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(15)

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Understanding_the_API_Reference
を読む。

Understanding the API Reference



ふーん。
.

[work][OpenOffice][SDK][java] Professional UNO読み中(14) Singletons

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Singletons
を読む。


Singletons
「a UNO component context」中でシングルトン。

で、書き方。


module com { module sun { module star { module deployment {
singleton thePackageManagerFactory: XPackageManagerFactory;
}; }; }; };
 

と書いておけば、staticなgetThePackageManagerFactory()でインスタンスを取得できるらしい。インスタンスが無ければnewしてくれる。
問題があれば、com.sun.star.uno.DeploymentExceptionがスローされるらしい。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(13) Exceptions

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Exceptions
を読む。



Exceptions
exceptionは関数の呼び出し元へエラーを知らせる型。
継承できる。
メソッドのパラメータや戻り値としては使わない。
UNO IDLでは全てのexceptionはcom.sun.star.uno.Exceptionを継承しなければならない。


// com.sun.star.uno.Exception is the base exception for all exceptions
exception Exception {
string Message;
Xinterface Context;
};

// com.sun.star.uno.RuntimeException is the base exception for serious problems
// occuring at runtime, usually programming errors or problems in the runtime
// environment
exception RuntimeException : com::sun::star::uno::Exception {
};

// com.sun.star.uno.SecurityException is a more specific RuntimeException
exception SecurityException : com::sun::star::uno::RuntimeException {
 };
 


RuntimeExceptionはいつでも生じうる。


.

[work][OpenOffice][SDK][java] Professional UNO読み中(12) Modules

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Modules
を読む。

Modules

ModuleとはC++でいうところのnamespace、Javaで言うところのpackage。
同じ名前のインタフェースとか作ってもModuleが違えば大丈夫よ。

で、com.sun.star.unoなんていうModuleを作るときはネストするんだって。


module com {
module sun {
module star {
module uno {
interface XInterface {
...
};
};
};
};
};
 

面倒くさー。


.

[work][OpenOffice][SDK][java] Professional UNO読み中(11) Sequences

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Sequences
を読む。

Sequences

シーケンスというのは同じ型のひとつの塊。


sequence< com::sun::star::uno::XInterface >
sequence< string > getNamesOfIndex( sequence< long > indexes );
 

こーんなかんじー。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(10) Predefined values

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Predefined_Values
を読む。

Predefined value
#defineとかconstとかfinalみたいな感じ?

UNOでは、2つのpredefined valueをサポートしている。
1つはconstでもうひとつはenumeration。

const
constはUNOで有効な型の名前のついた値を定義する。


const short ID = 23;
const boolean ERROR = true;
const double PI = 3.1415;
 

こんな感じ。
通常constはconstantの一部として使われる。


constant
constantはconst値の名前のついたまとまり。

constants ImageAlign {
const short LEFT = 0;
const short TOP = 1;
const short RIGHT = 2;
const short BOTTOM = 3;
};
 

こんな感じー。


enum
C++のenumみたいなもの。
1つ以上のlong値を表す識別子の順序付きリスト。
普通は0から始まり、1づつ増える。
任意の識別子に値が代入されたら、その識別子は代入された値になる。
代入されていない識別子は常に前の識別子に1足された値。

// com.sun.star.uno.TypeClass
enum TypeClass {
VOID,
CHAR,
BOOLEAN,
BYTE,
SHORT,
...
};

enum Error {
SYSTEM = 10, // value 10
RUNTIME, // value 11
FATAL, // value 12
USER = 30, // value 30
SOFT // value 31
};
 

こんな感じー。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(9) Structs

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Structs
を読む。

Structs
構造体のようなもの?
structの要素はstructの中で一意な名前をもつ、UNOで使える型のObject。
アクセサーを持たない。
さらに1つだけ継承できる。

で、その例。


struct EventObject
{
/** refers to the object that fired the event.
*/
com::sun::star::uno::XInterface Source;

};

// com.sun.star.beans.PropertyChangeEvent
struct PropertyChangeEvent : com::sun::star::lang::EventObject {
string PropertyName;
boolean Further;
long PropertyHandle;
any OldValue;
any NewValue;
};
 



polymorphic struct type
OpenOffice.org2.0で導入されたstruct。
ジェネリックスとかテンプレートみたいなもの?
1つ以上の型をパラメータとして受け取る。

で、その載っていた例。

// A polymorphic struct type template with two type parameters:
struct Poly {
T member1;
T member2;
U member3;
long member4;
};

// Using an instantiation of Poly as a UNO type:
interface XIfc { Poly fn(); };
 



.

2008年12月27日土曜日

[work][OpenOffice][SDK][java] Professional UNO読み中(8) Services

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Services
を読む。

Service
interfaceは多重継承できる。
実装する人がいらいらするんで、Serviceはインタフェースで分類されたメソッドコールを通して利用するらしい?

Referencing Interfaces
サービスの定義中のインタフェースへのリファレンスはサービスがインタフェースを実装しなければならないことをあらわす。
[optional]フラグが付いている場合には、可能であれば実装する。

で、その例。


service TextDocument
{
...

interface com::sun::star::text::XTextDocument;
interface com::sun::star::util::XSearchable;
interface com::sun::star::util::XRefreshable;
[optional] interface com::sun::star::text::XFootnotesSupplier;
[optional] interface com::sun::star::text::XEndnotesSupplier;

...
};
 

XTextDocument、XSearchable、XRefreshableは実装しなきゃならない。
で、XFootnotesSupplierとXEndnotesSupplierは「可能であれば」実装する。


Service Constructors

新スタイルサービスではコンストラクタも記述できる。
戻り値は書かない。

でその例。

service SomeService: XSomeInterface {
create1();
create2([in] long arg1, [in] string arg2);
create3([in] any... rest);
};
 


create1、create2、create3がコンストラクタ。

raises (Exception1, ...)
 

ってな感じで書いておけば、例外も記述できる。

典型的なサービスのコンストラクタは"create"だそうで。


Including Properties

Propertyというのはオブジェクトのデータ。
一般的なインタフェース、getPropertyValue()とsetPropertyValue()を通して
提供される。

で、プロパティ定義の例

service TextContent
{
interface com::sun::star::text::XTextContent;
[optional, property] com::sun::star::text::TextContentAnchorType AnchorType;
[optional, readonly, property] sequence AnchorTypes;
[optional, property] com::sun::star::text::WrapTextMode TextWrap;
};

TextContetサービスは、1つのインタフェースと、3つのオプショナルなプロパティを持つ。

プロパティを記述するときに使えるフラグは以下のとおり。
[optional]
実装時に必ずしも実装しなくても良いプロパティ。
[readonly]

プロパティの値はcom.sun.star.beans.XPropertySetで値を変えることができない。
[bound]

プロパティ値の変更はXPropertyChangeListenerへ伝達される。
ただし、com.sun.star.beans.XPropertySetで何か登録されてれば。

[constrained]

そのプロパティ値が変更される前にイベント起こす。
そのイベントリスナーは値の変更を拒否できる。
[maybeambiguous]

場合によりプロパティ値を決められないもの?
[maybedefault]

オブジェクトそのものの代わりにスタイルシートとか環境とかに保存されるかもしれない?
[maybevoid]

プロパティタイプの範囲によっては空になりうる。データベースのnull値に似てる。
[removable]

削除可能。ダイナミックプロパティなるものに使われる。
[transient]

オブジェクトがシリアライズされてればプロパティは保存されない?



Referencing other Services

old-styleサービスは他のold-styleサービスを含めることができる。
[optional]も指定可能。

service Paragraph
{
service com::sun::star::text::TextContent;
[optional] service com::sun::star::text::TextTable;
[optional] service com::sun::star::style::ParagraphProperties;
[optional] service com::sun::star::style::CharacterProperties;
[optional] service com::sun::star::style::CharacterPropertiesAsian;
[optional] service com::sun::star::style::CharacterPropertiesComplex;

...
};
 


ふーん。


Service Implementations in Components
コンポーネントは、共有ライブラリかJavaの1つ以上のサービスのある言語バインディング実装を含むアーカイブ。
UNOランタイムに登録しなきゃならない。

ふーーん。
.

[work][OpenOffice][SDK][java] Professional UNO読み中(7) Interfaces

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Interfaces
を読む。

Interface

UNOオブジェクト間通信はInterfaceなるものに基づいている。
Interfaceっつーのは、外側から見れば、そのオブジェクトを理解せずに使うことが
できるようになるものを提供する。
内側から、もしくはUNOインタフェースを実装する人から見れば、
Interfaceは抽象的な仕様である。

便利でしょと。

UNOではInterfaceなオブジェクトはinterface型というもの使う。
慣例でInterfaceなオブジェクトの先頭は'X'で始まると。
で、全てのInterfaceはcom.sun.star.uno.XInterfaceを継承しなきゃならん。
InterfaceはUNOオブジェクトへのアクセスを提供するために、メソッドを定義する。
exceptionを定義してもいいらしい。

なにも定義しないとRuntimeExceptionをスローするみたい。


で、載ってたサンプル。


// base interface for all UNO interfaces
interface XInterface
{
any queryInterface( [in] type aType );
[oneway] void acquire();
[oneway] void release();

};

// fragment of the Interface com.sun.star.io.XInputStream

interface XInputStream: com::sun::star::uno::XInterface
{
long readBytes( [out] sequence aData,
[in] long nBytesToRead )
raises( com::sun::star::io::NotConnectedException,
com::sun::star::io::BufferSizeExceededException,
com::sun::star::io::IOException);
...
};
 

Javaそっくりなんだけど、[]で囲まれたやつがなんじゃこりゃ。

[oneway]

非同期に実行するものを示すフラグ。

[in]

入力パラメータを示すフラグ

[out]

出力パラメータを示すフラグ

[inout]
入出力パラメータを示すフラグ。


.

[work][OpenOffice][SDK][java] Professional UNO読み中(6)

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/The_Any_Type

を読む。

Any型

全てのほかの型をあらわせるらしい。
各プログラミング言語バインディングでは特別な扱いをしなきゃならない。
JavaにはAnyConverterというのがあるらしい。
C++には特別なoperatorが用意されるらしい。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(5)

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Simple_Types
を読む。


UNOの型説明
void
boolean真偽値。trueかfalse
byte符号付き8ビット整数型(-128から127)
short符号付16ビット整数型(−32768から32767)
unsigned short符号なし16ビット整数型(deprecated)
long符号付き32ビット整数型(−2147483648から2147483647)
unsigned long符号なし32ビット整数型(deprecated)
hyper符号付き64ビット整数型(−9223372036854775808から9223372036854775807)
unsigned hyper符号なし64ビット整数型(deprecated)
floatIEC 60559(IEEE 754)単精度浮動小数点型
doubleIEC 60559(IEEE 754)倍精度浮動小数点型
char個々のUnicode文字を表現する型(正確にはUTF-16だそうで)
stringUnicode文字列(正確には「strings of Unicode scalar values」)
typeUNOの全てのタイプを記述しているメタ型
any他の全ての値を表すことができる特別な型


うーん。
ま、型ですな。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(4) Data Types

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Data_Types
を読む。

Data Types

APIリファレンスのデータタイプはUNOタイプ。
UNOタイプは各プログラミング言語にマップされ、APIで使用する。
FirstStepで触れたinterfaceとかpropertieとかserviceのほかにも、

  1. special flag
  2. condition
  3. relationship
っつーのがあるんだって。
で、UNOをプロフェッショナルレベルで使いたいなら、知っときたいだろうって。
で、その辺説明すっぺ。


だとさ。
.

[work][OpenOffice][SDK][java] Professional UNO読み中(3) APIConcepts

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/API_Concepts
を読む。

API コンセプト
OpenOffice.orgの機能へのアプローチに依存しないAPI。

API のゴール

  1. OpenOffice.orgの機能にアクセスするためのAPIの提供
  2. OpenOffice.orgの機能を拡張できるようにすること
  3. 内部の実装を交換可能にすること

で、長期的ロードマップとして今あるOpenOffice.orgをぶった切ってちっちゃい
コンポーネントにしていると。
で、これが完成すると、OpenOfficeは単なるOfficeスイートでなくなるよ
ってことが書いてあるかもしれない。

ほほー。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(2)

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Introduction

を読む。

UNOのゴール
プラットフォームやプログラミング言語を超えて「ネットワークオブジェクト」の環境を提供すること。

UNOゴールKPA

  1. UNOオブジェクトはメタ言語(UNOIDL)で指定。CORBAのIDLみたいなやつ。
  2. サービスマネージャというFactory機構を使ってnewする。
  3. オブジェクト間通信、プロセス間通信にブリッジを提供。(URPというプロトコルを使う)
  4. 大抵のOpenOffice.orgのオブジェクトをUNO環境で通信できるようにする

といった感じかもしれない。

.

[work][OpenOffice][SDK][java] Professional UNO読み中(1)

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Professional_UNO

を読む。


「Professional UNO」では、
UNOの詳細な情報といろんなプログラミング言語でUNOを使う情報を提供するらしい。

まず、
概念な感じの大枠から見てって、
APIの概念、その背景的なのを見てって、
UNOの概念、仕組みなぞを見てって、
UNOの各言語バインディングを詳しく見てったりする。
らしい。

ふうーん。
.

2008年12月26日金曜日

[work][OpenOffice][SDK][java] とりあえずfirstStep終了

やっとこさっとこ、FirstStep読み終えた。。

雑感としてはとっても面倒。
しょうがないとは思うけど。


次はProfessional UNOでインターネットのゴミを生産します。
.

[work][OpenOffice][SDK][java] FirstStepメモ(8) Shape

図形の位置、サイズなどを扱うのがShape。

com.sun.star.drawing.XShapeっつーインタフェースが定義されている。

OpenOfficeでは11個もある基本を成す図形があるそうだ。
特性を反映するプロパティ群を保持する6つ。

  1. com.sun.star.drawing.EllipseShape(円とか楕円とか).
  2. com.sun.star.drawing.RectangleShape(矩形).
  3. com.sun.star.drawing.TextShape(テキストボックス).
  4. com.sun.star.drawing.CaptionShape(ラベリングって何?).
  5. com.sun.star.drawing.MeasureShape(計量???)
  6. com.sun.star.drawing.ConnectorShape(図形同士をつなげたりする線)
独自のプロパティを持ってない5つ。
  1. com.sun.star.drawing.LineShape(線とか矢印とか)
  2. com.sun.star.drawing.PolyLineShape(まっすぐな感じの線)
  3. com.sun.star.drawing.PolyPolygonShape(多角形)
  4. com.sun.star.drawing.ClosedBezierShape(ベジェ曲線とか??)
  5. com.sun.star.drawing.PolyPolygonBezierShape(もはや意味不明・・・)
でもって、全てのShapeは以下のプロパティを使うよ。
  1. com.sun.star.drawing.Shape(全てのShapeの基本的プロパティ)
  2. com.sun.star.drawing.LineProperties(線はどんな感じにする?っていうプロパティ)
  3. com.sun.star.drawing.Text(こいつはプロパティを持っていないけど、以下を含むって。)
  4. com.sun.star.drawing.TextProperties(付番、テキストアラインなど)
  5. com.sun.star.style.ParagraphProperties(段落整形など)
  6. com.sun.star.style.CharacterProperties(文字の形式など)
  7. com.sun.star.drawing.ShadowProperties(図形の影を扱う)
  8. com.sun.star.drawing.RotationDescriptor(ローテイト関連)
  9. com.sun.star.drawing.FillProperties(どんな感じで塗りつぶす?)
  10. com.sun.star.presentation.Shape(はて?)

うーん。

とりあえず、やりたいことはこの辺でできそうだけど。。。
.

[work][OpenOffice][SDK][java] FirstStepメモ(7) Table

Table。

そもそもTableって何?
Cellのことかと思いきやそれだけじゃないみたい。良くわからない。

で、
XCellRangeインタフェースというのが提供されているんで、
こいつを使用してXCellを取得できる。
XCellを取得したら、そのXCellに式や値を設定できるんだそうだ。

Tableのプロパティを扱う場合には、スプレッドシートのテーブルか、テキストのテーブルかで
扱い方が異なる。

CellのプロパティはCellPropertiesを使う。
TextTableはcom.sun.star.text.TextTableを使う。

カーソルというものもある。

TextTableの場合にはcom.sun.star.text.TextTableCursorで、
スプレッドテーブルの場合にはcom.sun.star.sheet.SheetCellCursorだそうだ。

うーん。良く分からん。
.

[work][OpenOffice][SDK][java] FirstStepメモ(6) Text

共通で扱えることを強調したいんで、共通のインタフェース、プロパティからはじめるよってさ。んでもって、あとで違いを示しまっせと。

Textインタフェース

Textインタフェースは、com.sun.star.text.XTextだとのこと。
単一の文字列をセットしたりゲットしたりTextを置く場所を指定できるよ。
で、com.sun.star.text.XSimpleTextを継承してて、さらにcom.sun.star.text.XSimpleTextは
com.sun.star.text.XTextRangeを継承してるよ。
XTextは

  1. insertTextContent()
  2. removeTextContent()
メソッドを通して操作する。

テキストフォーマットは、
  1. com.sun.star.style.ParagraphProperties
  2. com.sun.star.style.CharacterProperties
を通してやりますよ?

で、シートに貼り付けるのはどうするんだろ。
.

[work][OpenOffice][SDK][java] FirstStepメモ(5) Text、Table、Shape

いよいよ、Text、Table、Shapeを扱ってみるところまできた。

Text、Table、Shapeの共通的な部分をざっくりやるらしい。
それらはScalc、Writer、Draw/Impressのどれでも同じように扱えるらしい。

ほほー。

.

[Haskell] HoogleとHayoo

知らなかった。

そんなのあるのね。

HoogleはGoogle、HayooはYahooって感じだけど、

読みはなんだろうー。

ほーぐる



はよー?

.

[work][OpenOffice][SDK][java] FirstStepメモ(4) サンプル

リモートのサービスマネージャからDesktopオブジェクトもらって
そいつのloadComponentFromURL()メソッド使って新しいスプレッドシートでも作ってみて、
そいつにシートつけて、そのシートのA1、A2、A3に値を入れるてみるサンプルらしい。

A3はA1とA2の合計値。


で、今回のきもっぽいところだけ。

1) 例のbootstrap()便利関数で、officeの起動とかやってもらって、リモートコンテキストを
取得する。


xRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
 


2) 取得したリモートコンテキスト使ってサービスマネージャを取得する。

xRemoteServiceManager = xRemoteContext.getServiceManager();
 


3) サービスマネージャのcreateInstanceWithContext()メソッド使ってDesktopオブジェクト
を取得する。


Object desktop = xRemoteServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", xRemoteContext);
 


4) queryする。

XComponentLoader xComponentLoader = (XComponentLoader)UnoRuntime.queryInterface(
XComponentLoader.class, desktop);
 


5) xComponentLoader.loadComponentFromURLメソッド使ってスプレッドシートコンポーネントを
取得。

XComponent xSpreadsheetComponent = xComponentLoader.loadComponentFromURL(
"private:factory/scalc", "_blank", 0, loadProps);
 

loadPropsにはプロパティがセットされるらしい。
"private:factory/scalc"って指定するとスプレッドシートコンポーネントが取得できるっぽい。

6) queryしてXSpredsheetDocument取得。

XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument)UnoRuntime.queryInterface(
XSpreadsheetDocument.class, xSpreadsheetComponent);
 



7) スプレッドシートコンテナなるものを取得。

XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets();
 


8) 新しいシート作成。


xSpreadsheets.insertNewByName("MySheet", (short)0);
 


9) 新しいシートを操作したいので、新しいシート"MySheet"を取得。

Object sheet = xSpreadsheets.getByName("MySheet");
XSpreadsheet xSpreadsheet = (XSpreadsheet)UnoRuntime.queryInterface(
XSpreadsheet.class, sheet);
 

うーん。面倒くさい。。
取得・クエリーはいつもセット??


10) そしたら、各セルに値をセット。A1は(0,0)、A2は(0,1)、A3は(0.2)らしい。

XCell xCell = xSpreadsheet.getCellByPosition(0, 0);
xCell.setValue(21);

xCell = xSpreadsheet.getCellByPosition(0, 1);
xCell.setValue(21);

xCell = xSpreadsheet.getCellByPosition(0, 2);
xCell.setFormula("=sum(A1:A2)");
 


11) その他いろいろプロパティセット。



--
今のところ、毎回queryするのが面倒。
これはこれで言語非依存のインタフェースを実現するにはやむ負えないのかもしれないけど。

.

2008年12月25日木曜日

[work][OpenOffice][SDK][java] FirstStepメモ(3) com.sun.star.beans.XPropertySet

オブジェクトはオブジェクト自身のプロパティをインタフェースを通して、
提供しなければならないとのこと。

インタフェースは以下の2つ。


com.sun.star.beans.XPropertySet
 



com.sun.star.beans.XMultiPropertySet
 

の2つ。

で、どちらも一回のコールで、複数のプロパティを設定、取得できる。


XPropertySetの方はすべてのサービスで提供される。
プロパティを扱うメソッドは、

void setPropertyValue(String propertyName, Object propertyValue)
Object getPropertyValue(String propertyName)
 

の2つ。アクセサー。

で、使っているサンプル。

// query the XPropertySet interface from cell object
XPropertySet xCellProps = (XPropertySet)UnoRuntime.queryInterfac(XPropertySet.class, xCell);

// set the CellStyle property
xCellProps.setPropertyValue("CellStyle", "Result");
 

上は、queryInterfaceを使用して、xCellのプロパティを取得している。
下は、上で取得したXPropertySetで、特定のプロパティに値を設定している。
もちろんポインタなので、xCellのプロパティが変更される。

.

[work][OpenOffice][SDK][java] FirstStepメモ(2) queryInterface()

queryInterface()には2つの定義がある。


java.lang.Object UnoRuntime.queryInterface(java.lang.Class targetInterface, Object sourceObject)
 



java.lang.Object UnoRuntime.queryInterface(com.sun.star.uno.Type targetInterface, Object sourceObject)
 

の2つ。

どちらも戻り値はjava.lang.Objectなので、明示的にキャストが必要。

もし、指定したターゲット(targetInterface)がとれない場合はnullが返される。

.

[work][OpenOffice][SDK][java] FirstStepメモ中(1)

UNOのすべてのオブジェクトはinterfaceで操作するとのこと。

で、オブジェクトのメソッドを呼びたい場合には、事前に適切な型にCastすると。

うげ。

実行時にチェックしないと、ClassCastExceptionですか。。
ここはとっても面倒そう。。


と思いきや、JavaのUNOにはqueryInterface()というメソッドが用意されていると。

いい感じにオブジェクトを取得して、いい感じにCastしたりしてくれると。

ほほー。

で、以下queryInterfaceメソッドを利用して、
DesktopオブジェクトからXComponentLoaderオブジェクトを取得する例。


Object desktop = xRemoteServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", xRemoteContext);

XComponentLoader xComponentLoader = (XComponentLoader)
UnoRuntime.queryInterface(XComponentLoader.class, desktop);
 

ほほー。
タイプ量が多いっす。。

で、XMultiComponentFactory.createInstanceWithContext()
を使用して、com.sum.star.frame.Desktopサービスを生成。
createInstanceWithContextは、

Object createInstanceWithContext(String serviceName, XComponentContext context)
 

と定義されている。
で、返されたObjectをqueryInterfaceを使用してCastやらなにやらして、XComponentLoaderを取得と。

すぐに慣れるらしい。

.

2008年12月24日水曜日

[work][OpenOffice][SDK][java] InterfaceとService

OpenOfficeでは、

  1. 仕様と実装を分けたい
  2. 実クラス名ではなく、仕様上のインタフェース名、サービス名で、newしたい
から、IDLみたいなので定義されているらしい。


module com { module sun { module star { module bridge {
serviceUnoUrlResolver: XUnoUrlResolver;
}; }; }; };
 

こんな感じで。

ふーん。
.

[work][OpenOffice][SDK][java] オブジェクト取得の方法

引き続きFirstStep中メモ。

OpenOffice中のオブジェクトを取得するには、

  1. serviceManagerからDesktopオブジェクトを取得する。
  2. 取得したDesktopオブジェクトからDocumentオブジェクトを取得する。
とするらしい。

Desktopオブジェクトはwindowやドキュメントのロードを担当、
DocumentオブジェクトはOpenOfficeで開かれたファイルを表している。

で、OpenOfficeのオブジェクトたちは、保持するオブジェクトを
他のオブジェクトたちに大きく2つの方法で渡すことができる。
  1. integralなgetメソッド群
  2. universalなプロパティ
の2つ。

getメソッド群はgetText()とかそういうの。
プロパティというのは、
getPropertyValue(propertyName)っていう特殊はメソッドで取得するやつ。

普段はgetメソッド群を使えばよいらしいが、たまに、オブジェクト固有の要素があったりするんで、
プロパティ経由でアクセスしなきゃならんよ、って書いてあった気がする。

ふーん。

.

[work][OpenOffice][SDK][java] とりあえずOpenOfficeのUNOポートに接続してみた

http://wiki.services.openoffice.org/wiki/Documentation/DevGuide
のとおり、FirstStep中。


# apt-get install openoffice.org openoffice.org-dev
 

でインストール。

FirstStepに書かれてあるbuild.xmlを参考に、ここで必要なjarは、、、、

/usr/lib/openoffice/program/classes/{jurt.jar,unoil.jar,ridl.jar,juh.jar}
 

だけ。

あと、CLASSPATHに入れておかなければいけないのは、、、

/usr/lib/openoffice/sdk/com/sun/star/lib/loader/*.class
 

らしい。

で、FirstStepのとおりのコードを書き・・・、ant。で、ant run。
おぉー。接続した。

X-Serverに接続しに行くので、Xも起動しておかないとダメ。
X-Serverなしでできないかと探してみたけど、OpenOfficeのメーリングリストで、
without X-Serverは非対応だって言っていた。
残念。

で、動かしたソースは、

public class FirstUnoContact {
public static void main(String[] args) {
try {
// get the remote office component context
com.sun.star.uno.XComponentContext xContext =
com.sun.star.comp.helper.Bootstrap.bootstrap();

System.out.println("Connected to a running office ...");

com.sun.star.lang.XMultiComponentFactory xMCF =
xContext.getServiceManager();

String available = (xMCF != null ? "available" : "not available");
System.out.println( "remote ServiceManager is " + available );
}
catch (java.lang.Exception e){
e.printStackTrace();
}
finally {
System.exit(0);
}
}
}
 

。。。
FirstStepのまんまでした。

OpenOffice の UNO APIを使用するには、
  1. クライアントでUNOの初期化
  2. サーバからコンポーネントコンテキスト取得
をしなきゃならないらしい。
内部的には、
  1. ServiceManagerを初期化して、
  2. OpenOffice.orgサーバとの接続を確立して、(サーバが居なければ立ち上げる)
  3. OpenOffice.orgサーバからコンポーネントコンテキストを取得する
だそうで。

FirstStepでは、この辺の面倒なところを、

com.sun.star.comp.helper.Bootstrap.bootstrap()

がやってくれているらしい。

次に、

xContext.getServiceManager();

がコールされ、serviceManagerを取得している。
OpenOffice.orgのUNO APIではこのserviceManagerが肝なんだってさ。

ふーん。


ついでに、OpenOffice.orgを事前にサーバとして立ち上げておく場合と
サーバとして立ち上げておかない場合でやってみたら、どちらもうまくうごく(もちろんそうだ。。)

が、やっぱり事前にサーバとして立ち上げておかないと重いねー。
.

2008年12月23日火曜日

[work][OpenOffice][SDK][java] サーバとして起動する

OpenOfficeをUNOポートソケット付きで起動するメモ。
UNOはUniversal Network Objectの略だそうで。
UNOポートソケット付きで機動すると、このポート経由でOpenOfficeを扱えるようになる、
らしい。

で、起動方法。


$ soffice '-accept=socket,port=8100;urp;' -display 127.0.0.1:1 -headless
 

意味は今のところ不明(後で追記予定)。
.

[git] コミット前に任意のworking tree中の1ファイルをリポジトリの状態に戻す

間違って編集してしまったあるファイルをローカルリポジトリの状態に戻すに は、、、



$ git checkout あるファイル
 


でオーケー。

.

[その他] ガソリン価格が100円台

今日も出社がてら近所のガソリンスタンドの価格を拝見。

レギュラーで、とうとう110円を割って108円でした。

というか、ニュースを見る限り、近所のガソリンスタンドは若干安いことが判明。

へー。
.

2008年12月20日土曜日

[jython] jythonc

え?なに?
.

[java][clojure] 使いたいなー

先生がclojureというLispの方言を使ってたから、自分も使いたかったんだけど、

使っちゃダメだってー。

使いたいなー。いいなー。

kawaだとちょっとミスすると、エラーにならずに壊れたclassファイルが出力されるんだよね・・。
それとJava<->kawa間でのやりとりが実は結構面倒に感じた。
.

[work] IE6のバグ

数年前も同じバグにひっかかった。。
no-cacheにすると、IE6でダウンロードできないバグ。
いい加減覚えろ!ということでメモ。

.

[mod_chxj] 0.12.31リリース

これまた今さら必要ないかもしれませんが、、

  1. QSConvOff
  2. JRConvOff
  3. NoCacheOn
の3つのオプションを加えました。

それぞれ、

ChxjConvRule "^/.+$" "EngineOn,QSConvOff,JRConvOff,NoCacheOn" "UTF-8"
 

などと指定します。

QSConvOff
QUERY_STRINGのhiddenタグへの振り替え処理を無効にします。

JRConvOff
SoftBank予約パラメータを透過的に扱えるようにするための変換を無効にします。

NoCacheOn

Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store
 

の3つのヘッダを強制出力します。既にセットされている場合は上書きします。

いつも、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans
PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean
id="noCacheHandlerInterceptor"
class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds"><value>0</value></property>
<property name="useCacheControlHeader"><value>true</value></property>
<property name="useExpiresHeader"><value>true</value></property>
</bean>
</beans>
 

なんてのを入れているのですが、毎回セットアップするのが馬鹿馬鹿しい。
ということで入れました。

HTMLファイルを直接変換させる場合などキャッシュが効きまくるのを防ぎます。

Wikiにも書きましたので、そちらもご参照ください。

.

2008年12月19日金曜日

[git][mod_chxj][subversion] trunkへのdcommitが失敗

reset --softオプションのメモ。

subversionのtrunk用ブランチmaster-svn
と、
gitのmaster用ブランチmaster
と2つあって、いつもmasterで修正をし、


$ git commit -a
$ git push sourceforge.git master
 

などとやって、sourceforge.jpにコミットする。
その修正分をsubversionにも反映したく

$ git checkout master-svn
$ git merge master --no-ff
 

とマージし、

$ git svn dcommit
 

とやっているんだけど、やり方がまずいのか、突然やたらと
コンフリクトが出てなんか変。

やむを得ないので、

$ git branch -D master-svn
$ git checkout -b master-svn master
 

とmasterからブランチを作成し、

$ git checkout master-svn
$ git reset --soft trunk
 

で切り替え、

$ git svn dcommit
 

で解決。
多分次から、git merge masterでいけると思う。。

.

[その他] Geek Test

I am 47% Geek.
Geek? Yes, but at least I got social skills.
You probably work in computers, or a history deptartment at a college. You never really fit in with the "normal" crowd. But you have friends, and this is a good thing.

2008年12月18日木曜日

[git][mod_chxj] clone

sourceforge.jpにも書いてあるし、もちろんドキュメントにも書いてあるんだけどメモ。


git clone git://git.sourceforge.jp/gitroot/modchxj/mod_chxj.git
 

が、

svn checkout http://svn.sourceforge.jp/svnroot/modchxj/mod_chxj
 

みたいな感じ。


git clone git://git.sourceforge.jp/gitroot/modchxj/mod_chxj.git hehehe
 



svn checkout http://svn.sourceforge.jp/svnroot/modchxj/mod_chxj hehehe
 

みたいな感じ。

originがセットされてるんで、branchを取りたい場合は

cd hehehe
git checkout -b branch_0.12.0 origin/branch_0.12.0
 

でいける。



で?
.

2008年12月16日火曜日

[mod_chxj] 0.12.28リリース

0.12.28をリリースしました。

0.12.27で追加したguidに関する機能のバグ修正と、SoftBankの予約パラメータを透過的に扱う機能追加です。

特にあたらしい設定はありません。

予約パラメータについてはこちらを参照ください。
.

[その他]ガソリン価格が111円

そういえば、昨日の出勤途中にガソリンスタンドをのぞいてみたら、
ガソリン価格が111円だった。
.

[mod_chxj] ふと、Apache2::Filter

Apache2::Filterを使えば、結構楽ちんだと思いますよー。

しかも、perlハッカーらがいろいろ便利なモジュール作ってくれてるし。

というか、すでに誰かフレームワーク作ってるんで、今から作る必要ないような気もしないでもない。
.

[work] えーと

眠い。

.

2008年12月15日月曜日

[work] ペース配分間違った

ペース配分間違った。。

やべー。

.

[mod_chxj] POSTデータ中の絵文字を変換する件

心配になったので、書いておきます。

現在のリリースバージョンでは、POST/GETデータ中の絵文字を変換していません。


POST/GETデータ中の絵文字変換はsubversionのold-trunkで実装したのですが、
根本的な問題があり、リリースは見合わせました。

現在のリリースバージョンはその根本的な問題が解決されていますが、
リリースバージョンに導入するタイミングは今のところ0.14.x以降の予定です。

すみません。
.

2008年12月14日日曜日

[python] エンコード宣言

毎回ぐぐってるんで、メモ。


# -*- coding: <encoding-name> -*-
 


.

2008年12月13日土曜日

[git]めんどいのでalias

なんとなくキー入力が面倒になってきたので、aliasすることにした。

やりたいことは、


git commit -a
 

が、面倒なので、

git ci
 

ってする。

git checkout xxxxx
 

は、

git co xxxxx
 

ってする。

ということで、
~/.gitconfigファイルを編集して以下を追加。


[alias]
ci = commit -a
co = checkout
 

を加えた。

終了ー。

これでちょっとだけ入力が減った。

ほっほー。
知らなかった。
.

2008年12月9日火曜日

[mod_chxj] 0.12.26リリース

昨日に引き続き、0.12.26をリリースしました。

内容は、


  • アニメーションGIFに関するバグを1つ修正

  • X-Chxj-Set-Content-Type


の2つです。

X-Chxj-Set-Content-Typeヘッダをアプリケーションから送出すると、
mod_chxjは、変換結果のContent-Typeヘッダと、metaタグを強制的に
X-Chxj-Set-Content-Typeヘッダで指定された文字列に置き換えます。

PHPでは、

<?php header("X-Chxj-Set-Content-Type: application/xhtml+xml; charset=SHIFT_JIS"); ?>
 

とすれば、出力されるContent-Typeヘッダは

Content-Type: application/xhtml+xml; charset=SHIFT_JIS
 

になり、
metaタグは、

<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=SHIFT_JIS" />
 

となります。

こちらにも同様のことを書いておきましたので、ご参照ください。

.

[その他] ガソリン価格が119円

毎日ではないけど、通勤途中にあるガソリンスタンドのガソリン価格を見ているんだけど、
今日見てみたら、レギュラーで119円。

あらら。。


石油王真っ青ですかね。

.

2008年12月8日月曜日

[mod_chxj] 0.12.25をリリース

必要ないかもしれませんが、、、

Z2hOnのほかに、Z2hAlphaOn、Z2hNumOnをつけました。

Z2hAlphaOnは全角英字を半角英字に変換します。
Z2hNumOnは全角数字を半角数字に変換します。

上記はそれぞれ、


ChxjConvertRule "^/.*$" "EngineOn,Z2hOn" "UTF-8"
ChxjConvertRule "^/.*$" "EngineOn,Z2hAlphaOn" "UTF-8"
ChxjConvertRule "^/.*$" "EngineOn,Z2hNumOn" "UTF-8"
 

と指定できます。
また、上記の3オプションとも有効にする、
Z2hAllOn
というものもつけました。


ChxjConvertRule "^/.*$" "EngineOn,Z2hAllOn" "UTF-8"
 

と指定すればOKです。

また、全角カタカナ、半角カタカナ変換機能(0.12.23以降)も参照ください。

.

2008年12月6日土曜日

[work][java] jodatime

うちの会社ではデフォルトで使っているJoda Timeというものを

生まれて初めて使ってみた。

Joda Timeは、Java標準のDateとかTimeとかに変わるものらしい。

Java標準の時間系クラスは最悪の設計で、バグだらけで、奇妙な動きをするとのこと。

さらにJava標準と比べて、速いらしいんだけど・・・。
うん。
体感できない・・。

.

2008年12月5日金曜日

2008年12月2日火曜日

[その他] 裁判員制度

裁判員制度で、通知が来たことを公開した方々が多数いるとのニュース。


裁判員や候補者に選ばれたことを、不特定多数に対して個人が特定できるような形で公表することを禁止。
 

らしいんだけど、知らなかったし、大多数の人たちが知らないと思うんだけど。。
ま、危険ぽいし公開しない方がよさそうだけど。


ところで、いつから我が国の司法関連が信頼無くなったことになったんだろう・・。
ごくたまに変なニュースが流れることもあったような気がするけど。

先進国(?)欧米では裁判沙汰覚悟で招集通知を無視する人が多いのだそうで。(本当?)

うーん。
.

2008年11月28日金曜日

[携帯] emoji4unicode

グーグルがemoji4unicodeというプロジェクトを開始したみたい。

これは良いかも。

と思ったけど、すでに誰かやっていた気が・・・。
.

2008年11月27日木曜日

[mod_chxj]とりあえずデータ追加終わり

やっと終わった。。

これで、11月7日発売分まで定義完了。

.

2008年11月25日火曜日

[mod_chxj] メモ:新たに追加しようとしているデータ


au W65K
au W62P
au W64S
SoftBank 830P
SoftBank 830SHs
SoftBank 830SH
au W64T
au W63Kカメラ無し
au W63SH
SoftBank 824T
DoCoMo SH706iw
au W62PT
DoCoMo N706iII
DoCoMo SH706ie
SoftBank 823T
DoCoMo N706ie
DoCoMo P706ie
DoCoMo NM706i
SoftBank 921P
DoCoMo F884iES
DoCoMo L706ie
au W64SA
SoftBank 824P
DoCoMo P706iμ
au W62CA
au W62H
au W62SH
DoCoMo SH706i
SoftBank 824SH
SoftBank 923SH
au W63S
au W63SA
DoCoMo SO706i
SoftBank 820N
SoftBank 821N
SoftBank 825SH
DoCoMo N706i
SoftBank 823P
DoCoMo F706i
DoCoMo SH906iTV
au W63K
au W64K
DoCoMo N906iL
DoCoMo N906i
au W63T
au W62K
 

.

2008年11月24日月曜日

[その他]ガソリン価格

とうとう120円代に突入したみたい。

こんなスピードで下落してて大丈夫なのかしら。

.

[Oracle]空文字列とnull

いつもOracle使うと思うのだけど、空文字列とnullが同じ扱いというのは
やだなー。

.

2008年11月21日金曜日

[その他] テレビニュースのターゲット層

どうもテレビニュースのターゲット層は

「高卒、50歳以上、専業主婦」

だそうで。ちょっと前のNHKがそうらしい。

民放の方はもう少しやさしめなのだそうで。



なるほどねー。

.

2008年11月15日土曜日

[git][mod_chxj] SubversionにあるリポジトリをSourceforge.JPのGitに公開してみた

SubversionのリポジトリをSourceforge.JPのGitに公開する手順のメモ。

手順は以下のとおり。

  1. Sourceforge.JPのプロジェクト管理ページでGitを有効にする
  2. Sourceforge.JPのプロジェクトページから空のGitリポジトリを作成する
  3. Subversionのリポジトリをgit使ってclone
  4. cloneしたローカルリポジトリにremoteとしてSourceforge.JPの空のリポジトリを追加
  5. remoteにpush

Sourceforge.JPのプロジェクト管理ページでGitを有効にする
Sourceforge.JPのプロジェクトページから空のGitリポジトリを作成する
これはさっきやってきた。

Subversionのリポジトリをgit使ってclone
これはすでに作成済み。

$ git svn clone -T trunk -b branches -t tags \
svn+ssh://konn@svn.sourceforge.jp/svnroot/modchxj/mod_chxj
 

 

として作成したと思う。

cloneしたローカルリポジトリにremoteとしてSourceforge.JPの空のリポジトリを追加

$ git remote add origin \
konn@git.sourceforge.jp:/gitroot/modchxj/mod_chxj.git
 

んで 確認。

$ git remote show
origin
 


remoteにpush
さっき追加したoriginにmasterをpushする。
まず、念のため、user.emailをチェック。

$ git config user.email
konn@users.sourceforge.jp
  

で、push。

$ git push origin master
Counting objects: 23847, done.
Compressing objects: 100% (3552/3552), done.
Writing objects: 100% (23847/23847), 5.77 MiB 73 KiB/s, done.
Total 23847 (delta 20981), reused 23091 (delta 20252)
To konn@git.sourceforge.jp:/gitroot/modchxj/mod_chxj.git
* [new branch] master -> master
 

ほっほっほ。
完了。

一応ブランチとかも追加しておく。

$ git push origin branch_0.13.0
Counting objects: 1498, done.
Compressing objects: 100% (601/601), done.
Writing objects: 100% (1492/1492), 206.84 KiB 104 KiB/s, done.
Total 1492 (delta 891), reused 1492 (delta 891)
To konn@git.sourceforge.jp:/gitroot/modchxj/mod_chxj.git
* [new branch] branch_0.13.0 -> branch_0.13.0
$ git push origin branch_0.12.0
Total 0 (delta 0), reused 0 (delta 0)
To konn@git.sourceforge.jp:/gitroot/modchxj/mod_chxj.git
* [new branch] branch_0.12.0 -> branch_0.12.0
$ git push origin branch_0.11.0
Counting objects: 655, done.
Compressing objects: 100% (211/211), done.
Writing objects: 100% (616/616), 257.79 KiB 100 KiB/s, done.
Total 616 (delta 527), reused 482 (delta 404)
To konn@git.sourceforge.jp:/gitroot/modchxj/mod_chxj.git
* [new branch] branch_0.11.0 -> branch_0.11.0
 


いやいや、おなかいっぱい。

ん?
Git公開一番のり?
.

[git][mod_chxj] とりあえずSourceForge.JPにリポジトリを作成してみた

さっそくSourceforge.JPにGitリポジトリを作成してみた。
数日待つのかと思いきや、1~2分でリポジトリが作成された。

くっそー。

一番乗りできなかった。
すでにmagic3とnkfが先にあった。
多分、リポジトリ作成したのは3番目。

.

2008年11月14日金曜日

[git][mod_chxj]とりあえずGitを有効にしてみた

とりあえず、SourceForge.JPでGitを有効にしてきた。

リポジトリが作成されていないんで、まだ使えないけど。

へへ。
.

[git][mod_chxj] SourceForge.JPでGitがサポートされた!!

11月14日付けで、SourceForge.JPでGitがサポートされたみたい。
まだ試してないけど、gitwebもつかえるらしい。
現状限定的らいしんだけど徐々に機能を追加していくらしい。

多分、そのうちGitHubみたいになるんだろうなぁー。

さっそくのり変えよう。
一応、Subversionも生かしつつ。

.

[git] ある日、trunkにdcommitできなくなった

教えて君卒業のためのメモ。

ある日、trunkにgit svn dcommitできなくなった。
どうもfastforwardでmergeしたのが問題らしい。
そこで、、、


$ git checkout trunk
$ git merge --no-ff branch_0.13.0
 

と、--no-ffを指定して実行し、fastforwardでmergeしないようにする。

すると、あら不思議。

git svn dcommitできるじゃありませんか。

fastforwardでマージしてしまうと、変更をgitが検知できなくなる場合があるらしい。

.

[git] working treeを指定した時点の状態に戻す

教えて君卒業のためのメモ。

working treeを指定した時点の状態に戻すには、、


$ git rest --hard HEAD
 


などとやる。

.

2008年11月13日木曜日

[その他] digital natives

テレビはほとんど見ないんだけど、
晩御飯を食べながらテレビつけてみたら、
digital nativesに関する番組がNHKでやってた。

digital nativesって人の「属性」とか「肩書き」とかは考えない
人たちらしい。
だから、たとえ大会社でも対等に接するそうな。

大会社達はdigital nativesたちに対して脅威を抱いているらしく、
集まって対応策やらを考え初めているらしい。
大会社における階層構造やなにかにdigital nativesは順応しない
とのこと。

これって、昨今派遣社員が増えていることにも関係するのかな?
全然違うか。

.

[その他] 適正年収

なんだかよくわからないけど、
思わず「適正年収診断」なる広告をクリックしちゃった。
で、つい、適正年収診断ってやつをやってみたら、、、

1071万円

って出ました。
うそつきっ!!
.

2008年11月12日水曜日

[携帯] 顧客満足auがトップ

顧客満足度調査ですべての要素でauがトップだそうで。

へー。

.

[経済関連] ガソリン代が130円台

ふとガソリンスタンドを見てみたら、ガソリン代が138円。
ついこの間は177円。

すごい値下がり様。
OPECの方々は真っ青って感じでしょうか。。

.

[mod_chxj] CSSテスト中・・・

0.13.xリリースに向けて
未だにCSS関連のテスト中・・・。


libserfは鬼門?

.

2008年11月7日金曜日

[mod_chxj][rpm][CentOS5.1] RPMを作ってみた

CentOS5.1用のRPMを作ってみた。

RPMを作成するにはspecファイルなるものを作成する必要があるらしい。
RPMにするには環境もRPM用の環境を構築しなくちゃならないらしい。

以下、RPM作成手順のメモ。CentOS5.1上で行った。

1) 環境構築


$ mkdir rpm
$ cd rpm
$ mkdir -p BUILD RPMS/i386 SOURCES SPECS SRPMS ROOT
 


2) .rpmmacrosを作成

$ vi ~/.rpmmacros
 

記述内容は以下な感じ。

%_topdir /home/konno/work/rpm
 

で確認。

$ rpm --eval %_topdir
/home/konno/work/rpm
 


2) SOURCESにソースを設置

$ cd /home/konno/work/rpm/SOURCES
$ wget http://download.tangent.org/libmemcached-0.23.tar.gz
$ wget http://keihanna.dl.sourceforge.jp/modchxj/33654/mod-chxj_0.12.18.src.tar.gz
 


3) specファイルの記述
specファイルを作成する。

$ vi /home/konno/work/rpm/SPECS/mod-chxj.spec
 


4) rpmbuild
$ RPM_BUILD_ROOT=/home/konno/work/rpm/ROOT rpmbuild -bb /home/konno/work/rpm/SPECS/mod-chxj.spec

おしまい。

参考にしたのは、
mod_uploaderのspecファイル
mod_perlのspecファイル
phpのspecファイル
でした。

.

2008年11月5日水曜日

[CentOS5.1][yum] yum -y


# yum -y install
 

と-yをつけると、いちいち[y/N]にこたえなくてよいのねー。

.

[CentOS5.1][yum] yumでSRPMをインストール

CentOS5.1に四苦八苦。

CentOS5.1のyumでSRPMをインストールする際のメモ。

yum-utilsのインストール。


# yum install yum-utils
 


そして、、
/etc/yum.repos.d/CentOS-Base.repoを編集。

# vim /etc/yum.repos.d/CentOS-Base.repo
 

で、以下を追加。


## SRPM
[updates-SRPM]
name=CentOS-$releasever - updates SRPMS
baseurl=http://ftp2.riken.jp/Linux/centos/5/updates/SRPMS/

[extras-SRPM]
name=CentOS-$releasever - extras SRPMS
baseurl=http://ftp2.riken.jp/Linux/centos/5/extras/SRPMS/

[centosplus-SRPM]
name=CentOS-$releasever - centosplus SRPMS
baseurl=http://ftp2.riken.jp/Linux/centos/5/centosplus/SRPMS/

[os-SRPM]
name=CentOS-$releasever - os SRPMS
baseurl=http://ftp2.riken.jp/Linux/centos/5/os/SRPMS/
 


上記がどうしてこうなっているのはは不明。他を見ながら勘でやってますので、注意。

で、ソースのインストール。

# yumdownloader --source mod_ssl
 

すると、httpdのソースが取得できる。あれ?

.

[mod_chxj] 一応拡張絵文字まで対応

0.12.16で拡張絵文字の定義をemoji.xmlに追加したので、
一応拡張絵文字まで対応。

emoji.xmlを追加する中で、絵文字変換表が必要な気がした・・。

完全独自変換なので、無理があるかも。。

emoji.xmlのフォーマットの説明もないことに気付いた・・。

やることいっぱいっす。
.

2008年11月2日日曜日

無料だったYahoo!ケータイのトップページの通信料有料化

2009年の2月からYahoo!ケータイのトップページを表示する際の通信料が有料化されるそうで。

今まで無料だったんだ・・。

知らなかった。
.

2008年10月29日水曜日

[経済関係] ガソリンの価格

いつも出勤する時にガソリンスタンドの前を通るんだけど、
ついこの間は確かレギュラーで177円ぐらいだったはず。

今日見てみたら146円。

ずいぶんと値下がりしたんだねー。

NYダウが勢い付けるとまたすぐに跳ね上がるんだろうけど。
.

2008年10月21日火曜日

[本] プログラミングGauche

プログラミングGaucheを読み終えた。

面白かった。
もっと早い段階(Schemeを勉強し始めたころ)に読めたら、もっとよかったかなぁ
って思う。

いや、でも満足。3回ほど読んだ。
Lisp関連の書籍を読むといつも思うんだけど、
「Lisp脳」を身に着けたい・・・。

さて、次は何を読もうかしら。
.

2008年10月15日水曜日

[mod_chxj] Googleのサジェスト

いつもSourceforge.jpにいくときにmod_chxjとGoogleに入力して、
検索結果をブックマーク代わりに使用している。
とっても遠回りな気がするが、なんとなくそうしている。とりたてて意味はないです。

で、そこで気づいたんだけど、Googleのサジェスト機能で
"mod_chxj"と"インストール"
"mod_chxj"と"絵文字"
"mod_chxj"と"apache2.2"
等が出力されている。
これって、mod_chxjとともに良く入力される検索ワードと思ってよいのかな??

インストール、絵文字、apache2.2が気になるところ。

良くわからないけど、一応現状を書いておきます。

インストール
インストールは経験的ドキュメントが足りていない気がします。
代わりにインストールして下さった方のブログなどに詳しく書いていただいているようです。
ありがたいことです。

絵文字
正式には絵文字は出力のみ対応していて、必要とあらば設定を変えることで
変換結果を変更できます。

ただちょっと前のtrunkで、入力にも実験的に対応してますが、これはリリースしない予定。
代わりに0.14.xで対応するつもり。
独自形式の変なのは使わないで、基本的には文字コードを直接変換する形をとる予定。
どうしても無理な部分はあるにはあるけど、そこら辺はPerlの世界に便利そうなのがあるので
参考にする予定です。
ちなみに、0.11.xの最新と0.12.xでは0.14.xで入れる予定の入力変換の土台となる部分を
入れてあります。

apache2.2
多分、対応しているかどうかが気になるのでは??
今年の最初の方に対応したつもりで、こちらの環境でも元気に動作しています。

こんなところか。

あとは、tomcat。
こちらでの動作実績はほとんどtomcat。
バージョンによってはmod_jkや、mod_proxy_ajpではなく、
mod_proxyを使わないとうまく動かせないかも。


とりあえず、さっき思ったことでした。
.

2008年10月14日火曜日

[経済関係] 買い気配に「特」

さっき株価ボードを見てみたら、買い気配のところに「特」と書いてあった。
なんじゃこりゃ。

ということで調べてみた。

「特」って特別気配の意味だそうで、
価格が急激に変わる場合、買い気配と売り気配が一致するまで、売買成立を一旦とめて
待っている状態で、5分たっても一致しない場合は、値段を上げたり、下げたりして
再度価格が一致するまで待機するのだそうで。

自分の持っている株の買い気配に「特」が付いていると、
少々アツくなるのは内緒の話。
.

2008年10月8日水曜日

[経済関係] 中古住宅販売保留

米の中古住宅販売保留が発表されたようで。

で、今のいままで、この中古住宅販売保留をてっきり
売れなくて保留中の件数かと思ってたら、そうではなくて、
契約が済んでいて保留中の件数だそうで、保留中の件数が多ければ
多いほど住宅市場は好調(?)らしい。

へぇ。
勉強になった。

.

2008年10月4日土曜日

[work][PHP] WordPressを使ったサイト

WordPressを利用したサイトを構築したんだけど、、、

WordPressの利用度合いによると思うけど直接DB見たほうが楽?

かと思った今日このごろでした。

ZendFramework使ってるからなのかな??

気のせいかもしれないけど。

.

2008年9月22日月曜日

[mod_chxj][libserf] libserf-0.2.0

ときどき白い画面が表示されるとのこと。
原因はlibserf-0.1.2にありました。

mod_chxjで使用しているlibserfをバージョンアップして対応。

が、libserf-0.2.0にすると、RFC 2616, section 4.2に準拠したようで、
ヘッダに同じキーが複数ある場合、1つにしてしまう模様。

たとえば、レスポンスにSet-Cookieヘッダが複数あった場合、
カンマ区切りで1つにされてしまう。。

ま、正しいのかもしれないが、、、、

.

2008年9月21日日曜日

[その他] 体調不良

8月はじめごろから体調をくずした。

仕事でPHP+ZendFramework+QIQ+RSKitで遊んでた(?)ためか
どうかは知らないが、ある日突然小便が出にくくなった。

ほっといたらすぐに出にくいのは直ったんだけど、その数日後
突然熱(39度以上)の熱が出た。
これも次の日には何事もなかったように直ったので、ほっといたら、
さらに数日後また熱が(39度以上)。
なんてことを数回繰り返し、
さらに腰が痛くなった。

そのときは仕事がデスマーチの3倍な感じだったので、とりあえず8月22日(第一次納品もどき日)
まで粘った。病院に今いったら入院だろうなと感じていたので、とにかく耐えた。

8月22日過ぎたら安心したのか、その後連日40度を越えたんで
さすがにやばいと思って隣の病院へ駆け込んでみた。

人生初の点滴を体験した。

それはさておき、診察の結果、腎臓が細菌に感染したとのこと。
いわゆる腎盂腎炎だそうで。

そのときのお医者さんの言葉が、
「まだ腎臓は機能している。まだ間に合う。」でした。

調べてみたところ、腎盂腎炎はほっとくとスイジンショウというものに
なったりして、そのうち腎不全になるそうで。

病院にお世話になったり、水を多く飲んだりして
今ではすっかり全快な感じなのですが、
最初に病院に駆け込んでから一ヶ月が経とうとしている
今でも薬を飲んでいる感じ。

今は原因を調べているところで、恐らく膀胱憩室という病気が原因
らしい、というところまで分かった感じ。詳細は良くわからないけど。

はっきりと調べるためにDIP造影なんたらという検査もやった。
10万人に1人の割合で死んでしまう検査らしいのだが無事
乗り越えたっぽい。


膀胱憩室だった場合、腎盂腎炎が再発した場合は手術するとのこと。
ぎゃー。

膀胱憩室の原因はその後調べるかどうかは知らない。

それよりも、今回いろいろと検査して検査結果を家に持ち帰ってきたのだが、
絶対成人病かと思いきや、意外に検査結果は健康っぽいところが驚いた。
もちろんC反応淡白(炎症を起こしていると高くなる?)と白血球(??)の値が
異常値だったんだけど。




.

2008年7月25日金曜日

[git] “You have some suspicious patch lines”


$ git commit -a
 

とやったら、

* You have some suspicious patch lines:
* In src/abc.c
* trailing whitespace (line 4083)
 

と言われて、コミットできない。。

調べてみると・・・、
line 4083行目のCRやらLFやらのコードがおかしいCRやらLFまでに空白文字が入っているという意味らしい。

該当行の最後のバイトを削除してやると、無事コミットできた。

--
追記


git-config core.autocrlf true
git-config core.safecrlf true
 

とやるとよいらしい。
.

[Ruby] gem install ってやったらいろいろ死んだ・・・

erubisをインストールしようと思って、


$ gem install erubis
 

ってやったらscreenが死んだ。
動作中のvimも死んだ。
さらに動作中のMySQLも死んだ。。

なんじゃこりゃー。
つうことで、

 # apt-get remove ruby rubygems rake
 

として、
最新のrubyをソースで取得。
んで、configureしてmake、make install。

gemも最新にした。

なんてことは無い。何事もなかったようにさくさく動作。

ふふふ。最新。

ま、環境の問題かと思うのだけど。
.

2008年7月24日木曜日

[PHP] XAMPP for LINUXなるものをインストール

qiqというものを使いたく、コンパイルしようかと思ったら、
etchだとphp5.2.0だもんで、インストールできず。
backportから持ってくるのもありなのだが、せっかくだから初LAMPPで、
XAMPP for LINUXをインストール。

etchのApacheからproxyして使います。

qiqも無事インストール完了。

以下、ログ。


#
# うごくものをとりあえずインストール
#
$ wget http://nchc.dl.sourceforge.net/sourceforge/xampp/xampp-linux-1.6.7.tar.gz
$ tar xvzf xampp-linux-1.6.7.tar.gz -C /opt
#
# コンパイルすんの面倒なんで、develで上書き
#
$ wget http://nchc.dl.sourceforge.net/sourceforge/xampp/xampp-linux-devel-1.6.7.tar.gz
$ tar xvzf xampp-linux-devel-1.6.7.tar.gz -C /opt
#
# qiq
#
$ wget http://www.opendogs.org/pub/php_qiq-0.6.0.tgz
$ tar xvzf php_qiq-0.6.0.tgz
$ cd php_qiq-0.6.0
$ /opt/lampp/bin/phpize
$ ./configure --with-php-config=/opt/lampp/bin/php-config
$ make
$ sudo make install
#
# この辺でphp.ini編集(qiq.so追加)
# この辺で/opt/lampp/etc/httpd.conf編集(Listen 80 -> Listen 8088に修正)
# この辺で/opt/lampp/lampp編集(testrun 80 -> testrun 8088に修正)
#
# で起動
$ /opt/lampp/lampp startapache
 


らくちんだす。


.

[PHP][ZendFramework] ローテイトしてくれるWriterがない?

どうも、Zend_LogにはローテイトしてくれるWriterが付いていない模様。
フォーラムなんかを見ると、後々作るみたいなことが書いてある。

ま、Linuxなんかを使っていればクーロンでローテイトさせてやればいいんだけど・・・。

と思っていたら
log4PHPっつうのがあるみたい。

早速使ってみようっと。
.

2008年7月22日火曜日

[PHP][work] PHP5がcoreダンプ

libphp5.soでコアダンプ。

環境に問題があるんだろうが、、、
うーむ。
.

-- 追記
A.phpにclass A。
B.phpにclass B。
で、class Bの中でAをnewする。
で、class Aの中でBをnewする。
するとコアダンプする???

ま、環境に問題があるんだろうが、、、
.

2008年7月21日月曜日

[PHP][work] なぜかPHPをやることに

できると言ったことは無いんだけど、なぜかPHPをやることに。

php3の時以来触って無いのでどうなんでしょう。
当時はとりたてて便利なライブラリとか無かった気がする。
最近ではフレームワークも出来てきているらしい。

ぐぐったらCakePHPとZendFrameworkが出てきますな。
本屋行ったら、Code何たらっていうフレームワークもあるらしい。

privateとかpublicとかもあるんすか??
へぇー。

うへぇー。
.

2008年7月19日土曜日

[本] ビューティフルコード

ビューティフルコード(日本語版)読み終わった。

いや、面白かった(わかるところだけ)。

面白かったのは、
カーニハンの章、
分割統治によるビットカウント、
VBでスパゲッティのソースを書いてしまったと言っていた章、
まつもとさんの章
最後の久野さんとまつもとさんの対談。

カーニハンの章は、まぁ、わかりやすかったというか、
カーニハン系だと似たようなものを読んだ気がする。

あと、プログラミング言語Schemeの人の章は気合入れて読んだけど、
勉強不足が露呈されました。

あとは半分ぐらい意味不明。。。
人ゲノムといわれても良くわからないのでした。

次、Gaucheの本にいこうかと。

2008年7月18日金曜日

[その他] さて

ここからですな。

継続は力なり。

.

[その他] ジンバブエ

ジンバブエは今、インフレ率220万%だそうで。。。

怖いんですけど・・・。

2008年7月17日木曜日

[その他] 正直少しがっかり

うーむ。

期待が大きかっただけに、
正直、少しがっかりした。。。
方向性が違ったみたい。

えーと、何の話?

.

2008年7月7日月曜日

[その他] Googleはスペルミスらしい

どっかで読んだんだけど、あのGoogleってgoogolのスペルミスだったらしい。
googol.comというドメインを取得しようとして、誤ってgoogle.comという
ドメインを取ってしまったとのこと。

へぇー・・・、本当かなぁ?
.

2008年7月3日木曜日

[C言語] ふと、、、

ふと、関数の中で関数を定義したいと思った・・・。


そんだけ。
.

[C言語] ふと、、、

ふと、クロージャがほしいと思った・・・。


そんだけ。
.

2008年7月2日水曜日

[mod_chxj][css] SACインタフェース

SACインタフェースも実装してみた。
といっても完全では無く一部のみ。

これでmod_chxj内部から使うことはできる。

さて、残りはテスト。

手当たり次第世の中のCSSを読み込ませてみよう。
もちろんCUnitもやる(予定)。

.

2008年7月1日火曜日

[mod_chxj][css] CSSパーサ実装

libcrocoが使えないので、困ったあげく
CSSパーサを実装しちゃった。

まだ、パース部分のみ。bison/flexは使ってない。

あとはSACインタフェースでも実装すればmod_chxjから使える。

一応現時点のものはbranchesのsandbox/src/css以下にコミットしてみた。

.
--
0.13.xに入れる予定。

2008年6月30日月曜日

[mod_chxj][libcroco] ミスった

libcrocoを使ってCSSをパースしようかと思っていたけど・・・、
ミスった。

libcrocoじゃ-wap-input-formatとか読めない。。
困った・・・。

さて、どうしたものか。
.

2008年6月27日金曜日

[mod_chxj] 0.11.x系、0.12.x系メンテ更新

多めのデータをPOSTするとアプリ側でデータを受け取れないバグを修正した。
原因は、
リクエストデータを全て受け取る前にアプリに制御を渡してしまっていたところ。
そもそも、Apacheのinput_filterはへっぽこらしく、期待する動作はしない模様。

だもんで、0.13.xでリリース予定だったproxyもどきを0.11.xと0.12.xにマージした。

ただいま0.12.x系で修正したバグを0.11.xにもマージ中(手マージ)。

ちなみに、proxyもどきはmod_proxy_ajpとは相性悪い。
代わりにmod_proxy_httpを使うことで対応可能。

.

2008年6月26日木曜日

[mod_chxj][mod_proxy_ajp] 相性悪い?

はまった。


ProxyPass ajp://xxxxxx:8009/xxxxx
 

などと指定していたんだけど、どうも、mod_proxy_ajpのバグらしく、


[error] ajp_read_header: ajp_ilink_receive failed
[error] (120006)APR does not understand this errorcode: proxy: read response failed from (null) (127.0.0.1)


てな感じで怒られる。さらにしばらく応答なし。。
とりあえず、

ProxyPass http://xxxxx:8080/xxxx
 

な感じにすれば問題ないので、これで対応。。

.

2008年6月25日水曜日

[git] working ディレクトリの修正を無かったことに

またもや何回も同じこと調べてるんで、メモ。


$ git reset --hard
 


以上。

2008年6月15日日曜日

[python][本] Jythonプログラミング

Jythonプログラミング読破。
とりあえず目を通しただけ。

でも、まぁ面白かったかな。

さて、一通り目につくPython入門書は目を通した。
あとはひたすらPythonと戯れるだけかな。
興味があるところとしてはDjango。
この辺の情報をあさってみよう。

さて、次は何を読もうかなーっと。
Gaucheにしようか、Beautiful Codeにしようか・・・。


.

2008年6月11日水曜日

[mod_chxj][css] CSSのセレクタ選択ルーチン

とりあえずCSSのセレクタファインダができた。

できたといっても

  • 全称セレクタ
  • タイプセレクタ
  • 子孫セレクタ
  • 子供セレクタ
  • クラスセレクタ
  • IDセレクタ
を見つけることができるだけ。
上記の組み合わせであれば大抵の場合見つけることができる。

さて、次は
擬似クラスをどう扱うかを考える。
あと、外部参照先がローカルの場合はHTTPリクエストを発行しないようにしよう・・。

-- 追記
擬似クラスは別途擬似クラス抽出ルーチンを用意する。
=>擬似クラスは内部参照に変換予定。
属性セレクタにはとりあえず対応しない。

-- 追記
とりあえずa:link a:visited a:focusの抽出はできた。

>あと、外部参照先がローカルの場合はHTTPリクエストを発行しないようにしよう・・。
とりあえず面倒なんで後回し。
.

2008年6月9日月曜日

[libcroco] 子供セレクタのバグ?


 a > .def#id1 > c { ... }
 

といった感じのセレクタを指定した場合、

a.def#id1 > c
 

と認識されてしまう・・・。

a > *.def#id1 > c { ... }
 

と、全称セレクタを明示的に指定すれば問題なし。

これはバグだよね?

.

2008年6月7日土曜日

[pcre] pcre_execのovector

個人的メモ。

pcreのpcre_exec()関数のovectorについて。


ovector[偶数番目]


は、マッチした文字列が何文字目から始まるかがセットされる。


ovector[奇数番目]
 

は、マッチした文字列が何文字目で終わるかがセットされる。

ovector配列の要素数は、

パターンのサブパターン、グルーピングしたものの数 * 3
 

だけ確保する。 * 3は三倍の意。
三倍にする理由は、
  1. 何文字目で始まるか
  2. 何文字目で終わるか
  3. 作業領域
に使用するからだそうで。

.

2008年6月6日金曜日

[Python] Pythonクイックリファレンス

やっと読破。

さて、次は何を読もうかな。

Jythonでも見ておくか。

ところでJythonを今まで「ジェイソン」って読んでたけど
これ「ジャイソン」が正解なのね・・・
.

2008年6月1日日曜日

[mod_chxj] libxml2を使ってみたが・・・

mod_chxjのパーサにlibxml2を使おうと思って、libxml2を使ってみた。

が、エラー通知をオフにするとエラーが通知できない(そりゃそうだ)
エラー通知をオンにするとxmlCtxtでやるとエラーだらけで、htmlCtxtを使うと
HTMLでないタグがエラーになってしまう・・・。

うーむ。やり方がまずいのかもしれないが、
とりあえずはlibxml2は使わないことにしようと思う。

ということでlibcrocoでもCSSOMでなくて当初考えていたSACで。
さらに自力でSelector検索機能を実装する。(うへー)

.

2008年5月30日金曜日

[stone] stoneを使う

結構昔から使っているんだけど、
最近のはmakeするときに-DUSE_EPOLLが定義されちゃうんで
My Linuxではコンパイルが通らない。。(kernelが2.4のため・・・)

ま、これは-DUSE_EPOLLをはずしてコンパイルすればよいっと。

で、stoneをKILLしてすぐに再起動するとエラーになっちゃう。
ま、しょうがないと言えばしょうがないんだけど、ちょっと使いづらいので、
tcpserver(djb)のまねしてreuseソケットを使うようにした。


diff -Nur stone.orig/stone.c stone/stone.c
--- stone.orig/stone.c 2006-09-17 09:53:35.000000000 +0900
+++ stone/stone.c 2008-05-30 12:52:01.000000000 +0900
@@ -3676,6 +3676,10 @@
return 0;
}
saPort(csa, 0);
+ {
+ int opt = 1;
+ setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt);
+ }
if (bind(sd, csa, csalen) < 0) {
#ifdef WINDOWS
errno = WSAGetLastError();



んで、そんときの何の役にも立たないパッチ。


そんだけ。
.

2008年5月26日月曜日

[その他] 岡山

先日ちょっと用があって岡山に行ってきた。

初岡山上陸。

ひとつ気になったことがある。
それは、エスカレータの乗り方。


大阪なんかだと急いでいる人用に左側を空けて乗る。
東京なんかだと急いでいる人用に右側を空けて乗る。

ところが、岡山では、思いっきりばらばら。
きっちり左よっている人ときっちり右に寄っている人が
入り乱れた感じ。
だもんで、お急ぎルートが無い!
いや、実に見事にばらばらでした。
(新幹線乗り場のエスカレータだから?)

ちょっと面白かったんで、書いてみた。
おしまい。
.

[libcroco][mod_chxj] sacじゃなくてCSSOM

CSS解析をSAC使ってなんとかしようかと思ったんだけど、
そうするとタグ、クラス、IDから対象スタイルを抽出するのがかなり面倒だと
いまさら気づいた。

libcrocoにはselector_engineという機能が提供されているんで、
これを使ってみようかと思う。
が、このエンジンはSACじゃなくてCSSOM。。

ということでSACやめ。

さらに、libcrocoのselector_engineを使うには、
libxml2でパースした結果のデータを渡す必要がある。
自前で作成したデータをlibxml2の形式に変換してもいいんだけど、
将来的にPCからアクセスしてきた場合にもHTMLパースかませたいので、
そもそものHTMLパースエンジンをlibxml2に変えようと思うのでした。

libxml2は壊れた感じのHTMLでも問題なく動作できるらしい。

ということで目下やることは、

  1. SACからCSSOMに変更
  2. HTMLパーサーをlibxml2を使うように変更
といった感じ。

うーむ。
.

2008年5月20日火曜日

[libserf] libserf使ってみた

へぼいプログラムを書いてみた。
といってもtest/serf_get.cのほぼパクリ。

では、さっそく。

SSLを使うかどうかのフラグとSSLを使用する場合のSSLコンテキスト保持用に
構造体を用意する。
また、この構造体にはserf内で使用するallocatorも保持しておく。


struct __app_ctx_t {
int ssl_flag; /* SSLを使用する場合は1 */
serf_ssl_context_t *ssl_ctx; /* SSL用のコンテキスト */
serf_bucket_alloc_t *bkt_alloc; /* serf用バケットアロケータ */
};
 

な感じ。
これをアプリケーションコンテキストと名づけた。

で次、

struct __handler_ctx_t {
#if APR_MAJOR_VERSION > 0
apr_uint32_t requests_outstanding;
#else
apr_atomic_t requests_outstanding;
#endif

serf_response_acceptor_t acceptor;
app_ctx_t *acceptor_ctx;

serf_response_handler_t handler;

const char *host;
const char *method;
const char *path;

apr_status_t rv;
const char *reason;
};
 

ハンドラのコンテキスト。
リクエストが終了したかどうかの判定に使用するrequest_outstanding、
セットアップに必要な各情報(acceptor、acceptor_ctx、handler)、
あとエラー終了時のステータスを覚えておくためのrvとreason
を保持する。

aprの初期化など

void
s_init(apr_pool_t **pool)
{
apr_initialize();

apr_pool_create(pool, NULL);
apr_atomic_init(*pool);
}


void
s_term(apr_pool_t *pool)
{
apr_pool_destroy(pool);
apr_terminate();
}
 

決まり文句的なaprの初期化ルーチン。

さて、libserfを使うためには5つほどコールバックを作成する必要がある。

で、以下そのコールバック。

コネクション確立時にコールされるコールバック

static serf_bucket_t *
s_connection_setup(apr_socket_t *skt, void *setup_ctx, apr_pool_t *pool)
{
serf_bucket_t *c;
app_ctx_t *ctx = (app_ctx_t *)setup_ctx;

if (ctx->ssl_flag) {
/* sslを使用する場合、ssl用serf_bucket_tを作成する */
c = serf_bucket_ssl_decrypt_create(c, ctx->ssl_ctx, ctx->bkt_alloc);
if (!ctx->ssl_ctx) {
/* sslコンテキストも生成する */
ctx->ssl_ctx = serf_bucket_ssl_decrypt_context_get(c);
}
return c;
}
/* 通常のsef_bucket_t */
return serf_bucket_socket_create(skt, ctx->bkt_alloc);
}
 

こんな感じ。sslを使用する場合にはsslでコネクション用serf_bucket_tを作る。
またコンテキストも生成する。


コネクション解放時にコールされるコールバック

static void
s_connection_closed(serf_connection_t *conn, void *closed_baton, apr_status_t why, apr_pool_t *pool)
{
fprintf(stderr, "コネクション切断:[%d]\n", why);
}
 

特に何もする必要ないんで、こんな感じ。

実際に投げるリクエストを生成するためのコールバック

static apr_status_t
s_setup_request(serf_request_t *request,
void *setup_ctx,
serf_bucket_t **req_bkt,
serf_response_acceptor_t *acceptor,
void **acceptor_ctx,
serf_response_handler_t *handler,
void **handler_ctx,
apr_pool_t *pool)
{
handler_ctx_t *ctx = setup_ctx;
serf_bucket_t *hdrs_bkt;
serf_bucket_t *body_bkt;

*req_bkt = serf_bucket_request_create(ctx->method, ctx->path, NULL, serf_request_get_alloc(request));

hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);

serf_bucket_headers_setn(hdrs_bkt, "Host", ctx->host);
serf_bucket_headers_setn(hdrs_bkt, "User-Agent", "Wget2/1.0");

/* 処理中 */
apr_atomic_inc32(&(ctx->requests_outstanding));

/* SSLなら */
if (ctx->acceptor_ctx->ssl_flag) {
serf_bucket_alloc_t *req_alloc;
app_ctx_t *app_ctx = ctx->acceptor_ctx;

req_alloc = serf_request_get_alloc(request);

if (app_ctx->ssl_ctx == NULL) {
*req_bkt = serf_bucket_ssl_encrypt_create(*req_bkt, NULL, app_ctx->bkt_alloc);
app_ctx->ssl_ctx = serf_bucket_ssl_encrypt_context_get(*req_bkt);
}
else {
*req_bkt = serf_bucket_ssl_encrypt_create(*req_bkt, app_ctx->ssl_ctx, app_ctx->bkt_alloc);
}
}

*acceptor = ctx->acceptor;
*acceptor_ctx = ctx->acceptor_ctx;
*handler = ctx->handler;
*handler_ctx = ctx;

return APR_SUCCESS;
}
 

とりあえず、body部はいらないんで、こんな感じ。
ここでrequest_outstandingを1にしている。1の間は「処理中」を表す。
で、acceptorとhandlerも設定。


レスポンスをacceptしたときにコールされるコールバック

static serf_bucket_t *
s_accept_response(serf_request_t *request, serf_bucket_t *stream, void *acceptor_baton, apr_pool_t *pool)
{
serf_bucket_alloc_t *bkt_alloc;
serf_bucket_t *c;

/* 入力バケットをwrapする */
bkt_alloc = serf_request_get_alloc(request);
c = serf_bucket_barrier_create(stream, bkt_alloc);
return serf_bucket_response_create(c, bkt_alloc);
}
 

acceptorはこんな感じ。wrapして返すだけ。


レスポンスの内容を処理するコールバック

static apr_status_t
s_handle_response(serf_request_t *request, serf_bucket_t *response, void *handler_ctx, apr_pool_t *pool)
{
const char *data;
apr_size_t len;
serf_status_line sl;
apr_status_t rv;
handler_ctx_t *ctx = handler_ctx;

/* レスポンスのステータスライン取得 */
rv = serf_bucket_response_status(response, &sl);
if (rv != APR_SUCCESS) {
if (APR_STATUS_IS_EAGAIN(rv)) {
return rv;
}
ctx->rv = rv;
apr_atomic_dec32(&ctx->requests_outstanding); /* 終了通知 */
return rv;
}
ctx->reason = sl.reason;

while (1) {
rv = serf_bucket_read(response, 2048, &data, &len);
if (SERF_BUCKET_READ_ERROR(rv)) {
ctx->rv;
apr_atomic_dec32(&ctx->requests_outstanding);
return rv;
}

fwrite(data, 1, len, stdout);

if (APR_STATUS_IS_EOF(rv)) {
apr_atomic_dec32(&ctx->requests_outstanding);
return APR_EOF;
}

if (APR_STATUS_IS_EAGAIN(rv))
return rv;
}
}
 

ステータスラインを調べて、レスポンスを読み込む。
読み込み終わったら、

apr_atomic_dec32(&ctx->requests_outstanding);
 

として、終了を通知。


で、しょぼしょぼメインはこんな感じ。

int
main(int argc, char *argv[])
{
apr_pool_t *pool;
apr_uri_t url;
apr_status_t rv;
apr_sockaddr_t *address = NULL;

serf_context_t *context;
serf_connection_t *connection;

/* serf用アロケータ、sslのctxなどを保持する */
app_ctx_t app_ctx;
/* handler用ctx */
handler_ctx_t handler_ctx;


if (argc != 2) {
fprintf(stderr, "usage: %s url\n", argv[0]);
return -1;
}

s_init(&pool);
apr_uri_parse(pool, argv[1], &url);
if (!url.port) {
url.port = apr_uri_port_of_scheme(url.scheme);
}
if (!url.port) {
url.port = 80;
}
if (!url.path) {
url.path = "/";
}
if (!url.hostname) {
url.hostname = "localhost";
}

/* addressの取得 */
rv = apr_sockaddr_info_get(&address, url.hostname, APR_UNSPEC, url.port, 0, pool);
if (rv != APR_SUCCESS) {
fprintf(stderr, "apr_sockaddr_info_get()失敗: %d\n", rv);
return -2;
}
fprintf(stderr, "url.hostname:[%s] url.port:[%d]\n", url.hostname, url.port);

/* アプリケーション用コンテキスト領域初期化 */
memset(&app_ctx, 0, sizeof(app_ctx_t));

/* serf用アロケータの設定 */
app_ctx.bkt_alloc = serf_bucket_allocator_create(pool, NULL, NULL);
if (strcasecmp(url.scheme, "https") == 0) {
app_ctx.ssl_flag = 1;
}

/* serfコンテキストの生成 */
context = serf_context_create(pool);

/* serfコネクションの生成 */
connection = serf_connection_create(context, address, s_connection_setup, &app_ctx, s_connection_closed, &app_ctx, pool);

memset(&handler_ctx, 0, sizeof(handler_ctx_t));
handler_ctx.requests_outstanding = 0;
handler_ctx.host = url.hostinfo;
handler_ctx.method = "GET";
handler_ctx.path = url.path;

handler_ctx.acceptor = s_accept_response;
handler_ctx.acceptor_ctx = &app_ctx;
handler_ctx.handler = s_handle_response;

/* リクエスト生成 */
serf_connection_request_create(connection, s_setup_request, &handler_ctx);

/* 処理ループ */
while (1) {
rv = serf_context_run(context, SERF_DURATION_FOREVER, pool);
if (APR_STATUS_IS_TIMEUP(rv))
continue;
if (rv) {
char buf[200];
fprintf(stderr, "Error running context: (%d) %s\n", rv, apr_strerror(rv, buf, sizeof(buf)));
break;
}
if (!apr_atomic_read32(&handler_ctx.requests_outstanding)) {
if (handler_ctx.rv != APR_SUCCESS) {
char buf[200];
fprintf(stderr, "Error running context: (%d) %s\n", handler_ctx.rv, apr_strerror(handler_ctx.rv, buf, sizeof(buf)));
}
break;
}
}


serf_connection_close(connection);
fprintf(stderr, "%s\n", handler_ctx.reason);
s_term(pool);
return 0;
}
 


はい。お粗末さまでした。

.

2008年5月19日月曜日

[libserf] libserfを調べてみた

css変換部からHTTPリクエストを発行したいので、Javaで言う、
httpclientのようなライブラリを探してみた。
有名どころとしては、libneonとlibserfらしい。
libneonはGPL。libserfはApache Licence 2.0。なので、できればlibserfを使いたい。

ということでlibserfを調べてみた。

処理の大きな流れは以下のとおり。

  1. serf用のpoolを用意する。
  2. apr_sockaddr_info_get()を使ってapr_socketaddr_tを取得する。
  3. serf_context_create()を使ってserf_context_tを生成。
  4. serf_connection_create()でserf_connection_tを生成。
  5. serf_connection_request_create()でserf_request_tを生成。
  6. serf_context_run()でループする。
  7. 終了を何かしらの方法で検知したら、ループを終了する。
  8. serf_connection_close()でコネクションを終了。
  9. serf用poolの解放。

このほかに、
  1. コネクション確立時にコールされるコールバック
  2. コネクション解放時にコールされるコールバック
  3. 実際に投げるリクエストを生成するためのコールバック
  4. レスポンスをacceptしたときにコールされるコールバック
  5. レスポンスの内容を処理するコールバック
を用意する必要がある。

コネクション確立時のコールバック関数

typedef serf_bucket_t * (*serf_connection_setup_t)(apr_socket_t *skt,
void *setup_baton,
apr_pool_t *pool);
 

と定義されているので、このインタフェースを満たす巻数を用意する。
やることは、コネクション確立時にapr_socket_tをserf用socketにwrapすること。
setup_batonはserf_connection_create()時にsetup_batonに渡されたものがわたってくる。

コネクション解放時にコールされるコールバック

typedef void (*serf_connection_closed_t)(serf_connection_t *conn,
void *closed_baton,
apr_status_t why,
apr_pool_t *pool);
 

と定義されている。
目的はコネクション切断を通知するもの。
切断時のステータスがwhyに入ってくる。
コネクション切断時にエラーが起きているなら、ここで何か処理をすることができる。

実際に投げるリクエストを生成するためのコールバック

typedef apr_status_t (*serf_request_setup_t)(serf_request_t *request,
void *setup_baton,
serf_bucket_t **req_bkt,
serf_response_acceptor_t *acceptor,
void **acceptor_baton,
serf_response_handler_t *handler,
void **handler_baton,
apr_pool_t *pool);
 

と定義されている。
1リクエストを生成し、設定することが目的。生成したリクエストはreq_bktに設定してやる。
また、レスポンスをacceptしたときのコールバック、レスポンスを処理するコールバックも
本関数で設定する。レスポンスをacceptしたときのコールバックは、acceptorに、
レスポンスを処理するコールバックは、handlerにそれぞれセットする。
本処理に渡したいものがあれば、serf_connection_request_create()の第三引数として渡して
あげれば、本関数のsetup_batonパラメータにセットされてわたってくる。

レスポンスをacceptしたときにコールされるコールバック

typedef serf_bucket_t * (*serf_response_acceptor_t)(serf_request_t *request,
serf_bucket_t *stream,
void *acceptor_baton,
apr_pool_t *pool);
 

目的は、パラメータのrequestに対応するレスポンス用serf_bucket_t領域の生成や確保。
acceptor_batonはserf_request_setup_tの方でセットしたものが渡される。
streamをwrapしてやったりする(serf_bucket_barrier_create()でできる)。


レスポンスの内容を処理するコールバック

typedef apr_status_t (*serf_response_handler_t)(serf_request_t *request,
serf_bucket_t *response,
void *handler_baton,
apr_pool_t *pool);
 

と定義されている。
レスポンスデータが届いたときに行うべき処理をここで書く。
handler_batonはserf_request_setup_tの中で設定した値がわたってくる。



ということで大体わかった。
次に実際にコードを書いてみるつもり。

.

2008年5月18日日曜日

[mod_chxj] CSS変換部考え中

@importルールやlinkタグがあった場合、cssファイルを取りにいかなきゃならない
のを忘れていた。

modules-devを見ていたら、libserfというものを見つけた。


a high-performance asynchronous HTTP client library
 

だそうで。
svnのra_serfで使われている??

ということでlibserfを調査してみることにした。

.

[携帯] TypePadの絵文字アイコン画像と、携帯コンテンツ表示モジュールをフリー(自由)ライセンスで公開

>TypePadの絵文字アイコン画像と、携帯コンテンツ表示モジュールをフリー(自由)ライセンスで公開
とのこと。
をを!

これを使えばPCサイトにも絵文字が表示できるっすね。
ちなみにクリエイティブ・コモンズ・ライセンスだそうで。
.

[mod_chxj] CSS変換部データ構造考え中

個人的メモ。

CSS変換部のデータ構造は


/**
* CSS property.
*/
typedef struct __css_property_t {
struct __css_property_t *next;
struct __css_property_t **ref;
char *name;
char *value;
} css_property_t;


/**
* CSS selector.
*/
typedef struct __css_selector_t {
struct __css_selector_t *next;
struct __css_selector_t **ref;
/* has tag or/and class or/and id */
char *name;
css_property_t *head;
css_property_t *tail;
} css_selector_t;

/**
* CSS stylesheet.
* Manager of css_selector_t.
*/
typedef struct __css_stylesheet_t {
css_selector_t *head;
css_selector_t *tail;
} css_stylesheet_t;

/**
* CSS current_stylesheet.
*/
typedef struct __css_current_stylesheet_t {
struct __css_property_t *head;
struct __css_property_t *tail;
struct __css_current_stylesheet_t *next;
struct __css_current_stylesheet_t **ref;
} css_current_stylesheet_t;

/**
* CSS current_stylesheet_stack_t.
*/
typedef struct __css_current_stylesheet_stack_t {
css_current_stylesheet_t *head;
css_current_stylesheet_t *tail;
} css_current_stylesheet_stack_t;

 


な感じかな。
足りないところがありそう。
ちなみに**refは馬鹿の一つ覚えの例。

.

2008年5月17日土曜日

[mod_chxj] css部分をざっくり考え中

個人的メモ。

CSS関連でやるべきことは、

  • CSSEngineOn/CSSEngineOff機能の追加
  • CSS変換エンジンの実装
ぐらいか。

## データ構造
### property型
* name
* value

### selector型
* name (tag, class, id)
* propertyのリスト


### stylesheet型
* selectorのリストを保持する。
* linkタグがあった場合、該当CSSを読み込み、同一セレクタが既にある場合には上書きする。
* linkタグがあった場合、該当CSSを読み込み、同一セレクタが無い場合は新規にselectorを追加する。
* @importルールがあった場合、該当CSSを読み込み、同一セレクタが既にある場合には、該当セレクタのプロパティだけ
を更新する。
* @importルールがあった場合、該当CSSを読み込み、同一セレクタが無い場合には、新規にselectorを追加する。

### current_stylesheet型
* 現在有効なプロパティのリストを保持する。
* 各プロパティは静的にもつ。
* 定義されていないプロパティについては、nullが設定されている。

### current_stylesheetスタック
* 現在有効なcurrent_stylesheet型を要素とするスタック。
* タグがオープンされると、現在最上位にあるcurrent_stylesheetをコピーして新しいcurrent_stylesheetを
作成し、current_stylesheetにpushする。
(extended_environment)
* タグがクローズされると、current_stylesheetスタックをpopする。

## 各コンバータでの処理
1) タグがオープンされる。
1-1) current_stylesheet型領域を確保する。
1-2) current_stylesheet型領域にcurrent_stylesheetスタックの最上位(if any)のプロパティを設定する。
1-3) オープンされたタグ名、クラス名、ID名により、該当selectorをstylesheet型から探す。
1-4) もしあれば、該当selectorのプロパティでcurrent_stylesheetのプロパティを更新する。
1-5) current_stylesheetをcurrent_stylesheetスタックにpushする。

2) タグ内の処理
2-1) style属性があれば、style属性のvalue値をパースする。
2-2) パース結果でcurrent_stylesheetスタックの最上位にあるcurrent_stylesheetのプロパティを更新する。

3) 各端末用タグの生成
3-1) current_stylesheetを考慮したうえで、各端末用にタグを出力する。
DoCoMoであればstyle属性出力等。

4) タグがクローズされる。
4-1) current_stylesheetスタックから1要素popする。

# selectorの特定方法
## class,IDが指定されている場合
1) tag.class#IDを検索する

2) tag#IDを検索する

3) #IDを検索する

4) 「classのみが指定されている場合」へ

IDのみが指定されている場合は、
1) tag#IDを検索する

2) #IDを検索する

3) 「tagのみが指定されている場合」へ

classのみが指定されている場合
1) tag.classを検索する
2) .classを検索する
3) 「tagのみが指定されている場合」へ

tagのみが指定されている場合
1) tagを検索する
2) *を検索する

同一定義があった場合は後に書かれているものが優先。


うーむ・・・。
.