001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.fukurou.util;
017
018/**
019 * KanaFilter.java は、半角カタカナを全角カタカナに変換するフィルターツールです。
020 *
021 * 大元の出典は、『CJKV日中韓越情報処理』のフィルターアルゴリズムです。
022 * 濁点や半濁点の正しい処理も含まれています。
023 *
024 * @version  4.0
025 * @author   Kazuhiko Hasegawa
026 * @since    JDK5.0,
027 */
028public final class KanaFilter {
029
030        // uFF61 から uFF9Fまでの半角カナに対応(u3002 ~ u309C)
031        private static final char ZEN_KANA[] = {
032                '。','「','」','、','・',
033                'ヲ','ァ','ィ','ゥ','ェ','ォ',
034                'ャ','ュ','ョ','ッ','ー',
035                'ア','イ','ウ','エ','オ',
036                'カ','キ','ク','ケ','コ',
037                'サ','シ','ス','セ','ソ',
038                'タ','チ','ツ','テ','ト',
039                'ナ','ニ','ヌ','ネ','ノ',
040                'ハ','ヒ','フ','ヘ','ホ',
041                'マ','ミ','ム','メ','モ',
042                'ヤ','ユ','ヨ',
043                'ラ','リ','ル','レ','ロ',
044                'ワ','ン','゛','゜'
045        };
046
047        /**
048         * すべてが staticメソッドなので、コンストラクタを呼び出さなくしておきます。
049         *
050         */
051        private KanaFilter() {}
052
053        /**
054         * 半角カタカナを全角カタカナに
055         *
056         * 半角カタカナの定義は、\uFF61 から \uFF9F までです。
057         *
058         * @param   in 半角カタカナ文字列
059         *
060         * @return  全角文字列
061         */
062        public static String han2zen( final String in ) {
063                int ixIn  = 0;
064                int ixOut = 0;
065                int len = in.length();
066                char[] input = in.toCharArray();
067                char[] output = new char[len + 1];
068
069                while( ixIn < len ) {
070                        // 半角カタカナの範囲
071                        if( input[ixIn] >= '\uFF61' && input[ixIn] <= '\uFF9F' ) {
072                                if( ixIn + 1 >= len ) {
073                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
074                                }
075                                else {
076                                        // 濁点(ヴ)
077                                        if( input[ixIn+1] == '゙' ||
078                                                        input[ixIn+1] == '\u3099' ||
079                                                        input[ixIn+1] == '゛' ) {
080                                                if( input[ixIn] == 'ウ' ) {
081                                                        output[ixOut++] = 'ヴ' ;
082                                                        ixIn +=2 ;
083                                                }
084                                                else {
085                                                        // 濁点(ガ~ド、バ~ボ)
086                                                        if( input[ixIn] >= 'カ' &&
087                                                                        input[ixIn] <= 'ト' ||
088                                                                        input[ixIn] >= 'ハ' &&
089                                                                        input[ixIn] <= 'ホ' ) {
090                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
091                                                                output[ixOut++]++;
092                                                                ixIn +=2 ;
093                                                        }
094                                                        else {
095                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
096                                                        }
097                                                }
098                                        }
099                                        else {
100                                                // 半濁点(パ~ポ)
101                                                if( input[ixIn+1] == '゚' ||
102                                                                input[ixIn+1] == '\u309A' ||
103                                                                input[ixIn+1] == '゜' ) {
104                                                        if( input[ixIn] >= 'ハ' &&
105                                                                        input[ixIn] <= 'ホ' ) {
106                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
107                                                                output[ixOut++]+=2;
108                                                                ixIn +=2 ;
109                                                        }
110                                                        else {
111                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
112                                                        }
113                                                }
114                                                else {
115                                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
116                                                }
117                                        }
118                                }
119                        }
120                        else {
121                                output[ixOut++] = input[ixIn++];
122                        }
123                }
124                String output_string = new String( output );
125                return output_string.substring(0,ixOut);
126        }
127
128        /**
129         * テスト用 mainメソッド
130         *
131         * @param       args    変換元文字列
132         */
133        public static void main( final String[] args ) {
134                System.out.println( KanaFilter.han2zen( args[0] ) );
135        }
136
137}