Mocha VNC Lite で右クリックするとき

あまりプログラムとは関係ないけど。


iPhoneからVNCで家PCにつなぐこととかあると思う。
そのときにはいまMocha VNC Liteを使っている。


そのときに右クリックがしたくなる。
しかし、Lite版は右クリック機能がついていない。



そんなときに役に立つのが、Winに備わっているスクリーンキーボード。
XPは

すべてのプログラム→アクセサリ→ユーザー補助→スクリーンキーボード

で起動できる。


それを表示させておいて、
右側のCtrlの1個左のアプリケーションキーを押すと、
見事右クリックの役目をはたす。


うん、いい感じだ!
まぁすでに誰かがこの答えを出している気もするけど。





アプリケーションキーってあまり使った覚えがないのだが、
このキーは有名なのかな…。
そもそもHHKBだからそのキーがないんだけど…w

printStackTraceの標準出力以外の方法

ド定番なのかもしれないけど、

} catch ( Exception e ) {
	StringWriter sw = new StringWriter();
	PrintWriter pw = new PrintWriter( sw );
	e.printStackTrace( pw );
	logger.error( sw.toString() );
}

ってやればStringWriterの中にprintStackTraceの値が入る。
これをtoStringすればいいわけだ。


これをやっててふと思ったのだが、
StringWriterってWriterなのに、closeってコールしなくていいものか と。


そこで、StringWriter#closeに飛んでみた。

    /**
     * Closing a <tt>StringWriter</tt> has no effect. The methods in this
     * class can be called after the stream has been closed without generating
     * an <tt>IOException</tt>.
     */
    public void close() throws IOException {
    }

JavaDocみても実装を見ても、何もしないよって。
なんかメモリ上の話しだし、よく考えてみれば当たり前なんだけど、
改めてよく見てみないとわからないもんだねぇ。


ちなみにPrintWriter#closeは

   public void close() {
	try {
	    synchronized (lock) {
		if (out == null)
		    return;
		out.close();
		out = null;
	    }
	}
	catch (IOException x) {
	    trouble = true;
	}
    }

で、コンストラクタで渡したWriterにたいしてcloseをしているだけなので、
今回の場合は、StringWriterなので、結果closeしても意味がないというわけでした。

SA-Strutsをバッチとして起動する時の注意点

注意点というか、実際に動かしてみると分かるけど、
ServletRequestが無いとか言われることがある。


Eclipse上では動くのに、サーバーにインスコしたwarでは起動できない。
それは何故か…。


それはSA-StrutsがWEBアプリケーションであるからである。
しかもTomcat用(?)のね。


Tomcatとしてのアプリ開発といえばGeronimo-Servlet
http://oreryu.eco.to/zairyo/orekin-gazo/geronimo-gazo1.gif
そうそう、これこれw


geronimo-servletといえばtomcatのライブラリのモック(多分)
WEBアプリだったらTomcatの下で動かすから、
TomcatのライブラリがあるのでServletRequestなどの専門のクラスがあるからいいけど、
バッチとしてスタンドアロンで起動する場合には、tomcatのもってるライブラリが無いので、
Geronimoをそのまま一緒に持っていってあげる必要がある。


最近のDoltengの設定(?)で生成したpom.xmlだと
geronimo-servletがprovidedになっているはず。

<dependency>
	<groupId>org.apache.geronimo.specs</groupId>
	<artifactId>geronimo-servlet_2.4_spec</artifactId>
	<version>1.0</version>
	<scope>provided</scope>
</dependency>

それとmvnでいつも指定しているオプション

mvn ... dependency:copy-dependencies ...

の設定が

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-dependency-plugin</artifactId>
	<version>2.0</version>
	<executions>
		<execution>
			<goals>
				<goal>copy-dependencies</goal>
			</goals>
			<configuration>
				<outputDirectory>./src/main/webapp/WEB-INF/lib</outputDirectory>
				<excludeScope>provided</excludeScope>
				<overWriteIfNewer>true</overWriteIfNewer>
				<overWriteReleases>true</overWriteReleases>
				<overWriteSnapshots>true</overWriteSnapshots>
			</configuration>
		</execution>
	</executions>
</plugin>

