2013年12月24日火曜日

Java ResouceBundleの使い方

使い方を皆さんに教えるのではなく、俺が初めて試したという意味の記事。

(確認したかったこと)

  • リソースをファイルシステム上に置いておくのではない方法での使い方。
(結論)
  • ResouceBundle.Controlのサブクラスを作る方向で考えていたが、とりあえずListResouceBundleでも十分なのかなと。
  • いずれにしても何とでもなりそうなので、とりあえずResouceBundleを使ってプロパティファイルを使っていても、後で動的な管理に差し替えることは可能だろう。
  • けど念のため、ResouceBundle自体をそこらじゅうで使うのではなく、これにたいするFacade的なラッパー的な何かを用意しておいた方がいいだろう。



----

package i18n;

import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.ResourceBundle;

public class Test {
public static void main(String[] args){

System.out.println("value for 'key1'");

for(Sample s : Sample.values())
System.out.println(String.format(
"%-20s : %s",
s.name(),
s.get().getString("key1")
));
}

interface Testable{
ResourceBundle get();
}
enum Sample implements Testable{
SIMPLE_CASE(){
public ResourceBundle get(){
return ResourceBundle.getBundle("i18n.hoge");
}
},
OF_JAPAN(){
public ResourceBundle get(){
return ResourceBundle.getBundle("i18n.hoge", Locale.JAPAN);
}
},
OF_ENGLISH(){
public ResourceBundle get(){
return ResourceBundle.getBundle("i18n.hoge", Locale.ENGLISH);
}
},
OF_US(){
public ResourceBundle get(){
return ResourceBundle.getBundle("i18n.hoge", Locale.US);
}
},
NAMED_CUSTOM(){
public ResourceBundle get(){
return new MyResourceBundle("key1");
}
}

}

static class MyResourceBundle extends ListResourceBundle{

private final String[] keys;

MyResourceBundle(String... keys) {
this.keys = keys;
}

@Override
protected Object[][] getContents() {
Object[][] con = new Object[keys.length][2];
for(int i = 0; i < keys.length; i++){
con[i] = new Object[]{keys[i], "To tell the truth, I don't know about " + keys[i] + "."};
}
return con;
}


}
}

2013年12月19日木曜日

CSSで縦が画面いっぱいで下端のフッターが常に表示されるレイアウト

※ 自分はデザイナではないので、かっこいい絵を作る方面の話ではないです。

多くはないけど一定の需要があり、少なくとも自分はちょいちょい必要性を感じている、ブラウザの縦いっぱいの下端にフッターが出るようなレイアウト。

以下のようにしたら出来た。

肝になったのは、

  • html要素にheight:100%
  • bodyをposition:relative, height:100%
  • footerをposition:absoluteでbottom:0
  • headerにマージンをとらない

