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
カテゴリ表示
 カテゴリ 開発魔法 に当てはまるもののみを表示します。

 存在する記事 737 件の中から 6-10 件を表示しています。
税制大菅波
2010/07/04(Sun)23:07:14
 税制発言で混迷に陥っている民主党ですが、今度は菅氏自ら所得税の最高税率引き上げを検討する考えを示しました。消費税に関しては、所得次第での還付措置と生活必需品の税率軽減の考えを表明しているものの、これも発言が一定していないとの批判を浴びています。また、法人税は「課税対象を広げれば、法人税収の総額を変えないことは可能」であると述べ、外部から財源を持ち込まない考えを示しています。
 いずれも案としては妥当であったり、諸外国で実際に導入・運用されていたりするものばかりですが、あまりにも行き当たりばったりであると言わざるを得ません。所得税の最高税率をかつての水準に近づけたり、法人税の課税を組み替えたりすること自体には検討の余地がありますが、このタイミングで行き当たりばったりに出されては、消費税を上げる際の批判をかわすためのポーズで、本当に実現する気はないのではないかと不安を持たれても仕方がありません。
 仮にこれらの案を出すだけ出しておいて、消費税だけ上げてこれらは実施しなかったとなれば、もはや詐欺以外の何者でもありません。特に法人税については、「消費税を上げて法人税を下げる」行為が批判を浴びるのは当然ですが、この批判を避けるために考えもなしに法人税内部での組み換えを主張し、後から産業界の主張に負けて撤回したり、または案の定失敗して消費税財源による穴埋めを余儀なくされたとなれば、冗談では済まされません。
 ある税を増税しても、それが他の減税によって相殺されれば、結果的に国の歳入は直接的には増えないわけですから、税制というものは一体的に論じる必要があります。したがって、仮に民主党が消費税増税と同時に「法人税減税は法人税の組み換えにより行う」ことと「所得税の最高税率引き上げ」を主張するのであれば、これらはセットでなくてはいけません。そして、行うと主張したからには必ず行わなくてはなりません。他方、もし所得税の最高税率引き上げや法人税減税の自己完結をする気がない、あるいはそれをするとは限らないのであれば、「消費税は上げるが、他はしないかもしれない」と明確に宣言しなければなりません。
 ことに法人税の場合、「内部で収支を合わせる」必要があるわけですから、行き当たりばったりの案で実施できるとは限りません。法人税減税の是非はともかくとして、問題のある優遇措置廃止による不公平性の解消は悪いことではありませんが、優遇対象額や産業の変動なども考えずにいい加減な制度改変を行えば、どのみち消費税から資金を充填しなくてはならなくなります。消費税増税で批判を浴びたからと、考えもなしに批判をそらす案を公表するのではなく、しっかり検証してもらわなくては困ります。
 消費税の税率軽減や還付措置については、実際に多くの諸外国でも採用されており、増税の際には導入を検討する価値は十分にあります。しかし、それでも消費税というものが本質的に逆進性の強い税である以上、増税するなら社会福祉など逆進性を軽減できる用途に充てることが大前提です。いくら軽減措置を導入したからといって、それを所得税や相続税の軽減などといった累進税の減税、または法人税減税など、逆進性を軽減できない用途に用いる大義名分ができるわけではありません。
 また、軽減措置を充実させれば税収も減少し、結局は消費税率を高く設定しなければならなくなったり、早めに次なる増税を行わなければならなくなったりといった本末転倒な事態を招くため、軽減にも限界があります。そのような面からも、消費税は社会福祉に使用して逆進性の問題を軽減する前提は揺らぎません。繰り返しますが、「逆進性軽減措置を導入さえすれば、消費税に固有の問題を考える必要がなくなる」わけではありません
 菅氏の「消費税増税」「自己完結による法人税減税」「所得税最高税率引き上げ」の税制3点セットは、それなりに面白い提案であるとはいえるでしょう。しかし、あまりに行き当たりばったりの提案、かつ消費税増税が批判されているタイミングとあって、後の2つを本当に実行する気があるのか疑問を抱かざるを得ない状態となっています。消費税増税の批判をかわすためではなく、本当にそれをする気があるのなら、氏はそれを明確に宣言する必要があります。一方、実際には行う気がない、または行うとは限らないのであれば、氏はそれを明確に宣言しなくてはなりません。

 JPAであえて@Embeddedを使用する理由といえば、何らかの汎用性のあるコードの再利用に他なりませんが、今回は以前のTitle.java及びRuby.javaを用いたコードを作成してみます。
 前回作成したのは辞書らしきものでしたが、今回作成するのは名簿とします。名前はまず苗字でソートし、さらに名前でソートするものとします。したがって、人物データはTitle型のプロパティを2つ(姓・名)持つことになります。
/WEB-INF
 /classes
  /com
   /yamicha
    /namelist
     Title.java
     Ruby.java
     Person.java
     Category.java
     NameListAccess.java
     NameListServlet.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>
 Title.javaとRuby.javaのコードは前回と全く同じです(パッケージ名だけは変えてあります)。
// Ruby.java
package com.yamicha.namelist;

import javax.persistence.*;

@Embeddable public class Ruby
  implements java.io.Serializable{
  private static final char RUBY_MAP[][] = {
    {'ぁ' , 'あ'} ,
    {'ぃ' , 'い'} ,
    {'ぅ' , 'う' , '\0' , 'ヴ'} ,
    {'ぇ' , 'え'} ,
    {'ぉ' , 'お'} ,

    {'\0' , 'か' , '\0' , 'が'} ,
    {'\0' , 'き' , '\0' , 'ぎ'} ,
    {'\0' , 'く' , '\0' , 'ぐ'} ,
    {'\0' , 'け' , '\0' , 'げ'} ,
    {'\0' , 'こ' , '\0' , 'ご'} ,

    {'\0' , 'さ' , '\0' , 'ざ'} ,
    {'\0' , 'し' , '\0' , 'じ'} ,
    {'\0' , 'す' , '\0' , 'ず'} ,
    {'\0' , 'せ' , '\0' , 'ぜ'} ,
    {'\0' , 'そ' , '\0' , 'ぞ'} ,

    {'\0' , 'た' , '\0' , 'だ'} ,
    {'\0' , 'ち' , '\0' , 'ぢ'} ,
    {'っ' , 'つ' , '\0' , 'づ'} ,
    {'\0' , 'て' , '\0' , 'で'} ,
    {'\0' , 'と' , '\0' , 'ど'} ,

    {'\0' , 'な'} ,
    {'\0' , 'に'} ,
    {'\0' , 'ぬ'} ,
    {'\0' , 'ね'} ,
    {'\0' , 'の'} ,

    {'\0' , 'は' , '\0' , 'ば' , 'ぱ'} ,
    {'\0' , 'ひ' , '\0' , 'び' , 'ぴ'} ,
    {'\0' , 'ふ' , '\0' , 'ぶ' , 'ぷ'} ,
    {'\0' , 'へ' , '\0' , 'べ' , 'ぺ'} ,
    {'\0' , 'ほ' , '\0' , 'ぼ' , 'ぽ'} ,

    {'\0' , 'ま'} ,
    {'\0' , 'み'} ,
    {'\0' , 'む'} ,
    {'\0' , 'め'} ,
    {'\0' , 'も'} ,

    {'ゃ' , 'や'} ,
    {} ,
    {'ゅ' , 'ゆ'} ,
    {} ,
    {'ょ' , 'よ'} ,

    {'\0' , 'ら'} ,
    {'\0' , 'り'} ,
    {'\0' , 'る'} ,
    {'\0' , 'れ'} ,
    {'\0' , 'ろ'} ,

    {'\0' , 'わ'} ,
    {} ,
    {} ,
    {} ,
    {'\0' , 'を'} ,

    {'\0' , 'ん'}
  };

  private String ruby;
  private String sort;

  public Ruby(){
  }
  public Ruby(String r){
    setRuby(r);
  }

  public String getRuby(){
    return ruby;
  }
  public String getSort(){
    return sort;
  }

  private static final char FIRST = ' ';
  public void setRuby(String r){
    ruby = r;

    StringBuffer sb = new StringBuffer();
    StringBuffer sbt = new StringBuffer();

    int before = -1;
    char bc = '';
    for(int i = 0; i < r.length(); i++){
      char c = r.charAt(i);

      int value = 0;
      int type = 0;

      if(c != 'ー'){
        boolean match = false;
        for(int v = 0; v < RUBY_MAP.length; v++){
          for(int t = 0; t < RUBY_MAP[v].length; t++){
            if(RUBY_MAP[v][t] == c){
              match = true;

              value = v;
              type = t;

              before = v;
              bc = c;
            }
          }
          if(match)
            break;
        }

        if(!match)
          throw new IllegalArgumentException(
            "文字 " + c + " は使用できません。");
      }else{
        if(before == -1)
          throw new IllegalArgumentException(
            "伸ばす音は先頭に配置できません。");

        if(bc == 'ん'){
          value = before;
          type = 1;
        }else{
          value = before % 5;
          type = 2;
        }
      }

      sb.append((char)(FIRST + value + 1));
      sbt.append((char)(FIRST + type + 1));
    }

    sb.append(FIRST);

    sb.append(sbt.toString());

    setSort(sb.toString());
  }
  private void setSort(String s){
    sort = s;
  }
}

