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

View file

@ -27,6 +27,8 @@ import java.awt.event.KeyEvent;
import javax.swing.text.*;
import java.awt.font.*;
import org.thdl.util.ThdlDebug;
/**
* Interfaces between Extended Wylie and the TibetanMachineWeb fonts.
* 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);
if (null != keyboard_url) {
try {
TibetanKeyboard kb = new TibetanKeyboard(keyboard_url);
setKeyboard(kb);
TibetanKeyboard kb = new TibetanKeyboard(keyboard_url);
setKeyboard(kb); // this can't throw the InvalidKeyboardException
}
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);
}
}
@ -473,17 +476,16 @@ public static boolean setKeyboard(TibetanKeyboard kb) {
* if there was an error
*/
public static boolean setKeyboard(URL url) {
TibetanKeyboard kb;
try {
kb = new TibetanKeyboard(url);
TibetanKeyboard kb = new TibetanKeyboard(url);
if (setKeyboard(kb))
return true;
else
return false;
}
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;
}
}