### Eclipse Workspace Patch 1.0
#P org.eclipse.equinox.bidi
Index: src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java
diff -N src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java
--- src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java 3 Feb 2010 20:00:59 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package org.eclipse.equinox.bidi.complexp;
-
-import org.eclipse.equinox.bidi.internal.complexp.BiDiTypesCollector;
-
-/**
- * @noinstantiate This class is not intended to be instantiated by clients.
- */
-// TBD do we really want to provide individual instances of the text processors?
-final public class ComplExpFactory implements IBiDiProcessor {
-
- /**
- * Factory method to create a new instance of the bi-directional text
- * processor for the specified text type. This method may return null
- * if it is unable to locate processor for the specified text type.
- *
- * @see #PROPERTY
- * @see #UNDERSCORE
- * @see #COMMA_DELIMITED
- * @see #SYSTEM_USER
- * @see #FILE
- * @see #EMAIL
- * @see #URL
- * @see #REGEXP
- * @see #XPATH
- * @see #JAVA
- * @see #SQL
- * @see #RTL_ARITHMETIC
- *
- * @param type specifies the type of complex expression to process.
- * @return a IComplExpProcessor
instance capable of handling
- * the type of complex expression specified. May return null
- * if the processor not found.
- */
- public static IComplExpProcessor create(String type) {
- return BiDiTypesCollector.getInstance().makeProcessor(type);
- }
-
-}
Index: src/org/eclipse/equinox/bidi/complexp/ComplExpUtil.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/ComplExpUtil.java
diff -N src/org/eclipse/equinox/bidi/complexp/ComplExpUtil.java
--- src/org/eclipse/equinox/bidi/complexp/ComplExpUtil.java 12 Apr 2010 18:51:17 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,369 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package org.eclipse.equinox.bidi.complexp;
-
-import java.util.Locale;
-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic;
-
-/**
- * This class provides a number of convenience functions facilitating the
- * processing of complex expressions.
- *
- * @noextend This class is not intended to be subclassed by clients.
- * @noinstantiate This class is not intended to be instantiated by clients.
- *
- * @author Matitiahu Allouche
- */
-final public class ComplExpUtil {
-
- /**
- * Flag specifying that all complex expressions should by default assume
- * that the GUI is mirrored (globally going from right to left).
- * The default can be overridden for specific instances of complex
- * expressions.
- * @see #assumeMirroredDefault
- * @see #isMirroredDefault
- */
- static boolean mirroredDefault;
-
- /**
- * prevents instantiation
- */
- private ComplExpUtil() {
- // empty
- }
-
- /** Specify whether the GUI where the complex expression will be displayed
- * is mirrored (is laid out from right to left). The value specified in
- * this method sets a default for all complex expressions to be created
- * from now on. If no value has been specified ever, the GUI
- * is assumed not to be mirrored.
- *
- * @param mirrored must be specified as false
if the GUI
- * is not mirrored, as true
if it is.
- *
- * @see #isMirroredDefault
- * @see IComplExpProcessor#assumeMirrored
- */
- public static void assumeMirroredDefault(boolean mirrored) {
- mirroredDefault = mirrored;
- }
-
- /** Retrieve the value currently assumed as default for GUI mirroring.
- *
- * @return the current value assumed by default for GUI mirroring.
- *
- * @see #assumeMirroredDefault
- */
- public static boolean isMirroredDefault() {
- return mirroredDefault;
- }
-
- /** This is a convenience method which can add directional marks in a given
- * text before the characters specified in the given array of offsets,
- * and can add a prefix and/or a suffix of directional formatting characters.
- * This can be used for instance after obtaining offsets by calling
- * {@link IComplExpProcessor#leanBidiCharOffsets() leanBidiCharOffsets} in order to
- * produce a full text corresponding to the source text.
- * The directional formatting characters that will be added at the given
- * offsets will be LRMs for expressions with LTR base direction and
- * RLMs for expressions with RTL base direction. Leading and
- * trailing LRE, RLE and PDF which might be needed as prefix or suffix
- * depending on the orientation of the GUI component used for display
- * may be added depending on argument affix
.
- *
- * @param text is the text of the complex expression.
- *
- * @param offsets is an array of offsets to characters in text
- * before which an LRM or RLM will be inserted.
- * Members of the array must be non-negative numbers smaller
- * than the length of text
.
- * The array must be sorted in ascending order without duplicates.
- * This argument may be null if there are no marks to add.
- *
- * @param direction specifies the base direction of the complex expression.
- * It must be one of the values {@link IComplExpProcessor#DIRECTION_LTR} or
- * {@link IComplExpProcessor#DIRECTION_RTL}.
- *
- * @param affix specifies if a prefix and a suffix should be added to
- * the result to make sure that the direction
- * specified as second argument is honored even if the expression
- * is displayed in a GUI component with a different orientation.
- *
- * @return a string corresponding to the source text
with
- * directional marks (LRMs or RLMs) added at the specified offsets,
- * and directional formatting characters (LRE, RLE, PDF) added
- * as prefix and suffix if so required.
- *
- */
- public static String insertMarks(String text, int[] offsets, int direction, boolean affix) {
- int textLen = text.length();
- if (textLen == 0)
- return ""; //$NON-NLS-1$
-
- String curPrefix, curSuffix, full;
- char curMark, c;
- char[] fullChars;
- if (direction == IComplExpProcessor.DIRECTION_LTR) {
- curMark = LRM;
- curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$
- curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$
- } else {
- curMark = RLM;
- curPrefix = "\u202b\u200f"; /* RLE+RLM *///$NON-NLS-1$
- curSuffix = "\u200f\u202c"; /* RLM+PDF *///$NON-NLS-1$
- }
- // add marks at offsets
- if ((offsets != null) && (offsets.length > 0)) {
- int offLen = offsets.length;
- fullChars = new char[textLen + offLen];
- int added = 0;
- for (int i = 0, j = 0; i < textLen; i++) {
- c = text.charAt(i);
- if ((j < offLen) && (i == offsets[j])) {
- fullChars[i + added] = curMark;
- added++;
- j++;
- }
- fullChars[i + added] = c;
- }
- full = new String(fullChars);
- } else {
- full = text;
- }
- if (affix)
- return curPrefix + full + curSuffix;
- return full;
- }
-
- /*************************************************************************/
- /* */
- /* The following code is provided for compatibility with TextProcessor */
- /* */
- /*************************************************************************/
-
- // The default set of delimiters to use to segment a string.
- private static final String defaultDelimiters = ".:/\\"; //$NON-NLS-1$
- // left to right mark
- private static final char LRM = '\u200e';
- // left to right mark
- private static final char RLM = '\u200f';
- // left to right embedding
- private static final char LRE = '\u202a';
- // right to left embedding
- private static final char RLE = '\u202b';
- // pop directional format
- private static final char PDF = '\u202c';
- // TBD use bundle properties
- private static String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ private static String
- private static boolean flagOS = osName.startsWith("windows") || osName.startsWith("linux"); //$NON-NLS-1$ //$NON-NLS-2$
- private static String lastLanguage;
- private static boolean lastGoodLang;
-
- static boolean isProcessingNeeded() {
- if (!flagOS)
- return false;
- // TBD use OSGi service
- String lang = Locale.getDefault().getLanguage();
- if (lang.equals(lastLanguage))
- return lastGoodLang;
- lastLanguage = lang;
- lastGoodLang = "iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || "fa".equals(lang) || "ur".equals(lang); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- return lastGoodLang;
- }
-
- /**
- * Process the given text and return a string with appropriate
- * directional formatting characters if the locale is a Bidi locale.
- * This is equivalent to calling
- * {@link #process(String, String)} with the default set of
- * delimiters (dot, colon, slash, backslash).
- *
- * @param str the text to be processed
- *
- * @return the processed string
- *
- */
- public static String process(String str) {
- return process(str, defaultDelimiters);
- }
-
- /**
- * Process a string that has a particular semantic meaning to render
- * it correctly on Bidi locales. This is done by adding directional
- * formatting characters so that presentation using the Unicode Bidi
- * Algorithm will provide the expected result.
- * The text is segmented according to the provided delimiters.
- * Each segment has the Unicode Bidi Algorithm applied to it,
- * but as a whole, the string is oriented left to right.
- *
- * For example, a file path such as d:\myfolder\FOLDER\MYFILE.java - * (where capital letters indicate RTL text) should render as - * d:\myfolder\REDLOF\ELIFYM.java.
- *
- * NOTE: this method inserts directional formatting characters into the
- * text. Methods like String.equals(String)
and
- * String.length()
called on the resulting string will not
- * return the same values as would be returned for the original string.
null
, return
- * the string itself
- *
- * @param delimiters delimiters by which the string will be segmented.
- * If null
, the default delimiters are used
- * (dot, colon, slash, backslash).
- *
- * @return the processed string
- */
- public static String process(String str, String delimiters) {
- if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
- return str;
-
- // do not process a string that has already been processed.
- if (str.charAt(0) == LRE && str.charAt(str.length() - 1) == PDF)
- return str;
-
- // do not process a string if all the following conditions are true:
- // a) it has no RTL characters
- // b) it starts with a LTR character
- // c) it ends with a LTR character or a digit
- boolean isStringBidi = false;
- int strLength = str.length();
- char c;
- for (int i = 0; i < strLength; i++) {
- c = str.charAt(i);
- if (((c >= 0x05d0) && (c <= 0x07b1)) || ((c >= 0xfb1d) && (c <= 0xfefc))) {
- isStringBidi = true;
- break;
- }
- }
- while (!isStringBidi) {
- if (!Character.isLetter(str.charAt(0)))
- break;
- c = str.charAt(strLength - 1);
- if (!Character.isDigit(c) && !Character.isLetter(c))
- break;
- return str;
- }
-
- if (delimiters == null)
- delimiters = defaultDelimiters;
-
- IComplExpProcessor processor = new ComplExpBasic(delimiters);
- // make sure that LRE/PDF are added around the string
- processor.assumeOrientation(IComplExpProcessor.ORIENT_UNKNOWN);
- return processor.leanToFullText(str);
- }
-
- /**
- * Process a string that has a particular semantic meaning to render
- * it correctly on Bidi locales. This is done by adding directional
- * formatting characters so that presentation using the Unicode Bidi
- * Algorithm will provide the expected result..
- * The text is segmented according to the syntax specified in the
- * type
argument.
- * Each segment has the Unicode Bidi Algorithm applied to it, but the
- * order of the segments is governed by the type of the complex expression.
- * - * For example, a file path such as d:\myfolder\FOLDER\MYFILE.java - * (where capital letters indicate RTL text) should render as - * d:\myfolder\REDLOF\ELIFYM.java.
- *
- * NOTE: this method inserts directional formatting characters into the
- * text. Methods like String.equals(String)
and
- * String.length()
called on the resulting string will not
- * return the same values as would be returned for the original string.
null
, return
- * the string itself
- *
- * @param type specifies the type of the complex expression. It must
- * be one of the values allowed as argument for method
- * {@link ComplExpFactory#create}.
- *
- * @return the processed string
- */
- public static String processTyped(String str, String type) {
- if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
- return str;
-
- // do not process a string that has already been processed.
- char c = str.charAt(0);
- if (((c == LRE) || (c == RLE)) && str.charAt(str.length() - 1) == PDF)
- return str;
-
- IComplExpProcessor processor = ComplExpFactory.create(type);
- if (processor == null) // invalid type
- return str;
-
- // make sure that LRE/PDF are added around the string
- processor.assumeOrientation(IComplExpProcessor.ORIENT_UNKNOWN);
- return processor.leanToFullText(str);
- }
-
- /**
- * Removes directional marker characters in the given string that were inserted
- * by the {@link #process(String)} or {@link #process(String, String)}
- * methods.
- *
- * @param str string with directional markers to remove
- *
- * @return string with no directional formatting characters
- *
- */
- public static String deprocess(String str) {
- if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
- return str;
-
- StringBuffer buf = new StringBuffer();
- int strLen = str.length();
- for (int i = 0; i < strLen; i++) {
- char c = str.charAt(i);
- switch (c) {
- case LRM :
- continue;
- case LRE :
- continue;
- case PDF :
- continue;
- default :
- buf.append(c);
- }
- }
- return buf.toString();
- }
-
- /**
- * Removes directional marker characters in the given string that were inserted
- * by the {@link #process(String, String)} method.
- *
- * @param str string with directional markers to remove
- *
- * @param type type of the complex expression as specified when
- * calling process(String str, int type)
- *
- * @return string with no directional formatting characters
- *
- */
- public static String deprocess(String str, String type) {
- if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
- return str;
-
- IComplExpProcessor processor = ComplExpFactory.create(type);
- if (processor == null) // invalid type
- return str;
-
- // make sure that LRE/PDF are added around the string
- processor.assumeOrientation(IComplExpProcessor.ORIENT_UNKNOWN);
- return processor.fullToLeanText(str);
- }
-
-}
Index: src/org/eclipse/equinox/bidi/complexp/CxpEnv.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/CxpEnv.java
diff -N src/org/eclipse/equinox/bidi/complexp/CxpEnv.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/equinox/bidi/complexp/CxpEnv.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,301 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.bidi.complexp;
+
+import java.util.Locale;
+
+/**
+ * This class defines certain details of the environment within which
+ * complex expressions are processed.
+ *
+ * All public fields in this class are final
, i.e. cannot be
+ * changed after creating an instance.
+ *
+ * A CxpEnv
instance can be associated with a CxpHelper
+ * instance either when creating the
+ * {@link CxpHelper#CxpHelper(java.lang.String, CxpEnv) CxpHelper} instance
+ * or using the {@link CxpHelper#setEnvironment setEnvironment} method.
+ *
+ *
Example 1 (set all environment parameters) + *
+ * + * CxpEnv myEnv = new CxpEnv("he_IL", true, CxpEnv.ORIENT_RTL); + * CxpHelper myHelper = new CxpHelper(IProcessorTypes.FILE, myEnv); + * + *+ *
Example 2 (change only the orientation) + *
+ * + * CxpEnv env1 = myHelper.getEnvironment(); + * CxpEnv env2 = new CxpEnv(env1.language, env1.mirrored, CxpEnv.ORIENT_UNKNOWN); + * myHelper.setEnvironment(env2); + * + *+ *
+ * This class also provides a number of convenience methods related to the environment. + *
+ * @see CxpHelper#CxpHelper(String, CxpEnv) + * @see CxpHelper#CxpHelper(ICxpProcessor, CxpEnv) + * @see CxpHelper#getEnvironment CxpHelper.getEnvironment + * @see CxpHelper#setEnvironment CxpHelper.setEnvironment + * @see ICxpProcessor#init ICxpProcessor.init + * @see ICxpProcessor#init2 ICxpProcessor.init2 + * + * @author Matitiahu Allouche + */ +public class CxpEnv { + + /** + * Constant specifying that the orientation of the GUI component + * where a complex expression will be displayed is LTR. + * It can appear as
orientation
argument for
+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the
+ * {@link CxpEnv#orientation} member of CxpEnv
.
+ */
+ public static final int ORIENT_LTR = 0;
+
+ /**
+ * Constant specifying that the orientation of the GUI component
+ * where a complex expression will be displayed is RTL.
+ * It can appear as orientation
argument for
+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the
+ * {@link CxpEnv#orientation} member of CxpEnv
.
+ */
+ public static final int ORIENT_RTL = 1;
+
+ /**
+ * Constant specifying that the orientation of the GUI component
+ * where a complex expression will be displayed is contextual with
+ * a default of LTR (if no strong character appears in the text).
+ * It can appear as orientation
argument for
+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the
+ * {@link CxpEnv#orientation} member of CxpEnv
.
+ */
+ public static final int ORIENT_CONTEXTUAL_LTR = 2;
+
+ /**
+ * Constant specifying that the orientation of the GUI component
+ * where a complex expression will be displayed is contextual with
+ * a default of RTL (if no strong character appears in the text).
+ * It can appear as orientation
argument for
+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the
+ * {@link CxpEnv#orientation} member of CxpEnv
.
+ */
+ public static final int ORIENT_CONTEXTUAL_RTL = 3;
+
+ /**
+ * Constant specifying that the orientation of the GUI component
+ * where a complex expression will be displayed is not known.
+ * Directional formatting characters must be added as prefix and
+ * suffix whenever a full text is generated using
+ * {@link CxpHelper#leanToFullText leanToFullText}.
+ * It can appear as orientation
argument for
+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the
+ * {@link CxpEnv#orientation} member of CxpEnv
.
+ */
+ public static final int ORIENT_UNKNOWN = 4;
+
+ /**
+ * Constant specifying that whatever the orientation of the
+ * GUI component where a complex expression will be displayed, no
+ * directional formatting characters must be added as prefix or
+ * suffix when a full text is generated using
+ * {@link CxpHelper#leanToFullText leanToFullText}.
+ * It can appear as orientation
argument for
+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the
+ * {@link CxpEnv#orientation} member of CxpEnv
.
+ */
+ public static final int ORIENT_IGNORE = 5;
+
+ /**
+ * Pre-defined CxpEnv
instance with values for a non-mirrored GUI
+ * and a Left-to-Right presentation component.null
, which defaults to the language
+ * of the current default locale.
+ */
+ public static final CxpEnv DEFAULT = new CxpEnv(null, false, ORIENT_LTR);
+
+ /**
+ * This string is a 2-letters code representing a language as defined by
+ * ISO-639. If left as null
, it defaults to the language
+ * of the current default locale.
+ */
+ public final String language;
+
+ /**
+ * Flag specifying that complex expressions processed under this environment
+ * should assume that the GUI is mirrored (globally going from right to left).
+ */
+ public final boolean mirrored;
+
+ /** Specify the orientation (a.k.a. base direction) of the GUI
+ * component in which the full text of the complex expression will
+ * be displayed.
+ * When the orientation is ORIENT_LTR
and the complex
+ * expression has a RTL base direction,
+ * {@link CxpHelper#leanToFullText leanToFullText}
+ * adds RLE+RLM at the head of the full text and RLM+PDF at its
+ * end.
+ *
+ * When the orientation is ORIENT_RTL
and the complex
+ * expression has a LTR base direction,
+ * {@link CxpHelper#leanToFullText leanToFullText}
+ * adds LRE+LRM at the head of the full text and LRM+PDF at its
+ * end.
+ *
+ * When the orientation is ORIENT_CONTEXTUAL_LTR
or
+ * ORIENT_CONTEXTUAL_RTL
and the data content would resolve
+ * to a RTL orientation while the complex expression has a LTR base
+ * direction, {@link CxpHelper#leanToFullText leanToFullText}
+ * adds LRM at the head of the full text.
+ *
+ * When the orientation is ORIENT_CONTEXTUAL_LTR
or
+ * ORIENT_CONTEXTUAL_RTL
and the data content would resolve
+ * to a LTR orientation while the complex expression has a RTL base
+ * direction, {@link CxpHelper#leanToFullText leanToFullText}
+ * adds RLM at the head of the full text.
+ *
+ * When the orientation is ORIENT_UNKNOWN
and the complex
+ * expression has a LTR base direction,
+ * {@link CxpHelper#leanToFullText leanToFullText}
+ * adds LRE+LRM at the head of the full text and LRM+PDF at its
+ * end.
+ *
+ * When the orientation is ORIENT_UNKNOWN
and the complex
+ * expression has a RTL base direction,
+ * {@link CxpHelper#leanToFullText leanToFullText}
+ * adds RLE+RLM at the head of the full text and RLM+PDF at its
+ * end.
+ *
+ * When the orientation is ORIENT_IGNORE
,
+ * {@link CxpHelper#leanToFullText leanToFullText} does not add any directional
+ * formatting characters as either prefix or suffix of the full text.
+ *
+ */
+ public final int orientation;
+
+ static Locale defLocale;
+ static String defLanguage;
+ static boolean defBidi;
+ boolean bidiFlag;
+
+ /**
+ * Constructor
+ *
+ * @param lang represents the language to be used in this environment.
+ * It should be specified as a 2-letters code as defined by
+ * ISO-639.
+ * If longer than 2 letters, the extra letters are ignored.
+ * If set to null
, it defaults to the language
+ * of the default locale.
+ * @see #language
+ *
+ * @param mirrored specifies if the GUI is mirrored.
+ * @see #mirrored
+ *
+ * @param orientation specifies the orientation of the component
+ * which is to display the complex expression. It must be
+ * one of the values
+ * {@link #ORIENT_LTR ORIENT_LTR},
+ * {@link #ORIENT_LTR ORIENT_RTL},
+ * {@link #ORIENT_CONTEXTUAL_LTR ORIENT_CONTEXTUAL_LTR},
+ * {@link #ORIENT_CONTEXTUAL_RTL ORIENT_CONTEXTUAL_RTL},
+ * {@link #ORIENT_UNKNOWN ORIENT_UNKNOWN} or
+ * {@link #ORIENT_IGNORE ORIENT_IGNORE}.
+ * If different, it defaults to {@link #ORIENT_UNKNOWN ORIENT_UNKNOWN}.
+ * @see #orientation
+ */
+ public CxpEnv(String lang, boolean mirrored, int orientation) {
+ if (lang == null) {
+ language = null;
+ } else {
+ if (lang.length() > 2) {
+ language = lang.substring(0, 2);
+ } else {
+ language = lang;
+ }
+ bidiFlag = isBidiLanguage(language);
+ }
+ this.mirrored = mirrored;
+ this.orientation = orientation >= ORIENT_LTR && orientation <= ORIENT_IGNORE ? orientation : ORIENT_UNKNOWN;
+ }
+
+ /**
+ * Check whether the current language uses a
+ * bidi script (Arabic, Hebrew, Farsi or Urdu).
+ *
+ * @return true
if the current language uses a bidi script.
+ * The language may have been set explicitly when creating the
+ * CxpEnv
instance, or it may have defaulted to
+ * the language of the current default locale.
+ * @see #CxpEnv CxpEnv
+ */
+ public boolean isBidi() {
+ // TBD use OSGi service
+ if (defLanguage != null && defLocale.equals(Locale.getDefault()))
+ return defBidi;
+
+ if (language == null) {
+ // TBD use OSGi service
+ defLocale = Locale.getDefault();
+ defLanguage = defLocale.getLanguage();
+ defBidi = isBidiLanguage(defLanguage);
+ return defBidi;
+ }
+
+ return bidiFlag;
+ }
+
+ static boolean isBidiLanguage(String lang) {
+ return "iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || "fa".equals(lang) || "ur".equals(lang); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ }
+
+ static String lineSep;
+
+ /**
+ * Retrieve the string which represents a line separator in this environment.
+ *
+ * @return the string which is used as line separator (e.g. CRLF).
+ */
+ public static String getLineSep() {
+ // TBD use bundle properties
+ if (lineSep == null)
+ lineSep = System.getProperty("line.separator", "\n"); //$NON-NLS-1$//$NON-NLS-2$
+ return lineSep;
+ }
+
+ static String osName;
+ static boolean flagOS;
+
+ /**
+ * Check if the current OS is supported by the complex expression packages.
+ *
+ * @return true
if the current OS is supported.
+ */
+ public static boolean isSupportedOS() {
+ if (osName == null) {
+ // TBD use bundle properties
+ osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$
+ flagOS = osName.startsWith("windows") || osName.startsWith("linux"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return flagOS;
+ }
+
+}
Index: src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java
diff -N src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.bidi.complexp;
+
+/**
+ * This class defines features of a complex expression processor.
+ *
+ * All public fields in this class are final
, i.e. cannot be
+ * changed after creating an instance.
+ *
+ * A CxpFeatures
instance can be associated with a
+ * CxpHelper
instance using
+ * the {@link CxpHelper#setFeatures setFeatures} method.
+ *
+ *
Example 1 (set all features) + *
+ * + * CxpFeatures myFeatures = new CxpFeatures("+-=", 0, -1, -1, false, false); + * CxpHelper myHelper = new CxpHelper(IProcessorTypes.FILE, myEnv); + * myHelper.setFeatures(myFeatures); + * + *+ *
Example 2 (change only the operators) + *
+ * + * CxpFeatures f1 = myHelper.getFeatures(); + * CxpFeatures f2 = new CxpFeatures("[]|()", f1.specialsCount, + * f1.dirArabic, f1.dirHebrew, + * f1.ignoreArabic, f1.ignoreHebrew); + * myHelper.setFeatures(f2); + * + *+ * + * @see CxpHelper#getFeatures CxpHelper.getFeatures + * @see CxpHelper#setFeatures CxpHelper.setFeatures + * @see ICxpProcessor#init ICxpProcessor.init + * @see ICxpProcessor#init2 ICxpProcessor.init2 + * + * @author Matitiahu Allouche + */ +public class CxpFeatures { + + /** + * Constant specifying that the base direction of a complex expression is LTR. + * The base direction may depend on whether the GUI is + * {@link CxpEnv#mirrored mirrored} and may + * may be different for Arabic and for Hebrew. + * This constant can appear as
dirArabic
+ * or dirHebrew
argument for
+ * {@link CxpFeatures#CxpFeatures CxpFeatures constructor} and as value
+ * for the {@link #dirArabic} or {@link #dirHebrew} members of
+ * CxpFeatures
.
+ */
+ public static final int DIR_LTR = 0;
+
+ /**
+ * Constant specifying that the base direction of a complex expression is RTL.
+ * The base direction may depend on whether the GUI is
+ * {@link CxpEnv#mirrored mirrored} and may
+ * may be different for Arabic and for Hebrew.
+ * This constant can appear as dirArabic
+ * or dirHebrew
argument for
+ * {@link CxpFeatures#CxpFeatures CxpFeatures constructor} and as value
+ * for the {@link #dirArabic} or {@link #dirHebrew} members of
+ * CxpFeatures
.
+ */
+ public static final int DIR_RTL = 1;
+
+ /**
+ * Pre-defined CxpFeatures
instance with values for no
+ * operators, no special processing, all directions LTR
+ * and support for neither Arabic nor Hebrew.true
, the
+ * processor will do nothing (but some overhead can be expected).
+ */
+ public final boolean ignoreArabic;
+
+ /**
+ * Flag indicating that Hebrew letters will not be considered for
+ * processing complex expressions. If both this flag and
+ * {@link #ignoreArabic} are set to true
, the
+ * processor will do nothing (but some overhead can be expected).
+ */
+ public final boolean ignoreHebrew;
+
+ /**
+ * Constructor
+ *
+ * @param operators is a string where each character is a delimiter
+ * which separates the complex expression into tokens.
+ * @see #operators
+ *
+ * @param specialsCount specifies the number of special cases handled
+ * by the processor.
+ * @see #specialsCount
+ *
+ * @param dirArabic specifies the base direction of the complex expression
+ * for Arabic. It must be {@link #DIR_LTR} or {@link #DIR_RTL}.
+ * If it is not (for instance if it is a negative value), it
+ * defaults to DIR_LTR
.
+ * @see #dirArabic
+ *
+ * @param dirHebrew specifies the base direction of the complex expression
+ * for Hebrew. It must be {@link #DIR_LTR} or {@link #DIR_RTL}.
+ * If it is not (for instance if it is a negative value), it
+ * defaults to DIR_LTR
.
+ * @see #dirHebrew
+ *
+ * @param ignoreArabic indicates that Arabic letters will not be
+ * considered for processing complex expressions.
+ * @see #ignoreArabic
+ *
+ * @param ignoreHebrew indicates that Hebrew letters will not be
+ * considered for processing complex expressions.
+ * @see #ignoreHebrew
+ */
+ public CxpFeatures(String operators, int specialsCount, int dirArabic, int dirHebrew, boolean ignoreArabic, boolean ignoreHebrew) {
+
+ this.operators = operators == null ? "" : operators; //$NON-NLS-1$
+ this.specialsCount = specialsCount;
+ this.dirArabic = dirArabic == DIR_LTR || dirArabic == DIR_RTL ? dirArabic : DIR_LTR;
+ this.dirHebrew = dirHebrew == DIR_LTR || dirHebrew == DIR_RTL ? dirHebrew : DIR_LTR;
+ this.ignoreArabic = ignoreArabic;
+ this.ignoreHebrew = ignoreHebrew;
+ }
+
+}
Index: src/org/eclipse/equinox/bidi/complexp/CxpHelper.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/CxpHelper.java
diff -N src/org/eclipse/equinox/bidi/complexp/CxpHelper.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/equinox/bidi/complexp/CxpHelper.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,570 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.bidi.complexp;
+
+import org.eclipse.equinox.bidi.internal.complexp.CxpDoer;
+
+/**
+ * This class acts as a mediator between applications and complex
+ * expression processors.
+ * The purpose of complex expression processors is to add directional
+ * formatting characters to ensure correct display.
+ * This class shields applications from the
+ * intricacies of complex expression processors.
+ * + * For a general introduction to complex expressions, see + * {@link + * the package documentation}. + * + *
The following code shows how to instantiate a CxpHelper adapted for a + * certain type of complex expression (directory and file paths), and how + * to obtain the full text corresponding to the lean text + * of such an expression. + * + *
+ * + * CxpHelper helper = new CxpHelper(IProcessorTypes.FILE); + * String leanText = "D:\\\u05d0\u05d1\\\u05d2\\\u05d3.ext"; + * String fullText = helper.leanToFullText(leanText); + * System.out.println("full text = " + fullText); + * + *+ * This class provides a user-oriented API but does not provides + * an actual implementation. The real work is done by the class + * {@link CxpDoer}. Users of the API need not be concerned by, and + * should not depend upon, details of the implementation by + *
CxpDoer
.
+ *
+ * @author Matitiahu Allouche
+ *
+ */
+public class CxpHelper {
+ /**
+ * Constant to use as initState
argument when calling
+ * {@link #leanToFullText(java.lang.String, int) leanToFullText} or
+ * {@link #fullToLeanText(java.lang.String, int) fullToLeanText}
+ * to indicate that there is no context of previous lines which
+ * should be initialized before performing the operation.
+ */
+ public static final int STATE_NOTHING_GOING = -1;
+
+ private static final int[] EMPTY_INT_ARRAY = new int[0];
+
+ /**
+ * Reference to the {@link CxpDoer} instance which accomplishes
+ * most of the work. This member should be accessed only by
+ * complex expression processors (implementing {@link ICxpProcessor}).
+ */
+ public CxpDoer ced;
+
+ /**
+ * Create a CxpHelper
instance which does nothing tangible
+ * but does it quickly. We will call it a no-op helper.
+ * The {@link #CxpHelper() no-op helper} does not modify text submitted to it, and can be
+ * used when it is known that no complex expression processing
+ * is needed, for instance because no bidi text is expected. With this
+ * helper, the cost of invoking the complex expression API is minimal.
+ */
+ public CxpHelper() {
+ // let ced stay null
+ }
+
+ /**
+ * Create a CxpHelper
instance to process expressions
+ * of type type
with a
+ * {@link CxpEnv#DEFAULT DEFAULT} environment.
+ *
+ * @param type represents the type of the complex expression. It must
+ * be one of the values in {@link IProcessorTypes}, or a type
+ * added in a plug-in extension.
+ *
+ * @throws IllegalArgumentException if the type
is not
+ * supported.
+ */
+ public CxpHelper(String type) {
+ this(type, null);
+ }
+
+ /**
+ * Create a CxpHelper
instance to process expressions
+ * of type type
operating under the environment
+ * {@link CxpEnv env}.
+ *
+ * @param type represents the type of the complex expression. It must
+ * be one of the values in {@link IProcessorTypes}, or a type
+ * added in a plug-in extension.
+ *
+ * @param env represents the environment where the complex expression
+ * will be displayed. It is better to specify the environment
+ * when instantiating a CxpHelper
than to specify
+ * it later using {@link #setEnvironment setEnvironment}.null
can be specified here for a
+ * {@link CxpEnv#DEFAULT DEFAULT} environment.
+ *
+ * @throws IllegalArgumentException if the type
is not
+ * supported.
+ */
+ public CxpHelper(String type, CxpEnv env) {
+ ICxpProcessor proc = StringProcessor.getProcessor(type);
+ if (proc == null) {
+ throw new IllegalArgumentException("Invalid processor type!"); //$NON-NLS-1$
+ }
+ ced = new CxpDoer(this, proc, env);
+ }
+
+ /**
+ * Create a CxpHelper
instance to process complex
+ * expressions by means of a given processor proc
,
+ * operating under the environment {@link CxpEnv env}.
+ *
+ * @param proc is a complex expression processor.
+ *
+ * @param env represents the environment where the complex expression
+ * will be displayed. It is better to specify the environment
+ * when instantiating a CxpHelper
than to specify
+ * it later using {@link #setEnvironment setEnvironment}.null
can be specified here for a
+ * {@link CxpEnv#DEFAULT DEFAULT} environment.
+ */
+ public CxpHelper(ICxpProcessor proc, CxpEnv env) {
+ ced = new CxpDoer(this, proc, env);
+ }
+
+ /** Add directional formatting characters to a complex expression
+ * to ensure correct presentation.
+ *
+ * @param text is the text of the complex expression.
+ *
+ * @return the complex expression with directional formatting
+ * characters added at proper locations to ensure correct
+ * presentation.text
.
+ */
+ public String leanToFullText(String text) {
+ return leanToFullText(text, STATE_NOTHING_GOING);
+ }
+
+ /**
+ * Add directional formatting characters to a complex expression
+ * to ensure correct presentation.
+ *
+ * @param text is the text of the complex expression.
+ *
+ * @param initState specifies that the first parameter is the
+ * continuation of text submitted in a previous call.
+ * The initState
of the present call must be
+ * the final state obtained by calling
+ * {@link #getFinalState() getFinalState}
+ * after the previous call.
+ * text
.
+ *
+ * @see #getFinalState getFinalState
+ */
+ public String leanToFullText(String text, int initState) {
+ if (ced == null)
+ return text;
+ return ced.leanToFullText(text, initState);
+ }
+
+ /**
+ * Given a complex expression, get the offsets of characters before
+ * which directional formatting characters must be added in order to
+ * ensure correct presentation.
+ * Only LRMs (for an expression with LTR base direction) and RLMs (for
+ * an expression with RTL base direction) are considered. Leading and
+ * trailing LRE, RLE and PDF which might be prefixed or suffixed
+ * depending on the {@link CxpEnv#orientation orientation} of the
+ * GUI component used for display are not reflected in this method.
+ *
+ * This method assumes that a successful call to
+ * {@link #leanToFullText leanToFullText} has been performed, and it
+ * returns the offsets relevant for the last text submitted.
+ *
+ * @return an array of offsets to the characters in the last submitted
+ * complex expression before which directional marks must be
+ * added to ensure correct presentation.
+ * The offsets are sorted in ascending order.
+ * The {@link #CxpHelper() no-op helper} returns an array of 0 elements.
+ */
+ public int[] leanBidiCharOffsets() {
+ if (ced == null)
+ return EMPTY_INT_ARRAY;
+ return ced.leanBidiCharOffsets();
+ }
+
+ /**
+ * Get the offsets of characters in the full text of a
+ * complex expression corresponding to directional formatting
+ * characters which have been added in order to ensure correct presentation.
+ * LRMs (for an expression with LTR base direction), RLMs (for
+ * an expression with RTL base direction) are considered as well as
+ * leading and trailing LRE, RLE and PDF which might be prefixed or suffixed
+ * depending on the {@link CxpEnv#orientation orientation} of the
+ * GUI component used for display.
+ *
+ * This method assumes that a successful call to
+ * {@link #leanToFullText leanToFullText} has been performed, and it
+ * returns the offsets relevant for the last text submitted.
+ *
+ * @return an array of offsets to the characters in the full
+ * text of the last submitted complex expression which are
+ * directional formatting characters added to ensure correct
+ * presentation.
+ * The offsets are sorted in ascending order.
+ * The {@link #CxpHelper() no-op helper} returns an array of 0 elements.
+ */
+ public int[] fullBidiCharOffsets() {
+ if (ced == null)
+ return EMPTY_INT_ARRAY;
+ return ced.fullBidiCharOffsets();
+ }
+
+ /**
+ * Remove directional formatting characters which were added to a
+ * complex expression to ensure correct presentation.
+ *
+ * @param text is the text of the complex expression including
+ * directional formatting characters.
+ *
+ * @return the complex expression without directional formatting
+ * characters which might have been added by processing it
+ * with {@link #leanToFullText leanToFullText}.
+ * The {@link #CxpHelper() no-op helper} returns text
+ *
+ */
+ public String fullToLeanText(String text) {
+ return fullToLeanText(text, STATE_NOTHING_GOING);
+ }
+
+ /**
+ * Remove directional formatting characters which were added to a
+ * complex expression to ensure correct presentation.
+ *
+ * @param text is the text of the complex expression including
+ * directional formatting characters.
+ *
+ * @param initState specifies that the first parameter is the
+ * continuation of text submitted in a previous call.
+ * The initState
of the present call must be
+ * the final state obtained by calling
+ * {@link #getFinalState getFinalState} after the previous call.
+ *
If the present call is not a continuation of
+ * text submitted in a previous call, the value
+ * {@link #STATE_NOTHING_GOING} should be used as argument.
+ *
+ * @return the complex expression without directional formatting
+ * characters which might have been added by processing it
+ * with {@link #leanToFullText leanToFullText}.
+ * The {@link #CxpHelper() no-op helper} returns text
+ *
+ * @see #getFinalState getFinalState
+ */
+ public String fullToLeanText(String text, int initState) {
+ if (ced == null)
+ return text;
+ return ced.fullToLeanText(text, initState);
+ }
+
+ /**
+ * Retrieve the final state achieved in a previous call to
+ * {@link #leanToFullText leanToFullText} or
+ * {@link #fullToLeanText fullToLeanText}.
+ * This state is an opaque value which is meaningful only
+ * within calls to the same complex expression processor.
+ * The only externalized value is
+ * {@link #STATE_NOTHING_GOING} which means that
+ * there is nothing to remember from the last call.
+ *
+ * The state should be used only for complex expressions which come
+ * in parts, like when spanning multiple lines. The user can make
+ * a separate call to
+ * leanToFullText
or fullToLeanText
for each
+ * line in the expression. The final state value retrieved after the
+ * call for one line should be used as the initial state in the call
+ * which processes the next line.
+ *
+ * If a line within a complex expression has already been processed by
+ * leanToFullText
and the lean version of that line has
+ * not changed, and its initial state has not changed either, the user
+ * can be sure that the full version of that line is also
+ * identical to the result of the previous processing.
+ *
+ * @see #leanToFullText(String text, int initState)
+ * @see #fullToLeanText(String text, int initState)
+ *
+ * @return the last final state.
+ * The {@link #CxpHelper() no-op helper} returns {@link #STATE_NOTHING_GOING}.
+ */
+ public int getFinalState() {
+ if (ced == null)
+ return STATE_NOTHING_GOING;
+ return ced.getFinalState();
+ }
+
+ /**
+ * After transforming a lean string into a full string
+ * using {@link #leanToFullText leanToFullText}, compute the index in the
+ * full string of the character corresponding to the
+ * character with the specified position in the lean string.
+ *
+ * @param pos is the index of a character in the lean string.
+ * It must be a non-negative number smaller than the length
+ * of the lean text.
+ *
+ * @return the index of the corresponding character in the
+ * full string.
+ * The {@link #CxpHelper() no-op helper} returns pos
.
+ */
+ public int leanToFullPos(int pos) {
+ if (ced == null)
+ return pos;
+ return ced.leanToFullPos(pos);
+ }
+
+ /**
+ * After transforming a lean string into a full string
+ * using {@link #leanToFullText leanToFullText}, compute the index in the
+ * lean string of the character corresponding to the
+ * character with the specified position in the full string.
+ *
+ * @param pos is the index of a character in the full string.
+ * It must be a non-negative number smaller than the length
+ * of the full text.
+ *
+ * @return the index of the corresponding character in the
+ * lean string. If there is no corresponding
+ * character in the lean string (because the
+ * specified character is a directional formatting character
+ * added when invoking {@link #leanToFullText leanToFullText}),
+ * the value returned will be that corresponding to the
+ * next character which is not a directional formatting
+ * character.
+ * If pos
corresponds to a directional formatting
+ * character beyond all characters of the original
+ * lean text, the value returned is the length of the
+ * lean text.
+ * The {@link #CxpHelper() no-op helper} returns pos
.
+ */
+ public int fullToLeanPos(int pos) {
+ if (ced == null)
+ return pos;
+ return ced.fullToLeanPos(pos);
+ }
+
+ /**
+ * Get the base direction of the complex expression last
+ * submitted to {@link #leanToFullText leanToFullText}.
+ * This base direction may depend on
+ * whether the expression contains Arabic or Hebrew words
+ * (if it contains both, the first Arabic or Hebrew letter in the
+ * expression determines which is the governing script) and on
+ * whether the GUI is {@link CxpEnv#mirrored mirrored}.
+ *
+ * @return the base direction of the last submitted complex
+ * expression. It must be one of the values
+ * {@link CxpFeatures#DIR_LTR} or {@link CxpFeatures#DIR_RTL}.
+ * The {@link #CxpHelper() no-op helper} returns DIR_LTR
.
+ */
+ public int getCurDirection() {
+ if (ced == null)
+ return CxpFeatures.DIR_LTR;
+ return ced.getCurDirection();
+ }
+
+ /**
+ * Get the current environment under which the CxpHelper
+ * operates.
+ * This environment may have been specified in the constructor or
+ * specified later using {@link #setEnvironment setEnvironment}.
+ *
+ * @return the current environment.
+ * The {@link #CxpHelper() no-op helper} returns a {@link CxpEnv#DEFAULT DEFAULT}
+ * environment.
+ *
+ * @see #setEnvironment setEnvironment
+ */
+ public CxpEnv getEnvironment() {
+ if (ced == null)
+ return CxpEnv.DEFAULT;
+ return ced.getEnvironment();
+ }
+
+ /**
+ * Specify the environment under which the CxpHelper
+ * must operate.
+ *
+ * Note that calling this method causes the processor
+ * associated with this instance of CxpHelper
+ * to re-initialize its features. The effect of a previous call
+ * to {@link #setFeatures(CxpFeatures) setFeatures} is lost.
+ * The {@link #CxpHelper() no-op helper} does nothing.
+ *
+ * @see #getEnvironment getEnvironment
+ * @see ICxpProcessor#init2 ICxpProcessor.init2
+ */
+ public void setEnvironment(CxpEnv environment) {
+ if (ced == null) {
+ return; // do nothing
+ }
+ ced.setEnvironment(environment);
+ }
+
+ /**
+ * Get the current features of the processor associated with this
+ * CxpHelper
instance.
+ *
+ * @return the current features.
+ * The {@link #CxpHelper() no-op helper} returns {@link CxpFeatures#DEFAULT DEFAULT}
+ * features.
+ *
+ * @see #setFeatures setFeatures
+ */
+ public CxpFeatures getFeatures() {
+ if (ced == null)
+ return CxpFeatures.DEFAULT;
+ return ced.getFeatures();
+ }
+
+ /**
+ * Specify the features to be applied to the processor associated with this
+ * CxpHelper
instance.
+ * Note that the value of {@link CxpFeatures#specialsCount specialsCount}
+ * cannot be changed (the new value will be ignored).
+ * The {@link #CxpHelper() no-op helper} does nothing.
+ *
+ * @see #getFeatures getFeatures
+ */
+ public void setFeatures(CxpFeatures features) {
+ if (ced == null) {
+ return; // do nothing
+ }
+ ced.setFeatures(features);
+ }
+
+ /**
+ * This method can be called from within
+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or
+ * {@link ICxpProcessor#processSpecial processSpecial} in implementations
+ * of {@link ICxpProcessor} to retrieve the bidirectional class of
+ * characters in the lean text.
+ *
+ * @param index position of the character in the lean text.
+ * It must be a non-negative number smaller than the length
+ * of the lean text.
+ *
+ * @return the bidirectional class of the character. It is one of the
+ * values which can be returned by
+ * java.lang.Character#getDirectionality
.
+ * However, it is recommended to use getDirProp
+ * rather than java.lang.Character.getDirectionality
+ * since getDirProp
manages a cache of character
+ * properties and so can be more efficient than calling the
+ * java.lang.Character method.
+ * The {@link #CxpHelper() no-op helper} returns
+ * Character.DIRECTIONALITY_UNDEFINED
.
+ */
+ public byte getDirProp(int index) {
+ if (ced == null)
+ return Character.DIRECTIONALITY_UNDEFINED;
+ return ced.getDirProp(index);
+ }
+
+ /**
+ * This method can be called from within
+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or
+ * {@link ICxpProcessor#processSpecial processSpecial} in implementations
+ * of {@link ICxpProcessor} to set or override the bidirectional
+ * class of characters in the lean text.
+ *
+ * @param index position of the character in the lean text.
+ * It must be a non-negative number smaller than the length
+ * of the lean text.
+ *
+ * @param dirProp bidirectional class of the character. It is one of the
+ * values which can be returned by
+ * java.lang.Character.getDirectionality
.
+ * The {@link #CxpHelper() no-op helper} does nothing.
+ */
+ public void setDirProp(int index, byte dirProp) {
+ if (ced != null)
+ ced.getDirProp(index);
+ }
+
+ /**
+ * This method can be called from within
+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or
+ * {@link ICxpProcessor#processSpecial processSpecial} in implementations
+ * of {@link ICxpProcessor}
+ * to specify that a mark character must be added before the character
+ * at the specified position of the lean text when generating the
+ * full text. The mark character will be LRM for complex expressions
+ * with a LTR base direction, and RLM for complex expressions with RTL
+ * base direction. The mark character is not added physically by this
+ * method, but its position is noted and will be used when generating
+ * the full text.
+ *
+ * @param offset position of the character in the lean text.
+ * It must be a non-negative number smaller than the length
+ * of the lean text.
+ * For the benefit of efficiency, it is better to insert
+ * multiple marks in ascending order of the offsets.
+ * The {@link #CxpHelper() no-op helper} does nothing.
+ */
+ public void insertMark(int offset) {
+ if (ced != null)
+ ced.insertMark(offset);
+ }
+
+ /**
+ * This method can be called from within
+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or
+ * {@link ICxpProcessor#processSpecial processSpecial} in
+ * implementations of {@link ICxpProcessor} to add a
+ * directional mark before an
+ * operator if needed for correct display, depending on the
+ * base direction of the expression and on the class of the
+ * characters in the lean text preceding and following
+ * the operator itself.
+ * The {@link #CxpHelper() no-op helper} does nothing.
+ *
+ * @param operLocation offset of the operator in the lean text.
+ * It must be a non-negative number smaller than the length
+ * of the lean text.
+ */
+ public void processOperator(int operLocation) {
+ if (ced != null)
+ ced.processOperator(operLocation);
+ }
+
+ /**
+ * This method can be called from within
+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or
+ * {@link ICxpProcessor#processSpecial processSpecial} in
+ * implementations of {@link ICxpProcessor} to
+ * set the final state which should be used for the next call to
+ * {@link #leanToFullText(java.lang.String, int)}.
+ * The {@link #CxpHelper() no-op helper} does nothing.
+ */
+ public void setFinalState(int newState) {
+ if (ced != null)
+ ced.setFinalState(newState);
+ }
+
+}
Index: src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java
diff -N src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.bidi.complexp;
+
+import org.eclipse.equinox.bidi.internal.complexp.CxpDoer;
+
+/**
+ * Generic processor which can be used as superclass (base class)
+ * for specific complex expression processors.
+ *
+ * Here are some guidelines about how to write complex expression + * processors. + *
ceh
.
+ * All calls to methods of CxpProcessor
have a
+ * ceh
argument.
+ * If a processor needs to retain some data across invocations, it may
+ * access the field {@link CxpDoer#procData ceh.ced.procData}.
+ * It is guaranteed that this field will not be modified by any code
+ * except the processor itself.CxpProcessor
this method returns a
+ * {@link CxpFeatures#DEFAULT DEFAULT} value which
+ * directs the processor to do nothing.
+ */
+ public CxpFeatures init(CxpHelper ceh, CxpEnv env) {
+ return CxpFeatures.DEFAULT;
+ }
+
+ /**
+ * In CxpProcessor
this method simply calls the
+ * {@link #init init} method. If this is good enough, i.e.
+ * if the {@link CxpFeatures features} of the processor are
+ * determined identically for initialization and after a
+ * change in the {@link CxpEnv environment}, subclasses of
+ * CxpProcessor
don't need to override this
+ * method.
+ */
+ public CxpFeatures init2(CxpHelper ceh, CxpEnv env) {
+ return init(ceh, env);
+ }
+
+ /**
+ * In CxpProcessor
this method throws an
+ * IllegalStateException
. This is appropriate behavior
+ * (and does not need to be overridden) for processors whose
+ * {@link CxpFeatures#specialsCount specialsCount} is zero, which
+ * means that indexOfSpecial
should never be called
+ * for them.
+ */
+ public int indexOfSpecial(CxpHelper ceh, int whichSpecial, String srcText, int fromIndex) {
+ // This method must be overridden by all subclasses with special cases.
+ throw new IllegalStateException();
+ }
+
+ /**
+ * In CxpProcessor
this method throws an
+ * IllegalStateException
. This is appropriate behavior
+ * (and does not need to be overridden) for processors whose
+ * {@link CxpFeatures#specialsCount specialsCount} is zero, which
+ * means that processSpecial
should never be called
+ * for them.
+ */
+ public int processSpecial(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) {
+ // This method must be overridden by all subclasses with any special case.
+ throw new IllegalStateException();
+ }
+
+}
Index: src/org/eclipse/equinox/bidi/complexp/CxpUtil.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/CxpUtil.java
diff -N src/org/eclipse/equinox/bidi/complexp/CxpUtil.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/equinox/bidi/complexp/CxpUtil.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.bidi.complexp;
+
+/**
+ * This class provides a number of convenience functions facilitating the
+ * processing of complex expressions.
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ *
+ * @author Matitiahu Allouche
+ */
+final public class CxpUtil {
+
+ /**
+ * prevent instantiation
+ */
+ private CxpUtil() {
+ // empty
+ }
+
+ /** This is a convenience method which can add directional marks in a given
+ * text before the characters specified in the given array of offsets,
+ * and can add a prefix and/or a suffix of directional formatting characters.
+ * This can be used for instance after obtaining offsets by calling
+ * {@link CxpHelper#leanBidiCharOffsets() leanBidiCharOffsets} in order to
+ * produce a full text corresponding to the source text.
+ * The directional formatting characters that will be added at the given
+ * offsets will be LRMs for expressions with LTR base direction and
+ * RLMs for expressions with RTL base direction. Leading and
+ * trailing LRE, RLE and PDF which might be needed as prefix or suffix
+ * depending on the orientation of the GUI component used for display
+ * may be added depending on argument affix
.
+ *
+ * @param text is the text of the complex expression.
+ *
+ * @param offsets is an array of offsets to characters in text
+ * before which an LRM or RLM will be inserted.
+ * Members of the array must be non-negative numbers smaller
+ * than the length of text
.
+ * The array must be sorted in ascending order without duplicates.
+ * This argument may be null if there are no marks to add.
+ *
+ * @param direction specifies the base direction of the complex expression.
+ * It must be one of the values {@link CxpFeatures#DIR_LTR} or
+ * {@link CxpFeatures#DIR_RTL}.
+ *
+ * @param affix specifies if a prefix and a suffix should be added to
+ * the result to make sure that the direction
+ * specified as third argument is honored even if the expression
+ * is displayed in a GUI component with a different orientation.
+ *
+ * @return a string corresponding to the source text
with
+ * directional marks (LRMs or RLMs) added at the specified offsets,
+ * and directional formatting characters (LRE, RLE, PDF) added
+ * as prefix and suffix if so required.
+ */
+ public static String insertMarks(String text, int[] offsets, int direction, boolean affix) {
+ int textLen = text.length();
+ if (textLen == 0)
+ return ""; //$NON-NLS-1$
+
+ String curPrefix, curSuffix, full;
+ char curMark, c;
+ char[] fullChars;
+ if (direction == CxpFeatures.DIR_LTR) {
+ curMark = LRM;
+ curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$
+ curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$
+ } else {
+ curMark = RLM;
+ curPrefix = "\u202b\u200f"; /* RLE+RLM *///$NON-NLS-1$
+ curSuffix = "\u200f\u202c"; /* RLM+PDF *///$NON-NLS-1$
+ }
+ // add marks at offsets
+ if ((offsets != null) && (offsets.length > 0)) {
+ int offLen = offsets.length;
+ fullChars = new char[textLen + offLen];
+ int added = 0;
+ for (int i = 0, j = 0; i < textLen; i++) {
+ c = text.charAt(i);
+ if ((j < offLen) && (i == offsets[j])) {
+ fullChars[i + added] = curMark;
+ added++;
+ j++;
+ }
+ fullChars[i + added] = c;
+ }
+ full = new String(fullChars);
+ } else {
+ full = text;
+ }
+ if (affix)
+ return curPrefix + full + curSuffix;
+ return full;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* The following code is provided for compatibility with TextProcessor */
+ /* */
+ /*************************************************************************/
+
+ // The default set of delimiters to use to segment a string.
+ private static final String defaultDelimiters = ".:/\\"; //$NON-NLS-1$
+ // left to right mark
+ private static final char LRM = '\u200e';
+ // left to right mark
+ private static final char RLM = '\u200f';
+ // left to right embedding
+ private static final char LRE = '\u202a';
+ // right to left embedding
+ private static final char RLE = '\u202b';
+ // pop directional format
+ private static final char PDF = '\u202c';
+
+ static boolean isProcessingNeeded() {
+ if (!CxpEnv.isSupportedOS())
+ return false;
+ return CxpEnv.DEFAULT.isBidi();
+ }
+
+ /**
+ * Process the given text and return a string with appropriate
+ * directional formatting characters if the locale is a bidi locale.
+ * This is equivalent to calling
+ * {@link #process(String str, String delimiters)} with the default
+ * set of delimiters (dot, colon, slash, backslash).
+ *
+ * @param str the text to be processed.
+ *
+ * @return the processed string.
+ */
+ public static String process(String str) {
+ return process(str, defaultDelimiters);
+ }
+
+ /**
+ * Process a string that has a particular semantic meaning to render
+ * it correctly on bidi locales. This is done by adding directional
+ * formatting characters so that presentation using the Unicode
+ * Bidirectional Algorithm will provide the expected result.
+ * The text is segmented according to the provided delimiters.
+ * Each segment has the Unicode Bidi Algorithm applied to it,
+ * but as a whole, the string is oriented left to right.
+ * + * For example, a file path such as d:\myfolder\FOLDER\MYFILE.java + * (where capital letters indicate RTL text) should render as + * d:\myfolder\REDLOF\ELIFYM.java.
+ *
+ * NOTE: this method inserts directional formatting characters into the
+ * text. Methods like String.equals(String)
and
+ * String.length()
called on the resulting string will not
+ * return the same values as would be returned for the original string.
null
, the default delimiters are used
+ * (dot, colon, slash, backslash).
+ *
+ * @return the processed string.
+ * If str
is null
,
+ * or of length 0, or if the current locale is not a bidi one,
+ * return the original string.
+ */
+ public static String process(String str, String delimiters) {
+ if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
+ return str;
+
+ // do not process a string that has already been processed.
+ if (str.charAt(0) == LRE && str.charAt(str.length() - 1) == PDF)
+ return str;
+
+ // do not process a string if all the following conditions are true:
+ // a) it has no RTL characters
+ // b) it starts with a LTR character
+ // c) it ends with a LTR character or a digit
+ boolean isStringBidi = false;
+ int strLength = str.length();
+ char c;
+ for (int i = 0; i < strLength; i++) {
+ c = str.charAt(i);
+ if (((c >= 0x05d0) && (c <= 0x07b1)) || ((c >= 0xfb1d) && (c <= 0xfefc))) {
+ isStringBidi = true;
+ break;
+ }
+ }
+ while (!isStringBidi) {
+ if (!Character.isLetter(str.charAt(0)))
+ break;
+ c = str.charAt(strLength - 1);
+ if (!Character.isDigit(c) && !Character.isLetter(c))
+ break;
+ return str;
+ }
+
+ if (delimiters == null)
+ delimiters = defaultDelimiters;
+
+ // make sure that LRE/PDF are added around the string
+ CxpEnv env = new CxpEnv(null, false, CxpEnv.ORIENT_UNKNOWN);
+ CxpHelper helper = new CxpHelper(new CxpProcessor(), env);
+ helper.setFeatures(new CxpFeatures(delimiters, 0, -1, -1, false, false));
+ return helper.leanToFullText(str);
+ }
+
+ /**
+ * Process a string that has a particular semantic meaning to render
+ * it correctly on bidi locales. This is done by adding directional
+ * formatting characters so that presentation using the Unicode
+ * Bidirectional Algorithm will provide the expected result..
+ * The text is segmented according to the syntax specified in the
+ * type
argument.
+ * Each segment has the Unicode Bidi Algorithm applied to it, but the
+ * order of the segments is governed by the type of the complex expression.
+ * + * For example, a file path such as d:\myfolder\FOLDER\MYFILE.java + * (where capital letters indicate RTL text) should render as + * d:\myfolder\REDLOF\ELIFYM.java.
+ *
+ * NOTE: this method inserts directional formatting characters into the
+ * text. Methods like String.equals(String)
and
+ * String.length()
called on the resulting string will not
+ * return the same values as would be returned for the original string.
str
is null
,
+ * or of length 0, or if the current locale is not a bidi one,
+ * return the original string.
+ */
+ public static String processTyped(String str, String type) {
+ if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
+ return str;
+
+ // do not process a string that has already been processed.
+ char c = str.charAt(0);
+ if (((c == LRE) || (c == RLE)) && str.charAt(str.length() - 1) == PDF)
+ return str;
+
+ // make sure that LRE/PDF are added around the string
+ CxpEnv env = new CxpEnv(null, false, CxpEnv.ORIENT_UNKNOWN);
+ CxpHelper helper = new CxpHelper(type, env);
+ return helper.leanToFullText(str);
+ }
+
+ /**
+ * Remove directional formatting characters in the given string that
+ * were inserted by one of the {@link #process process} methods.
+ *
+ * @param str string with directional characters to remove.
+ *
+ * @return string with no directional formatting characters.
+ */
+ public static String deprocess(String str) {
+ if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
+ return str;
+
+ StringBuffer buf = new StringBuffer();
+ int strLen = str.length();
+ for (int i = 0; i < strLen; i++) {
+ char c = str.charAt(i);
+ switch (c) {
+ case LRM :
+ continue;
+ case LRE :
+ continue;
+ case PDF :
+ continue;
+ default :
+ buf.append(c);
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Remove directional formatting characters in the given string that
+ * were inserted by the {@link #processTyped processTyped} method.
+ *
+ * @param str string with directional characters to remove.
+ *
+ * @param type type of the complex expression as specified when
+ * calling {@link #processTyped processTyped}.
+ *
+ * @return string with no directional formatting characters.
+ */
+ public static String deprocess(String str, String type) {
+ if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
+ return str;
+
+ // make sure that LRE/PDF are added around the string
+ CxpEnv env = new CxpEnv(null, false, CxpEnv.ORIENT_UNKNOWN);
+ CxpHelper helper = new CxpHelper(type, env);
+ return helper.fullToLeanText(str);
+ }
+
+}
Index: src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java
diff -N src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java
--- src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java 3 Feb 2010 20:00:59 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package org.eclipse.equinox.bidi.complexp;
-
-/**
- * Bi-directional processors supplied in this bundle.
- *
- * @noextend This interface is not intended to be extended by clients.
- */
-public interface IBiDiProcessor {
-
- /**
- * Constant indicating a type of complex expression processor adapted
- * to processing property file statements. It expects the following
- * string format:
- * - * name=value - *- */ - public String PROPERTY = "property"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing compound names. - * This type covers names made of one or more parts separated by underscores: - *
- * part1_part2_part3 - *- */ - public String UNDERSCORE = "underscore"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing comma-delimited lists, such as: - *
- * part1,part2,part3 - *- */ - public String COMMA_DELIMITED = "comma"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing expressions with the following string format: - *
- * system(user) - *- */ - public String SYSTEM_USER = "system"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing directory and file paths. - */ - public String FILE = "file"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing e-mail addresses. - */ - public String EMAIL = "email"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing URLs. - */ - public String URL = "url"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing regular expressions, possibly spanning more than one - * line. - */ - public String REGEXP = "regex"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing XPath expressions. - */ - public String XPATH = "xpath"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing Java code, possibly spanning more than one line. - */ - public String JAVA = "java"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing SQL statements, possibly spanning more than one line. - */ - public String SQL = "sql"; //$NON-NLS-1$ - - /** - * Constant indicating a type of complex expression processor adapted - * to processing arithmetic expressions with a RTL base direction. - */ - public String RTL_ARITHMETIC = "math"; //$NON-NLS-1$ -} Index: src/org/eclipse/equinox/bidi/complexp/ICxpProcessor.java =================================================================== RCS file: src/org/eclipse/equinox/bidi/complexp/ICxpProcessor.java diff -N src/org/eclipse/equinox/bidi/complexp/ICxpProcessor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/equinox/bidi/complexp/ICxpProcessor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ +package org.eclipse.equinox.bidi.complexp; + +import org.eclipse.equinox.bidi.internal.complexp.CxpDoer; + +/** + * Interface for all complex expression processors. + * For guidelines about implementation, see + * {@link CxpProcessor}. + * + * @author Matitiahu Allouche + */ +public interface ICxpProcessor { + + /** + * Do whatever initializations are needed and return the + * {@link CxpFeatures} characterizing the processor. + * + * @param env the current environment, which may affect the + * initializations. + * + * @param ceh
CxpHelper
instance which called this method.
+ * This allows access to the field
+ * {@link CxpDoer#procData ceh.ced.procData} where
+ * the processor can keep whatever data it needs.
+ *
+ * @return the features in use for this processor.
+ */
+ public abstract CxpFeatures init(CxpHelper ceh, CxpEnv env);
+
+ /**
+ * Do whatever renewed initializations are needed after a
+ * change in the environment and return the possibly updated
+ * {@link CxpFeatures} characterizing the processor.
+ *
+ * @param env the updated environment, which may affect the
+ * initializations.
+ *
+ * @param ceh CxpHelper
instance which called this method.
+ * This allows access to the field
+ * {@link CxpDoer#procData ceh.ced.procData} where
+ * the processor can keep whatever data it needs.
+ *
+ * @return the features to use for this processor.
+ */
+ public CxpFeatures init2(CxpHelper ceh, CxpEnv env);
+
+ /**
+ * Locate occurrences of special strings within a complex expression
+ * and return their indexes one after the other in successive calls.
+ * + * This method is called repeatedly from the code implementing + * {@link CxpHelper#leanToFullText leanToFullText} if the field + * {@link CxpFeatures#specialsCount specialsCount} returned when + * {@link #init initializing} the processor is greater than zero. + *
+ * The code implementing this method may use the following methods + * in {@link CxpHelper}: + *
specialsCount - 1
.
+ * The meaning of this number is internal to the class
+ * implementing indexOfSpecial
.
+ *
+ * @param srcText text of the complex expression before addition of any
+ * directional formatting characters.
+ *
+ * @param fromIndex the index within srcText
to start
+ * the search from.
+ *
+ * @return the position where the start of the special case was located.
+ * The method must return the first occurrence of whatever
+ * identifies the start of the special case starting from
+ * fromIndex
. The method does not have to check if
+ * this occurrence appears within the scope of another special
+ * case (e.g. a comment starting delimiter within the scope of
+ * a literal or vice-versa).
+ * + * The code implementing this method may use the following methods + * in {@link CxpHelper}: + *
+ * If a special processing cannot be completed within a current call to
+ * processSpecial
(for instance, a comment has been started
+ * in the current line but its end appears in a following line),
+ * processSpecial
should specify a final state using
+ * the method {@link CxpHelper#setFinalState setFinalState}.
+ * The meaning of this state is internal to the processor.
+ * On a later call to
+ * {@link CxpHelper#leanToFullText(String text, int initState)}
+ * specifying that state value, processSpecial
will be
+ * called with that value for parameter whichSpecial
and
+ * -1
for parameter operLocation
and should
+ * perform whatever initializations are required depending on the state.
+ *
+ * @param whichSpecial number of the special case to handle.
+ *
+ * @param srcText text of the complex expression.
+ *
+ * @param operLocation the position returned by
+ * {@link #indexOfSpecial indexOfSpecial}. In calls to
+ * {@link CxpHelper#leanToFullText(String text, int initState)} or
+ * {@link CxpHelper#fullToLeanText(String text, int initState)}
+ * specifying an initState
+ * parameter, processSpecial
is called when initializing
+ * the processing with the value of whichSpecial
+ * equal to initState
and the value of
+ * operLocation
equal to -1
.
+ *
+ * @return the position after the scope of the special case ends.
+ * For instance, the position after the end of a comment,
+ * the position after the end of a literal.
+ *
A value greater or equal to the length of srcText
+ * means that there is no further occurrence of this case in the
+ * current complex expression.
+ */
+ public int processSpecial(CxpHelper ceh, int whichSpecial, String srcText, int operLocation);
+
+}
Index: src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java
===================================================================
RCS file: src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java
diff -N src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.bidi.complexp;
+
+/**
+ * Bidirectional processors supplied in this bundle.
+ *
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IProcessorTypes {
+
+ /**
+ * Constant indicating a type of complex expression processor adapted
+ * to processing property file statements. It expects the following
+ * string format:
+ *
+ * name=value + *+ */ + public String PROPERTY = "property"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing compound names. + * This type covers names made of one or more parts separated by underscores: + *
+ * part1_part2_part3 + *+ */ + public String UNDERSCORE = "underscore"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing comma-delimited lists, such as: + *
+ * part1,part2,part3 + *+ */ + public String COMMA_DELIMITED = "comma"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing expressions with the following string format: + *
+ * system(user) + *+ */ + public String SYSTEM_USER = "system"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing directory and file paths. + */ + public String FILE = "file"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing e-mail addresses. + */ + public String EMAIL = "email"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing URLs. + */ + public String URL = "url"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing regular expressions, possibly spanning more than one + * line. + */ + public String REGEXP = "regex"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing XPath expressions. + */ + public String XPATH = "xpath"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing Java code, possibly spanning more than one line. + */ + public String JAVA = "java"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing SQL statements, possibly spanning more than one line. + */ + public String SQL = "sql"; //$NON-NLS-1$ + + /** + * Constant indicating a type of complex expression processor adapted + * to processing arithmetic expressions with a RTL base direction. + */ + public String RTL_ARITHMETIC = "math"; //$NON-NLS-1$ +} Index: src/org/eclipse/equinox/bidi/complexp/StringProcessor.java =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/complexp/StringProcessor.java,v retrieving revision 1.1 diff -u -r1.1 StringProcessor.java --- src/org/eclipse/equinox/bidi/complexp/StringProcessor.java 3 Feb 2010 20:00:59 -0000 1.1 +++ src/org/eclipse/equinox/bidi/complexp/StringProcessor.java 4 Jan 2011 18:03:21 -0000 @@ -10,22 +10,31 @@ ******************************************************************************/ package org.eclipse.equinox.bidi.complexp; -import org.eclipse.equinox.bidi.internal.complexp.BiDiTypesCollector; +import org.eclipse.equinox.bidi.internal.complexp.BidiTypesCollector; /** - * The API part for the TextProcessor replacement. + * This class provides access to registered complex expression processors. */ -// TBD processors currently are not thread-safe (ComplExpBasic has class variables containing -// parsing state). This means that either: -// a) a new instance of the processor needs to be created for every call; -// b) processors have to be made thread-safe. public class StringProcessor { + /** + * Retrieve all registered types of complex expression processors. + * + * @return an array of strings, each string identifying a type of + * complex expression processor. + */ + static public String[] getKnownTypes() { + return BidiTypesCollector.getInstance().getTypes(); + } - static public String[] getKnownTypes() { - return BiDiTypesCollector.getInstance().getTypes(); - } - - static public IComplExpProcessor getProcessor(String type) { - return BiDiTypesCollector.getInstance().getProcessor(type); - } + /** + * Get access to a complex expression processor of a given type. + * + * @param type string identifying a type of processor + * + * @return a reference to an instance of a processor of the + * required type. If the type is unknown, return
null
.
+ */
+ static public ICxpProcessor getProcessor(String type) {
+ return BidiTypesCollector.getInstance().getProcessor(type);
+ }
}
Index: src/org/eclipse/equinox/bidi/complexp/package.html
===================================================================
RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/complexp/package.html,v
retrieving revision 1.1
diff -u -r1.1 package.html
--- src/org/eclipse/equinox/bidi/complexp/package.html 2 Feb 2010 21:55:25 -0000 1.1
+++ src/org/eclipse/equinox/bidi/complexp/package.html 4 Jan 2011 18:03:21 -0000
@@ -5,7 +5,7 @@
-This package provides an interface and implementing classes for
+This package provides interfaces and classes for
processing complex expressions.
@@ -14,10 +14,10 @@
Bidirectional text offers interesting challenges to presentation systems.
For plain text, the Unicode Bidirectional Algorithm
(UBA)
-generally specifies satisfactorily how to reorder Bidirectional text for
+generally specifies satisfactorily how to reorder bidirectional text for
display. This algorithm is implemented in Java's presentation system.
-However, all Bidirectional text is not necessarily plain text. There +However, all bidirectional text is not necessarily plain text. There are also instances of text structured to follow a given syntax, which should be reflected in the display order. The general algorithm, which has no awareness of these special cases, often gives incorrect results @@ -27,37 +27,22 @@ formatting characters at proper locations in the text to supplement the standard algorithm, so that the final result is correctly displayed using the UBA. -A class which handles complex expressions is thus a transformation -engine which receives text without directional formatting characters -as input and produces as output the same text with added directional -formatting characters, hopefully in the minimum quantity which is -sufficient to ensure correct display, considering the type of complex -expression involved.
+A class which handles complex expressions is thus essentially a +transformation engine which receives text without directional formatting +characters as input and produces as output the same text with added +directional formatting characters, hopefully in the minimum quantity +which is sufficient to ensure correct display, considering the type of +complex expression involved.In this package, text without directional formatting characters is called lean text while the text with added directional formatting characters is called full text.
-{@link IComplExpProcessor} provides
-an interface for processing complex expressions. This package also
-includes several classes which implement IComplExpProcessor
,
-all of them based on class
-{@link ComplExpBasic}.
-
-There is also a class named
-ComplExpDoNothing
which actually adds no directional
-formatting characters. It can be considered as a null processor in
-relation to complex expressions. This class has a very small overhead and
-can be used as a low-cost default processor when no complex expression is
-involved and no processing is needed, but a general framework of
-handling complex expressions must be preserved.
-The class {@link ComplExpBasic} can -handle several types of relatively simple complex expressions.
-
-A number of subclasses of ComplExpBasic
are included in this
-package, each one adapted to handle some type of complex expression.
-The explicitly supported types are:
+The class {@link CxpHelper} is the main
+tool for processing complex expressions. It facilitates
+handling several types of complex expressions, each type
+being handled by a specific
+{@link processor} :
-More types can be supported using the classes provided in the package.
-It is also possible to develop new classes to handle types of
-complex expressions which cannot be supported with the existing classes.
-Using the framework provided by IComplExpProcessor
and
-ComplExpBasic
can facilitate
-considerably the development of such new support.
-The class {@link ComplExpUtil} provides -a number of convenience methods to process some common types of -complex expressions. When using methods in this class, there is no need -to refer to members of other classes of this package. -However, the other classes allow more precise control and possibly better -performance.
+Other classes and one interface in this package may be used to +complement and facilitate the action of +{@link CxpHelper}: ++{@link CxpHelper} and the other classes and +interface mentioned above are intended for users who need to process +complex expressions for which there already exist processors. +
+Developers who want to develop new processors to support types of complex +expressions not currently supported can use the following components of the +present package: +
+There are two other packages associated with the current one: +
+However, users wishing to process the currently supported types of +complex expressions typically don't need to interact with these +two packages.
@@ -121,15 +143,15 @@
The proposed solution is making extensive usage of LRM, RLM, LRE, RLE -and PDF directional controls which are invisible but affect the way Bidi -text is displayed. The following related two key points merit special +and PDF directional controls which are invisible but affect the way bidi +text is displayed. The following related key points merit special attention:
- -