yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2018/06 の記事
[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
文民統制というものは
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]
<- 前の記事を参照 次の記事を参照 ->

- Blog by yamicha.com -