Now with slightly better error handling.

This commit is contained in:
dchandler 2002-10-28 03:17:28 +00:00
parent 0ad135f8f1
commit 8433369d60
2 changed files with 400 additions and 398 deletions

View file

@ -1,391 +1,391 @@
/* /*
The contents of this file are subject to the THDL Open Community License The contents of this file are subject to the THDL Open Community License
Version 1.0 (the "License"); you may not use this file except in compliance Version 1.0 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License on the THDL web site with the License. You may obtain a copy of the License on the THDL web site
(http://www.thdl.org/). (http://www.thdl.org/).
Software distributed under the License is distributed on an "AS IS" basis, Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific terms governing rights and limitations under the License for the specific terms governing rights and limitations under the
License. License.
The Initial Developer of this software is the Tibetan and Himalayan Digital The Initial Developer of this software is the Tibetan and Himalayan Digital
Library (THDL). Portions created by the THDL are Copyright 2001 THDL. Library (THDL). Portions created by the THDL are Copyright 2001 THDL.
All Rights Reserved. All Rights Reserved.
Contributor(s): ______________________________________. Contributor(s): ______________________________________.
*/ */
package org.thdl.tib.text; package org.thdl.tib.text;
import java.util.*; import java.util.*;
import java.io.*; import java.io.*;
import java.lang.*; import java.lang.*;
import java.net.URL; import java.net.URL;
/** /**
* An alternate (non-Extended Wylie) keyboard input * An alternate (non-Extended Wylie) keyboard input
* method. A keyboard URL is passed to its constructor. This URL * method. A keyboard URL is passed to its constructor. This URL
* must follow a particular format, and include particular subparts. * must follow a particular format, and include particular subparts.
* For example, the keyboard URL must specify values for various * For example, the keyboard URL must specify values for various
* input parameters, as well as correspondences for the Wylie * input parameters, as well as correspondences for the Wylie
* characters this keyboard allows the user to input. For an example, * characters this keyboard allows the user to input. For an example,
* see the file 'sambhota_keyboard.ini' found in the same * see the file 'sambhota_keyboard.ini' found in the same
* directory as this class. * directory as this class.
* <p> * <p>
* It is normative practice for a null keyboard to be * It is normative practice for a null keyboard to be
* interpreted as the default Wylie keyboard. * interpreted as the default Wylie keyboard.
* A non-null keyboard defines a transformation of the default * A non-null keyboard defines a transformation of the default
* Wylie keyboard, setting new values for each Wylie value, as * Wylie keyboard, setting new values for each Wylie value, as
* well as (re-)defining various parameters. * well as (re-)defining various parameters.
* *
* @author Edward Garrett, Tibetan and Himalayan Digital Library * @author Edward Garrett, Tibetan and Himalayan Digital Library
* @version 1.0 * @version 1.0
*/ */
public class TibetanKeyboard { public class TibetanKeyboard {
private boolean hasDisambiguatingKey; private boolean hasDisambiguatingKey;
private char disambiguatingKey; private char disambiguatingKey;
private boolean hasSanskritStackingKey; private boolean hasSanskritStackingKey;
private boolean hasTibetanStackingKey; private boolean hasTibetanStackingKey;
private boolean isStackingMedial; private boolean isStackingMedial;
private char stackingKey; private char stackingKey;
private boolean isAChenRequiredBeforeVowel; private boolean isAChenRequiredBeforeVowel;
private boolean isAChungConsonant; private boolean isAChungConsonant;
private boolean hasAVowel; private boolean hasAVowel;
private Map charMap; private Map charMap;
private Map vowelMap; private Map vowelMap;
private Map puncMap; private Map puncMap;
private int command; private int command;
private final int NO_COMMAND = 0; private final int NO_COMMAND = 0;
private final int PARAMETERS = 1; private final int PARAMETERS = 1;
private final int CHARACTERS = 2; private final int CHARACTERS = 2;
private final int VOWELS = 3; private final int VOWELS = 3;
private final int PUNCTUATION = 4; private final int PUNCTUATION = 4;
/** /**
* A generic Exception to indicate an invalid keyboard. * A generic Exception to indicate an invalid keyboard.
*/ */
public class InvalidKeyboardException extends Exception { public class InvalidKeyboardException extends Exception {
} }
/** /**
* Opens the URL specified by the parameter, * Opens the URL specified by the parameter,
* and tries to construct a keyboard from it. If the file is * and tries to construct a keyboard from it. If the file is
* missing, or is invalid, an InvalidKeyboardException is * missing, or is invalid, an InvalidKeyboardException is
* thrown. * thrown.
* *
* @param url the URL of the keyboard * @param url the URL of the keyboard
* @throws InvalidKeyboardException a valid keyboard cannot be * @throws InvalidKeyboardException a valid keyboard cannot be
* constructed from this URL * constructed from this URL
*/ */
public TibetanKeyboard(URL url) throws InvalidKeyboardException { public TibetanKeyboard(URL url) throws InvalidKeyboardException {
try { try {
InputStreamReader isr = new InputStreamReader(url.openStream()); InputStreamReader isr = new InputStreamReader(url.openStream());
BufferedReader in = new BufferedReader(isr); BufferedReader in = new BufferedReader(isr);
System.out.println("reading "+url.toString()); System.out.println("reading "+url.toString());
String line; String line;
charMap = new HashMap(); charMap = new HashMap();
vowelMap = new HashMap(); vowelMap = new HashMap();
puncMap = new HashMap(); puncMap = new HashMap();
command = NO_COMMAND; command = NO_COMMAND;
boolean bool; boolean bool;
while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
if (line.startsWith("<?")) { //line is command if (line.startsWith("<?")) { //line is command
if (line.equalsIgnoreCase("<?parameters?>")) if (line.equalsIgnoreCase("<?parameters?>"))
command = PARAMETERS; command = PARAMETERS;
else if (line.equalsIgnoreCase("<?characters?>")) else if (line.equalsIgnoreCase("<?characters?>"))
command = CHARACTERS; command = CHARACTERS;
else if (line.equalsIgnoreCase("<?vowels?>")) else if (line.equalsIgnoreCase("<?vowels?>"))
command = VOWELS; command = VOWELS;
else if (line.equalsIgnoreCase("<?punctuation?>")) else if (line.equalsIgnoreCase("<?punctuation?>"))
command = PUNCTUATION; command = PUNCTUATION;
} }
else if (line.equals("")) //empty string else if (line.equals("")) //empty string
; ;
else { else {
StringTokenizer st = new StringTokenizer(line,"="); StringTokenizer st = new StringTokenizer(line,"=");
String left = null, right = null; String left = null, right = null;
if (st.hasMoreTokens()) if (st.hasMoreTokens())
left = st.nextToken(); left = st.nextToken();
if (st.hasMoreTokens()) if (st.hasMoreTokens())
right = st.nextToken(); right = st.nextToken();
switch (command) { switch (command) {
case NO_COMMAND: case NO_COMMAND:
break; break;
case PARAMETERS: case PARAMETERS:
if (left == null) if (left == null)
throw new InvalidKeyboardException(); throw new InvalidKeyboardException();
if (right == null) if (right == null)
break; break;
if (left.equals("stack key")) { if (left.equals("stack key")) {
stackingKey = right.charAt(0); stackingKey = right.charAt(0);
break; break;
} }
if (left.equals("disambiguating key")) { if (left.equals("disambiguating key")) {
disambiguatingKey = right.charAt(0); disambiguatingKey = right.charAt(0);
break; break;
} }
bool = new Boolean(right).booleanValue(); bool = new Boolean(right).booleanValue();
if (left.equalsIgnoreCase("has sanskrit stacking")) if (left.equalsIgnoreCase("has sanskrit stacking"))
hasSanskritStackingKey = bool; hasSanskritStackingKey = bool;
if (left.equalsIgnoreCase("has tibetan stacking")) if (left.equalsIgnoreCase("has tibetan stacking"))
hasTibetanStackingKey = bool; hasTibetanStackingKey = bool;
if (left.equalsIgnoreCase("is stacking medial")) if (left.equalsIgnoreCase("is stacking medial"))
isStackingMedial = bool; isStackingMedial = bool;
if (left.equalsIgnoreCase("has disambiguating key")) if (left.equalsIgnoreCase("has disambiguating key"))
hasDisambiguatingKey = bool; hasDisambiguatingKey = bool;
if (left.equalsIgnoreCase("needs achen before vowels")) if (left.equalsIgnoreCase("needs achen before vowels"))
isAChenRequiredBeforeVowel = bool; isAChenRequiredBeforeVowel = bool;
if (left.equalsIgnoreCase("has 'a' vowel")) if (left.equalsIgnoreCase("has 'a' vowel"))
hasAVowel = bool; hasAVowel = bool;
if (left.equalsIgnoreCase("is achung consonant")) if (left.equalsIgnoreCase("is achung consonant"))
isAChungConsonant = bool; isAChungConsonant = bool;
break; break;
case CHARACTERS: case CHARACTERS:
if (left == null) if (left == null)
throw new InvalidKeyboardException(); throw new InvalidKeyboardException();
if (right == null) if (right == null)
break; break;
charMap.put(right, left); charMap.put(right, left);
break; break;
case VOWELS: case VOWELS:
if (left == null) if (left == null)
throw new InvalidKeyboardException(); throw new InvalidKeyboardException();
if (right == null) if (right == null)
break; break;
vowelMap.put(right, left); vowelMap.put(right, left);
break; break;
case PUNCTUATION: case PUNCTUATION:
if (left == null) if (left == null)
throw new InvalidKeyboardException(); throw new InvalidKeyboardException();
if (right == null) if (right == null)
break; break;
puncMap.put(right, left); puncMap.put(right, left);
break; break;
} }
} }
} }
} }
catch (Exception e) { catch (Exception e) {
throw new InvalidKeyboardException(); throw new InvalidKeyboardException();
} }
} }
/** /**
* Does this keyboard have a disambiguating key? * Does this keyboard have a disambiguating key?
* @return true if this keyboard has a disambiguating key, e.g. * @return true if this keyboard has a disambiguating key, e.g.
* the period in Wylie 'g.y' vs. Wylie 'gy', false otherwise * the period in Wylie 'g.y' vs. Wylie 'gy', false otherwise
*/ */
public boolean hasDisambiguatingKey() { public boolean hasDisambiguatingKey() {
return hasDisambiguatingKey; return hasDisambiguatingKey;
} }
/** /**
* Gets the disambiguating key for this keyboard. * Gets the disambiguating key for this keyboard.
* @return the disambiguating key, assuming this keyboard has one * @return the disambiguating key, assuming this keyboard has one
*/ */
public char getDisambiguatingKey() { public char getDisambiguatingKey() {
return disambiguatingKey; return disambiguatingKey;
} }
/** /**
* Does this keyboard require a stacking key for Sanskrit stacks? * Does this keyboard require a stacking key for Sanskrit stacks?
* @return true if this keyboard requires a * @return true if this keyboard requires a
* stacking key for Sanskrit stacks * stacking key for Sanskrit stacks
*/ */
public boolean hasSanskritStackingKey() { public boolean hasSanskritStackingKey() {
return hasSanskritStackingKey; return hasSanskritStackingKey;
} }
/** /**
* Does this keyboard require a stacking key for Tibetan stacks? * Does this keyboard require a stacking key for Tibetan stacks?
* @return true if this keyboard requires a * @return true if this keyboard requires a
* stacking key for Tibetan stacks * stacking key for Tibetan stacks
*/ */
public boolean hasTibetanStackingKey() { public boolean hasTibetanStackingKey() {
return hasTibetanStackingKey; return hasTibetanStackingKey;
} }
/** /**
* Is stacking medial? * Is stacking medial?
* @return true if this keyboard has stacking, and * @return true if this keyboard has stacking, and
* if that stacking is medial rather than pre/post. * if that stacking is medial rather than pre/post.
* In other words, if you want a stack consisting * In other words, if you want a stack consisting
* of the (Wylie) characters 's', 'g', and 'r', and * of the (Wylie) characters 's', 'g', and 'r', and
* if the stack key is '+', then if you get the * if the stack key is '+', then if you get the
* stack by typing 's+g+r', then this method returns * stack by typing 's+g+r', then this method returns
* true. If you get it by typing '+sgr' or '+sgr+', * true. If you get it by typing '+sgr' or '+sgr+',
* then the method returns false. * then the method returns false.
*/ */
public boolean isStackingMedial() { public boolean isStackingMedial() {
return isStackingMedial; return isStackingMedial;
} }
/** /**
* Gets the stacking key. * Gets the stacking key.
* @return the stacking key, if there is one * @return the stacking key, if there is one
*/ */
public char getStackingKey() { public char getStackingKey() {
return stackingKey; return stackingKey;
} }
/** /**
* Must achen be typed first if you want achen plus a vowel? * Must achen be typed first if you want achen plus a vowel?
* @return true if it is necessary in this keyboard to * @return true if it is necessary in this keyboard to
* type achen plus a vowel to get achen plus a vowel, * type achen plus a vowel to get achen plus a vowel,
* or if you can (as in Wylie), simply type the vowel, * or if you can (as in Wylie), simply type the vowel,
* and then automatically get achen plus the vowel, * and then automatically get achen plus the vowel,
* assuming there is no preceding consonant. * assuming there is no preceding consonant.
*/ */
public boolean isAChenRequiredBeforeVowel() { public boolean isAChenRequiredBeforeVowel() {
return isAChenRequiredBeforeVowel; return isAChenRequiredBeforeVowel;
} }
/** /**
* Is achung treated as an ordinary consonant? * Is achung treated as an ordinary consonant?
* @return true if achung is counted as a consonant, * @return true if achung is counted as a consonant,
* and thus treated as stackable like any other * and thus treated as stackable like any other
* consonant; false if achung is treated as a vowel, * consonant; false if achung is treated as a vowel,
* as in Wylie. * as in Wylie.
*/ */
public boolean isAChungConsonant() { public boolean isAChungConsonant() {
return isAChungConsonant; return isAChungConsonant;
} }
/** /**
* Does the keyboard have a key for the invisible 'a' vowel? * Does the keyboard have a key for the invisible 'a' vowel?
* @return true if this keyboard has a keystroke * @return true if this keyboard has a keystroke
* sequence for the invisible Wylie vowel 'a', false * sequence for the invisible Wylie vowel 'a', false
* if there is no way to type this invisible vowel. * if there is no way to type this invisible vowel.
*/ */
public boolean hasAVowel() { public boolean hasAVowel() {
return hasAVowel; return hasAVowel;
} }
/** /**
* Decides whether or not a string is a character in this keyboard. * Decides whether or not a string is a character in this keyboard.
* @return true if the parameter is a character * @return true if the parameter is a character
* in this keyboard. This method checks to see * in this keyboard. This method checks to see
* if the passed string has been mapped to a * if the passed string has been mapped to a
* Wylie character - if not, then it returns false. * Wylie character - if not, then it returns false.
* *
* @param s the possible character * @param s the possible character
*/ */
public boolean isChar(String s) { public boolean isChar(String s) {
if (charMap.containsKey(s)) if (charMap.containsKey(s))
return true; return true;
else else
return false; return false;
} }
/** /**
* Gets the Extended Wylie corresponding to this character. * Gets the Extended Wylie corresponding to this character.
* @return the Wylie value corresponding to this * @return the Wylie value corresponding to this
* parameter, assuming it is in fact a character * parameter, assuming it is in fact a character
* in this keyboard; if not, returns null. * in this keyboard; if not, returns null.
* *
* @param the possible character * @param the possible character
*/ */
public String getWylieForChar(String s) { public String getWylieForChar(String s) {
if (!charMap.containsKey(s)) if (!charMap.containsKey(s))
return null; return null;
return (String)charMap.get(s); return (String)charMap.get(s);
} }
/** /**
* Decides whether or not a string is a punctuation mark in this keyboard? * Decides whether or not a string is a punctuation mark in this keyboard?
* @return true if the parameter is punctuation * @return true if the parameter is punctuation
* in this keyboard. This method checks to see if the * in this keyboard. This method checks to see if the
* passed string has been mapped to Wylie punctuation - * passed string has been mapped to Wylie punctuation -
* if not, then it returns false. * if not, then it returns false.
* *
* @param s the possible punctuation * @param s the possible punctuation
*/ */
public boolean isPunc(String s) { public boolean isPunc(String s) {
if (puncMap.containsKey(s)) if (puncMap.containsKey(s))
return true; return true;
else else
return false; return false;
} }
/** /**
* Gets the Extended Wylie corresponding to this punctuation. * Gets the Extended Wylie corresponding to this punctuation.
* @return the Wylie value corresponding to this * @return the Wylie value corresponding to this
* parameter, assuming it is in fact punctuation * parameter, assuming it is in fact punctuation
* in this keyboard; if not, returns null. * in this keyboard; if not, returns null.
* *
* @param s the possible punctuation * @param s the possible punctuation
*/ */
public String getWylieForPunc(String s) { public String getWylieForPunc(String s) {
if (!puncMap.containsKey(s)) if (!puncMap.containsKey(s))
return null; return null;
return (String)puncMap.get(s); return (String)puncMap.get(s);
} }
/** /**
* Decides whether or not the string is a vowel in this keyboard. * Decides whether or not the string is a vowel in this keyboard.
* @return true if the parameter is a vowel * @return true if the parameter is a vowel
* in this keyboard. This method checks to see if the * in this keyboard. This method checks to see if the
* passed string has been mapped to a Wylie vowel - * passed string has been mapped to a Wylie vowel -
* if not, then it returns false. * if not, then it returns false.
* *
* @param s the possible vowel * @param s the possible vowel
*/ */
public boolean isVowel(String s) { public boolean isVowel(String s) {
if (vowelMap.containsKey(s)) if (vowelMap.containsKey(s))
return true; return true;
else else
return false; return false;
} }
/** /**
* Gets the Extended Wylie corresponding to this vowel. * Gets the Extended Wylie corresponding to this vowel.
* @return the Wylie value corresponding to this * @return the Wylie value corresponding to this
* parameter, assuming it is in fact a vowel * parameter, assuming it is in fact a vowel
* in this keyboard; if not, returns null. * in this keyboard; if not, returns null.
* *
* @param the possible vowel * @param the possible vowel
*/ */
public String getWylieForVowel(String s) { public String getWylieForVowel(String s) {
if (!vowelMap.containsKey(s)) if (!vowelMap.containsKey(s))
return null; return null;
return (String)vowelMap.get(s); return (String)vowelMap.get(s);
} }
} }

