「おぼえがき」を強めに。

メイン

2010年06月30日

[おぼえがき] どうしよう?HDDがイッパイでWindowsが起動しないよ?

Windows そんなことはどうでもいい

つい先日、友人(の嫁さんの親戚)のPCが立ち上がらなくなったので、復旧対応してみました。
その時のお話。


最初に結論から。
・CドライブがイッパイだとWindowsが起動できなかったよ。
・KNOPPIXなどのCDからブートできるOSを立ち上げて、Cドライブを少し空けてあげると復旧したよ。


起動できない症状としては、
PCの電源をいれると、「Windowsが起動できませんでした。」の画面が表示される。そこから「通常起動」「セーフモードで起動」のどれを選んでも、結局起動できずに同じ画面が表示されてしまう。
というもの。


手元にKNOPPIXのCDがあったので、それ突っ込んで起動してみてHDDの状態を見てみると、
Cドライブがイッパイイッパイでした。
起動できなくなった状況など聞いてみると、どうもWindowsアップデートしている最中にCドライブの空き領域がなくなってしまい、どうにもこうにもできなくなっちゃったようです。


KNOPPIXからCドライブのファイルを削除するなり別のパーティションに移すなりすれば復旧しそうな感じだなーと思っていたのですが、KNOPPIXのバージョンが古いとNTFSなディスクに書き込みができないみたい。バージョン5以上だとNTFSに書き込みできるようなので、KNOPPIXのサイトから5.3.1のCDイメージを落としてCD作成して対応することにしました。

新たに作成したKNOPPIXを立ち上げて、デスクトップ上に表示されているマウント済みディスクを右クリックして、「Read/Writeなポリシーを変えるよ」みたいなのをクリックするとNTFSディスクも書き込みできるようになった!
CドライブからいくつかのファイルをDドライブに退避してあげてからWindowsを起動すると、おおお、きちんとブートしたじゃあーりませんか。

メーカーのサポートに問い合わせたら、セーフモードが起動しない時点で匙を投げられたみたいですが、ちょっと頑張るだけでカンタンに復旧できますね!にんにん。CDでブートできるOSは一家に一枚あった方がよいかもー。

2009年08月10日

[おぼえがき] fiber.exeでOffice2007系のファイルを開く件

Meadow Mew Windows

いまだにMUAにはMewを使ってる紀國ですが、普段会社で使っているPCはWindowsなのでMeadowの上でMewを動かしています。

Mew on Meadowでは添付ファイルはたいていfiber.exeに関連付けられているので、C-c C-eすると、fiber.exe経由でプログラムが起動するのです
が、
なぜか、Office2007系のファイル(.docxとか.xlsxとか.pptxなど)をfiberに渡すとzipファイル展開フォルダが開いてしまってうまく動かないんですよねー。

続きを読む "fiber.exeでOffice2007系のファイルを開く件" »

2009年06月08日

[おぼえがき] これからマラソンを始める男子が気をつけるべきたった1つの注意事項

マラソン

出場したマラソン大会はたいてい雨です。紀國です。(今日はちょっとブログっぽいタイトルにしてみました。)
マラソン走ると雨が降り、バイクに乗ると雪が降り、ライブをやると吹雪になる雨男のボクですが、昨日出場した第29回JAL千歳国際マラソンも予想通り(?)、雨でございました。
昨日走ったランナーの皆様、雨が降ったのはおそらく僕のせいです。ごめんなさい。

さて、まだまだ浅い経験ながら、マラソン大会に出場する上での自分なりの「これだけは守っておかなければならない心構え」みたいなものがありますので、書いてみます。
とゆーか、
昨日は何故か上記の心構えを忘れてしまって大変に痛い思いをしたので、自分のための備忘録でございます。


まぁ、マラソン走る上で気をつけることはたくさんあるのですが、その中でたった一つ、これだけは忘れない方がいいこと。

それは、、、

続きを読む "これからマラソンを始める男子が気をつけるべきたった1つの注意事項" »

2009年02月23日

[おぼえがき] WindowsのPCのセットアップでまずやること

Meadow Mew そんなことはどうでもいい

