2012年12月27日木曜日

Flex:DataGrid Columnの幅をパーセント指定

Flex DataGridでDataGridColumnの列幅を固定値ではなくパーセントで指定したい場合がある。
しかしながらDataGridColumn width="10%"など指定しても
「widthのイニシャライザ:ここではパーセンテージは使用できません」
というエラーに。

creationCompleteを使って動的に指定するやり方も紹介されていたが、うまく動かなかった・・・。
http://www.adobe.com/jp/support/flex/ts/documents/224468bb.htm

でも、なんと以下のように小数点以下を指定すればパーセント指定が出来た。

<mx:DataGridColumn width=".20" headerText="No."  />
<mx:DataGridColumn width=".40" headerText="contents1" />
<mx:DataGridColumn width=".40" headerText="contents2" />

これでウィンドウを手動でリサイズしても同じ比率でグリッドの幅が保てる。
ただし幅のパーセント指定と固定値指定の併用ができず、固定で表示したかった列も小数点でパーセント指定せざるをえなかった。どうやるのでしょう。

2012年12月19日水曜日

Basic認証で認証後に500 Internal Server Error.

Basic認証で、パスワード認証後にInternal Server Error 500が出た場合。

自分の場合は.htaccessに書いたパスワードファイルのパスが間違っていました。
認証ダイアログまで表示され、一見認証通ったかのように見えるため、何が悪いのか少しだけ考えてしまいました。

2012年12月12日水曜日

CakePHP 動的に生成したフォームのバリデーション

CakePHPで動的に生成したフォームに対し、どうやってバリデーションしたらいいのか小一時間悩む。小一日くらい悩みました。
やりたかったことは以下のとおり。

ある入力フォームのページで、ロード時にデータベースの値を取得し、その値によってページのフォームの数が変わるというページを作成。

