yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2017/11 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
ブログ - yamicha.com's Blog

 存在する記事 776 件の中から 26-30 件を表示しています。
税制壊政議論
2010/02/22(Mon)00:59:53
 次期衆院選までは消費税に手をつけないと公約してきた民主党ですが、3月から消費税を含む税制改正議論を開始する予定であることを、財務相の菅氏が明らかにしました。ただ、菅氏はなおも「次期衆院選までは消費税を上げない」と明言しており、消費税議論を対立軸にしようとした自民党をけん制する目的との見方もあるなど、実際に民主党がどこまで本気なのかは定かではありませんが、少なくとも消費税について論じられる土壌が形成される可能性は出てきました。
 なぜ政治家が消費税議論をやりたがらないかといえば、それは明らかに選挙に差し支えるためですが、つくづく小沢氏以後の民主党の姿勢には疑問を抱かざるを得ません。かつての民主党は「消費税を上げ、年金保険料を全額税化する」ことを訴えており、かなり好感が持てたのですが、小沢氏以後は選挙目当てに増税論が封印されてしまい、「マニフェスト」が「政権公約」に逆戻りしてしまった感さえあります。そのひずみで財源を確保できなくなり、約束を破って増税論を持ち出し、それで支持を失って政権が瓦解するようなことになれば、これほど無意味な話はありません
 民主党の一部からは、「2005年の郵政選挙で、まじめに公約を作って訴えても全く無駄であることを思い知らされたので、今回は理想論で勝負するよりなかった」などの恨み節も聞かれるようですが、確かにあの郵政選挙は嘆かわしいことこの上ないものでした。私も最後の最後まで、きっと多くの人は国民の知性を愚弄する小泉政権に憤り、ふざけた選挙に異議を申し立てるであろうと信じ、またそうなることを願っていましたが、残念ながらそれは完全に裏切られました。
 実際には、小選挙区制ではわずかな票差が勝敗に結びつくため、この戦術に引っかかった人はあまり多くないとも考えられますが、ともかく議席ベースでは自民党は歴史的大勝を遂げ、民主党ら野党は再可決も阻止できない立場に置かれてしまいました。この経験が民主党を含む各党にとってトラウマとなり、そのせいで各党が不利な政策を言い出しづらくなってしまったのであれば、あの選挙の罪は極めて重いと言わざるを得ません
 しかしながら、民主党を含む各党は、あの選挙がもたらした結果をも直視しなくてはなりません。郵政のデメリットも訴えず、郵政民営化さえあれば何もかもが上手くいくような言い分により、一時的には再可決すら可能なほど多くの議席を獲得し、さらに郵政民営化にも道筋をつけた自民党でしたが、およそデメリットの存在しない政策など存在し得ない以上、国民が何らかの負担をこうむるのは当然にもかかわらず、郵政選挙ではそれが完全に隠蔽されていたため、約束が違うとして大きな批判を受ける羽目になりました。それ以外にも、「小泉改革」のメッキは安部政権以後に次々と剥がれ落ち、最終的には当の自民党政権自身が小泉改革の修正を言い出さざるを得なくなる状況にまで追い込まれ、自民党敗北の直接の原因となりました。さらに、郵政選挙の大勝によってようやくこぎつけたはずの郵政民営化も、政権交代によって逆方向に進み始めている有様です。これが例のような選挙の末路なのですから、郵政選挙を悪い方向に教訓にしてしまった民主党のやり方は、明らかに誤りであったと結論して間違いないでしょう。
 ただ、民主党の「次期衆院選までは消費税を上げない」という主張自体は、全く正当性のないものではありません。底の抜けたバケツに水を注いでも、決して水はいっぱいになりません。すなわち、無駄をできるだけ削減してから増税するのでなければ、せっかくの増税も効果が薄れてしまいます。増税によって規律が緩み、増税が無駄になることを不安視しているのであれば、「今は増税しない」のも選択肢の1つとして有効でしょう。
 一方、自民党側は民主党が消費税増税議論に着手することを批判していますが、民主党が上記のような意図で増税を封印しているのであれば、今のうちから「無駄削減後」を論じておくのは十分に合理的な行為であり、これは決して「今は消費税を上げない」という言い分と矛盾するものではありません。むしろ、直前になって議論を開始する方が問題が大きく、早めに始めておくに越したことはありません。
 政治家の消費税議論が低調になりやすい原因としては、国民に「消費税アレルギー」があるためと言われますが、実際の国民は政治家が考えているほど単純ではありません。消費税増税論が国民から非常に嫌われているのも、消費税増税そのものに対する嫌悪というよりは、「消費税が目的外利用、または無駄遣いされることに対するアレルギー」の側面の方が強いと考えられます。
 もし消費税の全額が確実に福祉に使われるという確証があれば、少なからぬ人は増税を容認するはずです。消費税増税論がタブー視されるほどまでに嫌われる理由があるとすれば、政治家が全く信用されておらず、消費税があさっての方向に使用されるであろうと多くの国民が考えているために他なりません。
 例を出すならば、増税分の無駄遣いは当然として、消費税を上げつつ法人税や相続税を下げる行為などが挙げられます。日本の福祉費用は増大しており、それの維持のためにはどうしても増税が必要であることを多くの国民は理解していますが、せっかくの増税が法人税減税などに消えるのであれば、福祉も何もあったものではありません。これは決して無根拠の懸念ではなく、実際に経団連は「消費税を毎年上げつつ、法人税は下げる」ビジョンを発表していますし、自民党政権下では相続税非課税の国債発行、贈与税免除の時限措置など、相続税の課税対象者に有利な措置が実際に検討されていました。当然のことながら、相続税などを優遇できるほど余裕が有り余っているのなら、多大なリスクを背負って消費税を増やす必要はありません。すなわち、今後与党や野党が消費税増税を論じるのであれば、それを法人税や相続税などの減税とはセットにしないことが最低限必要です。
 また、消費税は逆進性の強い税ですので、その観点からの対策も必要となってきます。どうせ税制全般の改正を議論するのであれば、消費税を大幅に引き上げつつ、大規模な「負の所得税」などの制度も同時に導入して逆進性を打ち消し、さらに相続税の大幅強化で消費を促すなど、大胆な改革があっても良いでしょう。言うまでもありませんが、年金保険料は消費税などとは比べ物にならないほど逆進性が強く、しかも民主党はかねてから全額税化を主張していますので、議論の際には消費税を財源とした全額税化を第一に検討し、実現の道筋を作る必要があります。
 そして、もし近々消費税増税に着手する予定があるのであれば、与党も野党も参院選ではそれを主張しなくてはなりません。なぜ消費税増税が嫌われるかといえば、増税自体への嫌悪よりも政治家が信用されていないことによる部分が大きく、その上さらにだまし討ち増税などしようものなら、どうなるかは見えています。
 確かに、2005年の郵政解散においては、説明責任も政策論争も何もなく、ただ単に国民の知性を愚弄していた小泉氏が大勝しました。ところが、小泉氏自身はメッキが剥がれないうちに身を引いたものの、その後の自民党の末路といえば、大変にみじめなものでした。さらに、麻生内閣が起死回生の手段として用いた金配りは、ニンジンにつられた多くの支持を獲得するどころか、なおさら多くの人に怒りを植え付ける結果となりました。政治家はこれらの教訓に学ばなくてはなりません。

 前回までで、とりあえずJSF 2.0のAjaxを使ってはみたものの、基本的にはページ変移を省略して結果を表示するデザインとなっており、Ajax関連の記述さえはずしてしまえば普通のフォームとして機能するものが中心でした。これはこれで分かりやすく、しかも普通のフォームと同じ感覚でAjaxを書けて便利なのですが、せっかくJavaScriptを使っているのですから、普通のフォームでは行えないような対話型の処理も書いてみたいものです。
 そのような処理として有名なのは、いわゆるオートコンプリートであったり、フォームに何らかの入力をするたびにデータが絞り込まれていくようなページでしょう。すなわち、入力がそのつどサーバーに送信され、その結果をブラウザが受け取って表示するような仕組みです。
 実は私、Ajaxをこのように使用したサイトが大嫌いであり、見つけ次第「制限付きサイト」に投入してJavaScriptが動作しないようにしているのですが、そのような技術がある以上は習得しておかないわけにはいきません。
 対話型ということで、いかなるものを書いたものか迷いましたが、あまりに単純な文字数計算や足し算では味気ないため、今回はひとまず「ベクトル内積・外積計算機」としました。無論、データベースのデータを読み込み、入力した条件にしたがってデータを絞り込むような本格的なコードも書けるはずですが、そもそも動かせるかどうか不明な状態から習得を始めたため、ごく簡単なものとなりました。
/WEB-INF
 /classes
  /com
   /yamicha
    /autosend
     CalcBean.java
     Vector3D.java
 web.xml