となってて、provvidedを排除するようになっているなら、
dependencyのprovidedを消そう

<dependency>
	<groupId>org.apache.geronimo.specs</groupId>
	<artifactId>geronimo-servlet_2.4_spec</artifactId>
	<version>1.0</version>
</dependency>

そうするとlibに含まれるから、
ServletRequestが見当たらないとかにはならないので、
実行できます。


とそういうわけです。
ばーーーって走り書きなので間違いがあるかもぉ。

SA-Strutsでバッチの開発までの準備手順

Dultengでプロジェクト生成
いらんパッケージを削除(バッチなのでactionとかいらないし)
pom.xmlを編集
 profilesにリリース用の記述を追加
 repositoriesにいつものmavenサイトを追加
 dependencyにいつものを追加
 pluginのdependency:copy-dependenciesの記述を追加
 pluginのantrun:runでlibの下を消す記述を追加
 webappをsrc/mainじゃなくて、binの下にあるように記述を修正
mvnをpre-cleanで実行
convention.diconにいつも使うルートパッケージを追加
creator.diconからActionCreatorとFormCreatorを削除、自作のBatchCreatorを追加
customizer.diconからformCustomizerとactionCustomizerを削除、batchCustomizerを追加
jdbc.diconをPostgreSQL用に修正
s2jdbc.diconは今回選択していないのでなし
log4jに自分のパッケージを追加
自作のバッチ起動モジュールをmainクラスに指定し、DIするbatchクラスを引数に与え実行

fin
完全に自分用の走り書き。
こういうのは公共のところに乗せるのはいくないよなw

FC2のブログ投稿にXML-RPCを使ってみる

XML-RPCって大分古い技術なはずだよなぁ。
RPCってリモートプロシージャコール。
プロシージャってWinアプリを作るときにウィンドウプロシージャーってときに使って以来、
理解をずーと先送りにしていたのだけれども、
ようやく理解しなきゃいけないのかなっと。




理解した部分で言うところの、
XML-RPCをざーというと、
XMLでリクエストを送信して、処理して、レスポンスをXMLでもらう。
処理用の対話をXMLでやるってことだわね。
やりとりがXMLなのでXML
そのやり取りで処理してもらうのをRPC。
あわせて、XML-RPCだと思う。


XML-RPCはいろいろに使えるんでしょうけど、ブログの更新が標準化されているのかなと。
調べると主にMovableTypeが使っているようだ。



今回はFC2にバッチでブログを投稿したかったので、
APIないのかなぁ と思ったり、
HTTPリクエストを生成してやればいいなぁ と思ったりしたが、
調べるとFC2はXML-RPCに対応している と書いてあった…というより、
書いている人はいた、けど公式にはどこに書いてあるの分からなかったw




ググるPHPの例はいっぱいでてくるけどなぁ。
なので今回はJAVAでアドリブで実装してみた。





今回使用するXML-RPCのライブラリは

<dependency>
	<groupId>ws-common-util</groupId>
	<artifactId>ws-common-util</artifactId>
	<version>1.0.2</version>
</dependency>
<dependency>
	<groupId>org.apache.xmlrpc</groupId>
	<artifactId>xmlrpc-common</artifactId>
	<version>3.1.3</version>
</dependency>
<dependency>
	<groupId>org.apache.xmlrpc.client</groupId>
	<artifactId>xmlrpc-client</artifactId>
	<version>3.1.3</version>
</dependency>

この辺。
ただ、xmlrpc-clientに3.1.3がSeaserMavenサイトにも、MavenMavenサイトにもない…。
ので、独自のMavenサイトにインストールしておく。
2.x系はあるのだけれども、今この状況でXML-RPCをProxyの中から送信したかったので、
apacheXML-RPCのプロクシ対応は3.1.3からってどっかに書いてあった。


いきなりJAVAでのコードを書いてしまうと、

private static final Proxy PROXY;
static {
	SocketAddress sa = new InetSocketAddress( PROXY_SERVER, PROXY_PORT );
	PROXY = new Proxy( Proxy.Type.HTTP, sa );
}