DBから取得した値が2なら、0~1($i)までループを回して
echo $form->input('Model.name'.$i, array('name' => 'distribution', 'label' => false)
をctpで表示。

普通、Modelと関連付けてのバリデーションは、ひとつひとつのフォームのnameに対してあらかじめ設定します。
このような動的に生成したフォームに対してModelからバリデーションを設定できるのかとトライ・アンド・エラーでいろいろと試行錯誤するものの、動くというだけでエラー表示もはちゃめちゃな代物に。

で、思い余ってCakePHPフォーラム様におそるおそる聞いてみたところ、優しい方に配列でフォーム値を取得できるやり方をご回答いただいたので、そこからさらに色々と調査してみてどうにか出来ました。

動的に生成したフォームのバリデーション
http://cakephp.jp/modules/newbb/viewtopic.php?topic_id=2723&forum=7

2012年12月11日火曜日

OpenSSL httpsだとFlexのデバッグがamfphpに接続できない

本番サイトがSSLのため、とりあえず開発環境にOpenSSLを設定し、プログラム内の接続先をすべてhttpsに変更。
自己証明書(いわゆるオレオレ証明書)でもサーバ上にアクセスする分には警告が表示されるのを除けば問題なかった。
が、Flex Builderでデバッグを行った際、以下のような接続エラーが表示され、amfphpに接続出来なくなった。

--------------
(Object)#0
  code = "NetConnection.Call.Failed"
  description = "HTTP: Failed"
  details =
  level = "error"
--------------

 これを回避するには、ちゃんとブラウザで自己証明書を「信頼されたルート証明機関」としてインポートする必要があった。
証明書インポートの手順
  1. IE(Flexのデバッグするブラウザ)でサイトにアクセス
  2. アドレスバーの「証明書のエラー」をクリック
  3. 「証明書の表示」をクリックし、証明書ウィンドウを開く
  4. 「証明書のインストール」をクリックし、証明書のインポートウィザードを開く
  5. 「次へ」→「証明書をすべて次のストアに配置する」を選択→「参照」→「信頼されたルート証明機関」を選択→「OK」
  6. 「次へ」→「完了」を押下し、警告等にもOKを押下し、設定完了
これで再びデバッグモードで起動した際、正常に接続できる。
どうして接続出来ないのか全くわからなくて小一時間悩みました。

2012年12月7日金曜日

PrimoPDFで作成したPDFでテキストをコピーできない

PrimoPDFで作成したPDFでテキストをコピーできない。
PDF文書の日本語での検索ができない。

テキストコピーの件は、Adobe のポストスクリプト・プリンタ・ドライバ をインストールすることで、文字化けせずに貼り付けることができた。
ただし日本語検索が出来ないのは未解決。

参考サイト
http://d.hatena.ne.jp/kaz99969/20071105/1194276529

postgresql WITH RECURSIVEを応用した深さ優先探索

Postgresql8.4から使える再帰SQL、WITH RECURSIVEを応用した深さ優先探索。
指定した親から子、孫・・・と、深く取得してから次の親に移動して探索。
親子孫、親子孫・・・と上から並べてゆく場合に便利。
ツリー構造をすべて一括で出すなら深さ優先探索の方が見やすい。

WITH RECURSIVE tmp AS(
SELECT uid,pid,
Row_Number() over(order by uid asc) AS rn FROM Tree
),
rec(uid,pid,path,sortArray) AS(
SELECT uid,pid,array_append(null,uid),array[rn]
FROM tmp WHERE pid = '0'
union all
SELECT b.uid,b.pid,a.path || b.uid,
a.sortArray || b.rn
FROM rec a,tmp b WHERE a.uid = b.pid)
SELECT uid,pid,
array_length(path,1) AS LV,
array_to_string(path, ',') AS path
FROM rec ORDER BY sortArray;


uid, pidはいずれもvarchar。
Row_Number()関数でuidの降順の連番を別フィールド「rn」として取得。
根からの経路上のrnを配列型で保存していって、最後にorder byでソートキーとして使用。
array[uid]ではなくarray_append(null,uid)としているのは、
ERROR: recursive query "rec" column 4 has type character varying(12)[]...
というunion allにおける上下の型の不一致エラーが発生したため。
postgresは8.3あたりから型チェックが厳密になったよう。

すっごく勉強させていただきました
http://www.geocities.jp/oraclesqlpuzzle/postgresql-rec-with.html

postgresql ツリー構造のテーブルを再帰的に取得

postgresqlで、ツリー構造を持つテーブルにて、指定したIDを親として、親含めた子IDを再帰的に取得するSQL。
uidがユニークID、pidが親ID。

WITH RECURSIVE r AS
(SELECT * FROM Tree WHERE uid = '123'
UNION ALL
SELECT Tree.* FROM Tree, r WHERE Tree.pid = r.uid)
SELECT * FROM r ORDER BY uid;


※WITH RECURSIVEはpostgres8.4から。

Linuxでxalanのエラー Exception in thread "main" java.lang.NoClassDefFoundError

Linuxサーバでxmlをhtml変換するのにxalanを使ってみたのですが、コマンドの実行時でこのエラーが表示されて苦労しました。

[root@localhost ~]# java org.apache.xalan.xslt.Process -in sample.xml -xsl sample.xsl -out output.html
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xalan/xslt/Process
Caused by: java.lang.ClassNotFoundException: org.apache.xalan.xslt.Process
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: org.apache.xalan.xslt.Process.  Program will exit.

PATHが通ってないので怒られているらしい。
だけれどもxalanの実行ディレクトリにはPATHは通っている。
色々調べた結果、結局実行ファイルのxalan.jarそのものに「クラスパス」を通さないとならないということを知りました。
説明に「クラスパス」に通す、とあったのですが、私はjavaは全く明るくないため、実行フォルダだけでいいのかなと思っていたのが敗因。

以下の用にクラスパスをセットして再度実行したところ、無事に成功。

[root@localhost ~]# CLASSPATH=/usr/local/apache2/htdocs/todoxweb/xalan/xalan.jar
[root@localhost ~]# export CLASSPATH=$CLASSPATH:.
[root@localhost ~]# echo $CLASSPATH
/usr/local/apache2/htdocs/todoxweb/xalan/xalan.jar:.

あるいはコマンド実行時にクラスパスまで指定する。

[root@localhost ~]# java -classpath  /usr/share/xalan/xalan.jar org.apache.xalan.xslt.Process -in sample.xml -xsl sample.xsl -out output.html