// Title.java
package com.yamicha.namelist;

import javax.persistence.*;

@Embeddable public class Title
	implements java.io.Serializable{
	private String title;
	private Ruby ruby;

	public Title(){
		ruby = new Ruby();
	}
	public Title(String t , String r){
		this();
		title = t;
		ruby.setRuby(r);
	}
	public Title(String t , Ruby r){
		this();
		title = t;
		ruby = r;
	}

	public String getTitle(){
		return title;
	}
	@Embedded public Ruby getRuby(){
		return ruby;
	}

	public void setTitle(String t){
		title = t;
	}
	public void setRuby(Ruby r){
		ruby = r;
	}
}
 Person.javaはTitleを2つ持ちます。そうなるとカラム名がかぶって問題が生じそうですが、ここで用いるのが@AttributeOverride(s)です。これを使えばカラム名を任意のものに変更でき、しかもNested Embeddedにも対応しています。
// Person.java
package com.yamicha.namelist;

import javax.persistence.*;

@Entity @Table(name="namelist_person" , schema="yamicha")
	public class Person implements java.io.Serializable{
	private int id;
	private Category category;
	private Title fname;
	private Title lname;
	private String position;

	public Person(){
	}
	public Person(Title ln , Title fn , String p){
		this();
		lname = ln;
		fname = fn;
		position = p;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@ManyToOne @JoinColumn(name="category" ,
		referencedColumnName="id")
		public Category getCategory(){
		return category;
	}
	@AttributeOverrides({
		@AttributeOverride(name="title" , 
			column=@Column(name="first_name")) ,
		@AttributeOverride(name="ruby.ruby" , 
			column=@Column(name="first_ruby")) ,
		@AttributeOverride(name="ruby.sort" , 
			column=@Column(name="first_sort"))})
		@Embedded public Title getFirstName(){
		return fname;
	}
	@AttributeOverrides({
		@AttributeOverride(name="title" , 
			column=@Column(name="last_name")) ,
		@AttributeOverride(name="ruby.ruby" , 
			column=@Column(name="last_ruby")) ,
		@AttributeOverride(name="ruby.sort" , 
			column=@Column(name="last_sort"))})
		@Embedded public Title getLastName(){
		return lname;
	}
	@Column(name="position") public String getPosition(){
		return position;
	}

	public void setId(int i){
		id = i;
	}
	public void setCategory(Category c){
		category = c;
	}
	public void setFirstName(Title t){
		fname = t;
	}
	public void setLastName(Title t){
		lname = t;
	}
	public void setPosition(String s){
		position = s;
	}
}

// Category.java
package com.yamicha.namelist;

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

@Entity @Table(name="namelist_category" , schema="yamicha")
	public class Category implements java.io.Serializable{
	private int id;
	private String name;
	private List<Person> people;

	public Category(){
		people = new ArrayList<Person>();
	}
	public Category(String n){
		this();
		name = n;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@OneToMany(mappedBy="category" , cascade=CascadeType.ALL)
		public List<Person> getPeople(){
		return people;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String n){
		name = n;
	}
	public void setPeople(List<Person> p){
		people = p;
	}

	public void link(){
		for(Person p : people)
			p.setCategory(this);
	}
}
 本当はCategory.peopleプロパティに@OrderByをつけてソートさせるつもりでしたが、単一のプロパティを用いてソートすることはできるものの、なぜか複数のプロパティを使ってソートしようとするとエラーになってしまい、断念しました。複数プロパティを使用するサンプルはJava EE 6のAPIリファレンスにも記載されており、仕様上は問題ないはずなのですが、非常に不可解です。EclipseLinkの問題でしょうか。
 仕方がないので、NameListAccess.javaでJPQLを使ってソートしています。
package com.yamicha.namelist;

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

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

  public void regist(){
    em.createQuery("DELETE FROM Person p").executeUpdate();
    em.createQuery("DELETE FROM Category c").executeUpdate();

    Category pm = new Category("日本の総理大臣");
    pm.getPeople().add(new Person(new Title("村山" , "むらやま") ,
      new Title("富市" , "とみいち") , "内閣総理大臣(52人目)"));
    pm.getPeople().add(new Person(new Title("橋本" , "はしもと") ,
      new Title("龍太郎" , "りゅうたろう") , "内閣総理大臣(53人目)"));
    pm.getPeople().add(new Person(new Title("小渕" , "おぶち") ,
      new Title("恵三" , "けいぞう") , "内閣総理大臣(54人目)"));
    pm.getPeople().add(new Person(new Title("森" , "もり") ,
      new Title("喜朗" , "よしろう") , "内閣総理大臣(55人目)"));
    pm.getPeople().add(new Person(new Title("小泉" , "こいずみ") ,
      new Title("純一郎" , "じゅんいちろう") , "内閣総理大臣(56人目)"));
    pm.getPeople().add(new Person(new Title("安倍" , "あべ") ,
      new Title("晋三" , "しんぞう") , "内閣総理大臣(57人目)"));
    pm.getPeople().add(new Person(new Title("福田" , "ふくだ") ,
      new Title("康夫" , "やすお") , "内閣総理大臣(58人目)"));
    pm.getPeople().add(new Person(new Title("麻生" , "あそう") ,
      new Title("太郎" , "たろう") , "内閣総理大臣(59人目)"));
    pm.getPeople().add(new Person(new Title("鳩山" , "はとやま") ,
      new Title("由紀夫" , "ゆきお") , "内閣総理大臣(60人目)"));
    pm.getPeople().add(new Person(new Title("菅" , "かん") ,
      new Title("直人" , "なおと") , "内閣総理大臣(61人目)"));
    pm.link();
    em.persist(pm);

    Category y = new Category("日本円紙幣の肖像");
    y.getPeople().add(new Person(new Title("夏目" , "なつめ") ,
      new Title("漱石" , "そうせき") , "千円札D"));
    y.getPeople().add(new Person(new Title("野口" , "のぐち") ,
      new Title("英世" , "ひでよ") , "千円札E"));
    y.getPeople().add(new Person(new Title("新渡戸" , "にとべ") ,
      new Title("稲造" , "いなぞう") , "五千円札D"));
    y.getPeople().add(new Person(new Title("樋口" , "ひぐち") ,
      new Title("一葉" , "いちよう") , "五千円札E"));
    y.getPeople().add(new Person(new Title("福沢" , "ふくざわ") ,
      new Title("諭吉" , "ゆきち") , "一万円札D,E"));
    y.link();
    em.persist(y);
  }

  public List<Category> getCategories(){
    return em.createQuery(
      "SELECT c FROM Category c" , Category.class).getResultList();
  }
  public List<Person> getPeople(Category c){
    TypedQuery<Person> tq = em.createQuery(
      "SELECT p FROM Category c JOIN c.people p WHERE c.id = ?1 " +
      "ORDER BY p.lastName.ruby.sort , p.lastName.title , " +
      "p.firstName.ruby.sort , p.firstName.title" ,
      Person.class);
    tq.setParameter(1 , c.getId());
    return tq.getResultList();
  }
}
 NameListServlet.javaでサンプルを登録・表示します。
package com.yamicha.namelist;

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.List;
import java.util.ArrayList;

@WebServlet(name="namelistservlet" , urlPatterns={"/*"})
  public class NameListServlet extends HttpServlet{
  @EJB(beanName="NameListAccess") private NameListAccess na;

  public void doPost(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    doGet(request , response);
  }
  public void doGet(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    na.regist();

    request.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type" , "text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();

    out.println("<html>");
    out.println("<head>");
    out.println("<title>Name List</title>");
    out.println("</head>");
    out.println("<body>");

    out.println("<b>Name List</b><br /><br />");

    List<Category> categories = na.getCategories();
    for(Category category : categories){
      out.println("<b>" + category.getName() + "</b>");
      out.println("<ul>");
      List<Person> people = na.getPeople(category);
      for(Person person : people){
        out.println("<li>");
        out.println("<b>" + person.getLastName().getTitle() + " " +
          person.getFirstName().getTitle() + "</b>");
        out.println("<small>(" +
          person.getLastName().getRuby().getRuby() + " " +
          person.getFirstName().getRuby().getRuby() + ")</small>");
        out.println(" - " + person.getPosition());
        out.println("</li>");
      }
      out.println("</ul>");
    }

    out.println("</body>");
    out.println("</html>");

    out.close();
  }
}
 このプログラムを動かしてみるまで気づきませんでしたが、総理大臣はそれなりに名前が分散しているのに比べ、紙幣の文化人は出席番号が後ろの方になりそうな人ばかりなのはなぜなのでしょうか。
カテゴリ [開発魔法][社会問題][経済・知的財産] [トラックバック 0][コメント 0]

逆を以って累を助く
2010/06/27(Sun)23:15:08
 二大政党がそれぞれ消費税を競うという異例の2010年参院選ですが、やはり消費税は選挙の嫌われ者であるのか、民主党の支持には早速かげりが見え始めました。菅氏が「消費税10%」を実質的な公約とした部分が大きいようです。世論調査でも消費税の是非は真っ二つに割れており、消費税増税に理解を示す人も多数に上る反面、反対意見が根強いこともうかがわせます。
 確かに、消費税の増税は国民にとって望ましいことではありませんが、実際の国民はそれほど愚かではありません。麻生政権の金配り政策が失敗し、鳩山政権で「子ども手当て」があまり評価されなかったのを見ての通り、国民は目先の利益にばかり飛びつくわけではなく、おそらく国民の大多数は消費税を含む負担増がどうしても避けられないことを認識しています。
 消費税を上げるとなれば、それとセットで無駄の削減も絶対に必要ですが、民主党政権も事業仕分けである程度無駄をなくすのには成功したものの、これ以上に巨額の財源を歳出削減によって確保するあてはありません。今後とも歳出削減の努力を平行して行うのは当然としても、歳入を増やす方法を検討しないわけにはいきません。一部の弱小政党は、消費税増税論をあたかも「歳出削減を行わない」ような意味と解釈して批判したりしていますが、これは詭弁の一種に過ぎません。そして実際、おそらく大多数の国民は、必死で歳出削減の努力を続けたとしても、消費税増税の必要性がなくなるわけではないことを認識しているはずです。
 したがって、国民の消費税増税への理解はいつになく深まっているといえるでしょう。議論しようとするだけで大騒ぎになっていた今までと違い、議論の環境は十分に整っているといえます。ただ、それでも増税を口にした民主党の支持率が下落してしまうのは、鳩山時代の衆院の公約に反することもありますが、何より法人税減税とセットにしてしまった点が非常に大きいのではないかと推測されます。
 消費税は非常に逆進性が強い税ですから、これを累進的な政策の財源として使わないのであれば、それは不公平この上ない税制となります。つまり、消費税を財源として法人税を下げる行為は道理に反しているのです。これでは消費税増税に反対する人が増えるのも当たり前です。
 なお、自民党は消費税を福祉目的で使用するとの主張を展開していますが、もし法人税を減税し、さらに減税分の財源を逆進的でない方法で捻出しないのであれば、ただの言葉遊びに過ぎません。「消費税を増税して法人税を下げ、福祉は国債でまかなう」行為と「消費税を増税して福祉に充当、法人税減税は国債でまかなう」行為の間には、本質的に何の違いもないためです。むしろ、自民党はかねてから経済団体の主張をなぞったような主張をしているのですから、素直に「消費税増税と法人税減税をセットにする」と明確に方針を示した方が分かりやすくなります。
 法人税減税の財源としては、消費税などを増税して充当するのではなく、法人税の複雑な控除を廃止して財源を確保するとの主張も存在するようです。この場合は法人税の課税方法が変化するだけで、別の財源は必要ありません。しかし、仮にその方法を用いるのであれば、それを主張する政党はそのやり方と試算をしっかり訴える必要があります。八方美人的な言い方をしておきながら、例によって後から計算通りにならないと判明し、消費税増税分の財源に手をつけるような事態にでもなれば、詐欺以外の何者でもありません。
 また、自民党が攻勢に出る一方で、民主党が消費税発言でことさら支持を失った理由としては、民主党が一部経済団体の主張をなぞるような政策を言い始めたこともあるはずです。「消費税を増税して法人税を下げる」政策は繰り返し経団連が要求してきたものですし、その上に偽装請負が問題になった際には「それを合法化すべきだ」と主張してみたり、「みなし役員」問題を見れば結末は明らかでありながら年収400万円を基準とする無賃残業合法化を主張してみたりと、最近の同組織の傍若無人ぶりには目を覆いたくなるものがありました。さらには「団体献金」問題からも明らかですが、このような団体が裏で絡んでいると、制度改革や国民本位の政治は容易ではなくなります。自民党が先の衆院選で敗北したのも、経団連への退場勧告の意味が多分に含まれていたはずです。そのせいで経団連の影響力は地に落ち、会長にはこれまでの不文律を破って米倉氏が立てられました。
 ところが、今度は民主党が似たようなことを主張し始めたとなれば、とても冗談では済まされません。経済団体と蜜月の自民党ではもう改革は無理と踏んで民主党に取り替えたら、その民主党もまた同じことを言い出したというのが現在の状況なのです。自民党に比べて民主党の消費税発言が支持されないのは、その期待を裏切ったことによる部分があると考えるべきでしょう。
 なお、民主党は所得税の最高税率の引き上げにも言及しているようです。こちらは累進課税ですので、消費税に固有のいくつかの問題は回避または軽減できますが、もし所得税最高税率に言及だけはしておきながら、実際には消費税だけ上げて所得税には手をつけないようなことがあれば、実行する気もない累進課税をダシにして逆進増税を実現させたと批判されても仕方がありません。実現する気があるなら変更点や目安の時期をしっかり明示し、する気がないなら「しない」とはっきり断言しなくてはなりません。

 JPA 2.0の何とも地味な変更点として、Nested Embeddableが存在します。意味はそのまま、@Embeddableをネストできるというだけです。これはこれで便利な局面もありそうですが、機能として面白いかどうかは微妙なところです。
 @AttributeOverride(s)との合わせ技でそれなりに色々な使い方も可能ですが、今回は単純に「読み仮名を登録するとソート用データを自動的に生成してくれるクラス」を「記事タイトル」内に持たせ、さらに「記事項目」にそのタイトルデータを持たせる簡易な辞書を実装しています。
/com
 /yamicha
  /dic
   @Embeddable Ruby.java
   @Embeddable Title.java
   @Entity Content.java
   @Stateless DictionalAccess.java
   @WebServlet DictionalServlet.java
/META-INF
 persistence.xml
 Ruby.javaやTitle.javaは@Embeddableですから、流用したり複数個のオブジェクトを使用するなど@Embeddableらしい使い方が可能です。そうでもしなければ@Embeddableの意味があまりありませんので、そのうち実際にそのように使用してみるとしましょう。
 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>
 Ruby.javaにはルビ整列用文字列生成機構を実装しています。
package com.yamicha.dic;

import javax.persistence.*;

@Embeddable public class Ruby
  implements java.io.Serializable{
  // ※マップ中の '\0' はダミーデータ
  private static final char RUBY_MAP[][] = {
    {'ぁ' , 'あ'} ,
    {'ぃ' , 'い'} ,
    {'ぅ' , 'う' , '\0' , 'ヴ'} ,
    {'ぇ' , 'え'} ,
    {'ぉ' , 'お'} ,

    {'\0' , 'か' , '\0' , 'が'} ,
    {'\0' , 'き' , '\0' , 'ぎ'} ,
    {'\0' , 'く' , '\0' , 'ぐ'} ,
    {'\0' , 'け' , '\0' , 'げ'} ,
    {'\0' , 'こ' , '\0' , 'ご'} ,

    {'\0' , 'さ' , '\0' , 'ざ'} ,
    {'\0' , 'し' , '\0' , 'じ'} ,
    {'\0' , 'す' , '\0' , 'ず'} ,
    {'\0' , 'せ' , '\0' , 'ぜ'} ,
    {'\0' , 'そ' , '\0' , 'ぞ'} ,

    {'\0' , 'た' , '\0' , 'だ'} ,
    {'\0' , 'ち' , '\0' , 'ぢ'} ,
    {'っ' , 'つ' , '\0' , 'づ'} ,
    {'\0' , 'て' , '\0' , 'で'} ,
    {'\0' , 'と' , '\0' , 'ど'} ,

    {'\0' , 'な'} ,
    {'\0' , 'に'} ,
    {'\0' , 'ぬ'} ,
    {'\0' , 'ね'} ,
    {'\0' , 'の'} ,

    {'\0' , 'は' , '\0' , 'ば' , 'ぱ'} ,
    {'\0' , 'ひ' , '\0' , 'び' , 'ぴ'} ,
    {'\0' , 'ふ' , '\0' , 'ぶ' , 'ぷ'} ,
    {'\0' , 'へ' , '\0' , 'べ' , 'ぺ'} ,
    {'\0' , 'ほ' , '\0' , 'ぼ' , 'ぽ'} ,

    {'\0' , 'ま'} ,
    {'\0' , 'み'} ,
    {'\0' , 'む'} ,
    {'\0' , 'め'} ,
    {'\0' , 'も'} ,

    {'ゃ' , 'や'} ,
    {} ,
    {'ゅ' , 'ゆ'} ,
    {} ,
    {'ょ' , 'よ'} ,

    {'\0' , 'ら'} ,
    {'\0' , 'り'} ,
    {'\0' , 'る'} ,
    {'\0' , 'れ'} ,
    {'\0' , 'ろ'} ,

    {'\0' , 'わ'} ,
    {} ,
    {} ,
    {} ,
    {'\0' , 'を'} ,

    {'\0' , 'ん'}
  };

  private String ruby;
  private String sort;

  public Ruby(){
  }
  public Ruby(String r){
    setRuby(r);
  }

  public String getRuby(){
    return ruby;
  }
  public String getSort(){
    return sort;
  }

  private static final char FIRST = ' ';  // 0x20
  public void setRuby(String r){
    ruby = r;

    StringBuffer sb = new StringBuffer();
    StringBuffer sbt = new StringBuffer();

    int before = -1;
    char bc = '';
    for(int i = 0; i < r.length(); i++){
      char c = r.charAt(i);

      int value = 0;
      int type = 0;

      if(c != 'ー'){
        boolean match = false;
        for(int v = 0; v < RUBY_MAP.length; v++){
          for(int t = 0; t < RUBY_MAP[v].length; t++){
            if(RUBY_MAP[v][t] == c){
              match = true;

              value = v;
              type = t;

              before = v;
              bc = c;
            }
          }
          if(match)
            break;
        }

        if(!match)
          throw new IllegalArgumentException(
            "文字 " + c + " は使用できません。");
      }else{
        // 前の文字から母音を取り出す
        if(before == -1)
          throw new IllegalArgumentException(
            "伸ばす音は先頭に配置できません。");

        // 「ん」の場合は「ん」が続くとみなす
        // それ以外は母音となる
        // 伸ばす音が2つ以上連続している場合は
        // 同じ音が続いているとみなされる
        if(bc == 'ん'){
          value = before;
          type = 1;  // 優先度は通常の「ん」より低い
        }else{
          value = before % 5;
          type = 2;  // 優先度は2(「ぅ」「う」より後で「ヴ」より前)
        }
      }

      sb.append((char)(FIRST + value + 1));
      sbt.append((char)(FIRST + type + 1));
    }

    sb.append(FIRST);

    sb.append(sbt.toString());

    setSort(sb.toString());
  }
  private void setSort(String s){
    sort = s;
  }
}
 ソート順は基本的に辞書順です。すなわち、五十音(小文字や濁音を区別せず、伸ばす音は発音に変換したもの)をまず比較し、五十音では差がない場合は小文字、清音、伸ばし音、濁音、半濁音の順に並べます。「ヴ」に関しては、「う」の濁点と扱っている辞書と、「ば」行で扱っている辞書がありますが、ここでは前者の方式を採用しました(後者の方式を用いるなら、最初から「ば」行で読みを登録すれば済むので、そもそも「ヴ」をルビ用文字に加える必要がない)。
 ちなみに、日本語の五十音は「や」行を「やいゆえよ」、「わ」行を「わいうえを」と扱い、さらに「ん」を入れたとしても51個に過ぎず、文字の種別(清音の他、濁音、半濁音、伸ばす音、小文字)は5パターン程度に過ぎないため、当初は五十音に6ビット(64通り)、種別に3ビット(8通り)の1文字9ビットを使用し、五十音データと種別データの区切りとして1ビットを使用する(したがって、ソート用文字列のサイズは「文字数 * 9 + 1ビット」)実装としていましたが、何とEclipseLinkのJPQLは(あるいはJPAのJPQL仕様は)byte[]をORDER BYできないらしいため、仕方なくAscii文字を使用する形式に書き直した経緯があります。おかげで五十音に1バイト、種別に1バイト、さらに五十音と種別の区切りに1バイトで、サイズは「文字数 * 2 + 1バイト」です。なお、VARBINARYはMySQL側では正しくORDER BYできるため、なおさらJPAで動かないのが理不尽です。
 これに比べ、Title.javaやContent.javaはごく単純な@Embeddableや@Entityです。
// Title.java
package com.yamicha.dic;

import javax.persistence.*;

@Embeddable public class Title
	implements java.io.Serializable{
	private String title;
	private Ruby ruby;

	public Title(){
		ruby = new Ruby();
	}
	public Title(String t , String r){
		this();
		title = t;
		ruby.setRuby(r);
	}
	public Title(String t , Ruby r){
		this();
		title = t;
		ruby = r;
	}

	public String getTitle(){
		return title;
	}
	@Embedded public Ruby getRuby(){
		return ruby;
	}

	public void setTitle(String t){
		title = t;
	}
	public void setRuby(Ruby r){
		ruby = r;
	}
}

// Content.java
package com.yamicha.dic;

import javax.persistence.*;

@Entity @Table(name="dic_content" , schema="yamicha")
	public class Content implements java.io.Serializable{
	private int id;
	private Title title;
	private String description;

	public Content(){
		title = new Title();
	}
	public Content(Title t , String d){
		this();
		title = t;
		description = d;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Embedded public Title getTitle(){
		return title;
	}
	@Column(name="description" , columnDefinition="TEXT") @Lob
		public String getDescription(){
		return description;
	}

	public void setId(int i){
		id = i;
	}
	public void setTitle(Title t){
		title = t;
	}
	public void setDescription(String d){
		description = d;
	}
}
 DictionalAccess.javaでデータの取得や追加を行います。
package com.yamicha.dic;

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

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

	public void add(String title , String ruby , String desc){
		if(title == null || title.isEmpty())
			throw new IllegalArgumentException(
				"タイトルがありません。");
		if(ruby == null || ruby.isEmpty())
			throw new IllegalArgumentException(
				"ふりがながありません。");
		if(desc == null || desc.isEmpty())
			throw new IllegalArgumentException(
				"本文がありません。");

		em.persist(new Content(new Title(title , ruby) , desc));
	}

	public List getContents(){
		return em.createQuery(
			"SELECT c FROM Content c ORDER BY c.title.ruby.sort" ,
			Content.class).getResultList();
	}
}
 特筆すべきは、せいぜいORDER BY程度です。なぜかbyte[]をソートしてくれないのは困ったものです。
 DictionalServlet.javaで登録フォームや表示を実装しています。
package com.yamicha.dic;

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.List;
import java.util.ArrayList;

@WebServlet(name="dictionalservlet" , urlPatterns={"/*"})
  public class DictionalServlet extends HttpServlet{
  @EJB(beanName="DictionalAccess") private DictionalAccess da;

  public void doPost(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    doGet(request , response);
  }
  public void doGet(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    //da.regist();

    request.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type" , "text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();

    out.println("<html>");
    out.println("<head>");
    out.println("<title>Dictionaly</title>");
    out.println("</head>");
    out.println("<body>");

    out.println("<b>Dictionaly</b><br />");
    out.println("<a href=\"?c=form\">新しい項目の登録</a><hr />");

    String c = request.getParameter("c");

    if("add".equals(c)){
      try{
        da.add(request.getParameter("title") ,
          request.getParameter("ruby") ,
          request.getParameter("description"));

        c = null;
      }catch(EJBException e){
        out.println(e.getCausedByException().getMessage());
      }
    }

    if(c == null || c.isEmpty()){
      List<Content> contents = da.getContents();
      for(Content content : contents){
        Title title = content.getTitle();
        Ruby ruby = title.getRuby();

        out.println("<p>");
        out.println("<b>" + title.getTitle() + "</b><small>(" +
          ruby.getRuby() + ")</small><br />");
        out.println(content.getDescription().replace("\n" , "<br />"));
        out.println("</p>");
      }
    }else if("form".equals(c)){
      out.println("<form action=\"?\" method=\"POST\">");

      out.println("<table border=\"0\">");
      out.println("<tr>");
      out.println("<td>記事名</td>");
      out.println("<td><input type=\"text\" " +
        "name=\"title\" size=\"30\" /></td>");
      out.println("</tr>");

      out.println("<tr>");
      out.println("<td>ふりがな</td>");
      out.println("<td><input type=\"text\" " +
        "name=\"ruby\" size=\"30\" /><br />");
      out.println("<small>ひらがなと「ー」「ヴ」のみ有効</small></td>");
      out.println("</tr>");

      out.println("<tr>");
      out.println("<td>記事内容</td>");
      out.println("<td><textarea name=\"description\" " +
        "cols=\"50\" rows=\"6\"></textarea></td>");
      out.println("</tr>");
      out.println("</table>");

      out.println("<input type=\"hidden\" name=\"c\" value=\"add\" />");
      out.println("<input type=\"submit\" value=\"この内容を登録\" />");

      out.println("</form>");
    }

    out.println("</body>");
    out.println("</html>");

    out.close();
  }
}
 後は適当にデータを登録するだけです。
 データはこのように整列されて表示されます。Ruby.javaもTitle.javaも@Embeddableであるため、他にルビによるソートが必要な記事タイトルや人名など何らかのものがある場合、Title.javaを再利用できます。
 余談ながら、ソート用データは次のような文字列となっています。
SELECT TITLE , RUBY , SORT FROM dic_content ORDER BY SORT;

+--------+----------+-----------+
| TITLE  | RUBY     | SORT      |
+--------+----------+-----------+
| 州     | しゅう   | ,F# "!"   |
| シュー | しゅー   | ,F# "!#   |
| 私有   | しゆう   | ,F# """   |
| 十     | じゅう   | ,F# $!"   |
| 自由   | じゆう   | ,F# $""   |
| 修理   | しゅうり | ,F#J "!"" |
| 首都   | しゅと   | ,F4 "!"   |
+--------+----------+-----------+
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

消費税増税の先陣争い
2010/06/20(Sun)22:41:22
 自民党が消費税10%案を公約に明記し、民主党も消費税増税を公約に明記しました。税率については、菅氏は「自民党が提案している10%という数字を一つの参考にさせていただきたい」と述べており、おおむね自民党案と類似したものになることが予想されます。一方、党内や他の野党からは批判の声も出ており、自民党からは「民主党の公約は自民党のコピー」との声も聞かれます。
 民主党が自民党の後を追うように消費税案を設定したのは、ある程度仕方のないところでしょう。与党が消費税増税を主張するのは非常に難しく、下手に言い出そうものなら野党に攻め立てられて支持を失う恐れがあるため、野党がまず言い出さなければ議論にならない現状があります。消費税はこれまで非常に嫌われてきており、さらに野党時代の民主党が年金の財源として消費税増税を主張した際には、自民党が論点をかき乱してしまい、結局消費税議論はほとんど行われてきませんでしたが、今回の参院選では自民党はむしろ民主党との差別化のために消費税増税を主張しており、民主党もそれを受けて公約を設定したため、ここでようやく消費税増税を論じた選挙が行われそうです。
 現在の財政状況からして、望む望まざるにかかわらず消費税増税はいずれ避けようがなく、そのような意味では議論が深まるのは歓迎すべきことです。参院選終了後は最長で3年ほど選挙のない期間が続きますが、もし今回の参院選で消費税議論がなされなければ、最長3年にわたって消費税問題で大混乱を起こす可能性が考えられますので、このタイミングで二大政党がともに消費税を持ち出したのは、無難なものであるといえます。
 しかし、ここで重要になるのが消費税の使い道です。消費税は逆進性が強い税であるため、逆進性を抑えるには使い道を考える必要があります。例えば、消費税で確保した財源を福祉に充当すれば逆進性を緩和できますが、これを使って相続税を減免などすれば逆進性は緩和されません。逆進性を打ち消せない用途に財源を回したいのであれば、それは消費税増税によって捻出すべきではありません。
 中でも気になるのが法人税減税論です。法人税を減税すれば、その分が雇用や設備投資、給与に回って経済が回転し、国際競争力も高まるというのが減税の理屈ですが、これへの財源として消費税を充てることには慎重であるべきです。福祉財源の欠乏と消費税の逆進性を考慮すれば、福祉目的の消費税増税に比べて法人税減税目的の消費税増税が受け入れられにくいのは明白です。
 無論、本当に雇用や設備投資が回復し、経済の回転が見込めるのであれば、法人税減税も方法の1つとして検討されるべきです。しかし、大企業が未曾有の利益を出した際に日本で何が起こっていたかを考えれば、安易な減税が景気を刺激するかは非常に疑問と言わざるを得ません。その際には企業のパイが増えたはずですが、実際には派遣の使い捨てや偽装請負、下請けの締め付け、その他様々な問題が発生し、「実感なき景気回復」と揶揄される有様でした。せっかく国民全員に逆進的に負担をかけて法人税を減税したはずが、これの二の舞になっては困るのです。法人税を減税するために国民に負担を要求したければ、最低限これを防止する策を実現してからでなくてはいけません。
 また、消費税増税を公約に盛り込むのであれば、民主党は年金制度改革案も主要政策として堂々と訴えるべきでしょう。民主党がかねてから主張している全額税方式は、逆進性が極めて強い年金保険料と不公平かつ矛盾に満ちた第三号問題を解消できる優れた方法ですが、これを行うかどうかで消費税率の見方が変わってきます。福田内閣時に与党側が躍起になって全額税方式を否定しようとしたと推測される「社会保障国民会議」の試算ですら、事実上3%の消費税増税で全額税方式は可能とされていますが、それなら実質的に民主党の消費税10%は自民党の7%に相当します。この通り、消費税率の意味合いが全く変わってくる以上、民主党は年金制度改革案も同時に訴える必要があります。
 なぜ消費税増税がここまで国民に嫌われるかといえば、逆進性が強いとみなされているためです。そして、消費税で福祉などの社会保障を強化すれば、弱者ほど恩恵を受けるため累進的となり、本来なら歓迎されるはずのところを、なぜ逆進性が強いとみなされるかといえば、消費税が福祉以外に無駄遣いされる懸念を多数の国民が抱いているためです。すなわち、「消費税アレルギー」は政治への不信感に起因している部分が大きいといえます。
 また、今回の消費税議論は新聞などで一定の評価を受けていますが、消費税増税はそれを財源として有効な政策を実現して初めて意味があるのであって、消費税を上げること自体が評価に値するわけではありません。それを履き違え、やれ我々が先に増税を言い出した、ライバル政党の優位性を封じるためにこちらも消費税を持ち出した、などという争いを続けている限り、単に「消費税上げない論争」が「消費税増税論争」に切り替わっただけで、意味がありません。これでは消費税の使途に不安を抱かれるのも無理はありません。

 このほど、これまで何をしても動作しなかったParrot + Rakudo for Win32がようやく動作したため、ここに覚え書きをしたためておきます。
 Parrotはもともとエイプリルフールのネタから生まれたソフトウェアで、PerlやPython、その他様々なスクリプト言語を動かせるランタイムという触れ込みで開発されています。Rakudo Perlはこれの上で動作するPerl 6の実装です。
 ところが、このParrotやRakudo、実際には前代未聞の出る出る詐欺に陥っています。Perl 6が近いうちに出ると発表された際には、開発者の間には少なからず盛り上がりが見られ、今のPerl 5もいずれは6に移行するからPerl 6を習得すべしとの機運もありましたが、これがすでに何年も前の話です。途中でPugsなどの玩具的な実装は出たものの、待てど暮らせどまともなPerl 6が出る気配はなく、最近ようやくRakudo Perlがベータ程度に実装されてきている状態です。ParrotとRakudoは複数のプラットフォーム向けにリリースされています。
 肝心のインストール方法ですが、まずParrotをインストールし、それからRakudoを同じディレクトリにインストールします。同じディレクトリにインストールするものであるはずなのに、Rakudoのインストール時に警告を出してくるのが何とも意地悪です。ParrotとRakudoのバージョンは合わせなくてはならないとサイトにも書いてありますので、その通りにしておきます。
 また、インストールの際にはインストールディレクトリ名には手をつけない方が無難なようです(ドライブ名は変えてもよい)。これまで散々動作に失敗してきたのは、デフォルトではParrot-2.5.0などとバージョン名がついているところを、運用しやすくするために単にParrotと変更していたのが原因でした。それにしても、なぜインストーラにインストール先ディレクトリ変更機能がついているのでしょうか
 インストールが終了すると、自動的にParrotのbinディレクトリが環境変数PATHに追加されます。ちなみに、これはアンインストールしても除去されないため、アンインストールの際には手作業で取り除かなくてはなりません。前のバージョンを消して新しいバージョンを入れたりする際には面倒そうです。
 ひとまず、ドキュメントにしたがって次のようなファイルを作り(ファイルの最後に必ず空行を入れること。拡張子は.pasmでなければならない。pasmはおそらくParrotのアセンブリの意)、
say "It's Parrot!"
end

 コマンドプロンプトから次のように打ってみて、
parrot (ファイル名)
 動作したらParrotの導入は成功です。
 RakudoはParrotとは別物ですから、こちらもテストしてみる必要があります。かつて実際に、Parrotは普通に動くのに、Perl6は何をしても動作せず、泣きを見たことがあります。
 とはいえ、こちらは単に
perl6
 と打てば対話モードになりますので、後はPerl 6の世界を満喫するだけです。十分に満喫したら、「exit」で我に返りましょう。
Path> perl6
> "It's Perl6!".say();
It's Perl6!
> loop (my $i = 10; $i < 13; $i++) {$i.say();}
10
11
12
> "It's Perl6!".say();
It's Perl6!
> my @arr = (1 , 2 , 3); for(@arr) {$_.say();}
1
2
3
> loop (my $i = 10; $i < 13; $i++) {($i * $i).say();}
100
121
144
> exit
 ここからは自由にParrotやRakudoを使用するだけです。ひとまず簡素なCGIを書いてみるのも面白いのではないでしょうか。
#!/parrot-2.5.0/bin/parrot -a

say "Content-type: text/plain\n"
say "Hello Parrot."
say "You can speak various languages."
end

 オプション「-a」をつけておくと、.pasm以外のファイルでもpasmとみなして解釈してくれます。
 perl6も使用してみます。
#!/parrot-2.5.0/bin/perl6

"Content-type: text/plain\n".say();
"Hello Rakudo Perl.".say();
 エラー時の挙動など、実用に耐えるかはともかくとして、とりあえず動くようです。
カテゴリ [開発魔法][社会問題][経済・知的財産] [トラックバック 0][コメント 0]

テン菅
2010/06/12(Sat)20:11:03
 沖縄問題をめぐる福島氏の罷免と社民党の連立離脱に続き、今度は国民新党の亀井氏が金融・郵政改革相を辞任しました。国民新党は会期を延長しての郵政改革法案の成立を主張していましたが、民主党は選挙日程への影響を考慮して要求を受け入れず、亀井氏の辞任に至ったものです。ただし、社民党の場合とは違い、ただちに連立を解消するものではないとされています。高支持率に乗って一気に選挙になだれ込むはずが、菅内閣は最初からつまづきを余儀なくされました。
 前任者の時期に社民党には離脱され、今度は就任早々に国民新党との関係まで不安定化するとあって、菅氏は早速出鼻をくじかれた格好ですが、無理に会期を延長して郵政改革法案の成立を行わなかったのは正解といえるでしょう。国民新党と安易に「成立」の合意を交わしたのは菅氏の落ち度ですが、政治を有利に進めるために国民新党をつなぎとめる必要があり、そのために会期延長や郵政改革法案の成立を強行したとあっては、こちらもまた「政争の具」に他ならないためです。
 もし今の日本に何か喫急の課題があり、会期を延長してすぐにでも成立させなければならないところを、民主党が選挙目当てに会期延長を否定したなら、それは批判を浴びても仕方のない行為です。しかし、郵政改革法案は決して喫急の法案ではないどころか、民業圧迫などの問題点も多く指摘されている代物です。むしろ十分な検証が必要なはずで、連立相手をつなぎとめるために無理やり成立させるようなものではありません。
 したがって、選挙前に駆け込み成立を図るよりは、これを参院選の公約の1つとして設定し、信任を得た上で成立させる方が道理にかなっています。国民新党としては、民主党が力を失えば法案の成立は絶望的ですし、仮に民主党が勝利しても国民新党が力を失えば約束が反故にされてしまうという危機感があるはずですが、その場合は郵政改革法案が必要とされていなかったと判断するよりありません。
 つまり、民主党が国民新党の要請を蹴ったのは、選挙対策ではなく道理の面からも正当なものといえます。もし無理に会期延長の末に法案を成立させていれば、時間の経過による菅氏への期待感の消失だけでなく、連立維持のために問題のある法案を無理やり成立させた菅氏の行動への疑問、国民新党に好き勝手を許した菅氏の指導力への不信などが生じ、氏はおそらく支持を減らしていたでしょう。
 また、今のところ菅氏がかなりの支持を集めているのは、菅氏本人ではなく「脱小沢」の動きが評価されているためです。小沢氏に支配された民主党ではどうしようもなく、自民党も評価に値せず、第三極も国民の要求を勘違いした政党がほとんどであるため、一時期は森時代や麻生時代を上回るほどの閉塞感が漂っていました。しかし、選択肢のない状況下で民主党が小沢氏を排除したのと、小沢氏はともかく民主党自体は一定の評価を受けていたために、意外なほど支持を持ち直したものと考えられます。
 そうであるなら、政策を掲げて国民に信を問える今こそ、小沢・鳩山時代のおかしなバラマキに対して大ナタを振るう最大かつ絶好の機会であるはずです。国民の多くは小沢氏を支持せず、その行動や政策に疑問を抱いているのですから、小沢時代の政策を全面的に見直すのは小沢色及び小沢氏の影響力の排除にもつながり、国民から支持を得られるはずです。さらに、実現が極めて難しい、あるいは実現してもほとんど意味のない無駄なバラマキ政策に関しては、選挙を目前に控えた今であれば容易に見直せます。一方、選挙の後で実現不可能だから、または無駄だからと約束を反故にすれば、批判を浴びるのは免れません。
 特に子ども手当てに関しては、かねてから子どもへの予算の欠乏が指摘されている日本において、配偶者控除などの矛盾に満ちた控除を廃止し、代わりに子どもの福祉を充実させようとする政策なのですから、本来なら非の打ち所のない優れた政策です。しかし、これを選挙対策としてバラマキにしてしまったがために、意味不明な状況に陥っているのです。せっかく子ども重視の政策が登場したはずが、その予算が車の売り上げに貢献するのでは意味がありません。この財源を生かして育児環境や教育を充実させれば、その方が弱者救済になりますし、教育格差などの格差問題も軽減できます。
 このように、民主党が掲げている目玉政策には、理念自体には優れた点が見受けられるものの、一部のピントがずれているせいで台無しになっているものがあります。これらを是正するだけでもかなりの効果が出る上、是正であれば現行案の修正であって廃止ではないため、作り直すより簡単な上、国民にも受け入れられやすいはずです。
 また、この参院選が終了すれば、衆院の解散がない限りは3年ほど選挙のない期間が続きます。そこでぜひとも争点にすべきなのが年金改革です。民主党は3年内に年金一元化と全額税化を実現することを目玉公約とすべきですし、自民党も対抗した公約を行うべきです。財源として消費税が必要なら、民主党はそれも公約に盛り込むべきでしょう。ここで先延ばしをしたとしても、年金改革や消費税はいずれ必ず論じなくてはならない問題ですし、何よりタレントの人気投票よりも年金選挙の方が圧倒的に建設的です。
 菅氏が受け持つ最初の課題は、仮に目玉政策であったとしても、無用と見た政策は容赦なく覆すことです。氏にこれができなければ、「菅内閣も前の体制と変わらない」と判断され、逆に支持を失ってしまうでしょう。

 EJBにはTimer Serviceなるものがあります。タイマーの設定の記述が若干面倒なことを除けば、あるタイミングで特定の動作を行ったりと、なかなか面白い機能です。
 ところで、EJB 3.1には@Scheduleなるものが加わっています。どうやら、このアノテーションをメソッドにつけておけば、指定した時間や間隔でそのメソッドが呼び出されるらしい、何ともお手軽そうな機能です。
 TimerServiceを手書きで使うより自由度はなさそうですが、定期的な更新が必要なデータを更新したり、一定期間毎にログを削除したり、特定の曜日・日付・年月に必要な処理を実行したりするには困らないはずです。
 以下、「30秒毎にデータベースから最新のログを取得し、@SingletonのBeanに格納」「2分毎にログを確認し、5分以上前のログがあったらデータベースから削除」するサンプルです。特に最新のログを必要とはせず、しかもデータベースにアクセスが殺到してパフォーマンスが悪くなることを回避したいような状況を想定しています。
/com
 /yamicha
  /schedule
   @Entity Log.java
   @Stateless LogAccess.java
   @Singleton LogCache.java
   @WebServlet LogServlet.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>
 Log.javaはログですので、必要な情報を色々と格納できるようにしても構いませんが、今回は単純にIDとメッセージ、日時だけとしました。
package com.yamicha.schedule;

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

@Entity @Table(name="schedule_log" , schema="yamicha")
	public class Log implements java.io.Serializable{
	private int id;
	private String message;
	private Date date;

	public Log(){
		date = new Date();
	}
	public Log(String s){
		this();
		message = s;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="message") public String getMessage(){
		return message;
	}
	@Column(name="date") @Temporal(TemporalType.TIMESTAMP)
		public Date getDate(){
		return date;
	}

	public void setId(int i){
		id = i;
	}
	public void setMessage(String s){
		message = s;
	}
	public void setDate(Date d){
		date = d;
	}
}
 LogAccess.javaはデータベースにアクセスするBeanです。登録・取得・削除の機能を実装しています。これらを直接呼び出すと、データベースへの読み書きの動作が生じます。
package com.yamicha.schedule;

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

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

	public void add(Log log){
		log.setDate(new Date());
		em.persist(log);
	}
	public List<Log> getLogs(){
		return em.createQuery(
			"SELECT l FROM Log l ORDER BY l.date DESC" ,
			Log.class).getResultList();
	}
	public void clearOld(){
		// 5分以上前のものを削除
		Query q = em.createQuery(
			"DELETE FROM Log l WHERE l.date < ?1");
		q.setParameter(1 , new Date(new Date().getTime() -
			60 * 5 * 1000));
		q.executeUpdate();
	}
}
 LogCache.javaは30秒毎にログを読み込んで更新し、2分毎にLogAccessのclearOld()を呼び出します。読み込んだログは自身のフィールドに保管し、getLogs()ではそれを呼び出し側に返しています。
