Java tutorial
/* org.manalith.ircbot.plugin.keyseqconv/DubeolAutomataEngine.java ManalithBot - An open source IRC bot based on the PircBot Framework. Copyright (C) 2012 Seong-ho, Cho <darkcircle.0426@gmail.com> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.manalith.ircbot.plugin.keyseqconv; import java.text.ParseException; import java.util.IllegalFormatException; import org.apache.commons.lang3.CharUtils; import org.apache.commons.lang3.StringUtils; import org.manalith.ircbot.plugin.keyseqconv.symboltable.DubeolSymbol; public class DubeolAutomataEngine implements IAutomataEngine { private enum LetterState { Null, IConsonant, Vowel, FConsonant, Finish } private boolean enableParseExceptionSyntax; public DubeolAutomataEngine() { } @Override public void setEnableParsingExceptionSyntax(boolean enable) { enableParseExceptionSyntax = enable; } @Override public boolean isEnableParsingExceptionSyntax() { return enableParseExceptionSyntax; } @Override public boolean isISingleConsonant(String tICon) { try { @SuppressWarnings("unused") DubeolSymbol.DubeolISingleConsonant check1 = DubeolSymbol.DubeolISingleConsonant.valueOf(tICon); // dummy alloc. return true; } catch (Exception e) // if checked character is abnormal { return false; } } @Override public boolean isIDoubleConsonant(String tICon) { try { @SuppressWarnings("unused") DubeolSymbol.DubeolIDoubleConsonant check1 = DubeolSymbol.DubeolIDoubleConsonant.valueOf(tICon); // dummy alloc. return true; } catch (Exception e) // if checked character is abnormal { return false; } } @Override public boolean isVowel(String tVow) { try { @SuppressWarnings("unused") DubeolSymbol.DubeolVowel check1 = DubeolSymbol.DubeolVowel.valueOf(tVow); // dummy alloc. return true; } catch (Exception e) // if checked character is abnormal { return false; } } @Override public boolean isFConsonant(String tFCon) { try { @SuppressWarnings("unused") DubeolSymbol.DubeolFConsonant check1 = DubeolSymbol.DubeolFConsonant.valueOf(tFCon); // dummy alloc. return true; } catch (Exception e) // if checked character is abnormal { return false; } } @Override public String parseKoreanStringToEngSpell(String korean) throws IllegalFormatException { String result = ""; for (int i = 0; i < korean.length(); i++) { int ch = korean.charAt(i); if (((char) ch) >= '' && ((char) ch) <= '') { ch -= 0xAC00; int initialConsonant = ch / (21 * 28); ch %= (21 * 28); int Vowel = ch / 28; ch %= 28; int finalConsonant = ch; result += DubeolSymbol.DubeolIConsonant.values()[initialConsonant + 1] .toString() + DubeolSymbol.DubeolVowel.values()[Vowel + 1] .toString(); if (finalConsonant != 0) result += DubeolSymbol.DubeolFConsonant.values()[finalConsonant]; } else if (ch >= '' && ch <= '') { ch -= 0x3130; result += DubeolSymbol.DubeolSingleLetter.values()[ch - 1]; } else { result += (char) ch; } } return result; } @Override public String parseKeySequenceToKorean(String keySequence) throws ParseException, IllegalArgumentException { String result = ""; LetterState stateFlag = LetterState.Null; String tICon = ""; String tIConLookahead = ""; String tIConLookaheadCombination = ""; String tVow = ""; String tVowLookahead = ""; String tVowLookaheadCombination = ""; String tFCon = ""; String tFConLookahead = ""; String tFConLookaheadCombination = ""; LetterObject syl = new LetterObject(KeyboardLayout.Dubeol); if (isEnableParsingExceptionSyntax() && StringUtils.countMatches(keySequence, "\\") % 2 == 1) throw new ParseException("Back slashes do not match", keySequence.lastIndexOf("\\", 0)); for (int i = 0; i < keySequence.length(); i++) { if (stateFlag.equals(LetterState.Null) || stateFlag.equals(LetterState.Finish)) { stateFlag = LetterState.IConsonant; } if (!CharUtils.isAsciiAlpha(keySequence.charAt(i))) { if (keySequence.charAt(i) == '\\' && isEnableParsingExceptionSyntax()) { if (i < keySequence.length() - 1) if (keySequence.charAt(i + 1) == '\\') { result += "\\"; continue; } i++; while (true) { if (i + 1 <= keySequence.length() - 1) { if (keySequence.charAt(i) == '\\') { if (keySequence.charAt(i + 1) == '\\') { i++; result += '\\'; } else break; } else { result += keySequence.charAt(i); } } else { if (keySequence.charAt(i) == '\\') { break; } else { result += keySequence.charAt(i); } } i++; } } else { result += keySequence.charAt(i); } continue; } // (??, ???) if (stateFlag.equals(LetterState.IConsonant)) { // ? tIConLookahead = tIConLookaheadCombination = ""; // ?? ? ? ? ? tICon = hasTwoSymbolinOneKey(keySequence.charAt(i)) ? Character.toString(keySequence.charAt(i)) : Character.toString(keySequence.charAt(i)).toLowerCase(); // ? ? if (i < keySequence.length() - 1) { // ?? ? ? ? ? tIConLookahead = hasTwoSymbolinOneKey(keySequence.charAt(i + 1)) ? Character.toString(keySequence.charAt(i + 1)) : Character.toString(keySequence.charAt(i + 1)).toLowerCase(); tIConLookaheadCombination = tICon + tIConLookahead; } // ??? ??? ?, ? ?. // ( , ? ) if (isFConsonant(tIConLookaheadCombination)) { // 2 step - lookahead try if (i + 2 <= keySequence.length() - 1) { String lookOverTwoStep = hasTwoSymbolinOneKey(keySequence.charAt(i + 2)) ? Character.toString(keySequence.charAt(i + 2)) : Character.toString(keySequence.charAt(i + 2)).toLowerCase(); // ?? ? , ?? ? ?, , ? if (isISingleConsonant(lookOverTwoStep) || isIDoubleConsonant(lookOverTwoStep) || !CharUtils.isAsciiAlpha(lookOverTwoStep.charAt(0))) { result += getSingleChar(getSingleCharVal(tIConLookaheadCombination)); i++; } // ?? ? ? else if (isVowel(lookOverTwoStep)) { // ??? ? ? result += getSingleChar(getSingleCharVal(tICon)); continue; } } // ? ? () ?? ? else { result += getSingleChar(getSingleCharVal(tIConLookaheadCombination)); stateFlag = LetterState.Null; break; } } // ???, ??? ( () ?? ) else { // ??? ? ? if (isISingleConsonant(tICon) || isIDoubleConsonant(tICon)) { syl.setIConsonant(tICon); // init = DubeolSymbol.DubeolIConsonant.valueOf(tICon); } // ?? ??? ? ? else if (isVowel(tICon)) { stateFlag = LetterState.Vowel; i--; continue; } // ? ? ? ?? ? if (i == keySequence.length() - 1) { result += getSingleChar(getSingleCharVal(tICon)); syl.initLetter(); stateFlag = LetterState.Null; break; } // ??? ? ? ?? ?? ? ? if (isVowel(tIConLookahead)) { stateFlag = LetterState.Vowel; continue; } // ??? ? else { result += getSingleChar(getSingleCharVal(tICon)); syl.initLetter(); } } } // (?) else if (stateFlag.equals(LetterState.Vowel)) { // ? tVowLookahead = tVowLookaheadCombination = ""; // ?? ? ? ? ? tVow = hasTwoSymbolinOneKey(keySequence.charAt(i)) ? Character.toString(keySequence.charAt(i)) : Character.toString(keySequence.charAt(i)).toLowerCase(); // ? ? if (i < keySequence.length() - 1) { // ?? ? ? ? ? tVowLookahead = hasTwoSymbolinOneKey(keySequence.charAt(i + 1)) ? Character.toString(keySequence.charAt(i + 1)) : Character.toString(keySequence.charAt(i + 1)).toLowerCase(); tVowLookaheadCombination = tVow + tVowLookahead; } // ?? ? if (isVowel(tVowLookaheadCombination)) { syl.setVowel(tVowLookaheadCombination); // vow = // DubeolSymbol.DubeolVowel.valueOf(tVowLookaheadCombination); // 2 step - lookahead try if (i + 2 <= keySequence.length() - 1) { // ?? ? ? ? ? String lookOverTwoStep = hasTwoSymbolinOneKey(keySequence.charAt(i + 2)) ? Character.toString(keySequence.charAt(i + 2)) : Character.toString(keySequence.charAt(i + 2)).toLowerCase(); i++; // ?? ?? ? ? ? , ? ?? ??? . // ?? ??? ? ? ? ? if (isVowel(lookOverTwoStep) || ((isISingleConsonant(lookOverTwoStep) || isIDoubleConsonant(lookOverTwoStep)) && !isFConsonant(lookOverTwoStep))) { stateFlag = LetterState.Finish; } // ?? ? ? ? ? , ex: else if (isFConsonant(lookOverTwoStep)) { if (!syl.isCompleteSyllable()) { result += getSingleChar(getSingleCharVal(tVowLookaheadCombination)); stateFlag = LetterState.Null; } else { stateFlag = LetterState.FConsonant; continue; } } // ? ? else if (!CharUtils.isAsciiAlpha(lookOverTwoStep.charAt(0))) { if (!syl.isCompleteSyllable()) { result += getSingleChar(getSingleCharVal(tVowLookaheadCombination)); syl.initLetter(); stateFlag = LetterState.Null; } else stateFlag = LetterState.Finish; } } // ? ? ? ? (? ) else { // ??? ? ? ? if (!syl.isCompleteSyllable()) { result += getSingleChar(getSingleCharVal(tVowLookaheadCombination)); syl.initLetter(); i++; stateFlag = LetterState.Null; } else { stateFlag = LetterState.Finish; } // ?? ? ? if (i == keySequence.length() - 1) break; } } // ?? , ? ? else { // ?? if (isVowel(tVow)) { // ?? ? . if (!syl.isCompleteSyllable()) syl.setVowel(tVow); // ? ?? if (i == keySequence.length() - 1) { // ??? ? ? if (!syl.isCompleteSyllable()) { result += getSingleChar(getSingleCharVal(tVow)); syl.initLetter(); stateFlag = LetterState.Null; } // ??? ? ? else { stateFlag = LetterState.Finish; } break; } // 2? ? ??? ?? // ?? ? ? ? delimiter // ? , ?, ? ? . if (!CharUtils.isAsciiAlpha(tVowLookahead.charAt(0))) { // ? ? ? . if (!syl.isCompleteSyllable()) { result += getSingleChar(getSingleCharVal(tVow)); syl.initLetter(); stateFlag = LetterState.IConsonant; continue; } else stateFlag = LetterState.Finish; } // *// ? ? ?. ? // ??? ? ? if (!syl.isCompleteSyllable()) { // ? ? result += getSingleChar(getSingleCharVal(tVow)); syl.initLetter(); // ?? ??? ?? if (isISingleConsonant(tVowLookahead) || isIDoubleConsonant(tVowLookahead)) stateFlag = LetterState.IConsonant; // ?? ? else if (isVowel(tVowLookahead)) stateFlag = LetterState.Vowel; continue; } else { // ?? + ? + : good! if (isFConsonant(tVowLookahead)) stateFlag = LetterState.FConsonant; // ??? ?? ? ? ? , : // ? ??? ? . else stateFlag = LetterState.Finish; } } } } // else if (stateFlag.equals(LetterState.FConsonant)) { // ? tFConLookahead = tFConLookaheadCombination = ""; // ?? ? ? ? ? tFCon = hasTwoSymbolinOneKey(keySequence.charAt(i)) ? Character.toString(keySequence.charAt(i)) : Character.toString(keySequence.charAt(i)).toLowerCase(); // ? ? if (i < keySequence.length() - 1) { tFConLookahead = hasTwoSymbolinOneKey(keySequence.charAt(i + 1)) ? Character.toString(keySequence.charAt(i + 1)) : Character.toString(keySequence.charAt(i + 1)).toLowerCase(); tFConLookaheadCombination = tFCon + tFConLookahead; } stateFlag = LetterState.Finish; // ? ? ? ??. // ???? if (isFConsonant(tFConLookaheadCombination)) { // 2 step - lookahead try if (i + 2 <= keySequence.length() - 1) { String lookOverTwoStep = hasTwoSymbolinOneKey(keySequence.charAt(i)) ? Character.toString(keySequence.charAt(i + 2)) : Character.toString(keySequence.charAt(i + 2)).toLowerCase(); // () ??? ??? ? if (isISingleConsonant(lookOverTwoStep) || isIDoubleConsonant(lookOverTwoStep) || !CharUtils.isAsciiAlpha(lookOverTwoStep.charAt(0))) { // ? ? . ??? syl.setFConsonant(tFConLookaheadCombination); i++; // ?? ? ? . , ?? + ? } else if (isVowel(lookOverTwoStep)) syl.setFConsonant(tFCon); } else { // ? ?? ?? ? ??. if (isFConsonant(tFConLookaheadCombination)) { syl.setFConsonant(tFConLookaheadCombination); } break; } } else { // ?? ? ??? ? ? . if (isFConsonant(tFCon)) syl.setFConsonant(tFCon); // ? ???? ??. if (i == keySequence.length() - 1) break; // ? ? ?? backtracking. // ? ? if (isVowel(tFConLookahead)) { syl.setFConsonant("nul"); stateFlag = LetterState.Finish; i--; } } } // ? ? ? ? ?? if (stateFlag == LetterState.Finish) { result += syl.getLetter(); syl.initLetter(); } } // . if (stateFlag == LetterState.Finish) result += syl.getLetter(); return result; } private boolean hasTwoSymbolinOneKey(char ch) { return (ch == 'q' || ch == 'Q') || (ch == 'w' || ch == 'W') || (ch == 'e' || ch == 'E') || (ch == 'r' || ch == 'R') || (ch == 't' || ch == 'T') || ((ch == 'o' || ch == 'O') || (ch == 'p' || ch == 'P')); } @Override public int getSingleCharVal(String keySequence) { return DubeolSymbol.DubeolSingleLetter.valueOf(keySequence).value(); } @Override public String getSingleChar(int charVal) { char[] ch = new char[1]; // single char value starts from 0x3130 ch[0] = (char) (charVal + 0x3130); return new String(ch); } }