最後のheader(headじゃなくて、body内のヘッダーパート)のマージンがちょっとハマった。上端にナビゲーションを絶対位置で置いた都合、headerにmargin-top:20pxを指定していたのだが、そうするとbodyが100%からマージン分だけ伸びてしまってスクロールバーが出たり、変な余白が出来たりした。ので、headerのマージンはなくしてpadding-topを入れて、header内部のコンテンツをdivでまとめて下にずらした。



   *   *   *

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>縦が100%で下端にフッターが常にあるレイアウト</title>
<style type="text/css">
html{
  height:100%;
}
body{
  position:relative;
  margin:0;
  padding:0;
  height:100%;
  background-color:#cdc;
}
header{
  padding-top:20px;
}
header > div{
  boder-bottom:1px solid #000;
  background:linear-gradient(#999,#ccc);
  height:42px;
}
main{
  border:1px dotted green;
  background-color:#fff;
}
footer{
  position:absolute;
  bottom:0;left:0;
  margin:0;
  height:50px;width:100%;
  border-top:1px solid #000;
  background:linear-gradient(#ccc,#999);
}


header h1{
  display:block;
  float:right;
  font-size:150%;
}
nav {
   position:absolute;
   top:0;left:0;
   height:20px;
   border-bottom:1px solid orange;
   background:linear-gradient(#333,#666);
   width:100%;
   font-size:80%;
}
nav ul{
  padding:0;margin:0;
}
nav li{
   display:inline;
}
nav a{
   color:#fff;
}
section{
  border:1px solid #999;
  border-radius:1em;
  padding:1em;
  margin:1em;
}
</style>
</head>
<body>
<header>
  <div>
  <h1>ヘッダー</h1>
  </div>
</header>
<nav>
  <ul>
    <li><a href="some.html">何かのメニュー</a>
    <li><a href="some.html">何かのメニュー</a>
    <li><a href="some.html">何かのメニュー</a>
    <li><a href="some.html">何かのメニュー</a>
  </ul>
</nav>
<main>
  <section>
    <h1>height:100%</h1>
  </section>
</main>
<footer>
  footer height:50px
</footer>
</body>
</html>

2013年12月13日金曜日

JavaScriptでCSVをパース (jQuery使用)

※単に自分用メモです。

jQueryと、jQuery Parse Pluginを使う。

http://plugins.jquery.com/parse/


最初はパース部分は作るつもりで、周辺だけjQueryを使ってみようと思ったのだが、何かあったので。

試したサンプル。良い感じ。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<script type="text/javascript" src="./lib/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="./lib/jquery.parse.min.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
var tsv = 'ID\tDA(カンマ含む) \tDB(改行含む)\t数値型\t凸凹\n\
L1\tDA,1\t"DB1\n\
multiline"\t1\t+\n\
L2\tDA,2\tDB2\t2\t\n\
L3\tDA,3\tDB3\t3\t+\n\
\tDA,4\tDB4\t4\t\n\
\tDA,5\tDB5\t5\t+\n\
L6\tDA,6\tDB6\t6\t\n\
';
var csv = 'ID,DA(カンマ含む),DB(改行含む),数値型,凸凹\n\
    L1,"DA,1","DB1\n\
multiline",1,+\n\
    L2,"DA,2",DB2,2,\n\
    L3,"DA,3",DB3,3,+\n\
    ,"DA,4",DB4,4,\n\
    ,"DA,5",DB5,5,+\n\
    L6,"DA,6",DB6,6,';

function test(data, delim){
    $("#data").text(data);
    var res = parseText(data,delim);
    var table = $("<table />").appendTo($("#res"));
    {
        var tr = $("<tr />");
        tr.appendTo(table);
   res.results.fields.forEach(function(col){
            tr.append($("<th />", {"text":col}));
   });
    }
    res.results.rows.forEach(function(row){
        var tr = $("<tr />");
        tr.appendTo(table);
        res.results.fields.forEach(function(col){
            tr.append($("<td />", {"text":row[col]}));
        });
    });
}
function parseText(data, delim){
return $.parse(data, {delimiter:delim, header:true, dynamicTyping :true});
}
</script>
<style type="text/css">
#data{
    white-space:pre-wrap;
    border:1px solid #ccc;
    font-size:75%;
}
#res table{
    border:1px solid #666;
}
#res table td{
    border:1px solid #999;
    white-space:pre-wrap;
}
</style>
</head>
<body>
<button onclick="test(tsv, '\t')">TSV</button>
<button onclick="test(csv, ',')">CSV</button>
<div id="data"></div>
<div id="res"></div>
</body>
</html>

2013年12月1日日曜日

和風パスタ with めんつゆ, ガーリック, ベーコン

混ぜるだけのたらこスパに飽きてくるとペペロンチーノを作っているが、それだと5歳の娘は辛くて食べないので、娘の好きなめんつゆでのパスタ。


買い物帰りに寄った直売所で九条ねぎが売っていて、聞いてもいないのに婆さんが「これは白いところより青いところがおいしい」と教えてくれたのでそれを活かすという条件のための調理でもある。


当てずっぽ気味で作ったらわりと美味かったのでメモる。