package com.yamicha.schedule;

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

@Remote @Singleton(name="ScheduleLogCache" ,
	mappedName="ejb/ScheduleLogCache")
	public class LogCache{
	@EJB(beanName="ScheduleLogAccess") private LogAccess la;
	private List logs;
	private Date update;

	public LogCache(){
	}
	@Schedule(hour="*" , minute="*" , second="*/30")
		synchronized private void refresh(){
		logs = la.getLogs();
		update = new Date();
	}
	@Schedule(hour="*" , minute="*/2" , second="0")
		private void clear(){
		la.clearOld();
	}

	synchronized public List getLogs(){
		return logs;
	}
	synchronized public Date getLastUpdate(){
		return update;
	}
}
 一部をコメントアウトしようとした際に、"*/1"などの表現がコメントの終点とみなされて面食らったりしましたが、これで一定間隔での呼び出しを行ってくれます。記述方法は他にも色々あり、The Java EE 6 TutorialのUsing the Timer Serviceの項に詳しく書かれていました。
 いくつか簡単にまとめておくと、

hour="10-15" , minute="0" , second="0"
 10:00:00、11:00:00、12:00:00 ... 15:00:00。

hour="1,3,5" , minute="0" , second="0"
 01:00:00、03:00:00、05:00:00。

hour="*" , minute="*" , second="*/10"
 秒数が10で割り切れる10秒毎。