View file

@ -27,6 +27,8 @@ import java.awt.event.KeyEvent;
import javax.swing.text.*; import javax.swing.text.*;
import java.awt.font.*; import java.awt.font.*;
import org.thdl.util.ThdlDebug;
/** /**
* Interfaces between Extended Wylie and the TibetanMachineWeb fonts. * Interfaces between Extended Wylie and the TibetanMachineWeb fonts.
* To do this this must first read the code table, which lives in "tibwn.ini", * To do this this must first read the code table, which lives in "tibwn.ini",
@ -231,11 +233,12 @@ public class TibetanMachineWeb {
URL keyboard_url = TibetanMachineWeb.class.getResource(DEFAULT_KEYBOARD); URL keyboard_url = TibetanMachineWeb.class.getResource(DEFAULT_KEYBOARD);
if (null != keyboard_url) { if (null != keyboard_url) {
try { try {
TibetanKeyboard kb = new TibetanKeyboard(keyboard_url); TibetanKeyboard kb = new TibetanKeyboard(keyboard_url);
setKeyboard(kb); setKeyboard(kb); // this can't throw the InvalidKeyboardException
} }
catch (TibetanKeyboard.InvalidKeyboardException ike) { catch (TibetanKeyboard.InvalidKeyboardException ike) {
System.out.println("invalid keyboard file or file not found"); System.out.println("invalid keyboard file or file not found: " + keyboard_url.toString());
ThdlDebug.noteIffyCode();
setKeyboard(keyboard); setKeyboard(keyboard);
} }
} }
@ -473,17 +476,16 @@ public static boolean setKeyboard(TibetanKeyboard kb) {
* if there was an error * if there was an error
*/ */
public static boolean setKeyboard(URL url) { public static boolean setKeyboard(URL url) {
TibetanKeyboard kb;
try { try {
kb = new TibetanKeyboard(url); TibetanKeyboard kb = new TibetanKeyboard(url);
if (setKeyboard(kb)) if (setKeyboard(kb))
return true; return true;
else else
return false; return false;
} }
catch (TibetanKeyboard.InvalidKeyboardException ike) { catch (TibetanKeyboard.InvalidKeyboardException ike) {
System.out.println("can't create this keyboard"); System.out.println("can't create the keyboard associated with " + url);
ThdlDebug.noteIffyCode();
return false; return false;
} }
} }