材料 夫婦+幼児1
  • ニンニク大粒2つスライス
  • 九条葱4本斜め切り(青いところも)
  • ベーコン適当に切る
  • きのこ(しめじ)適当。今回は半株。
  • オリーブオイル(エクストラバージンじゃないやつ)

  1. 麺は250g(親子3人)
  2. オリーブオイル大さじ4をフライパンに入れ、弱火でニンニクを揚げる
  3. 揚がったらニンニクを取り出す
  4. 交代でベーコン、きのこ、葱の白いところを投入し、気休め程度に塩と黒胡椒をし、火を強め炒める
  5. 炒まったら火をとめ、パスタ茹で汁をお玉一杯投入。めんつゆを大さじ4投入。混ぜてネギの味見でもする。うまければOK。
  6. 茹で上がった麺を投入し、強火で炒める
  7. 気が済んだら子供の分を取り分ける
  8. 輪切り乾燥唐辛子と黒胡椒を追加し、もう少しだけ炒める(親の分)
  9. 皿によそう。
  10. 空いたフライパンにねぎの青いところ投入。オリーブオイルを軽くかけてさっと炒め、トッピングする

感想:予想よりうまかった。

味玉があったのでついでに乗せたのがまたピッタリ。あと、花かつおも散らした。マヨネーズは合うだろうが、たぶんすべてマヨネーズ味になるのでやめた。粉チーズも合わないではない。




出来上がるとすぐ食いたくなるので盛りつけが雑になる。

そういや、世間で噂の「誤表記」で、どこかのホテルの飯が九条ネギといいつつ普通のネギだった、とニュースで見たが、これ全然違うじゃん。つうか使い道が違うんじゃん。そんで食ってふーん、て納得してたなら食ってる方も実は大して気にしてなかったんだからいんじゃないのか。…とか思ってしまった。深谷ネギと普通のネギとかならわからん気がするけど。

2013年11月28日木曜日

VelocityをTomcat(JSP)で使う

JavaテンプレートエンジンのVelocity。2011年から更新されていない様子で「いまさら」なのかはよく知らないが、見る限りテンプレートとしての機能は十分そうだし、導入が簡単そうなので試してみる。

Velocityの利点はたぶん、

  • jar2つで動く
  • Web画面の出力と非Web帳票出力との両方に使える
だ。



・・・更新がないのは安定しているからだろう。きっとそうだ。

http://velocity.apache.org 本家
http://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html テンプレート記法


以下、Veloctityを、(Windows, Eclipse, Tomcatな環境で動かしてみた際のメモ。

  1. ダウンロード http://velocity.apache.org/download.cgi#engine
    1.   velocity-1.7.zip
  2.  解凍して、
    1. EclipseのDynamicWebProjectのプロパティで、
      1. velocity-1.7.jar ...本体
      2. velocity-1.7-dep.jar ...依存ライブラリ
    2. ..を外部JARファイルとして追加


これで、クラスが作れる。

サンプル。データを持つクラスはつまりgetXXXがあればいいらしい。ここではItemクラスを作った。
それを使うクラスは仮にこんな。

→ getXXXは、テンプレートから$item.XXXという$item.getXXX()の短縮系を使えるというだけだった。自分の好みとしては不要かも。最初からxxx()というメソッドを作って、$item.xxx()と呼ぶ方がいい。かも。いやどうかな?


package hoge;
import java.io.Writer;
import java.math.BigDecimal;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

public class Controller {
public static void write(Writer out, String tmpl){
Item item = new Item();
item.name = "Some Item";
item.price = new BigDecimal("1500");

Velocity.init();
VelocityContext vc = new VelocityContext();
vc.put("item", item);

Velocity.evaluate(vc, out, "logTag", tmpl);

}
}



Tomact側で動かす準備は、

まず、JSPを用意。一応はテンプレートエンジンのはずであるが、そこからテンプレートエンジンを呼ぶ。

<%@page import="hoge.Controller"%>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>
(...中略)
<body>
<%
  Controller.write(
out,
    "<h1>$item.name</h1><dl><dt>price</dt><dd>$item.price</dd></dl>"
  );
%>
</body>
</html>



  1. EclipseのプロジェクトのプロパティでDeployment Assemblyを選び、
  2. Java Build Path Entriesあたりから先ほどのVelocityのjar2つを追加


JSPにアクセスするとレンダリングされる。


通常は、テンプレートはitem.vmなどというテキストファイルを書いておいてVelocityに探させる。が、自分の好みとしては、そのテンプレートの内容も動的にしたいわけで、だからここでは仮にリテラルにしてある。


2013年11月25日月曜日

MediaWikiのCSS編集

以下のページで上書き用のCSSを追記する。

/wiki/index.php/MediaWiki:Common.css

"/wiki"はLocalSettings.phpの$wgScriptPath部分、"index.php"は隠すように設定しているなら抜く。


自分としては、標準のCSSで見出しの区切り目がわかりにくく、特にh3とh4の差がわからないのでh4が親のh3の節の中の小見出しなのに次の節のように見えてしまうのが気に入らない。

ので、

こんな風にしている。

body {
 font-family:'Lucida Grande','Hiragino Kaku Gothic ProN',Meiryo, sans-serif;
}
#bodyContent {
 line-height:175%;
}