hour="15/3" , minute="0" , second="0"
 15時より3時間毎。

 などの記述があるということが書かれています。
 LogServlet.javaでログの読み書きを実装しています。ログはLogCacheから取得しています。
package com.yamicha.schedule;

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.List;
import java.util.ArrayList;
import java.util.Date;

@WebServlet(name="logservlet" , urlPatterns={"/*"})
  public class LogServlet extends HttpServlet{
  @EJB(beanName="ScheduleLogCache") private LogCache lc;
  @EJB(beanName="ScheduleLogAccess") private LogAccess la;

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

    out.println("<html>");
    out.println("<head>");
    out.println("<title>Log</title>");
    out.println("</head>");
    out.println("<body>");

    out.println("<b>Log</b>");

    String c = request.getParameter("c");

    if("add".equals(c)){
      la.add(new Log(request.getParameter("message")));
      c = null;
    }

    if(c == null || c.isEmpty()){
      List<Log> logs = lc.getLogs();

      out.println("<table border="1">");
      out.println("<tr>");
      out.println("<td bgcolor="#CCDDFF">ログ</td>");
      out.println("<td bgcolor="#CCDDFF">日付</td>");
      out.println("</tr>");

      for(Log log : logs){
        out.println("<tr>");
        out.println("<td>" + log.getMessage() + "</td>");
        out.println("<td>" + log.getDate() + "</td>");
        out.println("</tr>");
      }

      out.println("</table>");

      out.println("Last Update: " + lc.getLastUpdate());

      out.println("<form action="?" method="POST">");
      out.println("<input type="submit" value="再読み込み" />");
      out.println("</form>");

      out.println("<form action="?" method="POST">");
      out.println("<input type="text" name="message" size="40" />");
      out.println("<input type="hidden" name="c" value="add" />");
      out.println("<input type="submit" value="登録" />");
      out.println("</form>");
    }

    out.println("</body>");
    out.println("</html>");

    out.close();
  }
}
 タイマーを開始したり止めたり変更したりしないのであれば、@Scheduleはかなり手軽に使えそうです。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

カン菅
2010/06/05(Sat)22:31:34
 鳩山氏の突然の辞任劇の後、後任の民主党代表には菅氏が選出され、新首相となりました。代表選は菅氏と樽床氏の対決でしたが、岡田氏や前原氏など有力者が相次いで菅氏の支持に回り、反小沢勢力の多くを取り込んだ菅氏が勝利しました。鳩山氏の残り任期が菅氏の任期となるため、今回の代表選における任期自体は9月末までと非常に短いですが、参院選はこの体制で行われることになります。
 民主党としても党内事情はあるはずですが、期待感に欠ける代表選であると言わざるを得ません。現状では民主党も自民党も支持を完全に失っていますが、それは双方が旧来的な体質を保持しているためです。政党どころか日本の政治自体が大混乱に陥っているのですから、ここで古い体質を払拭する必要があり、そのためには若手を代表にして大ナタを振るうのが早道でした。
 ところが、今回の民主党代表選の候補は、反小沢ではあってもベテランと評して差し支えない菅氏と、小沢氏の影響力がささやかれる樽床氏でした。仮に樽床氏が選ばれたとしても、小沢氏が体制に介入してくるようなら、当然ながら大ナタを振るうことはできませんから、今回の代表選はどう転んでも大きな期待は得られにくかったはずで、党の事情による性急な日程もあり、実質的に盛り上がりのない代表選でした。
 これだけの窮地にあって、果たして民主党には本当に体制を刷新する気があるのでしょうか。自民党政権下でも安部・福田・麻生各氏と1年程度での首相交代が続きましたが、3度目の麻生氏の時点では最初から非常に苦しい状況に置かれていました。つまり、もし2度目の菅氏で失敗してしまえば、「3度目」は非常に厳しい立場に置かれるのです。それを防ぐためには、当面は菅氏の体制で刷新を進めていくしかありませんが、ここで体制を刷新できるかといえば、道は険しいと評するよりありません。
 また、党内に小沢氏の勢力が残っているのも気がかりです。仮に人事面で小沢氏の影響力を排除できたとしても、政策面で小沢氏が余計な口出しをすれば、民主党は間違いなく混乱に陥りますし、支持も得られなくなります。国民が望んでいるのは、小沢氏が単に幹事長などのポストを去ることではなく、その影響力をも返上することに他なりません。党内に絶大な影響力が残っている限り、党を旧自民党的体質から脱却させるのは困難です。
 国民の審判を受ける参院選が迫っている今のタイミングは、これまでの政策を見直すまたとない機会でもあります。無意味なバラマキを改善し、財政を立て直す政策を示せば、支持を集められる可能性は十分にあります。しかし、小沢氏の影響力を気にしている限り、小沢氏の選挙目当ての政策を覆すのは非常に難しいはずで、政策面で不要なものを見直す行為の足かせにすらなります。そして、ここで政策見直しが上手く行えなければ、後に政策見直しを断行したくなったとしても、国民の負託もなしに政策を変更するか、解散に打って出るしかなくなるため、極めて選択肢が限られます。
 すなわち、菅氏は外からは期待を集められなくなりかねず、中からは小沢氏に脅かされ、最初から非常に苦しい立場に立たされているといえます。世論の後押しも限られてしまい、小沢氏と対立しようにもなかなか上手くいかないはずですし、かといって融和の姿勢を見せようものなら、即座に支持を失うのは間違いありません。
 ただ、民主党自体は決して能力が低い政党ではありませんので、小沢氏の勢力を上手く抑え込んだ上で、菅氏が積極的に能力のある若手を用い、大ナタを振るうことができるようにすれば、変化する可能性がないわけではありません。自民党にも第三党にも期待できない状況下では、それを望む以外にはありません。

 JPA 1.0では@OneToManyと@ManyToOneをセットで、あるいは@ManyToManyを両側に書かなくてはなりませんでしたが、JPA 2.0ではUnidirectionalの機能が導入されており、片側に書くだけでも動作させられるようになっています。この機能は初期のGlassFish v3 Previewでは使えませんでしたが、最近のGlassFishでは使えるようになっています。
 ひとまず簡単に使用してみました。
/com
 /yamicha
  /unidirect
   Category.java
   Content.java
   UnidirectAccess.java
   UnidirectServlet.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>
 通常の書き方とUnidirectの違いが出るのはここからです。Category.javaには@OneToManyと@JoinColumnの両方を書きます。
package com.yamicha.unidirect;

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

@Entity @Table(name="unidirect_category" , schema="yamicha")
	public class Category implements java.io.Serializable{
	private int id;
	private String name;
	private List<Content> contents;

	public Category(){
		contents = new ArrayList<Content>();
	}
	public Category(String s){
		this();
		name = s;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@OneToMany(fetch=FetchType.EAGER , cascade=CascadeType.ALL)
		@JoinColumn(name="category" , referencedColumnName="id")
		public List<Content> getContents(){
		return contents;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
	public void setContents(List<Content> c){
		contents = c;
	}
}
 ここで混乱しがちなのが@JoinColumnです。これはもともと@ManyToOneの側につけるものであるため、nameは「Content側が持つ、Categoryとのリレー用IDを格納する」カラム名、referencedColumnNameは「Category側が持つリレー用ID」となっています。うっかり逆に書くと大変です。
 Content.javaも普通のEntityですが、@ManyToOneをつけるべきプロパティ自体が不要である点が異なります。
package com.yamicha.unidirect;

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

@Entity @Table(name="unidirect_content" , schema="yamicha")
	public class Content implements java.io.Serializable{
	private int id;
	private String name;

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

	@Id @Column(name="id") @GeneratedValue public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
}
 Categoryを保持するプロパティは不要です。Many側からOne側にアクセスする必要がない場合、もしくはJAXBのように循環参照しているとまずい場合には効果を発揮しそうです。
 Many側がOne側を保持していない点を除けば、使い方は通常のものと全く同じです。
// UnidirectAccess.java
package com.yamicha.unidirect;

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

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

	public void regist(){
		Category c1 = new Category("資産");
		c1.getContents().add(new Content("現金"));
		c1.getContents().add(new Content("売掛金"));
		c1.getContents().add(new Content("社債発行差金"));

		Category c2 = new Category("負債");
		c2.getContents().add(new Content("未払金"));
		c2.getContents().add(new Content("当座借越"));

		Category c3 = new Category("収益");
		c3.getContents().add(new Content("売上"));
		c3.getContents().add(new Content("受取手数料"));

		em.persist(c1);
		em.persist(c2);
		em.persist(c3);
	}
	public List<Category> getCategories(){
		return em.createQuery("SELECT c FROM Category c" ,
			Category.class).getResultList();
	}
	public Category getCategory(Object id){
		return em.find(Category.class , id);
	}
}

// UnidirectServlet.java
package com.yamicha.unidirect;

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.List;
import java.util.ArrayList;

@WebServlet(name="unidirectservlet" , urlPatterns={"/*"})
	public class UnidirectServlet extends HttpServlet{
	@EJB(beanName="UnidirectAccess") private UnidirectAccess ua;

	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();

		ua.regist();

		List<Category> categories = ua.getCategories();
		for(Category category : categories){
			out.println(category.getName());
			for(Content c : category.getContents()){
				out.println("t" + c.getName());
			}
		}

		out.close();
	}
}
 JAXBと組み合わせれば@XmlTransientを書く必要もなくなるなど、様々な使い方ができそうです。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

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