入社してからずっと使っていたPCがだんだんしょぼくなってきたので、新しいPCを購入してもらいました!でも、ニューPCのセットアップって意外と大変ですよね。。。

そんなわけで、新しいPCのセットアップでまずやることを箇条書きにしてみました。
あ、対象のOSはWindowsXPでございます。

・キーボードレイアウトの変更(106⇒101)
・キーボードレイアウトの変更(CapsLock⇒Ctrl)
・ようこそ画面をやめる
・Ctrl + Alt + Delを有効にする
・フォルダオプションの変更
・Cygwinのインストール
・Meadowのインストール
・Mewのインストールおよび設定
・その他、最低限必要な人たちのインストール。

続きを読む "WindowsのPCのセットアップでまずやること" »

2009年01月24日

[おぼえがき] Postfixで「-(ハイフン)」から始まるメールアドレスに送信すると「bad address syntax」

Linux Postfix

先日、自宅で運用している個人用途メールサーバから友人にメールを送ると、 bad address syntax のエラーメールが返ってきてしまいました。その友人のメールアドレスは「-(ハイフン)」で始まるのですが、RFC的には問題ないのでエラーになる理由がよくわかりませんっ・・・

と、不思議に思ったのでちょっと調べてみると、Postfixがデフォルトでは「-」で始まっているメールアドレスの配送を拒否してしまうらしいことがわかりました。

で、これを回避するには、main.cfに以下のように記述すればいいようです。

allow_min_user = yes

参考サイト:


これは、外部コマンドでメールを配送しようとする時に、「-」で始まっているメールアドレスが、コマンドに対するオプションと解釈されてしまう危険性があるからである。

とのことですが、別にRFC違反じゃないのにデフォルトで拒否ってしまうなんて、ちょっと極悪仕様ですな。


追記:
postfixのバージョンによっては invalid recipient syntax というエラーになるかも☆

2008年11月30日

[おぼえがき] Eclipseが起動できない?「JVM terminated. Exit code=-1」

java

Eclipseを3.1から3.4に乗り換えたところ、「JVM terminated. Exit code=-1」とエラーこいて起動できない症状が発生。発生した環境右の通り。OSはWindowsXP、jdkは1.5.6、jreは1.5.11と1.6.7。
JVM terminated.
なんじゃこりゃー、と軽くWebで検索したところ、いくつかの解決策が紹介されていた。

  • eclipse.iniの-Xmx512mが悪者。これを256mに変えるとよい。
  • 複数のjava環境があることが悪者。利用バージョンのJREフォルダをeclipseにコピーするとよい。
  • 複数のjava環境があることが悪者。Eclipseの起動引数で使用するjavawを明示的に指定するとよい。

続きを読む "Eclipseが起動できない?「JVM terminated. Exit code=-1」" »

2008年11月17日

[おぼえがき] GoogleChromeでJavaScriptをOFFにする

google

今日の「そんな奴いねーよ」のコーナーです。
Webサイトの動作確認をする際に、「JavaScriptオフなユーザー」の見え方・動き方を確認するためにブラウザのJavaScript有効/無効オプションの設定をいじりながら確認するのですが、なんと、Google ChromeにはJavaScriptを無効にする設定がどこにも見当たりません!でも、できるはずだと思うのでちょっと調べてみました。

続きを読む "GoogleChromeでJavaScriptをOFFにする" »

2008年11月03日

[おぼえがき] PuttyでCtrl-S押しちゃったらどうしよう!?

Linux Putty

いや、puttyに限らずたいていの端末ソフトはそうなんだと思いますが、Ctrl-Sを押しちゃうと端末が固まってしまって何も操作できない感じになってしまいます。ボクはよくCtrl-Aを押そうとして間違ってCtrl-Sを押しちゃうことがたまーにあります。
一見端末がフリーズしているように見えますが、そんなときはあわてずに「CTRL-Q」すると復帰します。
っつーか、最近までフロー制御なんて気にしたことなかったですよ。。修行が足りませんな。

参考ブログとその引用↓