h1, h2 {
 margin-top:1.5em;
}
h3, h4 {
 margin-top:1em;
}

h4 span.mw-headline {
 font-size:100%;
 font-weight:normal;
 color:#333;
 border-bottom:1px solid #999;
}

2013年11月20日水曜日

UMLのアグリゲーション(集約)とコンポジション

どう使い分ければいいかいつも悩んでしまう。

自分はJavaなので、フィールドに持つか持たないかとかで分けるかな?なんて考えたりもしたが、そんな内部設計的なことで考えるのも違うだろうという気がするし。

で、わかりやすいひとつの基準として、いくつかのサイトの解説をもとにまとめておく。


早い話が、コンポジションはアグリゲーションの一種だが、その対象要素がそれぞれ独立しては存在し得ないほど結びつきが強いものがコンポジションだそうで。

パソコンをUMLで表現するとして、「デスクトップPCとモニタは集約、ノートパソコンとそのスクリーンはコンポジション」だそうです。

この場合、モニタが壊れたてもPCは使い続けられるが、ノートPCでスクリーンが割れたら捨てるしかないし、付け替えはできない。(※修理の話しを始めるややこしくなるので、修理などいっさい出来ないと仮定する)

・・・アグリゲーションの構成は可変だが、コンポジションは構成が変わらないというのはひとつ明確な基準かも知れない。

なお、引数などとして一時的に参照するだけならば「依存(dependancy)」、has-a関係ではないただの関連付けは「関連(association)」となり、集約ではない。

依存や関連で参照するクラスを、効率上の都合などから実装時のクラスがフィールドも持つこともあるだろうが、それは集約とはしない方がいいのだろうと思う。

あくまでも、本来の意味、構造的に包含関係がある場合に、集約を用いるべきなのだろう。



参考にしたサイト:

  • http://www.itmedia.co.jp/im/articles/0302/22/news001.html パソコンのたとえ話の出典
  • http://itref.fc2web.com/uml/#dependency 

2013年11月19日火曜日

Apache2にダイジェスト認証

Apache2にダイジェスト認証をつける。



httpd.confに追記

<Directory "/home/venzoline/apache2/htdocs/wiki">
    AuthType Digest
    AuthName "Private Zone"
    AuthDigestDomain /wiki/
    AuthDigestFile /home/venzoline/apache2/.htdigest
    Require valid-user
</Directory>

Apache再起動。


これで、AuthDigestFileに定義したユーザ名とパスワードで認証要求される。
が、そんなファイルは実在していないので以下のコマンドで作る。
コマンド打つとパスワード設定のプロンプトが出る。


$ htdigest -c .htdigest 'Private Zone' myusername

 ※-cは新規に".htdigest"という名前でその場にパスワードファイルを作るの意

$ htdigest .htdigest 'Private Zone' myusername2

 ※その後のユーザ追加

ユーザの削除は・・・知らない。コマンドのヘルプにはない。パスワードファイルから消せばいんじゃないかな。ユーザ名は平文のテキストファイルだったので。

ユーザ追加時にはApacheの再起動は不要。


参考:http://www.atmarkit.co.jp/flinux/rensai/linuxtips/699apachedigest.html