calc.xhtml
 実に簡単な構成ですが、たかだかこの程度のものを書くだけでも、JSF 1.xの時代は意味不明なXMLを長々と書く必要があったわけですから、いかに1.xが使い物にならなかったかが分かります。
 このweb.xmlもいい加減に書かずに済ませたいのですが、そこまで望むのは贅沢でしょうか。
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>

  <display-name>JSF 2.0 Calc Servlet</display-name>
  <description>JSF 2.0 Calc Servlet</description>

  <servlet>
    <servlet-name>jsf20vector3dcalc</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>jsf20vector3dcalc</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
</web-app>
 ManagedBeanはほとんど見ての通りですが、dotProduct及びcrossProductなるプロパティを用意しています。本来であれば、データが送信された際に1度だけ計算を実行して保持しておき、プロパティにアクセスした際にはそれを返すのが効率的なのですが、今回は単純な実装としました。
// CalcBean.java
package com.yamicha.autosend;

import javax.faces.bean.*;
import javax.faces.event.*;

@ManagedBean @ViewScoped public class CalcBean{
	private Vector3D vector1;
	private Vector3D vector2;

	public CalcBean(){
		vector1 = new Vector3D();
		vector2 = new Vector3D();
	}

	public Vector3D getVector1(){
		return vector1;
	}
	public Vector3D getVector2(){
		return vector2;
	}
	public double getDotProduct(){
		return vector1.dotProduct(vector2);
	}
	public Vector3D getCrossProduct(){
		return vector1.crossProduct(vector2);
	}

	public void setVector1(Vector3D v){
		vector1 = v;
	}
	public void setVector2(Vector3D v){
		vector2 = v;
	}
}

// Vector3D.java
package com.yamicha.autosend;

public class Vector3D{
	private int AXIS = 3;
	private double value[];

	public Vector3D(){
		value = new double[AXIS];
	}
	public Vector3D(double x , double y , double z){
		this();
		setX(x);
		setY(y);
		setZ(z);
	}

	public double getX(){
		return value[0];
	}
	public double getY(){
		return value[1];
	}
	public double getZ(){
		return value[2];
	}

	public void setX(double x){
		value[0] = x;
	}
	public void setY(double y){
		value[1] = y;
	}
	public void setZ(double z){
		value[2] = z;
	}

	private double get(int axis){
		return value[axis];
	}
	private void set(int axis , double v){
		value[axis] = v;
	}

	public double dotProduct(Vector3D v){
		double product = 0;
		for(int i = 0; i < AXIS; i++)
			product += get(i) * v.get(i);
		return product;
	}
	public Vector3D crossProduct(Vector3D v){
		Vector3D result = new Vector3D();
		for(int i = 0; i < AXIS; i++){
			int cos = (i + 1) % AXIS;
			int sin = (i + 2) % AXIS;

			result.set(i , get(cos) * v.get(sin) - 
				get(sin) * v.get(cos));
		}
		return result;
	}
	public String toString(){
		return String.valueOf(getX()) + " , " +
			getY() + " , " + getZ();
	}
}
 今回最も重要なのが、おそらくこのcalc.xhtmlでしょう。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:c="http://java.sun.com/jsp/jstl/core"
  xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
  <title>JSF 2.0 Vector Calculator</title>
</h:head>

<h:body>
  <b>JSF 2.0 Vector Calculator</b>

  <h:form id="calc">
    <h:panelGrid columns="4">
      <h:outputText value="Vector" />
      <h:outputText value="X" />
      <h:outputText value="Y" />
      <h:outputText value="Z" />

      <h:outputText value="Vector1" />
      <h:inputText size="6" id="vector1x" value="#{calcBean.vector1.x}">
        <f:ajax execute="@this" event="blur" render="calc_result" />
      </h:inputText>
      <h:inputText size="6" id="vector1y" value="#{calcBean.vector1.y}">
        <f:ajax execute="@this" event="blur" render="calc_result" />
      </h:inputText>
      <h:inputText size="6" id="vector1z" value="#{calcBean.vector1.z}">
        <f:ajax execute="@this" event="blur" render="calc_result" />
      </h:inputText>

      <h:outputText value="Vector2" />
      <h:inputText size="6" id="vector2x" value="#{calcBean.vector2.x}">
        <f:ajax execute="@this" event="blur" render="calc_result" />
      </h:inputText>
      <h:inputText size="6" id="vector2y" value="#{calcBean.vector2.y}">
        <f:ajax execute="@this" event="blur" render="calc_result" />
      </h:inputText>
      <h:inputText size="6" id="vector2z" value="#{calcBean.vector2.z}">
        <f:ajax execute="@this" event="blur" render="calc_result" />
      </h:inputText>
    </h:panelGrid>

    <hr />
    <b>Result:</b>
    <h:panelGrid id="calc_result" columns="2" border="1">
      <h:outputText value="Dot Product" />
      <h:outputText value="#{calcBean.dotProduct}" />

      <h:outputText value="Cross Product" />
      <h:outputText value="#{calcBean.crossProduct}" />
    </h:panelGrid>
  </h:form>

</h:body>

</html>
 ポイントは

<f:ajax execute="@this" event="blur" render="calc_result" />

 このタグです。IBMのチュートリアルなどを見る限り、eventで指定されたイベントが発生した際に(イベント名はJavaScript上の名称からonを除いたものを使用。blurであればonblur、clickであればonclick。event属性を省略した場合はonchangeとみなされる)、executeで指定されている部分のデータを送信し(@thisは自分自身のコンポーネントを表す)、その後にrenderで指定された部分を再描画する、という流れになっているようです。ちなみにonblurはフォーカスが外れた際に呼び出されるイベントです。今回の用途ではonchangeの方が適任なのですが、onchangeの場合はそもそもeventを省略できて味気なく、かといってevent="change"と明示するとなぜか動かなくなるため、blurにしてみました。
 JSF 2.0が面白いのは、データはサーバー上に保持されていて、送信の際には対象となったデータだけが送信・変更されている点でしょうか。無駄なデータの送信がないため、場合によっては有用そうです。このような処理を自力で書こうとするとかなり大変なのですが、JSFならすべて自動的にやってくれるため、手間もかかりません。逆に、途中でサーバー上のセッションが消えてしまった場合、ブラウザの側では入力しているはずなのに、サーバー上では入力されていないものとして扱われるといった問題も起こったりしますが、そこはご愛嬌です。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