Apparently CTRL-S actually does XOFF, which means the terminal will accept key strokes but won’t show the output of anything. It will appear as if your terminal is dead when it’s really just waiting to be turned back on. The fix? Simply press CTRL-Q to turn flow-control on (XON). If you pressed a whole bunch of keys before pressing CTRL+Q, you’ll see the output from those keystrokes.
from Recovering from CTRL+S in Putty | Raam Dev’s Weblog

2007年11月22日

[おぼえがき] 暗号化mailtoが見破られた!?

orz スパム対策 迷惑メール

以前から以下のエントリでご紹介していた、暗号化mailtoタグが最近見破られてしまったようですので、ご報告申し上げます。

上記に紹介した迷惑メール対策は、PHPのHTML_Cryptを利用して暗号化されたmailtoタグを生成する、というものでした。HTMLソース上に生のメールアドレスが記述されていないので、メールアドレスがクロールされにくい、というものでした。
が、、、、

先日から僕のアドレスにスパムメールがもりもり届くようになりました。
クローラーも賢くなってJavaScriptを解析するようになってしまったのでしょうか。

既に上記にご紹介した対策は万全ではありませんのでご注意ください!!

うーむ、次なる対策を講じなければいけないですね。。

2007年10月05日

[おぼえがき] 画面ロックはCtrl+Alt+Del派?Windowsロゴ+L派?

先日、ふとしたきっかけで、Windows ロゴ + L キーが (コンピュータをロックする)に割り当てられていることを知りました。
画面ロックといえば、長年Ctrl+Alt+Del⇒「コンプータのロック」ボタンに慣れ親しんできましたが、Windowsロゴ+Lの方が格段にラク!ちょっと感動。

でも、せっかく見つけたショートカットを使おうと思っても、席を離れる瞬間に指が勝手にCtrl+Alt+Delを叩いている毎日。習慣ってそんなもんですな。

WindowsXPで利用できるショートカットはWindows XP で使用可能なショートカット キー一覧にいろいろとまとまってますので、今まで知らなかったショートカットを見つけてみてはいかがでしょう。
個人的にはWindowsロゴ+E(エクスプローラ)とかWindowsロゴ+D(デスクトップ表示)を知った時はかるく感動しました。実際作業効率も(多分)格段にアップしましたし。

2007年08月09日

[おぼえがき] メールアドレス画像化ツールを作ってみた

PHP スパム対策 便利ツール 迷惑メール

前回の『迷惑メール防止のための暗号化mailtoタグ生成ツール』に引き続いて、【誰でも簡単に作れちゃうけどあったらあったで便利かもしれないツール】第二弾として、メールアドレスを画像にするツールを作ってみました。

MailAddress Image Gen

画面イメージはこんな感じ↓

mailaddressgen_1.jpg

メールアドレスを入力して「generate!」ボタンを押すと、入力されたメールアドレスを画像にして出力してくれます。表示された画像を右クリックして保存してご利用ください。

mailaddressgen_2.jpg

ホームページやブログにメールアドレスを生で載せると、迷惑メール収集くんに捕捉されて迷惑メールが飛んできてしまう場合がありますが、画像を載せる分にはそんな心配はないでしょう。
まぁ、画像なので、クリックしてもメーラーが立ち上がらないし、コピペもできないので不便な気もしますけど。。メールアドレス暗号化ツールと合わせ技しないと実用性は薄いかもしれませんね。。

出力する画像はPNG形式かJPG形式かを選択できます。
また、入力されたフォントサイズに従って画像が生成されます。
なんちゃってで作っているので、今の状態ではかゆいところには手が届かない感じですが、時々気まぐれでバージョンアップをしていこうかな、と思ってます。


2007年07月31日

[おぼえがき] 迷惑メール防止のための暗号化mailtoタグ生成ツール

JavaScript PHP スパム対策 迷惑メール

以前、「迷惑メールはイヤだけど、mailto:は使いたい。」というエントリでPEARのHTML_Cryptモジュールを利用してメールアドレスが暗号化されたmailtoタグを生成する方法を紹介しました。

紹介だけするのも出し惜しみな感じがしてきたので、メールアドレスを暗号化してくれるツールをこっそり公開してみました。

mailto暗号化ツール

