[jsword-svn] r1647 - in trunk: biblemapper/src/main/java/org/crosswire/biblemapper/swing common/src/main/java/org/crosswire/common/icu common-swing/src/main/java/org/crosswire/common/swing jsword/src/main/java/org/crosswire/jsword/book jsword/src/main/java/org/crosswire/jsword/book/install/sword jsword/src/main/java/org/crosswire/jsword/passage jsword-limbo/src/main/java/org/crosswire/jsword/book/install/sword
dmsmith at www.crosswire.org
dmsmith at www.crosswire.org
Sun Aug 5 18:35:25 MST 2007
Author: dmsmith
Date: 2007-08-05 18:35:25 -0700 (Sun, 05 Aug 2007)
New Revision: 1647
Modified:
trunk/biblemapper/src/main/java/org/crosswire/biblemapper/swing/BookChooser.java
trunk/common-swing/src/main/java/org/crosswire/common/swing/Msg_fa.properties
trunk/common/src/main/java/org/crosswire/common/icu/NumberShaper.java
trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/install/sword/FTPMsg.properties
trunk/jsword/src/main/java/org/crosswire/jsword/book/Books.java
trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/Msg.properties
trunk/jsword/src/main/java/org/crosswire/jsword/passage/VerseRangeFactory.java
Log:
Fixed spelling in documentation.
Added a method to determine the longest string length of a property in a filtered list of books.
Added a partial fix to the display of chapter:verse in Farsi.
Modified: trunk/biblemapper/src/main/java/org/crosswire/biblemapper/swing/BookChooser.java
===================================================================
--- trunk/biblemapper/src/main/java/org/crosswire/biblemapper/swing/BookChooser.java 2007-08-06 01:12:14 UTC (rev 1646)
+++ trunk/biblemapper/src/main/java/org/crosswire/biblemapper/swing/BookChooser.java 2007-08-06 01:35:25 UTC (rev 1647)
@@ -223,7 +223,7 @@
public static final int APPROVE_OPTION = 0;
/**
- * Return value if an error occured
+ * Return value if an error occurred
*/
public static final int ERROR_OPTION = -1;
Modified: trunk/common/src/main/java/org/crosswire/common/icu/NumberShaper.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/icu/NumberShaper.java 2007-08-06 01:12:14 UTC (rev 1646)
+++ trunk/common/src/main/java/org/crosswire/common/icu/NumberShaper.java 2007-08-06 01:35:25 UTC (rev 1647)
@@ -22,11 +22,8 @@
package org.crosswire.common.icu;
-import java.awt.font.NumericShaper;
import java.util.Locale;
-import org.crosswire.common.util.ReflectionUtil;
-
/**
* NumberShaper changes numbers from one number system to another.
* That is, the numbers 0-9 have different representations in some
@@ -37,6 +34,14 @@
* they should show as a user wishes. Further user input may, optionally,
* use the external form.
* </p>
+ * <p>
+ * This shaper has special behavior for Arabic numbers that are in the form "12:34"
+ * as this is taken as chapter:verse. Normally, a ':' is treated as a numeric
+ * separator, this results in "12:34", but for verses it should be "34:12".
+ * That is, Arabic, numbers are left-to-right (even though the rest of the language
+ * is right-to-left) and the ':' as a numeric separator does not change that.
+ * So to get around this we mark the ':' as a right-to-left character.
+ * </p>
* @see java.awt.font.NumericShaper
* @see com.ibm.icu.text.ArabicShaping
* @see gnu.lgpl.License for license details.<br>
@@ -62,46 +67,6 @@
{
this.locale = locale;
this.nineShape = '\u0000';
-
- if (locale.getLanguage().equals("fa")) //$NON-NLS-1$
- {
- try
- {
- Class[] classTypes = { int.class };
- Object[] shape = { new Integer(ICU_DIGIT_TYPE_AN_EXTENDED | ICU_DIGITS_EN2AN) };
- Object[] unshape = { new Integer(ICU_DIGIT_TYPE_AN_EXTENDED | ICU_DIGITS_AN2EN) };
- arabicShaper = ReflectionUtil.construct("com.ibm.icu.text.ArabicShaping", shape, classTypes); //$NON-NLS-1$
- unArabicShaper = ReflectionUtil.construct("com.ibm.icu.text.ArabicShaping", unshape, classTypes); //$NON-NLS-1$
- }
- catch (Exception e)
- {
- // This is OK. The jar is not on the classpath
- }
- if (arabicShaper == null)
- {
- numericShaper = NumericShaper.getShaper(NumericShaper.EASTERN_ARABIC);
- }
- }
-
- if (locale.getLanguage().equals("ar")) //$NON-NLS-1$
- {
- try
- {
- Class[] classTypes = { int.class };
- Object[] shape = { new Integer(ICU_DIGIT_TYPE_AN | ICU_DIGITS_EN2AN) };
- Object[] unshape = { new Integer(ICU_DIGIT_TYPE_AN | ICU_DIGITS_AN2EN) };
- arabicShaper = ReflectionUtil.construct("com.ibm.icu.text.ArabicShaping", shape, classTypes); //$NON-NLS-1$
- unArabicShaper = ReflectionUtil.construct("com.ibm.icu.text.ArabicShaping", unshape, classTypes); //$NON-NLS-1$
- }
- catch (Exception e)
- {
- // This is OK. The jar is not on the classpath
- }
- if (arabicShaper == null)
- {
- numericShaper = NumericShaper.getShaper(NumericShaper.EASTERN_ARABIC);
- }
- }
}
/**
@@ -111,7 +76,8 @@
*/
public boolean canShape()
{
- return arabicShaper != null || numericShaper != null || getNine() != '9';
+ //return arabicShaper != null || numericShaper != null || getNine() != '9';
+ return getNine() != '9';
}
/**
@@ -127,30 +93,13 @@
return input;
}
- if (arabicShaper != null)
- {
- Object[] params = { input };
- try
- {
- return (String) ReflectionUtil.invoke(arabicShaper, "shape", params); //$NON-NLS-1$
- }
- catch (Exception e)
- {
- // do nothing as it is OK for jar to not be present.
- }
- }
-
- if (numericShaper != null)
- {
- char[] src = input.toCharArray();
- numericShaper.shape(src, 0, src.length);
- return new String(src);
- }
-
char[] src = input.toCharArray();
- if (shape(src, 0, src.length))
+ boolean[] transformed = new boolean[1];
+ transformed[0] = false;
+ char[] dest = shaped(src, transformed);
+ if (transformed[0])
{
- return new String(src);
+ return new String(dest);
}
return input;
@@ -174,82 +123,178 @@
*/
public String unshape(String input)
{
- if (unArabicShaper != null)
- {
- Object[] params = { input };
- try
- {
- return (String) ReflectionUtil.invoke(unArabicShaper, "shape", params); //$NON-NLS-1$
- }
- catch (Exception e)
- {
- // do nothing as it is OK for jar to not be present.
- }
- }
-
char[] src = input.toCharArray();
- if (unshape(src, 0, src.length))
+ boolean[] transformed = new boolean[1];
+ transformed[0] = false;
+ char[] dest = unshaped(src, transformed);
+ if (transformed[0])
{
- return new String(src);
+ return new String(dest);
}
return input;
}
/**
- * Perform shaping from 0-9 into target script.
+ * Perform shaping back to 0-9.
*/
- private boolean shape(char[] src, int start, int count)
+ private char[] unshaped(char[] src, boolean[] transformed)
{
- char nine = getNine();
+ int nine = getNine();
if (nine == '9')
{
- return false;
+ return src;
}
- return transform(src, start, count, '0', '9', nine - '9');
+ int zero = nine - 9;
+ return transform(src, zero, nine, '9' - nine, transformed);
}
/**
- * Perform shaping back to 0-9.
+ * @param src
+ * @param transformed
+ * @return
*/
- private boolean unshape(char[] src, int start, int count)
+ private char[] shaped(char[] src, boolean[] transformed)
{
- int nine = getNine();
+ char nine = getNine();
if (nine == '9')
{
- return false;
+ return src;
}
- int zero = nine - 9;
- return transform(src, start, count, zero, nine, '9' - nine);
+ return transform(src, '0', '9', nine - '9', transformed);
}
/**
- * Transform in place either to or from 0-9 and the script representation, returning true when at least one character is transformed.
+ * Transform either to or from 0-9 and the script representation, returning the result and true when at least one character is transformed.
*
* @param src the text to transform
- * @param start the place in the string in which to start
- * @param count the number of characters to consume
* @param zero zero in the source representation
* @param nine nine in the source representation
- * @param offset the distance between zeros in the source and target representation
+ * @param offset the distance between zeros in the source and target representation
+ * @param transformed an input parameter of one boolean that can hold whether there was a transformation
* @return
*/
- private boolean transform(char[] src, int start, int count, int zero, int nine, int offset)
+ private char[] transform(char[] src, int zero, int nine, int offset, boolean[] transformed)
{
char[] text = src;
- boolean transformed = false;
- for (int i = start, e = start + count; i < e; ++i)
+ int srcLen = text.length;
+ int destLen = srcLen;
+
+ // offset > 0 when we are going from 0-9
+ if (offset > 0 && srcLen > 3)
{
+ // count the number of ':' flanked by '0' to '9'
+ // each one of these is going
+ // to be bracketed with RLO and PDF.
+ for (int i = 1; i < srcLen - 1; i++)
+ {
+ char prevChar = text[i - 1];
+ char curChar = text[i];
+ char nextChar = text[i + 1];
+ if (curChar == ':' && prevChar >= '0' && prevChar <= '9' && nextChar >= '0' && nextChar <= '9')
+ {
+ destLen += 2;
+ }
+ }
+
+ // Did we actually see a ':'
+ if (destLen != srcLen)
+ {
+ transformed[0] = true;
+ int sPos = 0;
+ int dPos = 0;
+ int stop = srcLen - 1; // ensure look-ahead
+ char[] dest = new char[destLen];
+ dest[dPos++] = text[sPos++];
+ while (sPos < stop)
+ {
+ char prevChar = text[sPos - 1];
+ char nextChar = text[sPos + 1];
+ char curChar = text[sPos++];
+ if (curChar == ':' && prevChar >= '0' && prevChar <= '9' && nextChar >= '0' && nextChar <= '9')
+ {
+ dest[dPos++] = '\u202E'; // RLO
+ dest[dPos++] = curChar;
+ dest[dPos++] = '\u202C'; // PDF
+ }
+ else if (curChar >= zero && curChar <= nine)
+ {
+ dest[dPos++] = (char)(curChar + offset);
+ }
+ else
+ {
+ dest[dPos++] = curChar;
+ }
+ }
+ // copy the rest
+ while (sPos < srcLen)
+ {
+ dest[dPos++] = text[sPos++];
+ }
+ return dest;
+ }
+ }
+ // Are we going to '0' - '9' with embedded, specially marked ':'
+ else if (offset < 0 && srcLen > 3)
+ {
+ for (int sPos = 0; sPos < srcLen - 2; sPos++)
+ {
+ if (text[sPos] == '\u202E' && text[sPos + 1] == ':' && text[sPos + 2] == '\u202C')
+ {
+ destLen -= 2;
+ sPos += 2;
+ }
+ }
+
+ // Did we actually see a '\u202E:\u202C'
+ if (destLen != srcLen)
+ {
+ transformed[0] = true;
+ char[] dest = new char[destLen];
+ int sPos = 0;
+ int dPos = 0;
+ int stop = srcLen - 2; // ensure look-ahead
+ while (sPos < stop)
+ {
+ char curChar = text[sPos++];
+ if (curChar == '\u202E' && text[sPos] == ':' && text[sPos + 1] == '\u202C')
+ {
+ dest[dPos++] = ':';
+ sPos += 2; // skip the whole pattern
+ }
+ else if (curChar >= zero && curChar <= nine)
+ {
+ dest[dPos++] = (char)(curChar + offset);
+ }
+ else
+ {
+ dest[dPos++] = curChar;
+ }
+ }
+
+ // copy the rest
+ while (sPos < srcLen)
+ {
+ dest[dPos++] = text[sPos++];
+ }
+
+ return dest;
+ }
+ }
+
+ for (int i = 0, e = src.length; i < e; i++)
+ {
char c = text[i];
if (c >= zero && c <= nine)
{
text[i] = (char)(c + offset);
- transformed = true;
+ transformed[0] = true;
}
}
- return transformed;
+
+ return text;
}
/**
@@ -262,11 +307,11 @@
if (nineShape == '\u0000')
{
nineShape = '9';
- if (locale.getLanguage().equals("fa")) //$NON-NLS-1$
+ if ("fa".equals(locale.getLanguage())) //$NON-NLS-1$
{
nineShape = '\u06f9';
}
- else if (locale.getLanguage().equals("ar")) //$NON-NLS-1$
+ else if ("ar".equals(locale.getLanguage())) //$NON-NLS-1$
{
nineShape = '\u0669';
}
@@ -274,34 +319,7 @@
return nineShape;
}
- // The following 4 values are replicated here from ArabicShaper.
- // This is needed for the sake of reflection.
- // If any of these change in ArabicShaper, they will need to be changed here as well.
/**
- * Digit shaping option: Replace European digits (U+0030...U+0039) by Arabic-Indic digits.
- * @stable ICU 2.0
- */
- private static final int ICU_DIGITS_EN2AN = 0x20;
-
- /**
- * Digit shaping option: Replace Arabic-Indic digits by European digits (U+0030...U+0039).
- * @stable ICU 2.0
- */
- private static final int ICU_DIGITS_AN2EN = 0x40;
-
- /**
- * Digit type option: Use Arabic-Indic digits (U+0660...U+0669).
- * @stable ICU 2.0
- */
- private static final int ICU_DIGIT_TYPE_AN = 0;
-
- /**
- * Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9).
- * @stable ICU 2.0
- */
- private static final int ICU_DIGIT_TYPE_AN_EXTENDED = 0x100;
-
- /**
* The locale for this shaper.
*/
private Locale locale;
@@ -310,14 +328,4 @@
* Nine for this shaper.
*/
private char nineShape;
-
- /**
- * Convert 0-9 to \u06f0-\u06f9 for Persian, and \u0660-\u0669 for Arabic
- */
- private Object arabicShaper;
- /**
- * Revert \u06f0-\u06f9 for Persian, and \u0660-\u0669 for Arabic to 0-9
- */
- private Object unArabicShaper;
- private NumericShaper numericShaper;
}
Modified: trunk/common-swing/src/main/java/org/crosswire/common/swing/Msg_fa.properties
===================================================================
--- trunk/common-swing/src/main/java/org/crosswire/common/swing/Msg_fa.properties 2007-08-06 01:12:14 UTC (rev 1646)
+++ trunk/common-swing/src/main/java/org/crosswire/common/swing/Msg_fa.properties 2007-08-06 01:35:25 UTC (rev 1647)
@@ -7,7 +7,7 @@
BeanPanel.ErrorReading=\u0627\u0634\u062A\u0628\u0627 \u062F\u0631 \u062E\u0648\u0627\u0646\u062F\u0646 \u060C \u0634\u0645\u0627\u0631\u0647 {0}
EirPanel.Close=\u0628\u062A\u0646
-ExceptionPane.ErrorOccurred=An error has occured:
+ExceptionPane.ErrorOccurred=An error has occurred:
ExceptionPane.OK=\u0642\u0628\u0648\u0644
ExceptionPane.Details=\u062C\u0632\u062B\u06CC\u0627\u062A
ExceptionPane.NoFile=\u067E\u0631\u0648\u0646\u062F\u0647 \u0648\u062C\u0648\u062F \u0646\u062F\u0627\u0631\u062F
Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/Books.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/Books.java 2007-08-06 01:12:14 UTC (rev 1646)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/Books.java 2007-08-06 01:35:25 UTC (rev 1647)
@@ -37,7 +37,7 @@
import org.crosswire.common.util.Reporter;
/**
- * The Bibles class (along with Bible) is the central point of contact
+ * The Books class (along with Book) is the central point of contact
* between the rest of the world and this set of packages.
*
* @see gnu.lgpl.License for license details.
@@ -142,6 +142,47 @@
return new BookSet(temp);
}
+ /**
+ * Get the maximum string length of a property
+ * @param propertyKey The desired property
+ * @return -1 if there is no match, otherwise the maximum length.
+ */
+ public int getMaxLength(String propertyKey)
+ {
+ int max = -1;
+ List bookList = getBooks();
+ Iterator iter = bookList.iterator();
+ while (iter.hasNext())
+ {
+ Book book = (Book) iter.next();
+ Object property = book.getProperty(propertyKey);
+ String value = property instanceof String ? (String) property : property.toString();
+ max = Math.max(max, value == null ? -1 : value.length());
+ }
+ return max;
+ }
+
+ /**
+ * Get the maximum string length of a property on a subset of books.
+ * @param propertyKey The desired property
+ * @param filter The filter
+ * @return -1 if there is no match, otherwise the maximum length.
+ */
+ public int getMaxLength(String propertyKey, BookFilter filter)
+ {
+ int max = -1;
+ List bookList = getBooks(filter);
+ Iterator iter = bookList.iterator();
+ while (iter.hasNext())
+ {
+ Book book = (Book) iter.next();
+ Object property = book.getProperty(propertyKey);
+ String value = property instanceof String ? (String) property : property.toString();
+ max = Math.max(max, value == null ? -1 : value.length());
+ }
+ return max;
+ }
+
/* (non-Javadoc)
* @see org.crosswire.jsword.book.BookList#addBooksListener(org.crosswire.jsword.book.BooksListener)
*/
Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/Msg.properties
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/Msg.properties 2007-08-06 01:12:14 UTC (rev 1646)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/Msg.properties 2007-08-06 01:35:25 UTC (rev 1647)
@@ -9,7 +9,7 @@
SwordInstaller.ConnectRefused=Failed to connect to remote server: {0}. FTP code={1}, {2}
SwordInstaller.CWDRefused=Failed to change to remote directory: {0}. FTP code={1}, {2}
SwordInstaller.DownloadRefused=Failed to download index file: {0}. FTP code={1}, {2}
-SwordInstaller.UnknownError=Unexpected Error occured
+SwordInstaller.UnknownError=Unexpected Error occurred
SwordInstaller.CacheError=Error loading from cache
SwordInstaller.InvalidURL=Not enough / symbols in url: {0}
SwordInstaller.Installed=Book already installed: {0}
Modified: trunk/jsword/src/main/java/org/crosswire/jsword/passage/VerseRangeFactory.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/passage/VerseRangeFactory.java 2007-08-06 01:12:14 UTC (rev 1646)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/passage/VerseRangeFactory.java 2007-08-06 01:35:25 UTC (rev 1647)
@@ -60,12 +60,12 @@
* range of 5 verses starting at Gen 1:1.
* <p>This constructor is different from the (String, Verse) constructor in that
* if the basis is a range that exactly covers a chapter and the string is a
- * single number, then we assume that the number referrs to a chapter and not to
+ * single number, then we assume that the number refers to a chapter and not to
* a verse. This allows us to have a Passage like "Gen 1,2" and have the 2
- * understood as chapter 2 and not verse 2 of Gen 1, which would have occured
+ * understood as chapter 2 and not verse 2 of Gen 1, which would have occurred
* otherwise.
* @param original The string describing the verse e.g "2:2"
- * @param basis The verse that forms the basis by which to understand the orginal.
+ * @param basis The verse that forms the basis by which to understand the original.
* @exception NoSuchVerseException If the reference is illegal
*/
public static VerseRange fromString(String original, VerseRange basis) throws NoSuchVerseException
Modified: trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/install/sword/FTPMsg.properties
===================================================================
--- trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/install/sword/FTPMsg.properties 2007-08-06 01:12:14 UTC (rev 1646)
+++ trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/install/sword/FTPMsg.properties 2007-08-06 01:35:25 UTC (rev 1647)
@@ -5,7 +5,7 @@
# The MessageName should be mixed case, with a leading capital.
# It should have no spaces or other punctuation (e.g. _, -, ', ...)
-SwordInstaller.UnknownError=Unexpected Error occured
+SwordInstaller.UnknownError=Unexpected Error occurred
SwordInstaller.CacheError=Error loading from cache
SwordInstaller.InvalidURL=Not enough / symbols in url: {0}
SwordInstallerFactory.URLAtCount=Too many @ symbols in url: {0}
More information about the jsword-svn
mailing list