文民統制というものは
2010/02/14(Sun)17:58:28
 自衛隊と米軍の共同訓練の開会式の場で、自衛隊の連隊長が「同盟というものは、外交や政治的な美辞麗句で維持されるものではなく、ましてや信頼してくれなどという言葉だけで維持されるものではない」との訓示を行い、問題となっています。もともとは「〜美辞麗句で維持されるものではない」までのくだりを訓示する予定となっていたはずが、言い換えられてしまったものです。本人は否定こそしているものの、鳩山氏がオバマ氏に語った「Trust me(私を信頼して欲しい)」の言葉を揶揄したとも受け取れる発言とあって、防衛省はこの連隊長を注意処分としました。
 つくづく疑問なのですが、最近の自衛隊上層部は一体どうなっているのでしょうか。先に田母神氏の問題が発生し、一部にせよ自衛隊内部に文民統制を無視するような風潮があることが明らかになった以上、再発防止が必要となっていたのは明白にもかかわらず、まもなく類似の問題が発生するようでは、嫌でも不安を抱かざるを得ません。
 一部の報道によれば、自衛隊内部にも「発言は危機感の表れ」などとして連隊長に同情する見方があるようですが、噴飯ものであると言わざるを得ません。田母神氏の問題も同様ですが、本件は文民統制の観点から問題となる可能性があるために問題視されているのであって、危機感など問題の根幹には全く関係がないためです。
 確かに、民主党政権における日米関係は今のところ上手く行っているとは言いがたく、その面での危機感を抱くのはある意味で当然ともいえます。特に鳩山氏の「信頼して欲しい」発言に至っては、結果的には完全に米国を裏切ってしまった格好ですから、揶揄されても仕方がないものでしょう。単に連隊長の言い分だけを評価しさえすれば良いのであれば、連隊長に同情する見方も分からないわけではありません。
 しかし、実際には本件はあくまで文民統制の問題である点を忘れてはいけません。かつて田母神氏の論文が問題になった際には、氏は「ヤフーでは60%が支持している」などという意味不明の主張を行っていましたが、本件において「危機感の表れ」などとして連隊長に同情するのも、これと同様であると言わざるを得ません。それどころか、自衛隊内部にそのような声があるというのが事実であるなら、文民統制を反故にする土壌は確実に存在していることになります。
 こうも容易に文民統制上懸念のある問題が繰り返されるようでは、自衛隊幹部の意識や思想にすら疑問符がつくのは避けられません。田母神氏を例にすれば、文民統制に反すると指摘されながらも持論を曲げず、結局は事実上の解雇となりましたが、すなわち自衛隊幹部の少なくとも一部には、文民統制の存在そのものを知らず、あるいは文民統制自体は知っていてもその重要性を理解できない無能者か、または文民統制の意義と重要性を理解していながら、それを平然と踏みにじった上に詭弁すら用いて自己正当化を図る危険思想者が存在していたことになります。しかも、このような問題を起こしたのが田母神氏だけであれば、たまたま無能者または危険思想者が1人だけ紛れ込んだものと考えられなくもありませんが、その後すぐさま今回の問題も発生している以上、田母神氏の件を単なる個人の資質の問題であるとして片付けるわけにはいきません。
 まして、自衛隊内部に同情の声があるとなれば、問題は本件だけにとどまりません。田母神氏は「ヤフーでの過半数の支持」を持ち出していましたが、この支持率に何の信頼性もないことは置くとしても、仮に国民の過半数が支持していたり、論自体には見るべき点があったとしても、それを理由に自衛隊が勝手な思想を持つことが許容されるわけではありません。今回の訓示が問題とされているのも、それが文民統制に反しかねないためであって、危機感を理由にすれば自衛隊が勝手な思想を持つことが許されるわけではない以上、「危機感」を理由とした同情の論理は根底から破綻しています
 文民統制がどれほど重要なものであるかは、今さら説明するまでもないでしょう。もし自衛隊上層部に文民統制を甘く見る風潮が広がっているのであれば、一刻も早く粛正しなくてはなりません。ところが、それをすべき政治の側に目を向けてみると、自民党はかつて田母神氏を事実上の解雇にしておきながら、今度は選挙に擁立しようとしたりする有様で、まるで文民統制の重要性を理解している様子がありません。これでは田母神氏のような無能者あるいは危険思想者が増長するのも当然です。
 文民統制が極めて重要なものである以上、本件のような事態が二度と起こってもらっては困ります。もし組織内で文民統制が周知されていない、または文民統制の重要性が理解されていないのであれば、これほど危険なことはありません。防衛省・自衛隊は徹底的な再発防止策を講じなくてはなりません。

 ここまでは基本的にJSFだけで完結するものを書いてみましたが、どうせGlassFishを使うのであれば、EJBを使わなくては損というものです。GlassFish v3 PreviewのManagedBean上でEJBのDIができるかは定かではありませんでしたが、試してみると上手く動作したため、この方法を使用してみます。
 今回はひとまず、製品(Product)の名前の一部を入れることで、それに該当する製品の一覧を表示するJSFを書くものとしました。製品データはデータベースから読み出しますので、今回のプログラムはJSF + EJB + JPAという豪華な構成です。
 使用する技術自体は以前までとさほど変わらないものの、おかげで無駄にファイル数が増えています。
/WEB-INF
 /classes
  /com
   /yamicha
    /ajaxsearch
     enum SearchType.java
     @ManagedBean SearchBean.java
     @Entity Product.java
     @Entity Maker.java
     @Stateless ProductSearch.java
  /META-INF
   persistence.xml
 web.xml
search.xhtml
 今回、検索方法として「前方一致」「後方一致」「部分一致」「完全一致」の4種類を用意しましたので、それをSearchType.javaで列挙しています。
// SearchType.java
package com.yamicha.ajaxsearch;

public enum SearchType{
	FRONT , BACK , OMNIDIRECT , PERFECT;

	// JPQL の LIKE 用文字列生成メソッド
	public String getLikeText(String s){
		String str = s.replace("%" , "\\%");

		switch(this){
		case FRONT:
			return str + "%";
		case BACK:
			return "%" + str;
		case OMNIDIRECT:
			return "%" + str + "%";
		case PERFECT:
			return str;
		}

		return null;
	}
}
 今回の目新しい点として、ドロップダウンリストを使用してみました。ManagedBean内にはドロップダウンの要素に使用するためのMapを用意しました。世にあるサンプルのほとんどでは、Mapの値型としてStringを使用していましたが、試しにSearchTypeを使用してみたところ、問題なく動作してくれました。enumは使いどころによってはそれなりに役に立つため、これが使えるのはありがたいです。
// SearchBean.java
package com.yamicha.ajaxsearch;

import javax.ejb.*;
import javax.faces.bean.*;
import java.util.*;

@ManagedBean @ViewScoped public class SearchBean{
	@EJB(beanName="AjaxProductSearch") private ProductSearch ps;
	private String word;
	private List<Product> products;
	private Map<String , SearchType> searchTypes;
	private SearchType searchType;

	public SearchBean(){
		products = new ArrayList<Product>();
		word = "";

		searchTypes = new Hashtable<String , SearchType>();
		searchTypes.put("部分一致" , SearchType.OMNIDIRECT);
		searchTypes.put("前方一致" , SearchType.FRONT);
		searchTypes.put("後方一致" , SearchType.BACK);
		searchTypes.put("完全一致" , SearchType.PERFECT);

		searchType = SearchType.OMNIDIRECT;
	}

	public void regist(){
		ps.regist();
	}
	public void search(){
		if(word != null && !word.isEmpty())
			products = ps.searchProducts(word , searchType);
		else
			products = new ArrayList<Product>();
	}

	public String getWord(){
		return word;
	}
	public List<Product> getProducts(){
		return products;
	}
	public SearchType getSearchType(){
		return searchType;
	}
	public Map<String , SearchType> getSearchTypes(){
		return searchTypes;
	}

	public void setWord(String w){
		word = w;
	}
	public void setProducts(List<Product> p){
		products = p;
	}
	public void setSearchType(SearchType s){
		searchType = s;
	}
	public void setSearchTypes(Map<String , SearchType> s){
		searchTypes = s;
	}
}
 上でDIしているEJBのコードは以下の通りです。
// ProductSearch.java
package com.yamicha.ajaxsearch;

import javax.ejb.*;
import javax.annotation.*;
import javax.persistence.*;
import java.util.List;
import java.util.ArrayList;

@Remote @Stateless(name="AjaxProductSearch" , 
	mappedName="ejb/AjaxProductSearch")
	public class ProductSearch{
	@PersistenceContext(unitName="MySQL") private EntityManager em;

	// データベースにサンプルデータを登録するメソッド
	public void regist(){
		Maker tp = new Maker("技術出版");
		tp.getProducts().add(
			new Product("Perl言語でCGI" , 1200));
		tp.getProducts().add(
			new Product("7日で入門Java" , 1400));
		tp.getProducts().add(
			new Product("関数型言語F#入門" , 1200));
		tp.getProducts().add(
			new Product("どんなバカでもSQLが分かる本" , 1500));
		tp.link();
		em.persist(tp);

		Maker op = new Maker("オークハブリッシング");
		op.getProducts().add(
			new Product("Java Servlet + Ajax 入門" , 1600));
		op.getProducts().add(
			new Product("Ruby言語によるCGI入門" , 2200));
		op.getProducts().add(
			new Product("今さら聞けないCOBOL入門" , 2500));
		op.link();
		em.persist(op);

		Maker pe = new Maker("パイソン・エデュケーション");
		pe.getProducts().add(new Product(
			"Java + MySQL Server プログラミング" , 3600));
		pe.getProducts().add(
			new Product("Apache HTTP Server" , 4800));
		pe.getProducts().add(
			new Product("Python CGI プログラミング" , 3500));
		pe.getProducts().add(new Product(
			"COBOL, Lisp, Fortran, 開発言語の系譜" , 4600));
		pe.link();
		em.persist(pe);
	}

	public List<Maker> getMakers(){
		return (List<Maker>)em.createQuery(
			"SELECT m FROM Maker m").getResultList();
	}
	public List<Product> getProducts(){
		return (List<Product>)em.createQuery(
			"SELECT p FROM Product p").getResultList();
	}

	// 製品を検索するメソッド
	public List<Product> searchProducts(
		String name , SearchType st){
		Query query = em.createQuery(
			"SELECT p FROM Product p WHERE p.name LIKE ?1");
		query.setParameter(1 , st.getLikeText(name));
		return (List<Product>)query.getResultList();
	}
}
 COBOLなど今さら聞きたくもありません。SELECTの1つも覚えるだけで、どれほど大変なことでしょうか。SQLのSELECTなどかわいいものです。
 Entityは次の通りです。
// Maker.java
package com.yamicha.ajaxsearch;

import javax.persistence.*;
import java.util.*;