private Object executeXmlRpc( String endpointURL, String method, List<Object> parameterList ) {
	try {
		XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
		config.setEncoding("UTF-8");
		config.setServerURL( new URL( endpointURL ) );

		XmlRpcClient client = new XmlRpcClient();
		client.setConfig( config );

		XmlRpcSun15HttpTransport t = new XmlRpcSun15HttpTransport( client );
		t.setProxy( PROXY );

		XmlRpcRequest r = new XmlRpcClientRequestImpl( config, method, parameterList );

		return t.sendRequest( r );
	} catch ( XmlRpcException e ) {
		logger.debug( e );
	} catch ( MalformedURLException e ) {
		logger.debug( e );
		e.printStackTrace();
	}
	return null;
}

これでOKだった。
methodは、

"metaWeblog.getRecentPosts"
"metaWeblog.newPost"
"mt.setPostCategories"
"mt.getCategoryList"

今回はこんなのを使用。

XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();

これはXmlRpcClientConfigのインターフェースでいい気もするんだけど、
setEncodeingとsetServerURLとかがなくて、
探したところImplを直接使うでいいのかなぁと。

XmlRpcSun15HttpTransport t = new XmlRpcSun15HttpTransport( client )

XmlRpcSun15HttpTransportじゃないないと、Proxyのセットがないという。


最終的に一番重要なのが送信するパラメータだと思う。
今回は、Listにした。

org.apache.xmlrpc.client.XmlRpcClientRequestImpl.XmlRpcClientRequestImpl(XmlRpcRequestConfig pConfig, String pMethodName, List pParams)

パラメーターがListなので、Java1.4の頃の技術なのかな…。
なので、型パラメータは何でもいいんでしょうけど。


たいてい、パラメータのパタンがListかStructになっているので、
ListかHashtableかで対応すれば問題なし。
(HashtableじゃなくてMapでも良かったかも)


Listのもの場合、

List<Object> parameterList = new ArrayList<Object>();
parameterList.add( BLOG_ID );
parameterList.add( FC2_USERNAME );
parameterList.add( FC2_PASSWORD );


Structがある場合、

Hashtable param = new Hashtable();

param.put( "title", title );
param.put( "description", blog );

List<Object> parameterList = new ArrayList<Object>();
parameterList.add( BLOG_ID );
parameterList.add( FC2_USERNAME );
parameterList.add( FC2_PASSWORD );
parameterList.add( param );
parameterList.add( "1" );


こーんな感じでいけました とさ。


しかしなんか、せっかくSeaser使ってんだし、
DIしたいもんだなぁ。


あとで考えてみよう。

iTunes COM APIを使ってアプリを作ってみる

iTunesを使って音楽を再生してたら、
「15秒戻る」、「30秒進む」
ということがしたいなぁ
と思った。


iTunesには外部操作させるAPIがたしかあったろうと思ったので、
それを使うことにした。


JScriptC#C++とかからさわれるらしいので、
一番簡単そうなC#からツールを作ってみようと。


一番難しかったのが、
VisualC#のプロジェクトで参照を追加するところw


いくつかやり方があるのだろうけど、

ここで何を追加したいいか分からなかったのだが、
今回はiTunesCOMなので、

  • COMタブを選択
  • iTunesがインストールしてあれば、iTunes 1.13 Type Libraryの同じようなのがあるはず


そうすれば、参照設定のところにiTunesLibっていうのが追加されるはず。

iTunes = new iTunesApp();
iTunes.OnPlayerPlayEvent += new iTunesLib._IiTunesEvents_OnPlayerPlayEventEventHandler(this.iTunes_OnPlayerPlayEvent);
iTunes.OnPlayerStopEvent += new iTunesLib._IiTunesEvents_OnPlayerStopEventEventHandler(this.iTunes_OnPlayerStopEvent);
nowPlay.Text = iTunes.CurrentTrack.Name;
before30.Enabled = true;
before15.Enabled = true;
after15.Enabled = true;
after30.Enabled = true;

後は各ボタンのところに下記のロジックを追加させて

if (iTunes.PlayerState == ITPlayerState.ITPlayerStatePlaying)
{
    iTunes.PlayerPosition += time;
}

ほぼこれだけでOK。


最終的にできあがったアプリは

基本的なコントロールiTunesでやればいいし、
無い機能だけを実装で、うむ、便利だw
自分で作ったのでうれしさも倍増かなw