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   inStr 半角カタカナ文字列
059         *
060         * @return  全角文字列
061         * @og.rtnNotNull
062         */
063        public static String han2zen( final String inStr ) {
064                int ixIn  = 0;
065                int ixOut = 0;
066                final int len = inStr.length();
067                final char[] input = inStr.toCharArray();
068                char[] output = new char[len + 1];
069
070                while( ixIn < len ) {
071                        // 半角カタカナの範囲
072                        if( input[ixIn] >= '\uFF61' && input[ixIn] <= '\uFF9F' ) {
073                                if( ixIn + 1 >= len ) {
074                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
075                                }
076                                else {
077                                        // 濁点(ヴ)
078                                        if( input[ixIn+1] == '゙' ||
079                                                        input[ixIn+1] == '\u3099' ||
080                                                        input[ixIn+1] == '゛' ) {
081                                                if( input[ixIn] == 'ウ' ) {
082                                                        output[ixOut++] = 'ヴ' ;
083                                                        ixIn +=2 ;
084                                                }
085                                                else {
086                                                        // 濁点(ガ~ド、バ~ボ)
087                                                        if( input[ixIn] >= 'カ' &&
088                                                                        input[ixIn] <= 'ト' ||
089                                                                        input[ixIn] >= 'ハ' &&
090                                                                        input[ixIn] <= 'ホ' ) {
091                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
092                                                                output[ixOut++]++;
093                                                                ixIn +=2 ;
094                                                        }
095                                                        else {
096                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
097                                                        }
098                                                }
099                                        }
100                                        else {
101                                                // 半濁点(パ~ポ)
102                                                if( input[ixIn+1] == '゚' ||
103                                                                input[ixIn+1] == '\u309A' ||
104                                                                input[ixIn+1] == '゜' ) {
105                                                        if( input[ixIn] >= 'ハ' &&
106                                                                        input[ixIn] <= 'ホ' ) {
107                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
108                                                                output[ixOut++]+=2;
109                                                                ixIn +=2 ;
110                                                        }
111                                                        else {
112                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
113                                                        }
114                                                }
115                                                else {
116                                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
117                                                }
118                                        }
119                                }
120                        }
121                        else {
122                                output[ixOut++] = input[ixIn++];
123                        }
124                }
125                return new String( output,0,ixOut );                    // 6.1.1.0 (2015/01/17) refactoring
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}