@Entity @Table(name="ajaxsearch_maker" , schema="yamicha")
	public class Maker implements java.io.Serializable{
	private int id;
	private String name;
	private List<Product> products;

	public Maker(){
		products = new ArrayList<Product>();
	}
	public Maker(String s){
		this();
		name = s;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@OneToMany(cascade=CascadeType.ALL ,
		fetch=FetchType.EAGER , mappedBy="maker")
		public List<Product> getProducts(){
		return products;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
	public void setProducts(List<Product> p){
		products = p;
	}

	public void link(){
		for(Product p : products)
			p.setMaker(this);
	}
}

// Product.java
package com.yamicha.ajaxsearch;

import javax.persistence.*;

@Entity @Table(name="ajaxsearch_product" , schema="yamicha")
	public class Product implements java.io.Serializable{
	private int id;
	private String name;
	private int price;
	private Maker maker;

	public Product(){
	}
	public Product(String s , int i){
		name = s;
		price = i;
	}

	@Id @Column(name="id") @GeneratedValue public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@ManyToOne @JoinColumn(name="maker") public Maker getMaker(){
		return maker;
	}
	@Column(name="price") public int getPrice(){
		return price;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
	public void setMaker(Maker m){
		maker = m;
	}
	public void setPrice(int p){
		price = p;
	}
}
 web.xmlとpersistence.xmlは以前までとほぼ同様です。
// web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>

  <display-name>JSF 2.0 AjaxSearch Servlet</display-name>
  <description>JSF 2.0 AjaxSearch Sample Servlet</description>

  <servlet>
    <servlet-name>jsf20ajaxsearch</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>jsf20ajaxsearch</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
</web-app>

// persistence.xml
<?xml version="1.0" encoding="UTF-8"?>

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="MySQL" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/MySQL</jta-data-source>
    <properties>
      <property name="eclipselink.jdbc.driver"
        value="com.mysql.jdbc.Driver" />
      <property name="eclipselink.ddl-generation"
        value="create-tables" />
      <property name="eclipselink.ddl-generation.output-mode"
        value="database" />
      <property name="eclipselink.target-database" value="MySQL" />
      <property name="eclipselink.logging.level" value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>
 search.xhtmlは以下の通りです。入力中に自動的に候補が絞り込まれるようにすることも、決してできないわけではないはずですが、私がその系統のAjaxの使い方が好きではないのと、まだJSF 2.0の使い方がいまいち飲み込めていないため、今回は普通にボタンを押して絞り込むものとしました。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:c="http://java.sun.com/jsp/jstl/core"
  xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
  <title>JSF 2.0 Ajax Product Search</title>
</h:head>

<h:body>
  <b>JSF 2.0 Ajax Product Search</b>

  <h:form id="productform">
    <h:inputText size="40" value="#{searchBean.word}">
      <f:ajax immediate="true" />
    </h:inputText>

    <h:selectOneMenu value="#{searchBean.searchType}">
      <f:selectItems value="#{searchBean.searchTypes}" />
      <f:ajax immediate="true" />
    </h:selectOneMenu>

    <h:commandButton value="Search" action="#{searchBean.search}">
      <f:ajax render="products" />
    </h:commandButton>

    <hr />

    <h:panelGroup id="products">
      <ui:repeat value="#{searchBean.products}" var="product" 
        begin="0" end="20">
        <b>#{product.name}</b><br />
        #{product.maker.name}<br />
        #{product.price}
        <hr />
      </ui:repeat>
    </h:panelGroup>

    <h:commandButton value="Regist Records"
      action="#{searchBean.regist}" />
  </h:form>

</h:body>
</html>
 最初に「Regist Records」ボタンを押すと、データベースにサンプルデータが登録されます。後はそのサンプルデータを任意のワード及び検索方法で検索し、無事に動作すれば成功です。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

恐怖の灰色幹事長
2010/02/07(Sun)22:29:09
 小沢氏の資金管理団体による土地購入をめぐる疑惑は、検察が小沢氏を嫌疑不十分で不起訴とすることで一応の決着を見ました。とりあえず、検察の捜査の上では「シロ」であることが示された格好です。しかし、世論調査でも国民の多くが納得していないことが示されており、民主党の人気も下落する傾向にあるなど、その余波は民主党内外に様々な影響を与えているようです。
 鳩山氏は「(小沢氏の犯罪行為は)検察の捜査により事実と認定されなかった」と主張し、小沢氏は潔白であることを強調、幹事長を辞任する必要はないとしていますが、もし法的に責任を問われるか否かを判断材料とするのであれば、鳩山氏の言い分にも一応の道理があります。しかしながら、法的に責任を問われないことと「潔白」とは同義ではありませんし、仮に小沢氏の行いが罪の要件には該当しなかったとしても、道義的な責任は免れません。まして、「李下に冠を正さず」の精神が求められる政治家にとっては、あまりに問題の大きい行為であると言わざるを得ません。
 小沢氏は幹事長にとどまるつもりのようですが、もし小沢氏以外の役職者が同じような嫌疑をかけられ、しかも非常に黒に近い状態とみなされていたなら、仮に最終的には不起訴となったとしても、辞任となっていた可能性は十分にあるといえるでしょう。徹底して小沢氏の弁護を図り、場合によっては検察への圧力とも取れる発言までする鳩山氏や民主党の対応は、大変疑問であると言うよりありません。
 そもそも、鳩山氏や民主党が「本件さえやり過ごせば小沢問題は終息する」と考えているのであれば、それは世論からあまりにも乖離した見方です。これまでにも小沢氏は、民主党合流前の「壊し屋」としての活動の他、下手をすると民主党を崩壊させかねなかった「大連立」騒動、政権を取った後の小沢院政など、不信感を抱かれても当然の行動を繰り返しており、国民の信頼はほとんど得られていません。
 そればかりか、このまま小沢氏を党内に隠者として抱えておけば、またしても大連立のような致命的な行動を考えつき、実行に移さないとも限りません。前の大連立はすんでのところで回避され、そのおかげで民主党は壊滅せずに政権与党となることができましたが、もし今後も同じような過ちを繰り返せば、仮に未遂に終わったとしても、今度こそ民主党への信頼は潰えるでしょう。
 すなわち、このところの世論による「辞任」コールは、今回の土地購入疑惑だけにとどまらず、これまでの小沢氏の様々な独善的な行動や疑惑、さらには今後の小沢院政への恐怖と不安にも向けられている、大変根が深いものであると見て間違いありません。つまり、今回の土地購入疑惑が一件落着したからといって、小沢氏や民主党への風当たりが弱まるというものでは決してありません
 民主党内では「選挙に強い小沢」の図式が出来上がっており、そのためにぞんざいな扱いができないという雰囲気になっているようですが、確かに選挙には小沢氏の功績もあるとはいえ、実際には自民党への著しい失望や変革の必要性への認識が民主党を押し上げたものであるため、小沢氏のみの力によって衆参での勝利が実現したわけではありませんし、せっかくの政権交代がすぐにつぶれるのでは、政権交代の意味がありません。
 それに何より、小沢氏をめぐる民主党の混乱のせいで、全く政策論争が聞かれなくなっているのは残念でなりません。麻生氏が首相の際にも、氏の資質ばかりに話題が集中し、政策論争があまり見られなくなる現象はありましたが、それでも「金配り」などがそれなりに大きく注目されただけマシというものです。民主党政権下においても、子ども手当てや外国人地方参政権など賛否のある一部の政策に関しては、必ずしも注目されていないとまではいえないものの、何よりもまず小沢氏関連の問題ばかりが注目を集めており、政策に関する論争や報道は非常に低調となってしまっています。
 さらには、こちらも小沢問題のせいでかすんでしまっていますが、民主党政権においてはこれまで必要性が繰り返し指摘されていながら、自民党議員の意味不明な妄想や利権のせいで阻まれてきた各種改正が、ようやく実現されつつあったり、実現される可能性が出てきているのですから、これは明らかに政権交代の功であるといえます。このような地味ながらも重要な改革まで考慮に入れて、私は今のところ民主党政権を及第点レベルと見ていますが、小沢氏の問題はそれすらも覆い隠すばかりか、そのような改正の芽すら摘み取ってしまいかねないものですから、その罪は非常に大きいと指摘せざるを得ません。
 これはすなわち、改革に向けて必死で奮闘しているまじめな民主党の関係者、さらには民主党に期待している国民をも、真正面から裏切る行為に他なりません。小沢氏が信用を失って没落するのは自身の勝手ですが、民主党を支持した者の多くは小沢氏を支持したわけではありませんので、小沢氏が民主党まで巻き込んで没落するとなれば、さすがに小沢氏の勝手とはいきません。
 そればかりか、今は自民党も非常に混乱しており、「和魂党」などの珍妙過ぎる案まで飛び出すような状況です。いずれ自民党には政権争奪の場に復帰してもらわなくてはなりませんが、今の自民党は完全に体力を消耗しきった病人のようなものですから、体力の戻りきらないうちに政権を再び握ろうものなら、ますます日本は混乱します。自民党が「和魂党」などと国民を愚弄したことを言っている限り、再び政権を握らせたところで今までの繰り返しになるだけですので、生まれ変わるのを待たなくてはなりません。
 さらに不安な材料として、最近は舛添氏などが不穏な動きを見せており、最悪な形での政界再編がなされる可能性が否定できません。すなわち、小沢氏の問題で多大な不信感を抱かれた民主党と、病み上がりでボロボロの自民党が争っている間に、なぜか国民の人気だけは高い舛添氏が「漁夫の利」を得て、重要なポストに就いてしまう可能性です。
 舛添氏の人格はいまさら説明するまでもありませんが、無賃残業合法化に「残業代が出ないとみんな早く帰るようになる」ことを理由として賛成し、同制度を非常に積極的に推進している人物です。この理由が建前なのか、本気でそのように考えているのかは不明ですが、そうはならないであろうことは「みなし役員」の問題を見れば明らかで、氏の言い分は完全に破綻しています。その上に「ホワイトカラー・エグゼンプションなどという横文字をつけるから、マスコミに残業代ゼロ法案と書かれて国民に反対される。名前さえ変えれば国民は反対しない」という理由で無賃残業合法化を「家庭だんらん法案」に改名して出そうとした、国民の知性をとことんなまでに愚弄した人物でもあります。
 さらに、氏は自民党について「今の自民党に必要なのは、民主党の小沢氏以上の独裁者」とも発言しており、ここからも氏の人格と手法がうかがえます。下手に権力を握らせようものなら、国民の知性を侮って適当なことを繰り返した挙句、「家庭だんらん法案」などの劣悪な制度を独裁的に成立させる可能性も否定できません。私は政界再編そのものを否定する気はありませんが、それで舛添氏が台頭してデタラメな政治が展開される恐れがある限り、現行の自民党と民主党の枠組みで処理する方がまだマシです。
 瀕死の病人同然の自民党に再び政権を背負わせて共倒れになったり、舛添氏が上り詰めたりといった最悪の事態を招いてからでは、反省しても遅すぎます。小沢氏も道義的にはともかく、これで一応法的には「潔白」となったのですから、けじめを理由として潔く幹事長ポストを去り、「潔白」で花道を飾っていただくのが一番でしょう。それが民主党のため、民主党を支持した国民のため、ひいては日本のためです。

 前回ではひとまずJSF 2.0のAjaxを使用してみましたが、案外手軽に扱えるものであることが判明しましたので、今回はアプリケーションスコープを使用した簡単なチャットを作成してみました。とはいえ、Cometを使ったリアルタイム通信などといった上等なものではなく、単に「ページ変移を経ないチャット」です。さらに言えば、チャットと呼べるかも疑わしいのですが、この際そこまでこだわっても仕方がありません。
 今回の構成は以下の通りにしました。
/WEB-INF
 /classes
  /com
   /yamicha
    /simplechat
     MessageBean.java
     LogBean.java
     ElementBean.java
 web.xml
chat.xhtml
 少しまともなものを作るとなると、考えなくてはならないのが各ManagedBeanの編成です。データベースなどを使わないとすれば、まずログのコレクションを持つApplicationScopedのBeanが必要として、1件ごとのログを表す(発言者名や発言などのプロパティを持つ)クラスも必要でしょう。また、Ajaxで通信して発言などを可能にするからには、フォームデータを受け持つViewScopedかRequestScopedが必要となるでしょう。また、送信したデータをログに登録しなくてはならないので、このManagedBeanがログ保持用ApplicationScopedのBeanをプロパティとして持つ必要がありそうです。
 まず、web.xmlは実にいつもの通りです。GlassFish v3 Previewが正式版となった暁には、絶対に省略できるようになるべきです。
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>

  <display-name>JSF 2.0 SimpleChat Servlet</display-name>
  <description>JSF 2.0 SimpleChat Sample Servlet</description>

  <servlet>
    <servlet-name>jsf20simplechat</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>jsf20simplechat</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
</web-app>
 ManagedBeanは次の通りです。ApplicationScopedを使っていますので、ぞんざいながら排他制御をつけておきました。友達の友達(logBean.element)にアクセスしようとすると複製が返ってくるので、とりあえず面倒なことにはならないはずです。もう少し複雑なものを書く場合には、コレクションをラップして排他制御を行うクラスを書くなどの方法が一般的のようです。
// ElementBean.java
package com.yamicha.simplechat;

import javax.faces.bean.*;

public class ElementBean{
	private String name;
	private String message;

	public ElementBean(){
	}
	public ElementBean(String n , String m){
		name = n;
		message = m;
	}

	public String getName(){
		return name;
	}
	public String getMessage(){
		return message;
	}

	public void setName(String n){
		name = n;
	}
	public void setMessage(String m){
		message = m;
	}
}

// LogBean.java
package com.yamicha.simplechat;

import javax.faces.bean.*;
import java.util.*;

@ManagedBean @ApplicationScoped public class LogBean{
	private List<ElementBean> elements;

	public LogBean(){
		elements = new ArrayList<ElementBean>();
	}

	synchronized public void addLog(ElementBean eb){
		elements.add(0 , eb);
	}
	synchronized public void clearLog(){
		elements.clear();
	}

	synchronized public List<ElementBean> getElements(){
		return new ArrayList<ElementBean>(elements);
	}
	synchronized public void setElements(List<ElementBean> e){
		elements = e;
	}
}

// MessageBean.java
package com.yamicha.simplechat;

import javax.faces.bean.*;

@ManagedBean @ViewScoped public class MessageBean{
	private String name;
	private String message;
	@ManagedProperty(value="#{logBean}") private LogBean log;

	public MessageBean(){
		name = "";
		message = "";
	}

	public void addMessage(){
		if(message != null && !message.isEmpty()){
			log.addLog(new ElementBean(name , message));
			message = "";
		}
	}

	public String getName(){
		return name;
	}
	public String getMessage(){
		return message;
	}

	public void setName(String n){
		name = n;
	}
	public void setMessage(String m){
		message = m;
	}

	public LogBean getLog(){
		return log;
	}
	public void setLog(LogBean l){
		log = l;
	}
}
 これでチャットのデータ処理部分はできましたので、後はxhtmlを書くだけです。以下、chat.xhtmlの内容です。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:c="http://java.sun.com/jsp/jstl/core"
  xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
  <title>JSF 2.0 SimpleChat</title>
</h:head>

<h:body>
  <b>JSF 2.0 SimpleChat</b>

  <h:form id="chatform">
    <h:inputText size="20" value="#{messageBean.name}">
      <f:ajax immediate="true" />
    </h:inputText>: 
    <h:inputText size="60" value="#{messageBean.message}">
      <f:ajax immediate="true" />
    </h:inputText>

    <h:commandButton value="Say" action="#{messageBean.addMessage}">
      <f:ajax render="chatform" />
    </h:commandButton>
    <h:commandButton value="Reload">
      <f:ajax render="chatlog" />
    </h:commandButton>
    <h:commandButton value="Clear" action="#{logBean.clearLog}">
      <f:ajax render="chatlog" />
    </h:commandButton>

    <hr />

    <h:panelGroup id="chatlog">
      <ui:repeat value="#{logBean.elements}" var="element" 
        begin="0" end="20">
        <b>#{element.name}</b>: #{element.message}
        <hr />
      </ui:repeat>
    </h:panelGroup>
  </h:form>

</h:body>

</html>
 ここで重要なのは次の2点です。私は両方とも実際に失敗し、散々悩む羽目になりました

1.上記のようにコレクションを使用するのであれば、c:forEachではなくui:repeatを使用しなくてはならない
2.Ajaxによるリクエストデータ送信時に、引数に含めたいコントロールには、<f:ajax immediate="true" />を書く必要がある

 1でc:forEachを使用してしまった場合、データ自体は一応表示されなくもないものの、コレクションのサイズが誤認されるなど、非常に挙動不審になります。したがって、ui:repeatを使わなくてはなりません。
 また、2の記述を忘れてしまうと、コントロールに入力したはずのデータが受け取れないという不思議な事態に陥ります。私はこのようなものが必要とはつゆ知らず、データが受け取れない現象に散々混乱した末、やむを得ずAPIドキュメントを読み込んでみて、やっと原因が分かりました。
 これでひとまず、ごく単純なチャットが作成できました。そろそろ考えるべきことが増えてきましたが、この程度なら生のAjaxを書くよりは比較的楽です。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

得票手当て
2010/01/31(Sun)19:02:22
 民主党の目玉政策である「子ども手当て」について、地方自治体から給食費の滞納分に充当できるようにすべきとの要望が出ていることに関して、鳩山氏は「そういう仕組みができないか考えたい。具体的な要望に応えられるような政府でありたい」として検討する考えを示しました。ただし現在の法案では、子ども手当ては差し押さえができないものとなっており、これを行うには法案を見直さなくてはなりません。
 鳩山氏によれば、知事や市町村長との意見交換の際に「滞納の2/3は経済的理由ではない」などとして充当を求める意見が相次いだ他、全国市長会は給食費や保育料などの各種の悪質な未納に対し、子ども手当てを充てることを検討すべきと主張しており、実際に実現される可能性も出てきました。
 かねてから全く理解できないのですが、民主党は子ども手当てに一体何を求めているのでしょうか。本来、国民に直接現金または金券を配るという方法はあまり望ましいものではありませんが、個別のケースで直接給付が望ましい状況というのはあり得ますので、そうであるなら必ずしも否定されるべきものではありません。しかしながら、本政策において民主党が一体何を目的としているのかが全く見えてこないため、妥当か否かの判断すらつけがたい状態です。
 かつて麻生氏が金配りを行おうとした際には、理念や目的が見事なまでに揺れ動き、庶民救済であるとしてみたり、経済振興政策であるとしてみたり、金持ちは辞退または制限すべきとしてみたり、金持ちも受け取るべきとしてみたりと、全く何がやりたいのか理解不能な、まれに見るひどい政策と化していました。そもそも、まずもって目的がはっきりしていなかったがために、所得制限などの手段面において迷走を深めることになりました。麻生氏がさもしくも票を買収しようとした金配り自体の愚かしさに加え、目的も何も意味不明では、支持が集められないのも当然です。
 現在の子ども手当ても、これと全く同じ状況に陥っています。すなわち、困窮家庭の子どもを救済する意味を持つのか、教育格差の縮小を狙うのか、金銭的負担の緩和で少子化対策を狙うのか、はたまた直接給付型の経済政策であるのかが全く見えてきません。いかなる目的に属するかによって、高所得者への給付をどうするか、差し押さえをどうするかといった部分が変わってくるはずなのですが、子ども手当て法案では差し押さえが禁止されているにもかかわらず、鳩山氏が給食費未納への充当を検討するものとした辺りは、見事にその矛盾ぶりを示しています
 もし本制度が困窮家庭の子を救済しようとするものであるのなら、給食費や保育料の未納への充当は妥当とはいえません。自治体側の「未納の2/3は経済的理由ではない」の主張がどこまで正しいのかは分かりませんが、これを信じても1/3は経済的困窮によるものであるわけですから、決して小さな数字とはいえません。まして、「経済的困窮」か「払えるのに払わない」かのボーダーライン上にあり、どちらかを明確に決定できないケースもあるものとみられ、線引きをするのも困難です。
 すなわち、未納者全員の子ども手当てから充当を行うのであれば、自治体側が言うところの1/3の困窮家庭はますますの困窮を余儀なくされる一方で、何の問題もなく給食費を出している家庭には、丸ごと子ども手当てが転がり込んできます。一方、「経済的理由がないのに未納している者」のみを対象に充当を行うのであるとしても、線引きが厄介な問題として残ります。所得などの数字を基準にしようにも、所得制限と似たような議論がまた起こるだけでしょう。
 また、本制度が貧困家庭の子を救済する意味合いを持つのであれば、制度の受益者は保護者ではなく子であるとみなすこともできますので、親の都合で差し押さえられることを禁止しようとする本来の法案の理念にはそれなりの正当性があり、充当を認める意味が分からなくなります。
 教育格差の縮小を狙うのであれば、子ども手当てに充てる分の財源を原資にして教育を充実したり、間接給付による高校授業料無料化のようなタイプの案を推進した方が無難であり、金を配る必要はありません。そればかりか、いわゆる富裕層にとっては可処分所得となり、同中流家庭にとっては塾や習い事の費用となり、貧困家庭では給食費や生活費に充填されるといった、何の意味もない状況すら生じかねません。
 また、間接給付の観点から言えば、保護者は子ども手当てを受け取っても給食費は払わなくてはならず、支払いを拒否すれば子ども手当てから充当されるというのであれば、「基準給食費」のようなものを定め、子ども手当ての財源を使って給食費を公費でまかなっても全く同じです。子ども手当てをめぐる各種の矛盾を考えれば、未納分の充当を可能にするより、こちらの方がまだ合理的とさえいえるでしょう。
 さらに、少子化対策として「現金給付」のエサを用いようとするのであれば、現実に日本で子を持つことに対する問題点はすでに大量に示されていますし、必ずしも直接給付が望まれていないことは明らかですから、子ども手当ての財源を必要な部分に振り向けた方が効率的です。仮に子ども手当ての実施後、多少の出生率向上効果があったとしても、日本での子育てが困難であるとされる本質的な問題点は全く改善しません。問題を解消しようとしない限り、所詮は一時しのぎです。
 まして、本制度が経済政策の一環であるというなら、全く論じる価値もないとしか言いようがありません。一部の調査によれば、子ども手当てによって車が売れる可能性があるようですが、せっかく「子ども」を標榜した大規模な政策が実施されるというのに、それが教育の充実などではなく車に消費されるとすれば、あまりにくだらないとしか言いようがありません。この種の政策が経済政策として優れたものでないことは、地域振興券と金配りが証明しています。
 子どもへの予算の財源として、配偶者控除を取り除いてしまう点までは、諸手を挙げて賛成します。この財源が子どものために生かされるとすれば、非常に優れた政策であるといえるでしょう。しかし、それを「配る」という発想は全く理解できませんし、その目的もはっきりしません。もし「配る」ことでしか達成できない目的があるのなら、配ることも理解できないわけではありませんが、今回の「充当」問題からも分かるように、鳩山氏に確固たる理念があるようには見えません
 途中までは決して間違っていない政策なのですから、子ども手当ては一旦白紙に戻し、教育を充実して「米百俵」を実施しつつ教育格差の軽減を図り、少子化対策としては金を渡すのではなく問題を解消しようと努力し、負担軽減が必要な部分は間接給付式に行うようにすべきです。また、私は必ずしも直接給付を全否定はしませんが、それが車の代金に消えてしまうのでは全く意味がありませんので、金持ちにも等しく配るのではなく、あくまで弱者救済策として行われなくてはなりません。
 民主党が仮に今からこの「目玉政策」を取り潰せば、おそらくマスコミは批判の大合唱を始めるでしょう。しかし、麻生氏は金配りを断念できなかったがゆえに、完全に支持を失い敗北しました。金を配ったからといって、選挙に勝てるわけではないのです。もし民主党が「金を配る」ことにこだわるのであれば、「金を配る以外の方法では実現できない目的があるので配るのだ」ということを説明すべきです。そのような事情がないのであれば、配るなどという芸のない方法は封印し、別のやり方を考えるべきでしょう。

 JSF 2.0ではかなり簡単にAjaxが書けるようになっているとのことですので、ひとまず簡単なサンプルを作成することにしました。
 とはいえ、私はJSFがあまり好きではありません。その上Ajaxに至っては大嫌いです。GoogleなどではオートコンプリートにAjaxが使われていますが、いまいましいことこの上ありません。いちいち入力が重くなった後には、頼んでもいない候補を並べ立ててくださいます。そんなもの必要ありませんので、ただテキストボックスとボタンしかなかった昔のGoogleに戻って欲しいです。
 AjaxでできることはFlashやJavaなどでもおおむね実現可能である一方、FlashやJavaにできてAjaxにできないことはあり得ますが、それらではなくAjaxを使う理由としては「操作性が普段のHTMLページと同じで分かりやすい」「環境に依存しにくい」などが述べられています。しかしながら、いずれも理解しがたいと言わざるを得ません。
 操作性に関しては、今までのCGIなど動的なHTMLは「リクエスト送信」と「レスポンスの受け取り」を1セットにしていましたが、Ajaxではいつどこでどのような送信があるのかも分からず、どこでレスポンスが来ているのかも分からず、かなり戸惑います。従来のページ変移型モデルの何と合理的なことでしょう。
 環境依存に関しては、Javaがそもそも環境依存を排そうとしているのに比べ、Ajaxは平気でブラウザごとにやり方が違い、そればかりかJavaScriptやHTMLへの対応もブラウザごとにまちまちですから、逆に厄介です。当然ながら標準化の流れもありますが、Ajax自体もMicrosoftが酔狂で生み出した独自規格からきているのですから、全く意味がありません。
 こんな作るも地獄、使うも地獄のものが普及してしまうなど世も末、という愚痴はこの辺で切り上げて、JSF 2.0の実装に入ります。
/WEB-INF
 /classes
  /com
   /yamicha
    /ajax
     CountBean.java
 web.xml
ajax.xhtml
 最初から難しいものを書く自信はありませんので、あえて簡単な構成としました。
 まずweb.xmlは完全にお決まりの内容です。
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>

  <display-name>JSF 2.0 Ajax Servlet</display-name>
  <description>JSF 2.0 Ajax Sample Servlet</description>

  <servlet>
    <servlet-name>jsf20ajax</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>jsf20ajax</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
</web-app>
 せっかくServletでもXMLが不要になったところですが、これはアノテーションで省略できないものでしょうか。
 今回のJavaソースは以下のCountBean.javaのみで、web.xml以外はXMLを書く必要もありません。JSF 1.x時代の何の価値もないXMLが不要になっているため、その点からすれば非常に楽です。
package com.yamicha.ajax;

import javax.faces.bean.*;

@ManagedBean @ViewScoped public class CountBean{
	private int number;

	public CountBean(){
		number = 0;
	}
	public void addCount(){
		number ++;
	}
	public void clearCount(){
		number = 0;
	}
	public int getNumber(){
		return number;
	}
}
 すなわち、numberの初期値は0で、numberプロパティにはgetterがあり、addCountとclearCountのメソッドがある、という構成です。
 後はこれをajax.xhtmlから使用するだけです。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">

<h:head>
  <title>JSF 2.0 Ajax</title>
</h:head>

<h:body>
  <b>JSF 2.0 Ajax</b>

  <h:form id="ajaxform">
  <fieldset>
    <h:commandButton value="Add" action="#{countBean.addCount}">
      <f:ajax render="ajaxform:number"/>
    </h:commandButton>

    <h:commandButton value="Clear" action="#{countBean.clearCount}">
      <f:ajax render="ajaxform:number"/>
    </h:commandButton>
    <br/>

    <h:outputText value="#{countBean.number}" id="number"/>
    </fieldset>
  </h:form>
</h:body>

</html>
 あの七面倒なAjaxを使用している割には、非常にスマートなコードです。実際に「Add」ボタンを押してみると、ページ変移なしに番号が次々と加算され、「Clear」では0に戻ります。
 これだけ手軽に扱えるなら、あまり手間をかけずとも、それなりのものは作れそうです。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

経済旧体連合会
2010/01/25(Mon)01:25:26
 経団連の次期会長として、住友化学の米倉氏を当てる人事が固まりました。財閥系企業出身者の会長就任は今回が初めてです。氏は2004年から4年に渡って経団連副会長、その後は評議員会の議長のポストに就いており、その手腕が高く評価されたものとみられます。また、氏には石油事業の海外展開に道筋をつけたなどの功績がある他、マラリア被害がひどいアフリカで用いる蚊帳を開発し、現地生産を成功させるといった活躍もあるようです。このまま人事が確定すれば、5月にも正式に就任することとなります。
 かねてから経団連は自民党に相当な比重を置いており、毎年の政策評価や献金額でも自民党が民主党を大幅に上回っていました。特に政策評価には明らかに恣意的にしか見えない部分も散見される有様で、実際に民主党が躍進した2009年には政策評価を見送らざるを得ませんでした。もし経団連が公平・公正に政策評価を行っていたか、少なくともその自負があるのなら、政権交代の可能性など無関係に政策評価を行ったとしても、何の問題もなかったはずです。これでは民主党政権下で経団連の影響力が地に落ちるのも当然というもので、「財閥系」の不文律を破っての会長就任となる米倉氏には、民主党との関係を充実させる役目も期待されているようです。
 しかしながら、経団連会長がまず取り組まなくてはならない難題は、国民からの信頼を回復することに他なりません。かつての与党である自民党と蜜月関係にあった経団連は、自民党に様々な政策を実現させてきましたが、それが自民党の敗因の1つとなったことは明らかです。ある意味、国民が直接投票可能な自民党を通し、経団連に退場勧告を突きつけたようなものと言っても過言ではありません。
 政権交代のある政治においては、相手が民主党どころか自民党であっても、これまでのように二つ返事で経団連の傍若無人な振る舞いを受け入れてくれるわけがありませんし、実際に受け入れれば選挙で敗北するのみです。そのような意味でも、経団連の発言力は著しく低下しているといえるでしょう。
 この状況を打破するには、経団連はまず国民の信頼を勝ち取らなくてはなりません。しかし、今まで経団連がやってきたことを考えると、それは非常に険しい道といえるでしょう。例えば、談合の課徴金引き上げの際には、当初提示されていた「欧米並み」の水準に文句をつけ、小幅の引き上げにとどめてしまいました。談合は要するに税金の横領に当たるわけですから、自己利益のために税金横領の罰則を引き下げたと非難されても仕方がありません。また、ミートホープや三菱自動車問題など生命や食品にかかわる複数の事件は、公益通報がなければ闇に葬られていた可能性がありますが、経団連は公益通報者保護法の適用基準を厳格に修正させてしまいました。自分の利益のためであれば、国民の生命や健康を犠牲にすることもいとわないようです。
 経済政策の面でも、以前の会長であった奥田氏(トヨタ)は「消費税を毎年1%ずつ上げ、法人税は下げる」という内容の「奥田ビジョン」を発表していますし、その次の会長である御手洗氏(キヤノン)の時期には無賃残業合法化を積極的に推進し、政府案では年収900万円以上を基準としていたところを、経団連は400万円にすべきと主張し、インターネット上ではごく小規模ながらもキヤノン製品不買の動きさえ見られました。本来なら信用第一のはずの企業の集合体でありながら、信用は完全に地に落ちていると考えて間違いないでしょう。
 無論、これまでの経団連の意義を全否定するつもりはありません。今後どうなるかは不明ではあるものの、少なくとも今までの経団連は「大企業の、大企業による、大企業のための組織」に過ぎず、決して日本や国民の利益など考えてはいませんでしたが、たまたま「経団連が望む政策」と「日本に必要な政策」が合致した場合の政策実現に関しては、経団連にも功績があるといえるでしょう。
 ところが、最近では野放図な規制緩和による弊害が次々と表に出てきており、世界同時不況もそれに拍車をかけている状況です。緩和すべき無用な規制が多く存在していた時代には、経団連もそれなりに活躍できていたはずですが、最近では「経団連が望む政策」と「日本に必要な政策」が完全に乖離・対立してしまっています。
 そして、経団連が自己利益至上主義の主張を行っている限り、国民からの信頼は決して回復しません。経団連は自ら「企業が海外に逃げる」と主張している通り、日本が荒廃したとしても海外に脱出すれば済むことですから、日本を壊滅させてでも自分の利益を最大化しようとするのは理にかなった行動ではありますが、前述の通りもはやそれは通用しないと知るべきでしょう。
 かつて鳩山氏は所信表明演説にて、自民・公明体制を「経済の合理性に偏った政治」であると批判していましたが、自公政治全体への評価はともかくとして、経団連の政策を実現してきたという意味で言えば、これは正しくありません。少なくとも今までの経団連は「自分の利益を最大化する」ことを至上命題としており、日本経済を省みてはきませんでした。経団連に参加している大企業に利益を与えつつ、経済の合理性に反する政策というのは十分に存在し得ます。例えば、無用な規制緩和によって大企業が利益を得たとしても、それが国民や日本経済にダメージを与えれば、それは経済の合理性に反しています。
 米国ではオバマ氏が大統領に就任し、日本でも民主党が政権の座に就きました。今度は経団連も変わらなくてはなりません。米日両方の民主党が苦戦しているように、経団連の変革も容易ではないはずですが、米倉氏は手腕を評価されているものとみられますので、やる気さえあれば不可能ではないはずです。
 無論、氏が奥田氏や御手洗氏のような方針・思想で事に臨むなら、国民の信頼を得ることなどできようはずがなく、民主党との距離を縮めるのも難しく、下手をすると自民党との蜜月も続かなくなり、旧体制を引きずってしまうことになりますが、氏はまたマラリア予防の蚊帳を開発するなどの活躍もあり、もしかすると今までの会長よりも大義が見える人かもしれません。大変に困難な道のりではありますが、果たして経団連は「大企業の、大企業による、大企業のための組織」から脱皮できるのでしょうか。

 続・MapKey。前回は@MapKeyJoinColumnを使用しましたので、今回は@MapKeyColumnを使用してみます。
 @MapKeyJoinColumnでは、キーとして何らかのEntityを使用していました。すなわち、@OneToManyのOne側のEntityとMany側のEntityに加え、キーの役目を持つEntityも書く必要がありました。当然のことながら、テーブルも3つ生成されます。例えば前回のコードでは、次の3つのテーブルが生成されました。
(キーにあたるテーブル)
mapkeyjoin_account
+------+----------+
| id   | name     |
+------+----------+
| 8751 | 現金     |
| 8752 | 当座預金 |
| 8753 | 売掛金   |
...

(One 側)
mapkeyjoin_office
+------+----------------+
| id   | name           |
+------+----------------+
| 8758 | 北朝鮮支店     |
| 8763 | ミャンマー支店 |
| 8768 | 阿久根支店     |
+------+----------------+

(Many 側)
mapkeyjoin_value
+------+---------+---------+--------+
| id   | price   | account | office |
+------+---------+---------+--------+
| 8759 |  350000 |    8753 |   8758 |
| 8760 |  150000 |    8751 |   8758 |
| 8761 |  800000 |    8754 |   8758 |
...
 @MapKeyColumnは@MapKeyJoinColumnと似ていますが、何らかのEntityをキーにするのではなく、カラムのデータがそのままキーとなるようです。すなわち、上記の例を@MapKeyColumnで書き換えるなら、テーブルは次のようになります。
(One 側)
mapkeyjoin_office
+------+----------------+
| id   | name           |
+------+----------------+
| 8758 | 北朝鮮支店     |
| 8763 | ミャンマー支店 |
| 8768 | 阿久根支店     |
+------+----------------+

(Many 側)
mapkeyjoin_value
+------+---------+----------+--------+
| id   | price   | account  | office |
+------+---------+----------+--------+
| 8759 |  350000 | 売掛金   |   8758 |
| 8760 |  150000 | 現金     |   8758 |
| 8761 |  800000 | 受取手形 |   8758 |
...
 これはすなわち、@MapKeyJoinColumnに比べて以下のような特徴があるとみなせます。

・キーにあたるデータはカラムに記録されるため、別のテーブルは生成されない。
・キーがカラムに記録される性質上、カラムに記録できるデータ以上のものはキーにできない。

 つまり、キーとなるデータに色々な属性を持たせたい場合、あるいは同じ名前のキーが複数存在しかねない場合には、@MapKeyJoinColumnの方が適任であるといえます。
 前者の例としては、以下のようなものが挙げられます。
id	name	type	genre	...
1	現金	借	資産
2	買掛金	貸	負債
3	売上	貸	収益
 この場合、勘定科目に色々なデータが含まれているため、単にString型のキーだけでは対応しきれません。
 後者の例としては、ややいい加減ではありますが、以下のようなものが挙げられます。
id	title
1	支店長
2	支店長補佐
3	支店長補佐
4	経理部長
...
 これをStringで表現しようとすると、"支店長補佐1"などのようにしなくてはなりません。
 また、使用するキーはあらかじめほとんど決まっていて、普段はその中から選択して使用すれば事足りるものの、場合によっては後からキーを新たに登録しなくてはならず、プログラム的に定数としてキーを定めておけないような場合にも、@MapKeyJoinColumnの方が便利です。勘定科目はまさにこの例に当てはまる代表格です。
 一方、特にそうした事情がないのであれば、@MapKeyColumnでも特に問題はなさそうです。単に文字列によるマップを使いたいだけであれば、@MapKeyColumnの方が分かりやすいでしょう。
/WEB-INF
 /classes
  /com
   /yamicha
    /mapkeyjoin
     Program.java
     Command.java
     MapKeyAccess.java
     MapKeyServlet.java
  /META-INF
   persistence.xml
 persistence.xmlは前回と同様です。
<?xml version="1.0" encoding="UTF-8"?>

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="MySQL" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/MySQL</jta-data-source>
    <properties>
      <property name="eclipselink.jdbc.driver"
        value="com.mysql.jdbc.Driver" />
      <property name="eclipselink.ddl-generation"
        value="create-tables" />
      <property name="eclipselink.ddl-generation.output-mode"
        value="database" />
      <property name="eclipselink.target-database"
        value="MySQL" />
      <property name="eclipselink.logging.level"
        value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>
 ソースは以下の通り作成しました。ただ、今回も1箇所ほど不可解なプロパティがあります。いつもながらサンプルデータは非常に適当です。
// Program.java
package com.yamicha.mapkey;

import javax.persistence.*;
import java.util.*;

@Entity @Table(name="mapkey_program" , schema="yamicha")
	public class Program implements java.io.Serializable{
	private int id;
	private String name;
	private String developer;
	// 今回のキーは String
	private Map<String , Command> commands;

	public Program(){
		commands = new Hashtable<String , Command>();
	}
	public Program(String s , String d){
		this();
		name = s;
		developer = d;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@Column(name="developer") public String getDeveloper(){
		return developer;
	}
	@OneToMany(fetch=FetchType.EAGER ,
		cascade=CascadeType.ALL , mappedBy="program")
		@MapKeyColumn(name="command_type")
		public Map<String , Command> getCommands(){
		return commands;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
	public void setDeveloper(String s){
		developer = s;
	}
	public void setCommands(Map<String , Command> c){
		commands = c;
	}

	public void link(){
		for(Command c : commands.values())
			c.setProgram(this);
	}
}

// Command.java
package com.yamicha.mapkey;

import javax.sql.*;
import javax.persistence.*;

@Entity @Table(name="mapkey_command" , schema="yamicha")
	public class Command implements java.io.Serializable{
	private int id;
	private String name;
	private String command_type;
	private Program program;

	public Command(){
	}
	public Command(String s){
		name = s;
	}

	@Id @Column(name="id") @GeneratedValue public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@ManyToOne @JoinColumn(name="program")
		public Program getProgram(){
		return program;
	}
	@Column(name="command_type") private String getCommandType(){
		return command_type;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
	public void setProgram(Program p){
		program = p;
	}
	private void setCommandType(String c){
		command_type = c;
	}
}

// MapKeyAccess.java
package com.yamicha.mapkey;

import javax.ejb.*;
import javax.annotation.*;
import javax.persistence.*;
import java.util.*;

@Remote @Stateless(name="MapKeyAccess" ,
	mappedName="ejb/MapKeyAccess")
	public class MapKeyAccess{
	@PersistenceContext(unitName="MySQL") private EntityManager em;

	public void regist(){
		Program java = new Program("Sun Java" ,
			"Sun Microsystems");
		java.getCommands().put("Compile" , new Command("javac"));
		java.getCommands().put("Execute" , new Command("java"));
		java.link();
		em.persist(java);

		Program mono = new Program("Mono C#" , "Novell");
		mono.getCommands().put("Compile" , new Command("gmcs"));
		mono.getCommands().put("Execute" , new Command("mono"));
		mono.link();
		em.persist(mono);

		Program ada = new Program("GNAT" , "AdaCore");
		ada.getCommands().put("Compile" , new Command("gnatmake"));
		ada.link();
		em.persist(ada);

		Program perl = new Program("perl" , "Larry Wall");
		perl.getCommands().put("Execute" , new Command("perl"));
		perl.link();
		em.persist(perl);
	}
	public List<Program> getPrograms(){
		return (List<Program>)em.createQuery(
			"SELECT p FROM Program p").getResultList();
	}
	public Program getProgram(Object id){
		return em.find(Program.class , id);
	}
}

// MapKeyServlet.java
package com.yamicha.mapkey;

import javax.servlet.annotation.*;
import javax.ejb.*;
import javax.annotation.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.persistence.*;
import java.io.*;
import java.util.*;

@WebServlet(name="mapkeyservlet" , urlPatterns={"/*"})
  public class MapKeyServlet extends HttpServlet{
  @EJB(beanName="MapKeyAccess") private MapKeyAccess ma;

  public void doGet(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    doPost(request , response);
  }
  public void doPost(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type" , "text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();

    ma.regist();

    List<Program> programs = ma.getPrograms();
    for(Program p : programs){
      out.println(p.getName() + " (" + p.getDeveloper() + ")");

      Map<String , Command> commands = p.getCommands();
      for(Map.Entry<String , Command> e : commands.entrySet())
        out.println("t" + e.getKey() + ": " + e.getValue().getName());

      out.println();
    }

    out.close();
  }
}
 前回に引き続き、commandTypeプロパティは必要なのか非常に謎です。当然ながらprivateにしてあります。
 これを実行すると、以下の結果が得られます。
Sun Java (Sun Microsystems)
	Execute: java
	Compile: javac

Mono C# (Novell)
	Execute: mono
	Compile: gmcs

GNAT (AdaCore)
	Compile: gnatmake

perl (Larry Wall)
	Execute: perl
 テーブルは次の通りです。
mapkey_program
+------+------------------+----------+
| id   | developer        | name     |
+------+------------------+----------+
| 8741 | Sun Microsystems | Sun Java |
| 8744 | Novell           | Mono C#  |
| 8747 | AdaCore          | GNAT     |
| 8749 | Larry Wall       | perl     |
+------+------------------+----------+

mapkey_command
+------+--------------+----------+---------+
| id   | command_type | name     | program |
+------+--------------+----------+---------+
| 8742 | Execute      | java     |    8741 |
| 8743 | Compile      | javac    |    8741 |
| 8745 | Execute      | mono     |    8744 |
| 8746 | Compile      | gmcs     |    8744 |
| 8748 | Compile      | gnatmake |    8747 |
| 8750 | Execute      | perl     |    8749 |
+------+--------------+----------+---------+
カテゴリ [開発魔法][社会問題][経済・知的財産] [トラックバック 0][コメント 0]

<-前のページ [2] [3] [4] [5] [6] [7] [8] [9] [10] 次のページ->
- Blog by yamicha.com -