メールアドレスを入力してボタンを押すと、JavaScriptコードが出力されるのでそのコードをHTMLに貼り付けるとmailtoなタグが生成されます。
生のメールアドレスがHTMLソースに含まれなくなるので、ちょっとだけ安心。

2007年07月27日

[おぼえがき] <Spring Framework>マルチスレッド環境でgetBeanすると稀にClassCastException

Java Spring

以前、Spring FrameworkのDIコンテナでオブジェクトを生成するプログラムを開発していたときにClassCastExceptionが稀に発生するという現象があったので忘れないように覚え書き。

現象が発生していたプログラムの主な特徴は下記の通り。
・Spring Framework 2.0.1
・Javaで作成されたバッチプログラム
・マルチスレッドで処理を行い、各スレッドの処理内でApplicationContext#getBean()で実処理オブジェクトを生成
・生成されるクラスは非シングルトンだった。(Bean定義XMLにて、singleton=falseとしていた)

発生した時のメッセージは以下のようなものでした。

Exception in thread "Thread-1" java.lang.ClassCastException: java.lang.Class
at org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClassName(AbstractBeanDefinition.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:317)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1008)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:347)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:264)
・・・

発生箇所(AbstractBeanDefinition#getBeanClass()メソッド)のソースを見ると、下記のように、this.beanClassがClassオブジェクトなのかStringオブジェクトなのかで処理をきりかえているようです。
public String getBeanClassName() {
if (this.beanClass instanceof Class) {
return ((Class) this.beanClass).getName();
}
else {
return (String) this.beanClass;
}
}

発生している現象としては、if文で判定した時にはStringオブジェクトだったのにStringにキャストして返却する(return (String) this.beanClass;)時にはClassオブジェクトになってしまっていた。ということですな。
あるスレッドがこのelse文の処理をしているまさにその瞬間に別スレッドがthis.beanClassをClassオブジェクトにしてしまったということなのでしょうか。

AbstractBeanDefinition#resolveBeanClassメソッド内で、クラス名からClassオブジェクトを生成してthis.beanClassに設定しているようなので上記のような現象が発生する可能性はありそうですね。
public Class resolveBeanClass(ClassLoader classLoader) throws ClassNotFoundException {
if (this.beanClass == null) {
return null;
}
Class resolvedClass = ClassUtils.forName(getBeanClassName(), classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
}

で、どうしたか。

ApplicationContext#getBean()するだけのオブジェクト生成クラスをシングルトンで作成して、そのクラスのメソッドをsynchronizedにして解決しました。

2007年07月04日

[おぼえがき] .forwardの書き込み権限

.forward メール 転送

自分のメールアドレスがたくさんありすぎてよくわからなくなってきたので、
プライベートなメールはgmailに集約させようかな、と思い、
転送設定をほどこしてみたり。

友人の管理しているサーバにもメールアカウントがあるので
これも転送設定をしてあげようと、
viを立ち上げて自分のメールアドレスを記述して、$HOME/.forwardとして保存。

よし、これで、きちんと転送できているハズだぞ、と、送信テストしてみる。
そして、転送先のアドレスにメールが届くまで待ってみる。
でも、
どれだけ待ってもメールは届きませんでした。

後日、友人に問い合わせてみると、メールサーバのログに
『.forwardの書き込み権限がおかしいよ』というエラーメッセージが
でていたとのこと。
早速、ファイルの権限を変更して再テストしてみる。

chmod 644 $HOME/.forward

すると、
お、おおー、きちんとメールが転送されました。

今日のおさらい
.forwardは自分以外のユーザに書き込み権限を与えてはいけません。
っつーか、フツーに考えて、当たり前ですな、こんなこと。
なんで最初に確認しなかったんだろう。。ちょっと反省。


2007年05月29日

[おぼえがき] XOOPSから連続ピリオドなメルアドにメール送信

XOOPS オープンソース

XOOPSベースのサイトを構築する過程でややハマったので。。

入力されたメールアドレス宛にメールを送信するというありがちな機能を
盛り込む必要があったのですが、
その際、XOOPSのメールチェック関数をちょっとイジって、
最近のケータイメールにありがちな、ピリオドが連続するような
ヘンなメルアドにも対応できるようにしてみました。
(参考:なにぃー、メルアドに連続するピリオド!? + 技の蔵之介

include/functions.php のcheckEmail関数をイジったおかげで、
登録時の入力チェックでヘンなメルアドがチェックにひっかかることなく
無事に登録することができました。
が、
メールがサッパリ届きません。

どうしてだろう?と思ってデバッグモードで実行してみると、
Invalid Mail Address Format.なんていうメッセージがでている。。
むむむ、checkEmail関数を修正して安心していたのですが、
他にも注意するべき箇所があったのでしょうか。

XOOPSのメール関数あたりをよ〜く調べてみると・・・
xoopsmailer.phpの最後の方に_checkValidEmail($addr)なんて関数があるじゃ
あ〜りませんか。
xoopsmailerは独自のメールアドレスチェック関数を持っていて
送信先メールアドレスなどを設定する際にチェックしていたんですねー。

この_checkValidEmail関数にも「なにぃー、メルアドに連続するピリオド!? + 技の蔵之介」で紹介されている
修正をほどこしてあげて、再度送信してみると、
お、おおー、メールが送れました。

んー、同じようなチェックロジックがいたるところに散りばめられているとは、
XOOPS、カオスですなぁ。

2007年02月06日

[おぼえがき] 迷惑メールはイヤだけど、mailto:は使いたい。

JavaScript PHP スパム対策

インターネットで公開しているサイトにメールアドレスをそのまんま載せてしまうと、悪い人たちにクロールされて迷惑メールの標的になってしまうことが多々あります。その対策として、「@」を「 at 」あるいは全角の「@」と記述したり、メールアドレスの部分を画像で表現するなどしている人も多いと思います。
が、それでもやっぱりmailto:でメーラーを起動させたい、そんな悩みをお持ちの方も多いのではないでしょうか。せっかくWebにメールアドレス公開するんだから、1クリックでメーラーを起動できた方がいいもんね。

何かいい方法はないのかなぁと探していたところ、Nさんが素敵なモジュールを発見してくれました。
PHPのPEARにHTML_Cryptというモジュールがあり、これを利用することでメールアドレスを暗号化してサイトに仕込むことができるようです。
マニュアルはコチラ⇒PEAR :: Manual :: HTML_Crypt

モジュールの利用法としては、とっても簡単。

<?php
// オフセット 8を指定して利用したいメールアドレスを暗号化。
$c = new HTML_Crypt('あなたのメールアドレス', 8);
// それを で囲みます
$c->addMailTo();
// 復号されたアドレスを表示するための javascriptの出力。
$c->output();
?>

※ 上記のマニュアルページのサンプルのまんまですが、メールアドレスの箇所だけ直しました。
このphpを実行すると、下記のようなJavaScriptが出力されます。
<script language="JavaScript" type="text/javascript">/*<![CDATA[*/var a,s,n;function j5fb0cb45e8d0261d0a495dbf221bdb91(s){r="";for(i=0;i<s.length;i++){n=s.charCodeAt(i);if(n<128){n=n-8;if(n<32){n=127+(n-32);}}r+=String.fromCharCode(n);}return r;}a="Di(pzmnE*uiqt|wBsqvws}vqHiv|i{6rx*Fsqvws}vqHiv|i{6rxD7iF";document.write(j5fb0cb45e8d0261d0a495dbf221bdb91(a));//]]></script>
これを実行するとこんなmailto:なリンクが表示されます。

見ている分には普通にメールアドレスも見れるし、クリックするとメーラーが立ち上がりますが、ソースを見るとメールアドレスの部分がしっかり暗号化されているので、クローラーには捕捉されなくてすみそうですね〜。

アンタスのホームページにもいくつかこのスクリプトを仕込んでみました。こちらのページなどでご覧いただけます。ちなみに、実際に使う場合にはJavaScript未対応な方のために、<NOSCRIPT>なタグの中で画像なり、at なりを記述しておく必要がありますね。

この方法の難点は毎度プログラムを書かないといけないのですが、僕はそれが面倒なのでメールアドレスを入力したらJavaScriptコードを出力してくれるCGIを作成して利用してたりしてます。
そのCGI、せっかくだからどこかに公開しましょうかね〜。誰か使ってくれる人、いらっしゃいますかね。

2006年10月31日

[おぼえがき] MySQL4.1のLOAD DATAで日本語データをインポートする

MySQL 日本語 文字化け

MySQL4.1のLOAD DATAコマンドで日本語データをインポートしようとした時に少しハマったので覚え書き。

【やったこと】
UTF8で作成された日本語を含むCSVファイルを下記のコマンドにてMySQLのテーブルにインポートしようとした。

LOAD DATA INFILE 'foo.csv' INTO TABLE 'bar_table' FIELDS TERMINATED BY ','

なお、テーブルのデフォルト文字コードもUTF8にあわせている。
mysql> show create table bar_table \G
*************************** 1. row ***************************
Table: bar_table
Create Table: CREATE TABLE `bar_table` (
〜〜(中略)〜〜
) ENGINE=MyISAM DEFAULT CHARSET=utf8

【起こった問題】
インポートした日本語データが文字化けしていた。

【疑問】
CSVファイルとテーブルの両方とも文字コードをUTF8に統一しているのにどうして文字化けするのだろうか?

【原因】
結論から先に書くと、この時、データベースのデフォルトキャラセットがlatin1になっていたことが文字化けの原因だったようです。

mysql> show create database moo_database \G
*************************** 1. row ***************************
Database: moo_database
Create Database: CREATE DATABASE `moo_database` /*!40100 DEFAULT CHARACTER SET latin1 */

そこで、databaseのデフォルトキャラクターセットもUTF8に統一して再度インポートしてみると・・・
おお!文字化けせずにデータを登録することができました。

試しに、eucのデータベースにeucのテーブルを作成し、eucのcsvデータをインポートすると、こちらも文字化けせずに登録することができました。

【結論・本日の覚え書き】
MySQL4.1で日本語データをインポートする際には文字コードを統一しよう!
データベースの文字コード=テーブルの文字コード=インポート元ファイルの文字コード

2006年10月13日

[おぼえがき] Digesterと文字エンコーディング

Digester Java XML 日本語 文字化け

Digesterを使ってXMLをパースする際に文字コードでハマった経験があるので、覚え書き。

今回のお題は「MS932のくせにencoding="Shift_JIS"と記述しているXMLをDigesterに食わせるとどうなるか。」です。
サンプルとして下記のようなXMLをDigesterを使ってパースしてみたいと思います。
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE sample SYSTEM "../dtd/932sample.dtd">
<sample>
<item>
<id>1</id>
<value>あああ</value>
</item>
<item>
<id>2</id>
<value>全角のにょろ「〜」</value>
</item>
<item>
<id>3</id>
<value>全角のマイナス「−」</value>
</item>
</sample>

最初のXML宣言のところで、
<?xml version="1.0" encoding="Shift_JIS"?>
と、エンコーディングをShift_JISで指定しています。が、もし、このXMLファイルがShift_JISのつもりなのに実際はMS932で作成されていたらどうなるでしょうか?
エンコーディングを気にせずに普通にDigester#parse(url)メソッドでパースすると、〜や−が文字化けしてしまいます。
/////////////////何も考えずにパースするの例///////////////////////////
/** パース対象のXML */
public static final String TARGET = "./xml/932sample.xml";

public Sample parseNormal() throws IOException, SAXException {

Digester digester = createDigester();
Sample sample = (Sample)digester.parse(TARGET);

return sample;
}

public static void main(String[] args) {
Digester932Test test = new Digester932Test();
try {
Sample sample = test.parseNormal();
System.out.println(sample);

} catch (IOException ex) {
System.out.println(ex.toString());
} catch (SAXException ex) {
System.out.println(ex.toString());
}
}

パースした結果を表示させて見ると、下記のように文字化けするはずです。

item = [ id:1, value:あああ ]
item = [ id:2, value:全角のにょろ「?」 ]
item = [ id:3, value:全角のマイナス「?」 ]

そこで、今度はparseする際にXMLファイルのURLを指定するのではなく、文字エンコーディングを指定したInputSourceを利用してみましょう。
/////////////////エンコーディングを指定してパースするの例///////////////////////////
public Sample parseByInputSource() throws IOException, SAXException {
InputSource is = null;
InputStreamReader reader = null;
//エンコーディングを指定したInputStreamReaderを作成してInputSourceを初期化する
reader = new InputStreamReader(
new FileInputStream(TARGET), "MS932");
is = new InputSource(reader);

Digester digester = createDigester();
Sample sample = (Sample)digester.parse(is);
return sample;
}

さて、これでエンコーディングを指定したので、ちゃんとパースされるはず。
ですが、実行してみると、環境によっては下記のようなエラーが発生します。

java.io.FileNotFoundException: /path/to/932sample.dtd (指定されたパスが見つかりません。)

どうも、XMLのDOCTYPEでDTDが相対パスで指定されている場合、

  • Digester#parse(url)を使用した場合:xmlファイルからの相対パスでDTDを探しに行く。

  • Digester#parse(inputsource)を使用した場合:javaを実行したディレクトリからの相対パスでDTDを探しに行く。


という動きになるように見受けられます。
これではイカンのでもう一工夫必要のようです。色々試してみた結果、下記の工夫に行き着きました。
InputSource#setSystemIdメソッドでXMLファイルを指定すると、XMLファイルからの相対パスでDTDを探しにいくようだ。
/////////////////エンコーディングを指定してパースするの例///////////////////////////
public Sample parseByInputSource() throws IOException, SAXException {
InputSource is = null;
InputStreamReader reader = null;
//エンコーディングを指定したInputStreamReaderを作成してInputSourceを初期化する
reader = new InputStreamReader(
new FileInputStream(TARGET), "MS932");
is = new InputSource(reader);
//XMLファイルのURLをSystemIdとしてsetする。
is.setSystemId(TARGET);

Digester digester = createDigester();
Sample sample = (Sample)digester.parse(is);
return sample;
}

こうすると、下記のように文字化けしないでパースできました。

item = [ id:1, value:あああ ]
item = [ id:2, value:全角のにょろ「〜」 ]
item = [ id:3, value:全角のマイナス「−」 ]


と、ここまで試してみて、InputSource#setEncodingというメソッドがあることに気がついてこれも試してみました。
InputSource is = new InputSource();
is.setSystemId(TARGET);
is.setEncoding("MS932");

APIドキュメント的にはこれで期待通りに動いてくれるはず。。。だったのですが、こちらはきれいに文字化けしてしまいました。
うーむ。なんか納得いかない。

本日のまとめ。
エンコーディングを指定したInputStreamReaderを渡してInputSourceを初期化する。
InputSource#setSytemIdでXMLファイルへのURLを指定する。
そのInputSourceをDigester#parseメソッドへ渡す。

2006年06月15日

[おぼえがき] なんちゃって画面作成の覚え書きその1

JavaScript スタイルシート

システムを作るときに、やっぱり気になるのは画面。
見た目や使い勝手を完成する前に確認しておきたいですよね。使う方も作る方も。
しかしながら、事前の確認では
「これからこんな感じで作りますね」という予定の時点、つまり何も作っていない時点で見てもらうわけで
当然ホントに動くものは見せられません。
とは言えども、
・エクセルやワードで書いたマンガよりは、ブラウザで確認できた方がよい。
 ⇒ その方が完成イメージに近いから
・何も動かないよりは動いた方がよい。
 ⇒ 見た目だけじゃなく、操作感も確認したいから
と、本物に近い状態のサンプル画面を作る必要があります。

そんなわけで、それっぽく動くサンプル画面を作ることがちょくちょくあるのですが、
(これを僕は「なんちゃって画面」と呼んでます)
いかんせん記憶力がないので
「あれ?これ、どうやるんだっけ?」
と毎回忘れてしまい、昔の資料を引っ張りだしたり、人に聞いたりしてます。
というのも非常に効率が悪いので備忘録はここに残しておくことにしました。

ようやく本題。なんちゃって画面の作り方その1.
JavaScriptとStyleSheetとDHTMLを使えばそれっぽく動きます。
今回のポイントは3つ。
 1.タグにid属性を設定して、document.getElementById()メソッドでタグ要素をオブジェクトとして取得する
 2.表示させたくないものはstyle属性にdisplay:noneを指定して隠す。
 3.表示内容の切り替えはobject.innerHTMLの内容の変更で実現する。

⇒ サンプルはコチラ

サンプルの解説
まずは、値を変更したい箇所やそのために(計算などで)値を取得しなければいけない箇所について、id属性で名前をつけていきます。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
実際に値を変えたい部分のHTMLの記述
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
<td>
<!-- ポイント1.値を参照したいタグ要素にはidで名前をつけておく。 -->
<select id="select_0" name="select_0" onChange="selectNum(0);">
<option value="z" selected>-- 選択してください。 --</option>
<option value="a">⇒1と表示される。</option>
<option value="b">⇒2と表示される。</option>
<option value="c">⇒3と表示される。</option>
</select>
</td>
<td>
<!-- ポイント1.値を参照したいタグ要素にはidで名前をつけておく。 -->
<div id="select_a_0" class="hid">1</div>
<div id="select_b_0" class="hid">2</div>
<div id="select_c_0" class="hid">3</div>
<!-- ポイント1.値を変更したいタグ要素にはidで名前をつけておく。 -->
<div id="select_val_0" style="display:block;"></div>
</td>


ちなみに、どうにも表示はしたくないのだが、計算や値の切り替えのために隠し項目を持ちたい場合は、style属性にdisplay:noneを与えれば見えなくなります。


〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
隠し項目のスタイルシートの記述
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
.hid {
border-color: #808080;
border-style: solid;
border-width: 2px;
background-color: #CCCCCC;
margin:2px;
// ポイント2.隠したい項目はdisplay:noneを設定する。
display:none;
}


実際に値を変更するのはJavaScriptによって行います。idを指定してオブジェクトを取得して、innerHTMLで値の参照や設定をしています。今回はdiv要素の値を変更していますが、タグの定義的にはspanの方がいいかもしれません。


〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
値を変更するJavaScript
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
<script type="text/javascript">
<!--
function selectNum(idx) {
// 引数idxでテーブルの行数が指定されます。
//ポイント1.id指定でイベント発生元の選択ボックスを取得
var selectbox = document.getElementById("select_"+idx);
// その選択された値を取得
var opt_val = selectbox.options[selectbox.selectedIndex].value

// ポイント1.値を参照するdiv要素をid指定で取得
var select_a = document.getElementById("select_a_"+idx);
var select_b = document.getElementById("select_b_"+idx);
var select_c = document.getElementById("select_c_"+idx);

// ポイント1.値を設定するためのdiv要素の取得
var select_val = document.getElementById("select_val_"+idx);


if(opt_val == "a") {
// 選択されたのが"a"だったら
// "a"の値をselect_Valに表示する。
//ポイント3.値の変更はinnerHTMLの変更にて実現する。
select_val.innerHTML = select_a.innerHTML;

} else if(opt_val == "b") {
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
後略
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜


こんな感じでそれっぽく動いているように見えるのではないでしょうか。
なんか、文章にすると、全然たいしたことやってないですな。これくらいちゃんと覚えておけ>自分。

おまけ
サンプルの合計の計算ではこんな原始的なことをやってます。
つまり、テーブルの行毎の要素に連番を振っておいて、ループしてぎゅんぎゅんまわしながらid指定でオブジェクトを取得する。id_0、id_1、id_2・・・・。すると、テーブルの行数を超えたところでid指定で取得できるオブジェクトがなくなってしまうので、それをループの終了条件にする。んー、原始的。もっとスマートにやりたい。


function sumVal() {
// 合計を計算する。
var sum = 0;
for(idx = 0; ; idx++) {
//ループしてテーブル毎のselect_valなdiv要素を取得する。
var o = document.getElementById("select_val_"+idx);

if(o == null) {
// id指定で要素が見つからなかった場合には
// 最後まで走査したことなので、breakする。
break;
}

あわせて読みたい

あわせて読みたい

最近のスポーツ(道新)