Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 188627 Details for
Bug 183164
[Implementation for] Display of Complex Expressions Containing Bidirectional Text
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Slightly updated "new version for bidi complex expression" patches
patch bidi 2011 1.txt (text/plain), 484.58 KB, created by
Oleg Besedin
on 2011-02-09 16:28:21 EST
(
hide
)
Description:
Slightly updated "new version for bidi complex expression" patches
Filename:
MIME Type:
Creator:
Oleg Besedin
Created:
2011-02-09 16:28:21 EST
Size:
484.58 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.equinox.bidi >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/META-INF/MANIFEST.MF,v >retrieving revision 1.3 >diff -u -r1.3 MANIFEST.MF >--- META-INF/MANIFEST.MF 22 Feb 2010 14:41:30 -0000 1.3 >+++ META-INF/MANIFEST.MF 9 Feb 2011 21:27:30 -0000 >@@ -7,13 +7,15 @@ > Bundle-Localization: plugin > Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.2 > Bundle-ActivationPolicy: lazy >-Export-Package: org.eclipse.equinox.bidi.complexp, >- org.eclipse.equinox.bidi.internal.complexp;x-internal:=true, >- org.eclipse.equinox.bidi.internal.complexp.consumable;x-internal:=true >+Export-Package: org.eclipse.equinox.bidi, >+ org.eclipse.equinox.bidi.custom, >+ org.eclipse.equinox.bidi.internal;x-internal:=true, >+ org.eclipse.equinox.bidi.internal.consumable;x-internal:=true > Require-Bundle: org.eclipse.equinox.common;bundle-version="3.6.0", > org.eclipse.equinox.registry;bundle-version="3.5.0" > Import-Package: org.eclipse.osgi.framework.log;version="1.0.0", >+ org.eclipse.osgi.service.localization;version="1.1.0", > org.eclipse.osgi.util;version="1.1.0", > org.osgi.framework;version="1.5.0", > org.osgi.util.tracker;version="1.4.0" >-Bundle-Activator: org.eclipse.equinox.bidi.internal.complexp.BiDiActivator >+Bundle-Activator: org.eclipse.equinox.bidi.internal.BidiComplexActivator >Index: build.properties >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/build.properties,v >retrieving revision 1.1 >diff -u -r1.1 build.properties >--- build.properties 2 Feb 2010 21:55:25 -0000 1.1 >+++ build.properties 9 Feb 2011 21:27:30 -0000 >@@ -13,9 +13,9 @@ > bin.includes = plugin.xml,\ > META-INF/,\ > .,\ >- .options,\ > about.html,\ >- plugin.properties >+ plugin.properties,\ >+ schema/ > src.includes = about.html,\ > schema/ > jre.compilation.profile = J2SE-1.3 >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/plugin.xml,v >retrieving revision 1.2 >diff -u -r1.2 plugin.xml >--- plugin.xml 3 Feb 2010 20:01:00 -0000 1.2 >+++ plugin.xml 9 Feb 2011 21:27:30 -0000 >@@ -8,61 +8,61 @@ > point="org.eclipse.equinox.bidi.bidiTypes"> > <typeDescription > description="%sqlProcessorName" >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpSql" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexSql" > type="sql"> > </typeDescription> > <typeDescription > description="%regexProcessorName" >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpRegex" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexRegex" > type="regex"> > </typeDescription> > <typeDescription > description="%javaProcessorName" >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpJava" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexJava" > type="java"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpComma" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexComma" > description="%commaProcessorName" > type="comma"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpEmail" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexEmail" > description="%emailProcessorName" > type="email"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpFile" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexFile" > description="%fileProcessorName" > type="file"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpMath" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexMath" > description="%mathProcessorName" > type="math"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpProperty" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexProperty" > description="%propertyProcessorName" > type="property"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpSystem" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexSystem" > description="%systemProcessorName" > type="system"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpUnderscore" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexUnderscore" > description="%underscoreProcessorName" > type="underscore"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpURL" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexURL" > description="%urlProcessorName" > type="url"> > </typeDescription> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.complexp.consumable.ComplExpXPath" >+ class="org.eclipse.equinox.bidi.internal.consumable.BidiComplexXPath" > description="%xpathProcessorName" > type="xpath"> > </typeDescription> >Index: schema/BiDiExpressionType.exsd >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/schema/BiDiExpressionType.exsd,v >retrieving revision 1.2 >diff -u -r1.2 BiDiExpressionType.exsd >--- schema/BiDiExpressionType.exsd 3 Feb 2010 20:01:02 -0000 1.2 >+++ schema/BiDiExpressionType.exsd 9 Feb 2011 21:27:30 -0000 >@@ -63,7 +63,7 @@ > The processor that provides specialized bi-directional handling for this type of strings. > </documentation> > <appInfo> >- <meta.attribute kind="java" basedOn=":org.eclipse.equinox.bidi.complexp.IComplExpProcessor"/> >+ <meta.attribute kind="java" basedOn=":org.eclipse.equinox.bidi.custom.IBidiComplexProcessor"/> > </appInfo> > </annotation> > </attribute> >Index: src/org/eclipse/equinox/bidi/BidiComplexEnvironment.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/BidiComplexEnvironment.java >diff -N src/org/eclipse/equinox/bidi/BidiComplexEnvironment.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/BidiComplexEnvironment.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,315 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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; >+ >+import java.util.Locale; >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+import org.eclipse.equinox.bidi.internal.BidiComplexActivator; >+ >+/** >+ * This class defines certain details of the environment within which >+ * complex expressions are processed. >+ * <p> >+ * All public fields in this class are <code>final</code>, i.e. cannot be >+ * changed after creating an instance. >+ * <p> >+ * A <code>BidiComplexEnvironment</code> instance can be associated with a <code>BidiComplexHelper</code> >+ * instance either when creating the >+ * {@link BidiComplexHelper#BidiComplexHelper(java.lang.String, BidiComplexEnvironment) BidiComplexHelper} instance >+ * or using the {@link BidiComplexHelper#setEnvironment setEnvironment} method. >+ * >+ * <h2>Code Samples</h2> >+ * <p>Example 1 (set all environment parameters) >+ * <pre> >+ * >+ * BidiComplexEnvironment myEnv = new BidiComplexEnvironment("he_IL", true, BidiComplexEnvironment.ORIENT_RTL); >+ * BidiComplexHelper myHelper = new BidiComplexHelper(IBidiComplexExpressionTypes.FILE, myEnv); >+ * >+ * </pre> >+ * <p>Example 2 (change only the orientation) >+ * <pre> >+ * >+ * BidiComplexEnvironment env1 = myHelper.getEnvironment(); >+ * BidiComplexEnvironment env2 = new BidiComplexEnvironment(env1.language, env1.mirrored, BidiComplexEnvironment.ORIENT_UNKNOWN); >+ * myHelper.setEnvironment(env2); >+ * >+ * </pre> >+ * <p> >+ * This class also provides a number of convenience methods related to the environment. >+ * <p> </p> >+ * @see BidiComplexHelper#BidiComplexHelper(String, BidiComplexEnvironment) >+ * @see BidiComplexHelper#BidiComplexHelper(IBidiComplexProcessor, BidiComplexEnvironment) >+ * @see BidiComplexHelper#getEnvironment BidiComplexHelper.getEnvironment >+ * @see BidiComplexHelper#setEnvironment BidiComplexHelper.setEnvironment >+ * @see IBidiComplexProcessor#init IBidiComplexProcessor.init >+ * @see IBidiComplexProcessor#updateEnvironment IBidiComplexProcessor.updateEnvironment >+ * >+ * @author Matitiahu Allouche >+ */ >+public class BidiComplexEnvironment { >+ >+ /** >+ * Constant specifying that the orientation of the GUI component >+ * where a complex expression will be displayed is LTR. >+ * It can appear as <code>orientation</code> argument for >+ * {@link BidiComplexEnvironment#BidiComplexEnvironment BidiComplexEnvironment constructor} and as value for the >+ * {@link BidiComplexEnvironment#orientation} member of <code>BidiComplexEnvironment</code>. >+ */ >+ 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 <code>orientation</code> argument for >+ * {@link BidiComplexEnvironment#BidiComplexEnvironment BidiComplexEnvironment constructor} and as value for the >+ * {@link BidiComplexEnvironment#orientation} member of <code>BidiComplexEnvironment</code>. >+ */ >+ 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 <code>orientation</code> argument for >+ * {@link BidiComplexEnvironment#BidiComplexEnvironment BidiComplexEnvironment constructor} and as value for the >+ * {@link BidiComplexEnvironment#orientation} member of <code>BidiComplexEnvironment</code>. >+ */ >+ 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 <code>orientation</code> argument for >+ * {@link BidiComplexEnvironment#BidiComplexEnvironment BidiComplexEnvironment constructor} and as value for the >+ * {@link BidiComplexEnvironment#orientation} member of <code>BidiComplexEnvironment</code>. >+ */ >+ 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 <i>full</i> text is generated using >+ * {@link BidiComplexHelper#leanToFullText leanToFullText}. >+ * It can appear as <code>orientation</code> argument for >+ * {@link BidiComplexEnvironment#BidiComplexEnvironment BidiComplexEnvironment constructor} and as value for the >+ * {@link BidiComplexEnvironment#orientation} member of <code>BidiComplexEnvironment</code>. >+ */ >+ 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 <i>full</i> text is generated using >+ * {@link BidiComplexHelper#leanToFullText leanToFullText}. >+ * It can appear as <code>orientation</code> argument for >+ * {@link BidiComplexEnvironment#BidiComplexEnvironment BidiComplexEnvironment constructor} and as value for the >+ * {@link BidiComplexEnvironment#orientation} member of <code>BidiComplexEnvironment</code>. >+ */ >+ public static final int ORIENT_IGNORE = 5; >+ >+ /** >+ * Pre-defined <code>BidiComplexEnvironment</code> instance with values for a non-mirrored GUI >+ * and a Left-to-Right presentation component.<br> >+ * The language is set to <code>null</code>, which defaults to the language >+ * of the current default locale. >+ */ >+ public static final BidiComplexEnvironment DEFAULT = new BidiComplexEnvironment(null, false, ORIENT_LTR); >+ >+ /** >+ * This string is a 2-letters code representing a language as defined by >+ * ISO-639. If left as <code>null</code>, 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 <i>full</i> text of the complex expression will >+ * be displayed.<br> >+ * The orientation must have 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}. >+ * <p> >+ * When the orientation is <code>ORIENT_LTR</code> and the complex >+ * expression has a RTL base direction, >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * adds RLE+RLM at the head of the <i>full</i> text and RLM+PDF at its >+ * end. >+ * <p> >+ * When the orientation is <code>ORIENT_RTL</code> and the complex >+ * expression has a LTR base direction, >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * adds LRE+LRM at the head of the <i>full</i> text and LRM+PDF at its >+ * end. >+ * <p> >+ * When the orientation is <code>ORIENT_CONTEXTUAL_LTR</code> or >+ * <code>ORIENT_CONTEXTUAL_RTL</code> and the data content would resolve >+ * to a RTL orientation while the complex expression has a LTR base >+ * direction, {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * adds LRM at the head of the <i>full</i> text. >+ * <p> >+ * When the orientation is <code>ORIENT_CONTEXTUAL_LTR</code> or >+ * <code>ORIENT_CONTEXTUAL_RTL</code> and the data content would resolve >+ * to a LTR orientation while the complex expression has a RTL base >+ * direction, {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * adds RLM at the head of the <i>full</i> text. >+ * <p> >+ * When the orientation is <code>ORIENT_UNKNOWN</code> and the complex >+ * expression has a LTR base direction, >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * adds LRE+LRM at the head of the <i>full</i> text and LRM+PDF at its >+ * end. >+ * <p> >+ * When the orientation is <code>ORIENT_UNKNOWN</code> and the complex >+ * expression has a RTL base direction, >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * adds RLE+RLM at the head of the <i>full</i> text and RLM+PDF at its >+ * end. >+ * <p> >+ * When the orientation is <code>ORIENT_IGNORE</code>, >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} does not add any directional >+ * formatting characters as either prefix or suffix of the <i>full</i> text. >+ * <p> >+ */ >+ public final int orientation; >+ >+ static Locale defaultLocale; >+ static String defaultLanguage; >+ static boolean defaultBidi; >+ 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.<br> >+ * If longer than 2 letters, the extra letters are ignored.<br> >+ * If set to <code>null</code>, 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}.<br> >+ * If different, it defaults to {@link #ORIENT_UNKNOWN ORIENT_UNKNOWN}. >+ * @see #orientation >+ */ >+ public BidiComplexEnvironment(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 <code>true</code> if the current language uses a bidi script. >+ * The language may have been set explicitly when creating the >+ * <code>BidiComplexEnvironment</code> instance, or it may have defaulted to >+ * the language of the current default locale. >+ * @see #BidiComplexEnvironment BidiComplexEnvironment >+ */ >+ public boolean isBidi() { >+ if (defaultLanguage != null && defaultLocale.equals(getDefaultLocale())) >+ return defaultBidi; >+ >+ if (language == null) { >+ defaultLocale = getDefaultLocale(); >+ defaultLanguage = defaultLocale.getLanguage(); >+ defaultBidi = isBidiLanguage(defaultLanguage); >+ return defaultBidi; >+ } >+ >+ 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() { >+ // use bundle properties >+ if (lineSep == null) { >+ // lineSep = System.getProperty("line.separator", "\n"); //$NON-NLS-1$//$NON-NLS-2$ >+ lineSep = getProperty("line.separator"); //$NON-NLS-1$/ >+ } >+ return lineSep; >+ } >+ >+ static String osName; >+ static boolean flagOS; >+ >+ private static String getProperty(String key) { >+ // use bundle properties >+ // osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ >+ BidiComplexActivator bidiComplexActivator = BidiComplexActivator.getInstance(); >+ return bidiComplexActivator.getProperty(key); >+ } >+ >+ private Locale getDefaultLocale() { >+ BidiComplexActivator bidiComplexActivator = BidiComplexActivator.getInstance(); >+ return bidiComplexActivator.getDefaultLocale(); >+ } >+ >+ /** >+ * Check if the current OS is supported by the complex expression packages. >+ * >+ * @return <code>true</code> if the current OS is supported. >+ */ >+ public static boolean isSupportedOS() { >+ if (osName == null) { >+ // use bundle properties >+ // osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ >+ osName = 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/BidiComplexFeatures.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/BidiComplexFeatures.java >diff -N src/org/eclipse/equinox/bidi/BidiComplexFeatures.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/BidiComplexFeatures.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,190 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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; >+ >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+ >+/** >+ * This class defines features of a complex expression processor. >+ * <p> >+ * All public fields in this class are <code>final</code>, i.e. cannot be >+ * changed after creating an instance. >+ * <p> >+ * A <code>BidiComplexFeatures</code> instance can be associated with a >+ * <code>BidiComplexHelper</code> instance using >+ * the {@link BidiComplexHelper#setFeatures setFeatures} method. >+ * >+ * <h2>Code Samples</h2> >+ * <p>Example 1 (set all features) >+ * <pre> >+ * >+ * BidiComplexFeatures myFeatures = new BidiComplexFeatures("+-=", 0, -1, -1, false, false); >+ * BidiComplexHelper myHelper = new BidiComplexHelper(IBidiComplexExpressionTypes.FILE, myEnv); >+ * myHelper.setFeatures(myFeatures); >+ * >+ * </pre> >+ * <p>Example 2 (change only the operators) >+ * <pre> >+ * >+ * BidiComplexFeatures f1 = myHelper.getFeatures(); >+ * BidiComplexFeatures f2 = new BidiComplexFeatures("[]|()", f1.specialsCount, >+ * f1.dirArabic, f1.dirHebrew, >+ * f1.ignoreArabic, f1.ignoreHebrew); >+ * myHelper.setFeatures(f2); >+ * >+ * </pre> >+ * >+ * @see BidiComplexHelper#getFeatures BidiComplexHelper.getFeatures >+ * @see BidiComplexHelper#setFeatures BidiComplexHelper.setFeatures >+ * @see IBidiComplexProcessor#init IBidiComplexProcessor.init >+ * @see IBidiComplexProcessor#updateEnvironment IBidiComplexProcessor.updateEnvironment >+ * >+ * @author Matitiahu Allouche >+ */ >+public class BidiComplexFeatures { >+ >+ /** >+ * Constant specifying that the base direction of a complex expression is LTR. >+ * The base direction may depend on whether the GUI is >+ * {@link BidiComplexEnvironment#mirrored mirrored} and may >+ * may be different for Arabic and for Hebrew. >+ * This constant can appear as <code>dirArabic</code> >+ * or <code>dirHebrew</code> argument for >+ * {@link BidiComplexFeatures#BidiComplexFeatures BidiComplexFeatures constructor} and as value >+ * for the {@link #dirArabic} or {@link #dirHebrew} members of >+ * <code>BidiComplexFeatures</code>. >+ */ >+ 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 BidiComplexEnvironment#mirrored mirrored} and may >+ * may be different for Arabic and for Hebrew. >+ * This constant can appear as <code>dirArabic</code> >+ * or <code>dirHebrew</code> argument for >+ * {@link BidiComplexFeatures#BidiComplexFeatures BidiComplexFeatures constructor} and as value >+ * for the {@link #dirArabic} or {@link #dirHebrew} members of >+ * <code>BidiComplexFeatures</code>. >+ */ >+ public static final int DIR_RTL = 1; >+ >+ /** >+ * Pre-defined <code>BidiComplexFeatures</code> instance with values for no >+ * operators, no special processing, all directions LTR >+ * and support for neither Arabic nor Hebrew.<br> >+ * Since there are no operators and no special processing, a complex >+ * expression processor with such features would do nothing.<br> >+ * It is more efficient to do nothing with a >+ * {@link BidiComplexHelper#BidiComplexHelper() BidiComplexHelper} >+ * instantiated with no arguments. >+ */ >+ public static final BidiComplexFeatures DEFAULT = new BidiComplexFeatures(null, 0, -1, -1, true, true); >+ >+ /** >+ * String grouping one-character operators which >+ * separate the text of the complex expression into tokens. >+ */ >+ public final String operators; >+ >+ /** >+ * Number of special cases for the associated processor. >+ * Special cases exist for some types of complex expression processors. >+ * They are implemented by overriding methods >+ * {@link IBidiComplexProcessor#indexOfSpecial indexOfSpecial} and >+ * {@link IBidiComplexProcessor#processSpecial processSpecial}. >+ * Examples of special cases are comments, literals, or anything which >+ * is not identified by a one-character operator. >+ */ >+ public final int specialsCount; >+ >+ /** >+ * Base direction of the complex expression for Arabic. >+ * If a complex expression contains both Arabic and >+ * Hebrew words, the first Arabic or Hebrew letter in the >+ * expression determines which is the governing script).<br> >+ * The value of this field must be one of >+ * {@link #DIR_LTR} or {@link #DIR_RTL}. >+ * >+ * @see #dirHebrew >+ */ >+ public final int dirArabic; >+ >+ /** >+ * Base direction of the complex expression for Hebrew. >+ * If a complex expression contains both Arabic and >+ * Hebrew words, the first Arabic or Hebrew letter in the >+ * expression determines which is the governing script).<br> >+ * The value of this field must be one of >+ * {@link #DIR_LTR} or {@link #DIR_RTL}. >+ * >+ * @see #dirArabic >+ */ >+ public final int dirHebrew; >+ >+ /** >+ * Flag indicating that Arabic letters will not be considered for >+ * processing complex expressions. If both this flag and >+ * {@link #ignoreHebrew} are set to <code>true</code>, 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 <code>true</code>, 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 <code>DIR_LTR</code>. >+ * @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 <code>DIR_LTR</code>. >+ * @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 BidiComplexFeatures(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/BidiComplexHelper.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/BidiComplexHelper.java >diff -N src/org/eclipse/equinox/bidi/BidiComplexHelper.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/BidiComplexHelper.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,568 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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; >+ >+import org.eclipse.equinox.bidi.custom.BidiComplexStringProcessor; >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+import org.eclipse.equinox.bidi.internal.BidiComplexImpl; >+ >+/** >+ * 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. >+ * <p> >+ * For a general introduction to complex expressions, see >+ * {@link <a href="package-summary.html"> >+ * the package documentation</a>}. >+ * >+ * <h2>Code Sample</h2> >+ * >+ * <p>The following code shows how to instantiate a BidiComplexHelper adapted for a >+ * certain type of complex expression (directory and file paths), and how >+ * to obtain the <i>full</i> text corresponding to the <i>lean</i> text >+ * of such an expression. >+ * >+ * <pre> >+ * >+ * BidiComplexHelper helper = new BidiComplexHelper(IBidiComplexExpressionTypes.FILE); >+ * String leanText = "D:\\\u05d0\u05d1\\\u05d2\\\u05d3.ext"; >+ * String fullText = helper.leanToFullText(leanText); >+ * System.out.println("full text = " + fullText); >+ * >+ * </pre> >+ * This class provides a user-oriented API but does not provides >+ * an actual implementation. The real work is done by the class >+ * {@link BidiComplexImpl}. Users of the API need not be concerned by, and >+ * should not depend upon, details of the implementation by >+ * <code>BidiComplexImpl</code>. >+ * >+ * @author Matitiahu Allouche >+ * >+ */ >+public class BidiComplexHelper { >+ /** >+ * Constant to use as <code>initState</code> 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 BidiComplexImpl} instance which accomplishes >+ * most of the work. This member should be accessed only by >+ * complex expression processors (implementing {@link IBidiComplexProcessor}). >+ */ >+ public BidiComplexImpl impl; >+ >+ /** >+ * Create a <code>BidiComplexHelper</code> instance which does nothing tangible >+ * but does it quickly. We will call it a <i>no-op helper</i>. >+ * The {@link #BidiComplexHelper() 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 BidiComplexHelper() { >+ // let impl stay null >+ } >+ >+ /** >+ * Create a <code>BidiComplexHelper</code> instance to process expressions >+ * of type <code>type</code> with a >+ * {@link BidiComplexEnvironment#DEFAULT DEFAULT} environment. >+ * >+ * @param type represents the type of the complex expression. It must >+ * be one of the values in {@link IBidiComplexExpressionTypes}, or a type >+ * added in a plug-in extension. >+ * >+ * @throws IllegalArgumentException if the <code>type</code> is not >+ * supported. >+ */ >+ public BidiComplexHelper(String type) { >+ this(type, null); >+ } >+ >+ /** >+ * Create a <code>BidiComplexHelper</code> instance to process expressions >+ * of type <code>type</code> operating under the environment >+ * {@link BidiComplexEnvironment environment}. >+ * >+ * @param type represents the type of the complex expression. It must >+ * be one of the values in {@link IBidiComplexExpressionTypes}, or a type >+ * added in a plug-in extension. >+ * >+ * @param environment represents the environment where the complex expression >+ * will be displayed. It is better to specify the environment >+ * when instantiating a <code>BidiComplexHelper</code> than to specify >+ * it later using {@link #setEnvironment setEnvironment}.<br> >+ * <code>null</code> can be specified here for a >+ * {@link BidiComplexEnvironment#DEFAULT DEFAULT} environment. >+ * >+ * @throws IllegalArgumentException if the <code>type</code> is not >+ * supported. >+ */ >+ public BidiComplexHelper(String type, BidiComplexEnvironment environment) { >+ IBidiComplexProcessor processor = BidiComplexStringProcessor.getProcessor(type); >+ if (processor == null) { >+ throw new IllegalArgumentException("Invalid processor type!"); //$NON-NLS-1$ >+ } >+ impl = new BidiComplexImpl(this, processor, environment); >+ } >+ >+ /** >+ * Create a <code>BidiComplexHelper</code> instance to process complex >+ * expressions by means of a given processor <code>myProcessor</code>, >+ * operating under the environment {@link BidiComplexEnvironment environment}. >+ * >+ * @param myProcessor is a complex expression processor. >+ * >+ * @param environment represents the environment where the complex expression >+ * will be displayed. It is better to specify the environment >+ * when instantiating a <code>BidiComplexHelper</code> than to specify >+ * it later using {@link #setEnvironment setEnvironment}.<br> >+ * <code>null</code> can be specified here for a >+ * {@link BidiComplexEnvironment#DEFAULT DEFAULT} environment. >+ */ >+ public BidiComplexHelper(IBidiComplexProcessor myProcessor, BidiComplexEnvironment environment) { >+ impl = new BidiComplexImpl(this, myProcessor, environment); >+ } >+ >+ /** 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.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns <code>text</code>. >+ */ >+ 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 <code>initState</code> of the present call must be >+ * the final state obtained by calling >+ * {@link #getFinalState() getFinalState} >+ * after the previous call. >+ * <br>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 with directional formatting >+ * characters added at proper locations to ensure correct >+ * presentation.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns <code>text</code>. >+ * >+ * @see #getFinalState getFinalState >+ */ >+ public String leanToFullText(String text, int initState) { >+ if (impl == null) >+ return text; >+ return impl.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 BidiComplexEnvironment#orientation orientation} of the >+ * GUI component used for display are not reflected in this method. >+ * <p> >+ * 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.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns an array of 0 elements. >+ */ >+ public int[] leanBidiCharOffsets() { >+ if (impl == null) >+ return EMPTY_INT_ARRAY; >+ return impl.leanBidiCharOffsets(); >+ } >+ >+ /** >+ * Get the offsets of characters in the <i>full</i> 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 BidiComplexEnvironment#orientation orientation} of the >+ * GUI component used for display. >+ * <p> >+ * 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 <i>full</i> >+ * text of the last submitted complex expression which are >+ * directional formatting characters added to ensure correct >+ * presentation. >+ * The offsets are sorted in ascending order.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns an array of 0 elements. >+ */ >+ public int[] fullBidiCharOffsets() { >+ if (impl == null) >+ return EMPTY_INT_ARRAY; >+ return impl.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}.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns <code>text</code> >+ * >+ */ >+ 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 <code>initState</code> of the present call must be >+ * the final state obtained by calling >+ * {@link #getFinalState getFinalState} after the previous call. >+ * <br>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}.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns <code>text</code> >+ * >+ * @see #getFinalState getFinalState >+ */ >+ public String fullToLeanText(String text, int initState) { >+ if (impl == null) >+ return text; >+ return impl.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. >+ * <p> >+ * 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 >+ * <code>leanToFullText</code> or <code>fullToLeanText</code> 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. >+ * <p> >+ * If a line within a complex expression has already been processed by >+ * <code>leanToFullText</code> and the <i>lean</i> version of that line has >+ * not changed, and its initial state has not changed either, the user >+ * can be sure that the <i>full</i> 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.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns {@link #STATE_NOTHING_GOING}. >+ */ >+ public int getFinalState() { >+ if (impl == null) >+ return STATE_NOTHING_GOING; >+ return impl.getFinalState(); >+ } >+ >+ /** >+ * After transforming a <i>lean</i> string into a <i>full</i> string >+ * using {@link #leanToFullText leanToFullText}, compute the index in the >+ * <i>full</i> string of the character corresponding to the >+ * character with the specified position in the <i>lean</i> string. >+ * >+ * @param position is the index of a character in the <i>lean</i> string. >+ * It must be a non-negative number smaller than the length >+ * of the <i>lean</i> text. >+ * >+ * @return the index of the corresponding character in the >+ * <i>full</i> string.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns <code>position</code>. >+ */ >+ public int leanToFullPos(int position) { >+ if (impl == null) >+ return position; >+ return impl.leanToFullPos(position); >+ } >+ >+ /** >+ * After transforming a <i>lean</i> string into a <i>full</i> string >+ * using {@link #leanToFullText leanToFullText}, compute the index in the >+ * <i>lean</i> string of the character corresponding to the >+ * character with the specified position in the <i>full</i> string. >+ * >+ * @param position is the index of a character in the <i>full</i> string. >+ * It must be a non-negative number smaller than the length >+ * of the <i>full</i> text. >+ * >+ * @return the index of the corresponding character in the >+ * <i>lean</i> string. If there is no corresponding >+ * character in the <i>lean</i> 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.<br> >+ * If <code>position</code> corresponds to a directional formatting >+ * character beyond all characters of the original >+ * <i>lean</i> text, the value returned is the length of the >+ * <i>lean</i> text.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns <code>position</code>. >+ */ >+ public int fullToLeanPos(int position) { >+ if (impl == null) >+ return position; >+ return impl.fullToLeanPos(position); >+ } >+ >+ /** >+ * 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 BidiComplexEnvironment#mirrored mirrored}. >+ * >+ * @return the base direction of the last submitted complex >+ * expression. It must be one of the values >+ * {@link BidiComplexFeatures#DIR_LTR} or {@link BidiComplexFeatures#DIR_RTL}.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns <code>DIR_LTR</code>. >+ */ >+ public int getCurDirection() { >+ if (impl == null) >+ return BidiComplexFeatures.DIR_LTR; >+ return impl.getCurDirection(); >+ } >+ >+ /** >+ * Get the current environment under which the <code>BidiComplexHelper</code> >+ * operates. >+ * This environment may have been specified in the constructor or >+ * specified later using {@link #setEnvironment setEnvironment}.<br> >+ * >+ * @return the current environment.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns a {@link BidiComplexEnvironment#DEFAULT DEFAULT} >+ * environment. >+ * >+ * @see #setEnvironment setEnvironment >+ */ >+ public BidiComplexEnvironment getEnvironment() { >+ if (impl == null) >+ return BidiComplexEnvironment.DEFAULT; >+ return impl.getEnvironment(); >+ } >+ >+ /** >+ * Specify the environment under which the <code>BidiComplexHelper</code> >+ * must operate. >+ * <p> >+ * <b>Note</b> that calling this method causes the processor >+ * associated with this instance of <code>BidiComplexHelper</code> >+ * to re-initialize its features. The effect of a previous call >+ * to {@link #setFeatures(BidiComplexFeatures) setFeatures} is lost.<br> >+ * The {@link #BidiComplexHelper() no-op helper} does nothing. >+ * >+ * @see #getEnvironment getEnvironment >+ * @see IBidiComplexProcessor#updateEnvironment IBidiComplexProcessor.updateEnvironment >+ */ >+ public void setEnvironment(BidiComplexEnvironment environment) { >+ if (impl != null) >+ impl.setEnvironment(environment); >+ } >+ >+ /** >+ * Get the current features of the processor associated with this >+ * <code>BidiComplexHelper</code> instance. >+ * >+ * @return the current features.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns {@link BidiComplexFeatures#DEFAULT DEFAULT} >+ * features. >+ * >+ * @see #setFeatures setFeatures >+ */ >+ public BidiComplexFeatures getFeatures() { >+ if (impl == null) >+ return BidiComplexFeatures.DEFAULT; >+ return impl.getFeatures(); >+ } >+ >+ /** >+ * Specify the features to be applied to the processor associated with this >+ * <code>BidiComplexHelper</code> instance. >+ * Note that the value of {@link BidiComplexFeatures#specialsCount specialsCount} >+ * cannot be changed (the new value will be ignored).<br> >+ * The {@link #BidiComplexHelper() no-op helper} does nothing. >+ * >+ * @see #getFeatures getFeatures >+ */ >+ public void setFeatures(BidiComplexFeatures features) { >+ if (impl != null) >+ impl.setFeatures(features); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link IBidiComplexProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link IBidiComplexProcessor#processSpecial processSpecial} in implementations >+ * of {@link IBidiComplexProcessor} to retrieve the bidirectional class of >+ * characters in the <i>lean</i> text. >+ * >+ * @param index position of the character in the <i>lean</i> text. >+ * It must be a non-negative number smaller than the length >+ * of the <i>lean</i> text. >+ * >+ * @return the bidirectional class of the character. It is one of the >+ * values which can be returned by >+ * <code>java.lang.Character#getDirectionality</code>. >+ * However, it is recommended to use <code>getDirProp</code> >+ * rather than <code>java.lang.Character.getDirectionality</code> >+ * since <code>getDirProp</code> manages a cache of character >+ * properties and so can be more efficient than calling the >+ * java.lang.Character method.<br> >+ * The {@link #BidiComplexHelper() no-op helper} returns >+ * <code>Character.DIRECTIONALITY_UNDEFINED</code>. >+ */ >+ public byte getDirProp(int index) { >+ if (impl == null) >+ return Character.DIRECTIONALITY_UNDEFINED; >+ return impl.getDirProp(index); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link IBidiComplexProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link IBidiComplexProcessor#processSpecial processSpecial} in implementations >+ * of {@link IBidiComplexProcessor} to set or override the bidirectional >+ * class of characters in the <i>lean</i> text. >+ * >+ * @param index position of the character in the <i>lean</i> text. >+ * It must be a non-negative number smaller than the length >+ * of the <i>lean</i> text. >+ * >+ * @param dirProp bidirectional class of the character. It is one of the >+ * values which can be returned by >+ * <code>java.lang.Character.getDirectionality</code>.<br> >+ * The {@link #BidiComplexHelper() no-op helper} does nothing. >+ */ >+ public void setDirProp(int index, byte dirProp) { >+ if (impl != null) >+ impl.getDirProp(index); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link IBidiComplexProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link IBidiComplexProcessor#processSpecial processSpecial} in implementations >+ * of {@link IBidiComplexProcessor} >+ * to specify that a mark character must be added before the character >+ * at the specified position of the <i>lean</i> text when generating the >+ * <i>full</i> 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 <i>full</i> text. >+ * >+ * @param offset position of the character in the <i>lean</i> text. >+ * It must be a non-negative number smaller than the length >+ * of the <i>lean</i> text. >+ * For the benefit of efficiency, it is better to insert >+ * multiple marks in ascending order of the offsets.<br> >+ * The {@link #BidiComplexHelper() no-op helper} does nothing. >+ */ >+ public void insertMark(int offset) { >+ if (impl != null) >+ impl.insertMark(offset); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link IBidiComplexProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link IBidiComplexProcessor#processSpecial processSpecial} in >+ * implementations of {@link IBidiComplexProcessor} 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 <i>lean</i> text preceding and following >+ * the operator itself.<br> >+ * The {@link #BidiComplexHelper() no-op helper} does nothing. >+ * >+ * @param operLocation offset of the operator in the <i>lean</i> text. >+ * It must be a non-negative number smaller than the length >+ * of the <i>lean</i> text. >+ */ >+ public void processOperator(int operLocation) { >+ if (impl != null) >+ impl.processOperator(operLocation); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link IBidiComplexProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link IBidiComplexProcessor#processSpecial processSpecial} in >+ * implementations of {@link IBidiComplexProcessor} to >+ * set the final state which should be used for the next call to >+ * {@link #leanToFullText(java.lang.String, int)}.<br> >+ * The {@link #BidiComplexHelper() no-op helper} does nothing. >+ */ >+ public void setFinalState(int newState) { >+ if (impl != null) >+ impl.setFinalState(newState); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/BidiComplexStringRecord.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/BidiComplexStringRecord.java >diff -N src/org/eclipse/equinox/bidi/BidiComplexStringRecord.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/BidiComplexStringRecord.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,195 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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; >+ >+import java.lang.ref.SoftReference; >+import org.eclipse.equinox.bidi.custom.BidiComplexStringProcessor; >+ >+/** >+ * This class records strings which are complex expressions. Several static >+ * methods in this class allow to record such strings in a pool, and to find if >+ * a given string is member of the pool. >+ * <p> >+ * Instances of this class are the records which are members of the pool. >+ * <p> >+ * The pool is managed as a cyclic list, each new element overrides the oldest >+ * element in the list. >+ */ >+public class BidiComplexStringRecord { >+ /** >+ * Number of entries in the pool of recorded strings >+ */ >+ public static final int POOLSIZE = 100; >+ >+ // maximum index allowed >+ private static final int MAXINDEX = POOLSIZE - 1; >+ >+ // index of the last entered record >+ private static int last = MAXINDEX; >+ >+ // the pool >+ private static BidiComplexStringRecord[] records = new BidiComplexStringRecord[POOLSIZE]; >+ >+ // complex expression types >+ private static final String[] types = BidiComplexStringProcessor.getKnownTypes(); >+ >+ // maximum type index allowed >+ private static int MAXTYPE = types.length - 1; >+ >+ // reference to the recorded string >+ private SoftReference strRef; >+ >+ // hash code of the recorded string >+ private int hash; >+ >+ // reference to the triplets of the recorded string >+ private SoftReference triRef; >+ >+ /** >+ * Constructor. >+ * >+ * @param string >+ * the string to record >+ * >+ * @param triplets >+ * array of short integers, the number of elements in the array >+ * must be a multiple of 3, so that the array is made of one or >+ * more triplets of short integers. >+ * <p> >+ * The first element in each triplet is the beginning index of a >+ * susbstring of <code>string</code> which is a complex >+ * expression. >+ * <p> >+ * The second element in each triplet is the ending index of a >+ * susbstring of <code>string</code> which is a complex >+ * expression. This index points to one position beyond the last >+ * character of the substring. >+ * <p> >+ * The third element in each triplet is the numeric type of the >+ * complex expression.<br> >+ * The type of a complex expression must be one of the string >+ * values listed in {@link IBidiComplexExpressionTypes}.<br> >+ * The corresponding numeric type must be obtained using the >+ * method {@link #typeStringToShort typeStringToShort}. >+ */ >+ public BidiComplexStringRecord(String string, short[] triplets) { >+ if (string == null || triplets == null || (triplets.length % 3) != 0) >+ throw new IllegalArgumentException(); >+ for (int i = 2; i < triplets.length; i += 3) >+ if (triplets[i] < 0 || triplets[i] > MAXTYPE) >+ throw new IllegalArgumentException(); >+ strRef = new SoftReference(string); >+ triRef = new SoftReference(triplets); >+ hash = string.hashCode(); >+ } >+ >+ /** >+ * Get the numeric type of a complex expression given its string type. >+ * >+ * @param type >+ * type of complex expression as string. It must be one of the >+ * strings listed in {@link IBidiComplexExpressionTypes}. >+ * >+ * @return a value which is the corresponding numeric type. If >+ * <code>type</code> is invalid, the method returns <code>-1</code>. >+ */ >+ public static short typeStringToShort(String type) { >+ for (int i = 0; i < types.length; i++) >+ if (types[i].equals(type)) >+ return (short) i; >+ return -1; >+ } >+ >+ /** >+ * Get the string type of a complex expression given its numeric type. >+ * >+ * @param shType >+ * the numeric type of a complex expression. It should be a value >+ * obtained using {@link #typeStringToShort typeStringToShort}. >+ * >+ * @return the corresponding string type. If <code>shType</code> is invalid, >+ * the method returns <code>null</code>. >+ */ >+ public static String typeShortToString(short shType) { >+ if (shType < 0 || shType > MAXTYPE) >+ return null; >+ return types[shType]; >+ } >+ >+ /** >+ * /** Add a record to the pool. >+ * >+ * @param record >+ * a BidiComplexStringRecord instance >+ */ >+ public static synchronized void add(BidiComplexStringRecord record) { >+ if (last < MAXINDEX) >+ last++; >+ else >+ last = 0; >+ records[last] = record; >+ } >+ >+ /** >+ * Check if a string is recorded and retrieve its triplets. >+ * >+ * @param string >+ * the string to check >+ * >+ * @return <code>null</code> if the string is not recorded in the pool; >+ * otherwise, return the triplets associated with this string. >+ */ >+ public static short[] getTriplets(String string) { >+ if (records[0] == null) // no records at all >+ return null; >+ if (string == null || string.length() < 1) >+ return null; >+ BidiComplexStringRecord rec; >+ String str; >+ short[] tri; >+ int myLast = last; >+ int hash = string.hashCode(); >+ for (int i = myLast; i >= 0; i--) { >+ rec = records[i]; >+ if (hash == rec.hash && (tri = (short[]) rec.triRef.get()) != null && (str = (String) rec.strRef.get()) != null && string.equals(str)) { >+ return tri; >+ } >+ } >+ if (records[MAXINDEX] == null) // never recorded past myLast >+ return null; >+ for (int i = MAXINDEX; i > myLast; i--) { >+ rec = records[i]; >+ if (hash == rec.hash && (tri = (short[]) rec.triRef.get()) != null && (str = (String) rec.strRef.get()) != null && string.equals(str)) { >+ return tri; >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * Clear the pool. All elements of the pool are erased and any associated >+ * memory is freed. >+ * >+ */ >+ public static synchronized void clear() { >+ for (int i = 0; i <= MAXINDEX; i++) { >+ BidiComplexStringRecord sr = records[i]; >+ if (sr == null) >+ break; >+ sr.hash = 0; >+ sr.strRef.clear(); >+ sr.triRef.clear(); >+ records[i] = null; >+ } >+ last = MAXINDEX; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/BidiComplexUtil.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/BidiComplexUtil.java >diff -N src/org/eclipse/equinox/bidi/BidiComplexUtil.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/BidiComplexUtil.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,315 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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; >+ >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * 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 BidiComplexUtil { >+ >+ /** >+ * prevent instantiation >+ */ >+ private BidiComplexUtil() { >+ // 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 BidiComplexHelper#leanBidiCharOffsets() leanBidiCharOffsets} in order to >+ * produce a <i>full</i> 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 <code>affix</code>. >+ * >+ * @param text is the text of the complex expression. >+ * >+ * @param offsets is an array of offsets to characters in <code>text</code> >+ * before which an LRM or RLM will be inserted. >+ * Members of the array must be non-negative numbers smaller >+ * than the length of <code>text</code>. >+ * 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 BidiComplexFeatures#DIR_LTR} or >+ * {@link BidiComplexFeatures#DIR_RTL}. >+ * >+ * @param affix specifies if a prefix and a suffix should be added to >+ * the result to make sure that the <code>direction</code> >+ * 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 <code>text</code> 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 == BidiComplexFeatures.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 (!BidiComplexEnvironment.isSupportedOS()) >+ return false; >+ return BidiComplexEnvironment.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. >+ * <p> >+ * For example, a file path such as <tt>d:\myfolder\FOLDER\MYFILE.java</tt> >+ * (where capital letters indicate RTL text) should render as >+ * <tt>d:\myfolder\REDLOF\ELIFYM.java</tt>.</p> >+ * <p> >+ * NOTE: this method inserts directional formatting characters into the >+ * text. Methods like <code>String.equals(String)</code> and >+ * <code>String.length()</code> called on the resulting string will not >+ * return the same values as would be returned for the original string.</p> >+ * >+ * @param str the text to process. >+ * >+ * @param delimiters delimiters by which the string will be segmented. >+ * If <code>null</code>, the default delimiters are used >+ * (dot, colon, slash, backslash). >+ * >+ * @return the processed string. >+ * If <code>str</code> is <code>null</code>, >+ * 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 >+ BidiComplexEnvironment env = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_UNKNOWN); >+ BidiComplexHelper helper = new BidiComplexHelper(new BidiComplexProcessor(), env); >+ helper.setFeatures(new BidiComplexFeatures(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 >+ * <code>type</code> 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. >+ * <p> >+ * For example, a file path such as <tt>d:\myfolder\FOLDER\MYFILE.java</tt> >+ * (where capital letters indicate RTL text) should render as >+ * <tt>d:\myfolder\REDLOF\ELIFYM.java</tt>.</p> >+ * <p> >+ * NOTE: this method inserts directional formatting characters into the >+ * text. Methods like <code>String.equals(String)</code> and >+ * <code>String.length()</code> called on the resulting string will not >+ * return the same values as would be returned for the original string.</p> >+ * >+ * @param str the text to process. >+ * >+ * @param type specifies the type of the complex expression. It must >+ * be one of the values in {@link IBidiComplexExpressionTypes} or a value. >+ * added by a plug-in extension. >+ * >+ * @return the processed string. >+ * If <code>str</code> is <code>null</code>, >+ * 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 >+ BidiComplexEnvironment env = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_UNKNOWN); >+ BidiComplexHelper helper = new BidiComplexHelper(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 >+ BidiComplexEnvironment env = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_UNKNOWN); >+ BidiComplexHelper helper = new BidiComplexHelper(type, env); >+ return helper.fullToLeanText(str); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/IBidiComplexExpressionTypes.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/IBidiComplexExpressionTypes.java >diff -N src/org/eclipse/equinox/bidi/IBidiComplexExpressionTypes.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/IBidiComplexExpressionTypes.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,106 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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; >+ >+/** >+ * Bidirectional processors supplied in this bundle. >+ * >+ * @noextend This interface is not intended to be extended by clients. >+ */ >+public interface IBidiComplexExpressionTypes { >+ >+ /** >+ * Constant indicating a type of complex expression processor adapted >+ * to processing property file statements. It expects the following >+ * string format: >+ * <pre> >+ * name=value >+ * </pre> >+ */ >+ 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: >+ * <pre> >+ * part1_part2_part3 >+ * </pre> >+ */ >+ public String UNDERSCORE = "underscore"; //$NON-NLS-1$ >+ >+ /** >+ * Constant indicating a type of complex expression processor adapted >+ * to processing comma-delimited lists, such as: >+ * <pre> >+ * part1,part2,part3 >+ * </pre> >+ */ >+ 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: >+ * <pre> >+ * system(user) >+ * </pre> >+ */ >+ 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/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 <code>null</code> >- * 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 <code>IComplExpProcessor</code> instance capable of handling >- * the type of complex expression specified. May return <code>null</code> >- * 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 <code>false</code> if the GUI >- * is not mirrored, as <code>true</code> 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 <i>full</i> 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 <code>affix</code>. >- * >- * @param text is the text of the complex expression. >- * >- * @param offsets is an array of offsets to characters in <code>text</code> >- * before which an LRM or RLM will be inserted. >- * Members of the array must be non-negative numbers smaller >- * than the length of <code>text</code>. >- * 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 <code>direction</code> >- * 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 <code>text</code> 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. >- * <p> >- * For example, a file path such as <tt>d:\myfolder\FOLDER\MYFILE.java</tt> >- * (where capital letters indicate RTL text) should render as >- * <tt>d:\myfolder\REDLOF\ELIFYM.java</tt>.</p> >- * <p> >- * NOTE: this method inserts directional formatting characters into the >- * text. Methods like <code>String.equals(String)</code> and >- * <code>String.length()</code> called on the resulting string will not >- * return the same values as would be returned for the original string.</p> >- * >- * @param str the text to process. If <code>null</code>, return >- * the string itself >- * >- * @param delimiters delimiters by which the string will be segmented. >- * If <code>null</code>, 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 >- * <code>type</code> 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. >- * <p> >- * For example, a file path such as <tt>d:\myfolder\FOLDER\MYFILE.java</tt> >- * (where capital letters indicate RTL text) should render as >- * <tt>d:\myfolder\REDLOF\ELIFYM.java</tt>.</p> >- * <p> >- * NOTE: this method inserts directional formatting characters into the >- * text. Methods like <code>String.equals(String)</code> and >- * <code>String.length()</code> called on the resulting string will not >- * return the same values as would be returned for the original string.</p> >- * >- * @param str the text to process. If <code>null</code>, 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 <code>process(String str, int type)</code> >- * >- * @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/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: >- * <pre> >- * name=value >- * </pre> >- */ >- 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: >- * <pre> >- * part1_part2_part3 >- * </pre> >- */ >- public String UNDERSCORE = "underscore"; //$NON-NLS-1$ >- >- /** >- * Constant indicating a type of complex expression processor adapted >- * to processing comma-delimited lists, such as: >- * <pre> >- * part1,part2,part3 >- * </pre> >- */ >- 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: >- * <pre> >- * system(user) >- * </pre> >- */ >- 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/IComplExpProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/IComplExpProcessor.java >diff -N src/org/eclipse/equinox/bidi/complexp/IComplExpProcessor.java >--- src/org/eclipse/equinox/bidi/complexp/IComplExpProcessor.java 12 Apr 2010 18:51:17 -0000 1.4 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,606 +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; >- >- >-/** >- * This interface provides a generic mechanism to handle >- * complex expressions, with as main purpose to ensure that they are >- * correctly presented. >- * >- * <p> </p> >- * >- * <h2>Code Sample</h2> >- * >- * <p>The following code shows how to instantiate a processor adapted for a >- * certain type of complex expression (directory and file paths), and how >- * to obtain the <i>full</i> text corresponding to the <i>lean</i> text >- * of such an expression. >- * >- * <pre> >- * >- * IComplExpProcessor processor = ComplExpFactory.create(IBiDiProcessor.FILE); >- * String leanText = "D:\\\u05d0\u05d1\\\u05d2\\\u05d3.ext"; >- * String fullText = processor.leanToFullText(leanText); >- * System.out.println("full text = " + fullText); >- * </pre> >- * >- * <p> </p> >- * >- * @author Matitiahu Allouche >- * >- */ >-public interface IComplExpProcessor { >- /** >- * Constant to use as <code>type</code> 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; >- >- /** >- * Constant specifying that the orientation of the GUI component >- * where a complex expression will be displayed is LTR. >- * It can appear as argument for {@link #assumeOrientation assumeOrientation} >- * or return value for {@link #recallOrientation recallOrientation}. >- */ >- 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 argument for {@link #assumeOrientation assumeOrientation} >- * or return value for {@link #recallOrientation recallOrientation}. >- */ >- 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 argument for {@link #assumeOrientation assumeOrientation} >- * or return value for {@link #recallOrientation recallOrientation}. >- */ >- 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 argument for {@link #assumeOrientation assumeOrientation} >- * or return value for {@link #recallOrientation recallOrientation}. >- */ >- 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 <i>full</i> text is generated using >- * {@link #leanToFullText leanToFullText}. >- * This constant can appear as argument for >- * {@link #assumeOrientation assumeOrientation} >- * or return value for {@link #recallOrientation recallOrientation}. >- */ >- 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 whenever a <i>full</i> text is generated using >- * {@link #leanToFullText leanToFullText}. >- * This constant can appear as argument for >- * {@link #assumeOrientation assumeOrientation} >- * or return value for {@link #recallOrientation recallOrientation}. >- */ >- public static final int ORIENT_IGNORE = 5; >- >- /** >- * Constant specifying that the base direction of a complex expression is LTR. >- * The base direction may depend on whether the GUI is mirrored and may >- * may be different for Arabic and for Hebrew. >- * This constant can appear as argument for {@link #setDirection(int) setDirection} >- * or return value for {@link #getDirection getDirection}. >- * >- * @see ComplExpUtil#isMirroredDefault() >- */ >- public static final int DIRECTION_LTR = 0; >- >- /** >- * Constant specifying that the base direction of a complex expression is RTL. >- * The base direction may depend on whether the GUI is mirrored and may >- * be different for Arabic and for Hebrew. >- * This constant can appear as argument for {@link #setDirection(int) setDirection} >- * or return value for {@link #getDirection getDirection}. >- * >- * @see ComplExpUtil#isMirroredDefault() >- */ >- public static final int DIRECTION_RTL = 1; >- >- /** >- * This method specifies whether Arabic letters, Hebrew letters or >- * both will be considered for processing complex expressions. >- * If neither is selected, the processor will do nothing (but >- * some overhead can be expected). >- * <p> >- * By default, both Arabic and Hebrew are selected for processing. >- * >- * @param arabic a <code>true</code> value means that Arabic letters >- * will be processed. >- * >- * @param hebrew a <code>true</code> value means that Hebrew letters >- * will be processed. >- * >- * @see #handlesArabicScript >- * @see #handlesHebrewScript >- */ >- public void selectBidiScript(boolean arabic, boolean hebrew); >- >- /** >- * This method specifies whether Arabic letters >- * will be considered for processing complex expressions. >- * >- * @return <code>true</code> if Arabic letters will be processed. >- * >- * @see #selectBidiScript selectBidiScript >- */ >- public boolean handlesArabicScript(); >- >- /** >- * This method specifies whether Hebrew letters >- * will be considered for processing complex expressions. >- * >- * @return <code>true</code> if Hebrew letters will be processed. >- * >- * @see #selectBidiScript selectBidiScript >- */ >- public boolean handlesHebrewScript(); >- >- /** 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. >- * >- */ >- public String leanToFullText(String text); >- >- /** 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 <code>initState</code> of the present call must be >- * the final state obtained by calling >- * {@link #getFinalState() getFinalState} >- * after the previous call. >- * >- * @return the complex expression with directional formatting >- * characters added at proper locations to ensure correct >- * presentation. >- * >- * @see #getFinalState getFinalState >- */ >- public String leanToFullText(String text, int 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 orientation of the GUI component used for display >- * are not reflected in this method. >- * >- * @param text is the text of the complex expression. >- * >- * @return an array of offsets to the characters in the <code>text</code> >- * before which directional marks must be added to ensure correct >- * presentation. >- * The offsets are sorted in ascending order. >- * >- */ >- public int[] leanBidiCharOffsets(String text); >- >- /** 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 orientation of the GUI component used for display >- * are not reflected in this method. >- * >- * @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 <code>initState</code> of the present call must be >- * the final state obtained by calling >- * {@link #getFinalState() getFinalState} >- * after the previous call. >- * >- * @return an array of offsets to the characters in the <code>text</code> >- * before which directional marks must be added to ensure correct >- * presentation. >- * The offsets are sorted in ascending order. >- * >- * @see #getFinalState getFinalState >- */ >- public int[] leanBidiCharOffsets(String text, int 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 orientation of the GUI component used for display >- * are not reflected in this method. >- * <p> >- * 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. >- * >- */ >- public int[] leanBidiCharOffsets(); >- >- /** Get the offsets of characters in the <i>full</i> 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 orientation of the GUI component used for display. >- * <p> >- * 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 <i>full</i> >- * text of the last submitted complex expression which are >- * directional formatting characters added to ensure correct >- * presentation. >- * The offsets are sorted in ascending order. >- * >- */ >- public int[] 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}. >- * >- */ >- public String fullToLeanText(String text); >- >- /** 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 <code>initState</code> of the present call must be >- * the final state obtained by calling >- * {@link #getFinalState getFinalState} after the previous call. >- * >- * @return the complex expression without directional formatting >- * characters which might have been added by processing it >- * with {@link #leanToFullText leanToFullText}. >- * >- * @see #getFinalState >- */ >- public String fullToLeanText(String text, int initState); >- >- /** Retrieve the final state achieved in a previous call to >- * {@link #leanToFullText leanToFullText} or >- * {@link #fullToLeanText fullToLeanText}, >- * {@link #leanBidiCharOffsets(java.lang.String text)} or >- * {@link #leanBidiCharOffsets(java.lang.String text, int initState)}. >- * >- * @return the last final state. >- * >- */ >- public int getFinalState(); >- >- /** After transforming a <i>lean</i> string into a <i>full</i> string >- * using {@link #leanToFullText leanToFullText}, compute the index in the >- * <i>full</i> string of the character corresponding to the >- * character with the specified position in the <i>lean</i> string. >- * >- * @param pos is the index of a character in the <i>lean</i> string. >- * >- * @return the index of the corresponding character in the >- * <i>full</i> string. >- * >- */ >- public int leanToFullPos(int pos); >- >- /** After transforming a <i>lean</i> string into a <i>full</i> string >- * using {@link #leanToFullText leanToFullText}, compute the index in the >- * <i>lean</i> string of the character corresponding to the >- * character with the specified position in the <i>full</i> string. >- * >- * @param pos is the index of a character in the <i>full</i> string. >- * >- * @return the index of the corresponding character in the >- * <i>lean</i> string. If there is no corresponding >- * character in the <i>lean</i> 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. >- * >- */ >- public int fullToLeanPos(int pos); >- >- /** Set the operators which separate a complex expression into tokens. >- * >- * @param operators is a string where each character is an operator. >- * >- * @see #getOperators >- */ >- public void setOperators(String operators); >- >- /** Get the operators which separate a complex expression into tokens. >- * >- * @return a string where each character is an operator. >- * >- * @see #getOperators >- */ >- public String getOperators(); >- >- /** 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 overrides the default assumed for all complex expressions >- * as specified by >- * {@link ComplExpUtil#assumeMirroredDefault assumeMirroredDefault}. >- * >- * @param shouldBeMirrored must be specified as <code>false</code> if the GUI >- * is not mirrored, as <code>true</code> if it is. >- * >- * @see #isMirrored >- * @see ComplExpUtil#assumeMirroredDefault assumeMirroredDefault >- */ >- public void assumeMirrored(boolean shouldBeMirrored); >- >- /** Retrieve the value assumed for GUI mirroring for the current >- * complex expression. >- * >- * @return the current value assumed for GUI mirroring. >- * >- * @see #assumeMirrored >- */ >- public boolean isMirrored(); >- >- /** Specify the orientation (a.k.a. base direction) of the GUI >- * component in which the <i>full</i> text of the complex expression will >- * be displayed. If no orientation was specified, <code>ORIENT_LTR</code> >- * is assumed. >- * <p> >- * When the orientation is <code>ORIENT_RTL</code> and the complex >- * expression has a LTR base direction, {@link #leanToFullText leanToFullText} >- * adds LRE+LRM at the head of the <i>full</i> text and LRM+PDF at its >- * end. >- * <p> >- * When the orientation is <code>ORIENT_LTR</code> and the complex >- * expression has a RTL base direction, {@link #leanToFullText leanToFullText} >- * adds RLE+LRM at the head of the <i>full</i> text and RLM+PDF at its >- * end. >- * <p> >- * When the orientation is <code>ORIENT_CONTEXTUAL_LTR</code> or >- * <code>ORIENT_CONTEXTUAL_RTL</code> and the data content would resolve >- * to a RTL orientation while the complex expression has a LTR base >- * direction, {@link #leanToFullText leanToFullText} >- * adds LRM at the head of the <i>full</i> text. >- * <p> >- * When the orientation is <code>ORIENT_CONTEXTUAL_LTR</code> or >- * <code>ORIENT_CONTEXTUAL_RTL</code> and the data content would resolve >- * to a LTR orientation while the complex expression has a RTL base >- * direction, {@link #leanToFullText leanToFullText} >- * adds RLM at the head of the <i>full</i> text. >- * <p> >- * When the orientation is <code>ORIENT_UNKNOWN</code> and the complex >- * expression has a LTR base direction, {@link #leanToFullText leanToFullText} >- * adds LRE+LRM at the head of the <i>full</i> text and LRM+PDF at its >- * end. >- * <p> >- * When the orientation is <code>ORIENT_UNKNOWN</code> and the complex >- * expression has a RTL base direction, {@link #leanToFullText leanToFullText} >- * adds RLE+LRM at the head of the <i>full</i> text and RLM+PDF at its >- * end. >- * <p> >- * When the orientation is <code>ORIENT_IGNORE</code>, >- * {@link #leanToFullText leanToFullText} does not add any directional >- * formatting characters as either prefix or suffix of the <i>full</i> text. >- * >- * @param componentOrientation orientation of the GUI component where the >- * complex expression will be displayed. It must be one of the >- * values {@link #ORIENT_LTR}, {@link #ORIENT_RTL}, >- * {@link #ORIENT_CONTEXTUAL_LTR}, {@link #ORIENT_CONTEXTUAL_RTL}, >- * {@link #ORIENT_UNKNOWN} or {@link #ORIENT_IGNORE}. >- * >- * @see #recallOrientation >- */ >- public void assumeOrientation(int componentOrientation); >- >- /** Retrieve the value currently assumed for the orientation. >- * >- * @return the current value of the orientation. It will be one of the >- * values {@link #ORIENT_LTR}, {@link #ORIENT_RTL}, >- * {@link #ORIENT_CONTEXTUAL_LTR}, {@link #ORIENT_CONTEXTUAL_RTL}, >- * {@link #ORIENT_UNKNOWN} or {@link #ORIENT_IGNORE}. >- * >- * @see #assumeOrientation >- */ >- public int recallOrientation(); >- >- /** Set the base direction of a complex expression including Arabic words. >- * It is specified separately for when the GUI is not mirrored and for >- * when it is mirrored. Each argument must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * If the values are different for Arabic and Hebrew, the values for >- * Arabic will be used if an Arabic letter precedes all Hebrew letters >- * in the expression. >- * >- * @param not_mirrored base direction when the GUI is not mirrored. >- * >- * @param mirrored base direction when the GUI is mirrored. >- * >- * @see #setHebrewDirection(int, int) >- * @see #getDirection >- */ >- public void setArabicDirection(int not_mirrored, int mirrored); >- >- /** Set the base direction of a complex expression including Arabic words. >- * This direction applies both for when the GUI is not mirrored and for >- * when it is mirrored. >- * If the values are different for Arabic and Hebrew, the values for >- * Arabic will be used if an Arabic letter precedes all Hebrew letters >- * in the expression. >- * >- * @param direction base direction of the expression. >- * It must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * >- * @see #setHebrewDirection(int) >- * @see #getDirection >- */ >- public void setArabicDirection(int direction); >- >- /** Set the base direction of a complex expression including Hebrew words. >- * It is specified separately for when the GUI is not mirrored and for >- * when it is mirrored. Each argument must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * If the values are different for Arabic and Hebrew, the values for >- * Hebrew will be used if a Hebrew letter precedes all Arabic letters >- * in the expression. >- * >- * @param not_mirrored base direction when the GUI is not mirrored. >- * >- * @param mirrored base direction when the GUI is mirrored. >- * >- * @see #setArabicDirection(int, int) >- * @see #getDirection >- */ >- public void setHebrewDirection(int not_mirrored, int mirrored); >- >- /** Set the base direction of a complex expression including Hebrew words. >- * This direction applies both for when the GUI is not mirrored and for >- * when it is mirrored. >- * If the values are different for Arabic and Hebrew, the values for >- * Hebrew will be used if a Hebrew letter precedes all Arabic letters >- * in the expression. >- * >- * @param direction base direction of the expression. >- * It must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * >- * @see #setArabicDirection(int) >- * @see #getDirection >- */ >- public void setHebrewDirection(int direction); >- >- /** Set the base direction of a complex expression. >- * It is specified separately for when the GUI is not mirrored and for >- * when it is mirrored. Each argument must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * The values apply whether the expression contains Arabic or Hebrew >- * letters, or both. >- * >- * @param not_mirrored base direction when the GUI is not mirrored. >- * >- * @param mirrored base direction when the GUI is mirrored. >- * >- * @see #setArabicDirection(int, int) >- * @see #setHebrewDirection(int, int) >- * @see #getDirection >- */ >- public void setDirection(int not_mirrored, int mirrored); >- >- /** Set the base direction of a complex expression. >- * This direction applies both for when the GUI is not mirrored and for >- * when it is mirrored. >- * The direction applies whether the expression contains Arabic or Hebrew >- * letters, or both. >- * >- * @param direction base direction of the expression. >- * It must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * >- * @see #setArabicDirection(int) >- * @see #setHebrewDirection(int) >- * @see #getDirection >- */ >- public void setDirection(int direction); >- >- /** Get the base direction of a complex expression. >- * Different base directions may have been specified depending 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). >- * Different base directions may also have been specified depending on >- * whether the GUI is or is not mirrored. >- * The values for all the possible cases are returned in an array. >- * Each element of the array must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * >- * @return a two dimensional array with 2 rows and 2 columns such that >- * <ul> >- * <li>element [0][0] represents the base direction for Arabic >- * when the GUI is not mirrored. >- * <li>element [0][1] represents the base direction for Arabic >- * when the GUI is mirrored. >- * <li>element [1][0] represents the base direction for Hebrew >- * when the GUI is not mirrored. >- * <li>element [1][1] represents the base direction for Hebrew >- * when the GUI is mirrored. >- * </ul> >- * >- * @see #setDirection >- */ >- public int[][] getDirection(); >- >- /** Get the base direction of the current complex expression. >- * This base direction may depend on whether the GUI is mirrored and 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). >- * >- * @return the base direction of the current instance of a complex >- * expression. It must be one of the values >- * {@link #DIRECTION_LTR} or {@link #DIRECTION_RTL}. >- * >- * @see #setDirection >- */ >- public int getCurDirection(); >-} >Index: src/org/eclipse/equinox/bidi/complexp/StringProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/StringProcessor.java >diff -N src/org/eclipse/equinox/bidi/complexp/StringProcessor.java >--- src/org/eclipse/equinox/bidi/complexp/StringProcessor.java 3 Feb 2010 20:00:59 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,31 +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; >- >-/** >- * The API part for the TextProcessor replacement. >- */ >-// 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 { >- >- static public String[] getKnownTypes() { >- return BiDiTypesCollector.getInstance().getTypes(); >- } >- >- static public IComplExpProcessor getProcessor(String type) { >- return BiDiTypesCollector.getInstance().getProcessor(type); >- } >-} >Index: src/org/eclipse/equinox/bidi/complexp/package.html >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/package.html >diff -N src/org/eclipse/equinox/bidi/complexp/package.html >--- src/org/eclipse/equinox/bidi/complexp/package.html 2 Feb 2010 21:55:25 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,158 +0,0 @@ >-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> >-<html> >-<head> >-<META name="Author" content="Matitiahu Allouche"> >-</head> >-<body bgcolor="white"> >- >-This package provides an interface and implementing classes for >-processing complex expressions. >- >- >-<h2>Introduction to Complex Expressions</h2> >-<p> >-Bidirectional text offers interesting challenges to presentation systems. >-For plain text, the Unicode Bidirectional Algorithm >-(<a href="http://www.unicode.org/reports/tr9/">UBA</a>) >-generally specifies satisfactorily how to reorder Bidirectional text for >-display. This algorithm is implemented in Java's presentation system.</p> >-<p> >-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 >-when displaying such structured text.</p> >-<p> >-The general idea in handling complex expressions is to add directional >-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.</p> >-<p> >-In this package, text without directional formatting characters is >-called <b><i>lean</i></b> text while the text with added directional >-formatting characters is called <b><i>full</i></b> text.</p> >-<p> >-{@link <a href="IComplExpProcessor.html">IComplExpProcessor</a>} provides >-an interface for processing complex expressions. This package also >-includes several classes which implement <code>IComplExpProcessor</code>, >-all of them based on class >-{@link <a href="ComplExpBasic.html">ComplExpBasic</a>}. >-<p> >-There is also a class named >-<code>ComplExpDoNothing</code> 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.</p> >-<p> >-The class {@link <a href="ComplExpBasic.html">ComplExpBasic</a>} can >-handle several types of relatively simple complex expressions.</p> >-<p> >-A number of subclasses of <code>ComplExpBasic</code> are included in this >-package, each one adapted to handle some type of complex expression. >-The explicitly supported types are: >-<ul> >- <li>property (name=value)</li> >- <li>compound name (xxx_yy_zzzz)</li> >- <li>comma delimited list</li> >- <li>system(user)</li> >- <li>directory and file path</li> >- <li>e-mail address</li> >- <li>URL</li> >- <li>regular expression</li> >- <li>Xpath</li> >- <li>Java code</li> >- <li>SQL statements</li> >- <li>RTL arithmetic expressions</li> >-</ul> >-<p> >-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 <code>IComplExpProcessor</code> and >-<code>ComplExpBasic</code> can facilitate >-considerably the development of such new support.</p> >-<p> >-The class {@link <a href="ComplExpUtil.html">ComplExpUtil</a>} 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.</p> >-<p> >- >-<p> </p> >- >-<h2>Abbreviations used in the documentation of this package</h2> >- >-<dl> >-<dt><b>UBA</b><dd>Unicode Bidirectional Algorithm >- >-<dt><b>Bidi</b><dd>Bidirectional >- >-<dt><b>GUI</b><dd>Graphical User Interface >- >-<dt><b>UI</b><dd>User Interface >- >-<dt><b>LTR</b><dd>Left to Right >- >-<dt><b>RTL</b><dd>Right to Left >- >-<dt><b>LRM</b><dd>Left-to-Right Mark >- >-<dt><b>RLM</b><dd>Right-to-Left Mark >- >-<dt><b>LRE</b><dd>Left-to-Right Embedding >- >-<dt><b>RLE</b><dd>Right-to-Left Embedding >- >-<dt><b>PDF</b><dd>Pop Directional Formatting >-</dl> >- >-<p> </p> >- >-<h2>Known Limitations</h2> >- >-<p>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 >-attention:</p> >- >-<ul> >-<li>Implementations of the UBA on various platforms (e.g., Windows and >-Linux) are very similar but nevertheless have known differences. Those >-differences are minor and will not have a visible effect in most cases. >-However there might be cases in which the same Bidi text on two >-platforms might look different. These differences will surface in Java >-applications when they use the platform visual components for their UI >-(e.g., AWT, SWT).</li> >- >-<li>It is assumed that the presentation engine supports LRE, RLE and >-PDF directional formatting characters.</li> >- >-<li>Because some presentation engines are not strictly conformant to the >-UBA, the implementation of complex expressions in this package adds LRM >-or RLM characters in association with LRE, RLE or PDF in cases where >-this would not be needed if the presentation engine was fully conformant >-to the UBA. Such added marks will not have harmful effects on >-conformant presentation engines and will help less conformant engines to >-achieve the desired presentation.</li> >-</ul> >- >-<p> </p> >- >-<h2>References</h2> >- >-@see <a href="IComplExpProcessor.html">IComplExpProcessor</a> >-@see <a href="ComplExpBasic.html">ComplExpBasic</a> >-@see <a href="ComplExpDoNothing.html">ComplExpDoNothing</a> >- >-</body> >-</html> >Index: src/org/eclipse/equinox/bidi/custom/BidiComplexProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/custom/BidiComplexProcessor.java >diff -N src/org/eclipse/equinox/bidi/custom/BidiComplexProcessor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/custom/BidiComplexProcessor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,98 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.custom; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.internal.BidiComplexImpl; >+ >+/** >+ * Generic processor which can be used as superclass (base class) >+ * for specific complex expression processors. >+ * <p> >+ * Here are some guidelines about how to write complex expression >+ * processors. >+ * <ul> >+ * <li>Processor instances may be accessed simultaneously by >+ * several threads. They should have no instance variables.</li> >+ * <li>Each use of a processor is initialized with the {@link #init init} >+ * or the {@link #updateEnvironment updateEnvironment} methods. >+ * Both methods have a {@link BidiComplexHelper} argument named <code>caller</code>. >+ * All calls to methods of <code>BidiComplexProcessor</code> have a >+ * <code>caller</code> argument. >+ * If a processor needs to retain some data across invocations, it may >+ * access the field {@link BidiComplexImpl#processorData caller.impl.processorData}. >+ * It is guaranteed that this field will not be modified by any code >+ * except the processor itself.</li> >+ * <li>The behavior of a processor is governed by 3 factors: >+ * <ul> >+ * <li>The {@link BidiComplexFeatures#operators operators} field of its >+ * {@link BidiComplexFeatures features} determines how submitted >+ * complex expressions are split into tokens.</li> >+ * <li>The tokens are displayed one after the other according >+ * to the appropriate {@link BidiComplexFeatures#dirArabic direction}. >+ * <li>The counter {@link BidiComplexFeatures#specialsCount specialsCount} >+ * determines how many special cases need to be handled by >+ * code specific to that processor. >+ * </ul> >+ * >+ * @author Matitiahu Allouche >+ */ >+public class BidiComplexProcessor implements IBidiComplexProcessor { >+ >+ /** >+ * In <code>BidiComplexProcessor</code> this method returns a >+ * {@link BidiComplexFeatures#DEFAULT DEFAULT} value which >+ * directs the processor to do nothing. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper caller, BidiComplexEnvironment environment) { >+ return BidiComplexFeatures.DEFAULT; >+ } >+ >+ /** >+ * In <code>BidiComplexProcessor</code> this method simply calls the >+ * {@link #init init} method. If this is good enough, i.e. >+ * if the {@link BidiComplexFeatures features} of the processor are >+ * determined identically for initialization and after a >+ * change in the {@link BidiComplexEnvironment environment}, subclasses of >+ * <code>BidiComplexProcessor</code> don't need to override this >+ * method. >+ */ >+ public BidiComplexFeatures updateEnvironment(BidiComplexHelper caller, BidiComplexEnvironment environment) { >+ return init(caller, environment); >+ } >+ >+ /** >+ * In <code>BidiComplexProcessor</code> this method throws an >+ * <code>IllegalStateException</code>. This is appropriate behavior >+ * (and does not need to be overridden) for processors whose >+ * {@link BidiComplexFeatures#specialsCount specialsCount} is zero, which >+ * means that <code>indexOfSpecial</code> should never be called >+ * for them. >+ */ >+ public int indexOfSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int fromIndex) { >+ // This method must be overridden by all subclasses with special cases. >+ throw new IllegalStateException(); >+ } >+ >+ /** >+ * In <code>BidiComplexProcessor</code> this method throws an >+ * <code>IllegalStateException</code>. This is appropriate behavior >+ * (and does not need to be overridden) for processors whose >+ * {@link BidiComplexFeatures#specialsCount specialsCount} is zero, which >+ * means that <code>processSpecial</code> should never be called >+ * for them. >+ */ >+ public int processSpecial(BidiComplexHelper caller, int caseNumber, 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/custom/BidiComplexStringProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/custom/BidiComplexStringProcessor.java >diff -N src/org/eclipse/equinox/bidi/custom/BidiComplexStringProcessor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/custom/BidiComplexStringProcessor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,40 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.custom; >+ >+import org.eclipse.equinox.bidi.internal.BidiComplexTypesCollector; >+ >+/** >+ * This class provides access to registered complex expression processors. >+ */ >+public class BidiComplexStringProcessor { >+ /** >+ * 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 BidiComplexTypesCollector.getInstance().getTypes(); >+ } >+ >+ /** >+ * 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 <code>null</code>. >+ */ >+ static public IBidiComplexProcessor getProcessor(String type) { >+ return BidiComplexTypesCollector.getInstance().getProcessor(type); >+ } >+} >Index: src/org/eclipse/equinox/bidi/custom/IBidiComplexProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/custom/IBidiComplexProcessor.java >diff -N src/org/eclipse/equinox/bidi/custom/IBidiComplexProcessor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/custom/IBidiComplexProcessor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,150 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.custom; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.internal.BidiComplexImpl; >+ >+/** >+ * Interface for all complex expression processors. >+ * For guidelines about implementation, see >+ * {@link BidiComplexProcessor}. >+ * >+ * @author Matitiahu Allouche >+ */ >+public interface IBidiComplexProcessor { >+ >+ /** >+ * Do whatever initializations are needed and return the >+ * {@link BidiComplexFeatures} characterizing the processor. >+ * >+ * @param env the current environment, which may affect the >+ * initializations. >+ * >+ * @param caller <code>BidiComplexHelper</code> instance which called this method. >+ * This allows access to the field >+ * {@link BidiComplexImpl#processorData caller.impl.processorData} where >+ * the processor can keep whatever data it needs. >+ * >+ * @return the features in use for this processor. >+ */ >+ public abstract BidiComplexFeatures init(BidiComplexHelper caller, BidiComplexEnvironment env); >+ >+ /** >+ * Do whatever renewed initializations are needed after a >+ * change in the environment and return the possibly updated >+ * {@link BidiComplexFeatures} characterizing the processor. >+ * >+ * @param env the updated environment, which may affect the >+ * initializations. >+ * >+ * @param caller <code>BidiComplexHelper</code> instance which called this method. >+ * This allows access to the field >+ * {@link BidiComplexImpl#processorData caller.impl.processorData} where >+ * the processor can keep whatever data it needs. >+ * >+ * @return the features to use for this processor. >+ */ >+ public BidiComplexFeatures updateEnvironment(BidiComplexHelper caller, BidiComplexEnvironment env); >+ >+ /** >+ * Locate occurrences of special strings within a complex expression >+ * and return their indexes one after the other in successive calls. >+ * <p> >+ * This method is called repeatedly from the code implementing >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} if the field >+ * {@link BidiComplexFeatures#specialsCount specialsCount} returned when >+ * {@link #init initializing} the processor is greater than zero. >+ * <p> >+ * The code implementing this method may use the following methods >+ * in {@link BidiComplexHelper}: >+ * <ul> >+ * <li>{@link BidiComplexHelper#getDirProp getDirProp}</li> >+ * <li>{@link BidiComplexHelper#setDirProp setDirProp}</li> >+ * <li>{@link BidiComplexHelper#insertMark insertMark}</li> >+ * <li>{@link BidiComplexHelper#processOperator processOperator}</li> >+ * <li>{@link BidiComplexHelper#setFinalState setFinalState}</li> >+ * </ul> >+ * >+ * @param caseNumber number of the special case to locate. >+ * This number varies from zero to <code>specialsCount - 1</code>. >+ * The meaning of this number is internal to the class >+ * implementing <code>indexOfSpecial</code>. >+ * >+ * @param srcText text of the complex expression before addition of any >+ * directional formatting characters. >+ * >+ * @param fromIndex the index within <code>srcText</code> 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 >+ * <code>fromIndex</code>. 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). >+ * <br>If no occurrence is found, the method must return -1. >+ */ >+ public int indexOfSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int fromIndex); >+ >+ /** >+ * This method is called by {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * when a special case occurrence is located by >+ * {@link #indexOfSpecial indexOfSpecial}. >+ * <p> >+ * The code implementing this method may use the following methods >+ * in {@link BidiComplexHelper}: >+ * <ul> >+ * <li>{@link BidiComplexHelper#getDirProp getDirProp}</li> >+ * <li>{@link BidiComplexHelper#setDirProp setDirProp}</li> >+ * <li>{@link BidiComplexHelper#insertMark insertMark}</li> >+ * <li>{@link BidiComplexHelper#processOperator processOperator}</li> >+ * <li>{@link BidiComplexHelper#setFinalState setFinalState}</li> >+ * </ul> >+ * <p> >+ * If a special processing cannot be completed within a current call to >+ * <code>processSpecial</code> (for instance, a comment has been started >+ * in the current line but its end appears in a following line), >+ * <code>processSpecial</code> should specify a final state using >+ * the method {@link BidiComplexHelper#setFinalState setFinalState}. >+ * The meaning of this state is internal to the processor. >+ * On a later call to >+ * {@link BidiComplexHelper#leanToFullText(String text, int initState)} >+ * specifying that state value, <code>processSpecial</code> will be >+ * called with that value for parameter <code>caseNumber</code> and >+ * <code>-1</code> for parameter <code>operLocation</code> and should >+ * perform whatever initializations are required depending on the state. >+ * >+ * @param caseNumber 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 BidiComplexHelper#leanToFullText(String text, int initState)} or >+ * {@link BidiComplexHelper#fullToLeanText(String text, int initState)} >+ * specifying an <code>initState</code> >+ * parameter, <code>processSpecial</code> is called when initializing >+ * the processing with the value of <code>caseNumber</code> >+ * equal to <code>initState</code> and the value of >+ * <code>operLocation</code> equal to <code>-1</code>. >+ * >+ * @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. >+ * <br>A value greater or equal to the length of <code>srcText</code> >+ * means that there is no further occurrence of this case in the >+ * current complex expression. >+ */ >+ public int processSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int operLocation); >+ >+} >Index: src/org/eclipse/equinox/bidi/custom/package.html >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/custom/package.html >diff -N src/org/eclipse/equinox/bidi/custom/package.html >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/custom/package.html 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,27 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> >+<html> >+<head> >+<META name="Author" content="Matitiahu Allouche"> >+</head> >+<body bgcolor="white"> >+ >+This package provides an interface and classes for >+developing complex expressions processors. >+ >+<ul> >+ <li>{@link <a href="IBidiComplexProcessor.html">IBidiComplexProcessor</a>} >+ is an interface specifying which methods a processor must provide.</li> >+ <li>{@link <a href="BidiComplexProcessor.html">BidiComplexProcessor</a>} >+ is a generic processor which can be used as superclass for specific >+ processors.</li> >+ <li>{@link <a href="BidiComplexStringProcessor.html">BidiComplexStringProcessor</a>} >+ is a class which allows retrieval of the defined processor types and of the >+ corresponding processors.</li> >+</ul> >+ >+This package is to be used together with package >+{@link <a href="..\package-summary.html"> >+org.eclipse.equinox.bidi</a>}. >+ >+</body> >+</html> >Index: src/org/eclipse/equinox/bidi/internal/BidiComplexActivator.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/BidiComplexActivator.java >diff -N src/org/eclipse/equinox/bidi/internal/BidiComplexActivator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/BidiComplexActivator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,91 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal; >+ >+import java.util.Locale; >+import org.eclipse.osgi.framework.log.FrameworkLog; >+import org.eclipse.osgi.framework.log.FrameworkLogEntry; >+import org.eclipse.osgi.service.localization.LocaleProvider; >+import org.osgi.framework.*; >+import org.osgi.util.tracker.ServiceTracker; >+ >+public class BidiComplexActivator implements BundleActivator { >+ >+ private ServiceTracker logTracker = null; >+ private BundleContext bundleContext; >+ private static BidiComplexActivator instance; >+ >+ public BidiComplexActivator() { >+ instance = this; // there is only one bundle activator >+ } >+ >+ public void start(BundleContext context) throws Exception { >+ bundleContext = context; >+ instance = this; >+ } >+ >+ public void stop(BundleContext context) throws Exception { >+ if (logTracker != null) { >+ logTracker.close(); >+ logTracker = null; >+ } >+ bundleContext = null; >+ } >+ >+ public static BidiComplexActivator getInstance() { >+ return instance; >+ } >+ >+ public String getProperty(String key) { >+ return bundleContext.getProperty(key); >+ } >+ >+ public Locale getDefaultLocale() { >+ // use OSGi service >+ ServiceReference[] references = null; >+ try { >+ references = bundleContext.getAllServiceReferences(null, LocaleProvider.class.getName()); >+ } catch (InvalidSyntaxException e) { >+ // do nothing >+ } >+ if (references == null || references.length < 1) >+ return Locale.getDefault(); >+ Object service = bundleContext.getService(references[0]); >+ LocaleProvider localeProvider = (LocaleProvider) service; >+ if (localeProvider != null) { >+ Locale currentLocale = localeProvider.getLocale(); >+ bundleContext.ungetService(references[0]); >+ if (currentLocale != null) >+ return currentLocale; >+ } >+ return Locale.getDefault(); >+ } >+ >+ private FrameworkLog getFrameworkLog() { >+ if (logTracker == null) { >+ logTracker = new ServiceTracker(bundleContext, FrameworkLog.class.getName(), null); >+ logTracker.open(); >+ } >+ return (FrameworkLog) logTracker.getService(); >+ } >+ >+ static public void logError(String message, Exception e) { >+ FrameworkLog frameworkLog = instance.getFrameworkLog(); >+ if (frameworkLog != null) { >+ frameworkLog.log(new FrameworkLogEntry("org.eclipse.equinox.bidi", FrameworkLogEntry.ERROR, 1, message, 0, e, null)); //$NON-NLS-1$ >+ return; >+ } >+ System.err.println(message); >+ if (e != null) >+ e.printStackTrace(); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/BidiComplexDelims.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/BidiComplexDelims.java >diff -N src/org/eclipse/equinox/bidi/internal/BidiComplexDelims.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/BidiComplexDelims.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,61 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal; >+ >+import org.eclipse.equinox.bidi.BidiComplexHelper; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * <code>BidiComplexDelims</code> is a processor for complex expressions >+ * composed of text segments separated by operators where the text segments >+ * may include delimited parts within which operators are treated like >+ * regular characters. >+ * >+ * @author Matitiahu Allouche >+ */ >+public abstract class BidiComplexDelims extends BidiComplexProcessor { >+ >+ /** >+ * This method locates occurrences of start delimiters. >+ */ >+ public int indexOfSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int fromIndex) { >+ char delim = getDelimiters().charAt(caseNumber * 2); >+ return srcText.indexOf(delim, fromIndex); >+ } >+ >+ /** >+ * This method skips until after the matching end delimiter. >+ */ >+ public int processSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int operLocation) { >+ helper.processOperator(operLocation); >+ int loc = operLocation + 1; >+ char delim = getDelimiters().charAt((caseNumber * 2) + 1); >+ loc = srcText.indexOf(delim, loc); >+ if (loc < 0) >+ return srcText.length(); >+ return loc + 1; >+ } >+ >+ /** >+ * @return a string containing the delimiters implemented in this class >+ * instance. This string must include an even >+ * number of characters. The first 2 characters of a string >+ * constitute a pair, the next 2 characters are a second pair, etc... >+ * In each pair, the first character is a start delimiter and >+ * the second character is an end delimiter. In the <i>lean</i> >+ * text, any part starting with a start delimiter and ending with >+ * the corresponding end delimiter is a delimited part. Within a >+ * delimited part, operators are treated like regular characters, >+ * which means that they do not define new segments. >+ */ >+ protected abstract String getDelimiters(); >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/BidiComplexDelimsEsc.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/BidiComplexDelimsEsc.java >diff -N src/org/eclipse/equinox/bidi/internal/BidiComplexDelimsEsc.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/BidiComplexDelimsEsc.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,55 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal; >+ >+import org.eclipse.equinox.bidi.BidiComplexHelper; >+ >+/** >+ * <code>BidiComplexDelims</code> is a processor for complex expressions >+ * composed of text segments separated by operators where the text segments >+ * may include delimited parts within which operators are treated like >+ * regular characters and the delimiters may be escaped. >+ * This is similar to {@link BidiComplexDelims} except >+ * that delimiters can be escaped using the backslash character. >+ * <ul> >+ * <li>Two consecutive backslashes in a delimited part are treated like >+ * one regular characters.</li> >+ * <li>An ending delimiter preceded by an odd number of backslashes is >+ * treated like a regular character of a delimited part.</li> >+ * </ul> >+ * >+ * @author Matitiahu Allouche >+ */ >+public abstract class BidiComplexDelimsEsc extends BidiComplexDelims { >+ >+ /** >+ * This method skips until after the matching end delimiter, >+ * ignoring possibly escaped end delimiters. >+ */ >+ public int processSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int operLocation) { >+ helper.processOperator(operLocation); >+ int location = operLocation + 1; >+ char delim = getDelimiters().charAt((caseNumber * 2) + 1); >+ while (true) { >+ location = srcText.indexOf(delim, location); >+ if (location < 0) >+ return srcText.length(); >+ int cnt = 0; >+ for (int i = location - 1; srcText.charAt(i) == '\\'; i--) { >+ cnt++; >+ } >+ location++; >+ if ((cnt & 1) == 0) >+ return location; >+ } >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/BidiComplexImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/BidiComplexImpl.java >diff -N src/org/eclipse/equinox/bidi/internal/BidiComplexImpl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/BidiComplexImpl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,761 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+ >+/** >+ * <code>BidiComplexImpl</code> provides the code which implements the API in >+ * {@link BidiComplexHelper}. All its public methods are shadows of similarly >+ * signed methods of <code>BidiComplexHelper</code>, and their documentation >+ * is by reference to the methods in <code>BidiComplexHelper</code>. >+ * >+ * @author Matitiahu Allouche >+ */ >+public class BidiComplexImpl { >+ >+ static final String EMPTY_STRING = ""; //$NON-NLS-1$ >+ static final byte B = Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR; >+ static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT; >+ static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT; >+ static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC; >+ static final byte AN = Character.DIRECTIONALITY_ARABIC_NUMBER; >+ static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER; >+ static final char LRM = 0x200E; >+ static final char RLM = 0x200F; >+ static final char LRE = 0x202A; >+ static final char RLE = 0x202B; >+ static final char PDF = 0x202C; >+ static final char[] MARKS = {LRM, RLM}; >+ static final char[] EMBEDS = {LRE, RLE}; >+ static final byte[] STRONGS = {L, R}; >+ static final int PREFIX_LENGTH = 2; >+ static final int SUFFIX_LENGTH = 2; >+ static final int FIXES_LENGTH = PREFIX_LENGTH + SUFFIX_LENGTH; >+ >+ BidiComplexHelper helper; >+ >+ BidiComplexEnvironment environment; >+ >+ IBidiComplexProcessor processor; >+ >+ /** >+ * This field is reserved for use of the complex expression >+ * processor associated with this instance of <code>BidiComplexImpl</code>. >+ * The processor can keep here a reference to an object that it >+ * has sole control of. >+ */ >+ public Object processorData; >+ >+ /** >+ * Features of the associated processor. >+ * >+ */ >+ public BidiComplexFeatures features; >+ >+ int state = BidiComplexHelper.STATE_NOTHING_GOING; >+ >+ // strong bidi class (L or R) for current expression direction >+ byte curStrong = -1; >+ // strong character (LRM or RLM) for current expression direction >+ char curMark; >+ // strong directional control (LRE or RLE) for current expression direction >+ char curEmbed; >+ int prefixLength; >+ // index of next occurrence for each operator and each special case >+ int[] locations; >+ // number of special cases >+ int specialsCount; >+ String leanText; >+ // positions where LRM/RLM must be added >+ int[] offsets; >+ // number of LRM/RLM to add >+ int count; >+ // For positions where it has been looked up, the entry will receive >+ // the Character directionality + 2 (so that 0 indicates that the >+ // the directionality has not been looked up yet. >+ byte[] dirProps; >+ // current UI orientation (after resolution if contextual) >+ int curOrient = -1; >+ // Current expression base direction (after resolution if depending on >+ // script and/or on GUI mirroring (0=LTR, 1=RTL)) >+ int curDirection = -1; >+ >+ /** >+ * @see BidiComplexHelper#BidiComplexHelper(IBidiComplexProcessor myProcessor, BidiComplexEnvironment environment) >+ */ >+ public BidiComplexImpl(BidiComplexHelper caller, IBidiComplexProcessor myProcessor, BidiComplexEnvironment environment) { >+ helper = caller; >+ if (environment == null) { >+ this.environment = BidiComplexEnvironment.DEFAULT; >+ } else { >+ this.environment = environment; >+ } >+ processor = myProcessor; >+ features = processor.init(helper, this.environment); >+ // keep private copy of specialsCount to avoid later modification >+ specialsCount = features.specialsCount; >+ locations = new int[features.operators.length() + specialsCount]; >+ } >+ >+ long computeNextLocation(int curPos) { >+ int operCount = features.operators.length(); >+ int len = leanText.length(); >+ int nextLocation = len; >+ int idxLocation = 0; >+ // Start with special sequences to give them precedence over simple >+ // operators. This may apply to cases like slash+asterisk versus slash. >+ for (int i = 0; i < specialsCount; i++) { >+ int location = locations[operCount + i]; >+ if (location < curPos) { >+ location = processor.indexOfSpecial(helper, i, leanText, curPos); >+ if (location < 0) >+ location = len; >+ locations[operCount + i] = location; >+ } >+ if (location < nextLocation) { >+ nextLocation = location; >+ idxLocation = operCount + i; >+ } >+ } >+ for (int i = 0; i < operCount; i++) { >+ int location = locations[i]; >+ if (location < curPos) { >+ location = leanText.indexOf(features.operators.charAt(i), curPos); >+ if (location < 0) >+ location = len; >+ locations[i] = location; >+ } >+ if (location < nextLocation) { >+ nextLocation = location; >+ idxLocation = i; >+ } >+ } >+ return nextLocation + (((long) idxLocation) << 32); >+ } >+ >+ int getCurOrient() { >+ if (curOrient >= 0) >+ return curOrient; >+ >+ if ((environment.orientation & BidiComplexEnvironment.ORIENT_CONTEXTUAL_LTR) == 0) { >+ // absolute orientation >+ curOrient = environment.orientation; >+ return curOrient; >+ } >+ // contextual orientation >+ int len = leanText.length(); >+ byte dirProp; >+ for (int i = 0; i < len; i++) { >+ // In the following lines, B, L, R and AL represent bidi categories >+ // as defined in the Unicode Bidirectional Algorithm >+ // ( http://www.unicode.org/reports/tr9/ ). >+ // B represents the category Block Separator. >+ // L represents the category Left to Right character. >+ // R represents the category Right to Left character. >+ // AL represents the category Arabic Letter. >+ dirProp = dirProps[i]; >+ if (dirProp == 0) { >+ dirProp = Character.getDirectionality(leanText.charAt(i)); >+ if (dirProp == B) // B char resolves to L or R depending on orientation >+ continue; >+ dirProps[i] = (byte) (dirProp + 2); >+ } else { >+ dirProp -= 2; >+ } >+ if (dirProp == L) { >+ curOrient = BidiComplexEnvironment.ORIENT_LTR; >+ return curOrient; >+ } >+ if (dirProp == R || dirProp == AL) { >+ curOrient = BidiComplexEnvironment.ORIENT_RTL; >+ return curOrient; >+ } >+ } >+ curOrient = environment.orientation & 1; >+ return curOrient; >+ } >+ >+ /** >+ * @see BidiComplexHelper#getCurDirection >+ */ >+ public int getCurDirection() { >+ if (curDirection >= 0) >+ return curDirection; >+ >+ curStrong = -1; >+ // same direction for Arabic and Hebrew? >+ if (features.dirArabic == features.dirHebrew) { >+ curDirection = features.dirArabic; >+ return curDirection; >+ } >+ // check if Arabic or Hebrew letter comes first >+ int len = leanText.length(); >+ byte dirProp; >+ for (int i = 0; i < len; i++) { >+ // In the following lines, R and AL represent bidi categories >+ // as defined in the Unicode Bidirectional Algorithm >+ // ( http://www.unicode.org/reports/tr9/ ). >+ // R represents the category Right to Left character. >+ // AL represents the category Arabic Letter. >+ dirProp = getDirProp(i); >+ if (dirProp == AL) { >+ curDirection = features.dirArabic; >+ return curDirection; >+ } >+ if (dirProp == R) { >+ curDirection = features.dirHebrew; >+ return curDirection; >+ } >+ } >+ // found no Arabic or Hebrew character >+ curDirection = BidiComplexFeatures.DIR_LTR; >+ return curDirection; >+ } >+ >+ void setMarkAndFixes() { >+ int dir = getCurDirection(); >+ if (curStrong == STRONGS[dir]) >+ return; >+ curStrong = STRONGS[dir]; >+ curMark = MARKS[dir]; >+ curEmbed = EMBEDS[dir]; >+ } >+ >+ /** >+ * @see BidiComplexHelper#getDirProp(int index) >+ */ >+ public byte getDirProp(int index) { >+ byte dirProp = dirProps[index]; >+ if (dirProp == 0) { >+ // In the following lines, B, L and R represent bidi categories >+ // as defined in the Unicode Bidirectional Algorithm >+ // ( http://www.unicode.org/reports/tr9/ ). >+ // B represents the category Block Separator. >+ // L represents the category Left to Right character. >+ // R represents the category Right to Left character. >+ dirProp = Character.getDirectionality(leanText.charAt(index)); >+ if (dirProp == B) >+ dirProp = getCurOrient() == BidiComplexEnvironment.ORIENT_RTL ? R : L; >+ dirProps[index] = (byte) (dirProp + 2); >+ return dirProp; >+ } >+ return (byte) (dirProp - 2); >+ } >+ >+ /** >+ * @see BidiComplexHelper#setDirProp(int index, byte dirProp) >+ */ >+ public void setDirProp(int index, byte dirProp) { >+ dirProps[index] = (byte) (dirProp + 2); >+ } >+ >+ /** >+ * @see BidiComplexHelper#processOperator(int operLocation) >+ */ >+ public void processOperator(int operLocation) { >+ // In this method, L, R, AL, AN and EN represent bidi categories >+ // as defined in the Unicode Bidirectional Algorithm >+ // ( http://www.unicode.org/reports/tr9/ ). >+ // L represents the category Left to Right character. >+ // R represents the category Right to Left character. >+ // AL represents the category Arabic Letter. >+ // AN represents the category Arabic Number. >+ // EN represents the category European Number. >+ int len = leanText.length(); >+ boolean doneAN = false; >+ >+ if (getCurDirection() == BidiComplexFeatures.DIR_RTL) { >+ // the expression base direction is RTL >+ for (int i = operLocation - 1; i >= 0; i--) { >+ byte dirProp = getDirProp(i); >+ if (dirProp == R || dirProp == AL) >+ return; >+ >+ if (dirProp == L) { >+ for (int j = operLocation; j < len; j++) { >+ dirProp = getDirProp(j); >+ if (dirProp == R || dirProp == AL) >+ return; >+ if (dirProp == L || dirProp == EN) { >+ insertMark(operLocation); >+ return; >+ } >+ } >+ return; >+ } >+ } >+ return; >+ } >+ >+ // the expression base direction is LTR >+ if (features.ignoreArabic) { >+ if (features.ignoreHebrew) /* process neither Arabic nor Hebrew */ >+ return; >+ /* process Hebrew, not Arabic */ >+ for (int i = operLocation - 1; i >= 0; i--) { >+ byte dirProp = getDirProp(i); >+ if (dirProp == L) >+ return; >+ if (dirProp == R) { >+ for (int j = operLocation; j < len; j++) { >+ dirProp = getDirProp(j); >+ if (dirProp == L) >+ return; >+ if (dirProp == R || dirProp == EN) { >+ insertMark(operLocation); >+ return; >+ } >+ } >+ return; >+ } >+ } >+ } else { >+ if (features.ignoreHebrew) { /* process Arabic, not Hebrew */ >+ for (int i = operLocation - 1; i >= 0; i--) { >+ byte dirProp = getDirProp(i); >+ if (dirProp == L) >+ return; >+ if (dirProp == AL) { >+ for (int j = operLocation; j < len; j++) { >+ dirProp = getDirProp(j); >+ if (dirProp == L) >+ return; >+ if (dirProp == EN || dirProp == AL || dirProp == AN) { >+ insertMark(operLocation); >+ return; >+ } >+ } >+ return; >+ } >+ if (dirProp == AN && !doneAN) { >+ for (int j = operLocation; j < len; j++) { >+ dirProp = getDirProp(j); >+ if (dirProp == L) >+ return; >+ if (dirProp == AL || dirProp == AN) { >+ insertMark(operLocation); >+ return; >+ } >+ } >+ doneAN = true; >+ } >+ } >+ } else { /* process Arabic and Hebrew */ >+ for (int i = operLocation - 1; i >= 0; i--) { >+ byte dirProp = getDirProp(i); >+ if (dirProp == L) >+ return; >+ if (dirProp == R || dirProp == AL) { >+ for (int j = operLocation; j < len; j++) { >+ dirProp = getDirProp(j); >+ if (dirProp == L) >+ return; >+ if (dirProp == R || dirProp == EN || dirProp == AL || dirProp == AN) { >+ insertMark(operLocation); >+ return; >+ } >+ } >+ return; >+ } >+ if (dirProp == AN && !doneAN) { >+ for (int j = operLocation; j < len; j++) { >+ dirProp = getDirProp(j); >+ if (dirProp == L) >+ return; >+ if (dirProp == AL || dirProp == AN || dirProp == R) { >+ insertMark(operLocation); >+ return; >+ } >+ } >+ doneAN = true; >+ } >+ } >+ } >+ } >+ } >+ >+ /** >+ * @see BidiComplexHelper#getFinalState() >+ */ >+ public int getFinalState() { >+ return state; >+ } >+ >+ /** >+ * @see BidiComplexHelper#setFinalState(int newState) >+ */ >+ public void setFinalState(int newState) { >+ state = newState; >+ } >+ >+ /** >+ * @see BidiComplexHelper#leanToFullText(String text, int initState) >+ */ >+ public String leanToFullText(String text, int initState) { >+ if (text.length() == 0) { >+ prefixLength = 0; >+ count = 0; >+ return text; >+ } >+ leanToFullTextNofix(text, initState); >+ return addMarks(true); >+ } >+ >+ void leanToFullTextNofix(String text, int initState) { >+ int operCount = features.operators.length(); >+ // current position >+ int curPos = 0; >+ int len = text.length(); >+ // location of next token to handle >+ int nextLocation; >+ // index of next token to handle (if < operCount, this is an operator; otherwise a special case >+ int idxLocation; >+ leanText = text; >+ offsets = new int[20]; >+ count = 0; >+ dirProps = new byte[len]; >+ curOrient = -1; >+ curDirection = -1; >+ // initialize locations >+ int k = locations.length; >+ for (int i = 0; i < k; i++) { >+ locations[i] = -1; >+ } >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ if (initState != BidiComplexHelper.STATE_NOTHING_GOING) >+ curPos = processor.processSpecial(helper, initState, leanText, -1); >+ >+ while (true) { >+ long res = computeNextLocation(curPos); >+ nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */ >+ if (nextLocation >= len) >+ break; >+ idxLocation = (int) (res >> 32); /* high word */ >+ if (idxLocation < operCount) { >+ processOperator(nextLocation); >+ curPos = nextLocation + 1; >+ } else { >+ curPos = processor.processSpecial(helper, idxLocation - operCount, leanText, nextLocation); >+ } >+ } >+ } >+ >+ /** >+ * @see BidiComplexHelper#leanBidiCharOffsets() >+ */ >+ public int[] leanBidiCharOffsets() { >+ int[] result = new int[count]; >+ System.arraycopy(offsets, 0, result, 0, count); >+ return result; >+ } >+ >+ /** >+ * @see BidiComplexHelper#fullBidiCharOffsets() >+ */ >+ public int[] fullBidiCharOffsets() { >+ int lim = count; >+ if (prefixLength > 0) { >+ if (prefixLength == 1) >+ lim++; >+ else >+ lim += FIXES_LENGTH; >+ } >+ int[] fullOffsets = new int[lim]; >+ for (int i = 0; i < prefixLength; i++) { >+ fullOffsets[i] = i; >+ } >+ int added = prefixLength; >+ for (int i = 0; i < count; i++) { >+ fullOffsets[prefixLength + i] = offsets[i] + added; >+ added++; >+ } >+ if (prefixLength > 1) { >+ int len = leanText.length(); >+ fullOffsets[lim - 2] = len + lim - 2; >+ fullOffsets[lim - 1] = len + lim - 1; >+ } >+ return fullOffsets; >+ } >+ >+ /** >+ * @see BidiComplexHelper#fullToLeanText(String text, int initState) >+ */ >+ public String fullToLeanText(String text, int initState) { >+ int i; // used as loop index >+ setMarkAndFixes(); >+ // remove any prefix and leading mark >+ int lenText = text.length(); >+ for (i = 0; i < lenText; i++) { >+ char c = text.charAt(i); >+ if (c != curEmbed && c != curMark) >+ break; >+ } >+ if (i > 0) { // found at least one prefix or leading mark >+ text = text.substring(i); >+ lenText = text.length(); >+ } >+ // remove any suffix and trailing mark >+ for (i = lenText - 1; i >= 0; i--) { >+ char c = text.charAt(i); >+ if (c != PDF && c != curMark) >+ break; >+ } >+ if (i < 0) { // only suffix and trailing marks, no real data >+ leanText = EMPTY_STRING; >+ prefixLength = 0; >+ count = 0; >+ return leanText; >+ } >+ if (i < (lenText - 1)) { // found at least one suffix or trailing mark >+ text = text.substring(0, i + 1); >+ lenText = text.length(); >+ } >+ char[] chars = text.toCharArray(); >+ // remove marks from chars >+ int cnt = 0; >+ for (i = 0; i < lenText; i++) { >+ char c = chars[i]; >+ if (c == curMark) >+ cnt++; >+ else if (cnt > 0) >+ chars[i - cnt] = c; >+ } >+ String lean = new String(chars, 0, lenText - cnt); >+ leanToFullTextNofix(lean, initState); >+ String full = addMarks(false); /* only marks, no prefix/suffix */ >+ if (full.equals(text)) >+ return lean; >+ >+ // There are some marks in full which are not in text and/or vice versa. >+ // We need to add to lean any mark appearing in text and not in full. >+ // The completed lean can never be longer than text itself. >+ char[] newChars = new char[lenText]; >+ char cFull, cText; >+ int idxFull, idxText, idxLean, markPos, newCharsPos; >+ int lenFull = full.length(); >+ idxFull = idxText = idxLean = newCharsPos = 0; >+ while (idxText < lenText && idxFull < lenFull) { >+ cFull = full.charAt(idxFull); >+ cText = text.charAt(idxText); >+ if (cFull == cText) { /* chars are equal, proceed */ >+ idxText++; >+ idxFull++; >+ continue; >+ } >+ if (cFull == curMark) { /* extra Mark in full text */ >+ idxFull++; >+ continue; >+ } >+ if (cText == curMark) { /* extra Mark in source full text */ >+ idxText++; >+ // idxText-2 always >= 0 since leading Marks were removed from text >+ if (text.charAt(idxText - 2) == curMark) >+ continue; // ignore successive Marks in text after the first one >+ markPos = fullToLeanPos(idxFull); >+ // copy from chars (== lean) to newChars until here >+ for (i = idxLean; i < markPos; i++) { >+ newChars[newCharsPos++] = chars[i]; >+ } >+ idxLean = markPos; >+ newChars[newCharsPos++] = curMark; >+ continue; >+ } >+ // we should never get here (extra char which is not a Mark) >+ throw new IllegalStateException("Internal error: extra character not a Mark."); //$NON-NLS-1$ >+ } >+ if (idxText < lenText) /* full ended before text - this should never happen */ >+ throw new IllegalStateException("Internal error: unexpected EOL."); //$NON-NLS-1$ >+ >+ // copy the last part of chars to newChars >+ for (i = idxLean; i < lean.length(); i++) { >+ newChars[newCharsPos++] = chars[i]; >+ } >+ lean = new String(newChars, 0, newCharsPos); >+ leanText = lean; >+ return lean; >+ } >+ >+ /** >+ * @see BidiComplexHelper#leanToFullPos(int pos) >+ */ >+ public int leanToFullPos(int pos) { >+ int added = prefixLength; >+ for (int i = 0; i < count; i++) { >+ if (offsets[i] <= pos) >+ added++; >+ else >+ return pos + added; >+ } >+ return pos + added; >+ } >+ >+ /** >+ * @see BidiComplexHelper#fullToLeanPos(int pos) >+ */ >+ public int fullToLeanPos(int pos) { >+ int len = leanText.length(); >+ int added = 0; >+ pos -= prefixLength; >+ for (int i = 0; i < count; i++) { >+ if ((offsets[i] + added) < pos) >+ added++; >+ else >+ break; >+ } >+ pos -= added; >+ if (pos < 0) >+ pos = 0; >+ else if (pos > len) >+ pos = len; >+ return pos; >+ } >+ >+ /** >+ * @see BidiComplexHelper#insertMark(int offset) >+ */ >+ public void insertMark(int offset) { >+ int index = count - 1; // index of greatest member <= offset >+ // look up after which member the new offset should be inserted >+ while (index >= 0) { >+ int wrkOffset = offsets[index]; >+ if (offset > wrkOffset) >+ break; >+ if (offset == wrkOffset) >+ return; // avoid duplicates >+ index--; >+ } >+ index++; // index now points at where to insert >+ // check if we have an available slot for new member >+ if (count >= (offsets.length - 1)) { >+ int[] newOffsets = new int[offsets.length * 2]; >+ System.arraycopy(offsets, 0, newOffsets, 0, count); >+ offsets = newOffsets; >+ } >+ >+ int length = count - index; // number of members to move up >+ if (length > 0) // shift right all members greater than offset >+ System.arraycopy(offsets, index, offsets, index + 1, length); >+ >+ offsets[index] = offset; >+ count++; >+ // if the offset is 0, adding a mark does not change anything >+ if (offset < 1) >+ return; >+ >+ byte dirProp = getDirProp(offset); >+ // if the current char is a strong one or a digit, we change the >+ // dirProp of the previous char to account for the inserted mark. >+ // In the following lines, L, R, AL, AN and EN represent bidi categories >+ // as defined in the Unicode Bidirectional Algorithm >+ // ( http://www.unicode.org/reports/tr9/ ). >+ // L represents the category Left to Right character. >+ // R represents the category Right to Left character. >+ // AL represents the category Arabic Letter. >+ // AN represents the category Arabic Number. >+ // EN represents the category European Number. >+ if (dirProp == L || dirProp == R || dirProp == AL || dirProp == EN || dirProp == AN) >+ index = offset - 1; >+ else >+ // if the current char is a neutral, we change its own dirProp >+ index = offset; >+ setMarkAndFixes(); >+ setDirProp(index, curStrong); >+ } >+ >+ String addMarks(boolean addFixes) { >+ // add prefix/suffix only if addFixes is true >+ if ((count == 0) && (!addFixes || (getCurOrient() == getCurDirection()) || (curOrient == BidiComplexEnvironment.ORIENT_IGNORE))) { >+ prefixLength = 0; >+ return leanText; >+ } >+ int len = leanText.length(); >+ int newLen = len + count; >+ if (addFixes && ((getCurOrient() != getCurDirection()) || (curOrient == BidiComplexEnvironment.ORIENT_UNKNOWN))) { >+ if ((environment.orientation & BidiComplexEnvironment.ORIENT_CONTEXTUAL_LTR) == 0) { >+ prefixLength = PREFIX_LENGTH; >+ newLen += FIXES_LENGTH; >+ } else { /* contextual orientation */ >+ prefixLength = 1; >+ newLen++; /* +1 for a mark char */ >+ } >+ } else { >+ prefixLength = 0; >+ } >+ char[] fullChars = new char[newLen]; >+ // add a dummy offset as fence >+ offsets[count] = len; >+ int added = prefixLength; >+ // add marks at offsets >+ setMarkAndFixes(); >+ for (int i = 0, j = 0; i < len; i++) { >+ char c = leanText.charAt(i); >+ if (i == offsets[j]) { >+ fullChars[i + added] = curMark; >+ added++; >+ j++; >+ } >+ fullChars[i + added] = c; >+ } >+ if (prefixLength > 0) { /* add prefix/suffix ? */ >+ if (prefixLength == 1) { /* contextual orientation */ >+ fullChars[0] = curMark; >+ } else { >+ // When the orientation is RTL, we need to add EMBED at the >+ // start of the text and PDF at its end. >+ // However, because of a bug in Windows' handling of LRE/PDF, >+ // we add EMBED_PREFIX at the start and EMBED_SUFFIX at the end. >+ fullChars[0] = curEmbed; >+ fullChars[1] = curMark; >+ fullChars[newLen - 1] = PDF; >+ fullChars[newLen - 2] = curMark; >+ } >+ } >+ return new String(fullChars); >+ } >+ >+ /** >+ * @see BidiComplexHelper#getEnvironment() >+ */ >+ public BidiComplexEnvironment getEnvironment() { >+ return environment; >+ } >+ >+ /** >+ * @see BidiComplexHelper#setEnvironment(BidiComplexEnvironment environment) >+ */ >+ public void setEnvironment(BidiComplexEnvironment environment) { >+ this.environment = environment; >+ features = processor.updateEnvironment(helper, environment); >+ specialsCount = features.specialsCount; >+ if ((features.operators.length() + specialsCount) > locations.length) >+ locations = new int[features.operators.length() + specialsCount]; >+ >+ } >+ >+ /** >+ * @see BidiComplexHelper#getFeatures() >+ */ >+ public BidiComplexFeatures getFeatures() { >+ return features; >+ } >+ >+ /** >+ * @see BidiComplexHelper#setFeatures(BidiComplexFeatures features) >+ */ >+ public void setFeatures(BidiComplexFeatures features) { >+ if ((features.operators.length() + specialsCount) > locations.length) >+ locations = new int[features.operators.length() + specialsCount]; >+ this.features = features; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/BidiComplexSingle.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/BidiComplexSingle.java >diff -N src/org/eclipse/equinox/bidi/internal/BidiComplexSingle.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/BidiComplexSingle.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,53 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal; >+ >+import org.eclipse.equinox.bidi.BidiComplexFeatures; >+import org.eclipse.equinox.bidi.BidiComplexHelper; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * <code>BidiComplexSingle</code> is a processor for complex expressions >+ * composed of two parts separated by an operator. >+ * The first occurrence of the operator delimits the end of the first part >+ * and the start of the second part. Further occurrences of the operator, >+ * if any, are treated like regular characters of the second text part. >+ * The processor makes sure that the expression be presented in the form >+ * (assuming that the equal sign is the operator): >+ * <pre> >+ * part1=part2 >+ * </pre> >+ * The {@link BidiComplexFeatures#operators operators} >+ * field in the {@link BidiComplexFeatures features} >+ * of this processor should contain exactly one character. >+ * Additional characters will be ignored. >+ * >+ * @author Matitiahu Allouche >+ */ >+public abstract class BidiComplexSingle extends BidiComplexProcessor { >+ >+ /** >+ * This method locates occurrences of the operator. >+ */ >+ public int indexOfSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int fromIndex) { >+ return srcText.indexOf(helper.impl.features.operators.charAt(0), fromIndex); >+ } >+ >+ /** >+ * This method inserts a mark before the operator if needed and >+ * skips to the end of the source string. >+ */ >+ public int processSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int operLocation) { >+ helper.processOperator(operLocation); >+ return srcText.length(); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/BidiComplexTypesCollector.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/BidiComplexTypesCollector.java >diff -N src/org/eclipse/equinox/bidi/internal/BidiComplexTypesCollector.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/BidiComplexTypesCollector.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,111 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal; >+ >+import java.util.HashMap; >+import java.util.Map; >+import org.eclipse.core.runtime.*; >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+ >+public class BidiComplexTypesCollector implements IRegistryEventListener { >+ >+ private static final String EXT_POINT = "org.eclipse.equinox.bidi.bidiTypes"; //$NON-NLS-1$ >+ >+ private static final String CE_NAME = "typeDescription"; //$NON-NLS-1$ >+ private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ >+ private static final String ATTR_PROCESSOR = "class"; //$NON-NLS-1$ >+ >+ private Map types; >+ private Map factories; >+ >+ static private BidiComplexTypesCollector instance = new BidiComplexTypesCollector(); >+ >+ private BidiComplexTypesCollector() { >+ IExtensionRegistry registry = RegistryFactory.getRegistry(); >+ registry.addListener(this, EXT_POINT); >+ } >+ >+ static public BidiComplexTypesCollector getInstance() { >+ return instance; >+ } >+ >+ public String[] getTypes() { >+ if (types == null) >+ read(); >+ int size = types.size(); >+ String[] result = new String[size]; >+ types.keySet().toArray(result); >+ return result; >+ } >+ >+ public IBidiComplexProcessor getProcessor(String type) { >+ if (types == null) >+ read(); >+ Object processor = types.get(type); >+ if (processor instanceof IBidiComplexProcessor) >+ return (IBidiComplexProcessor) processor; >+ return null; >+ } >+ >+ private void read() { >+ if (types == null) >+ types = new HashMap(); >+ else >+ types.clear(); >+ >+ if (factories == null) >+ factories = new HashMap(); >+ else >+ factories.clear(); >+ >+ IExtensionRegistry registry = RegistryFactory.getRegistry(); >+ IExtensionPoint extPoint = registry.getExtensionPoint(EXT_POINT); >+ IExtension[] extensions = extPoint.getExtensions(); >+ >+ for (int i = 0; i < extensions.length; i++) { >+ IConfigurationElement[] confElements = extensions[i].getConfigurationElements(); >+ for (int j = 0; j < confElements.length; j++) { >+ if (CE_NAME != confElements[j].getName()) >+ BidiComplexActivator.logError("BiDi types: unexpected element name " + confElements[j].getName(), new IllegalArgumentException()); //$NON-NLS-1$ >+ String type = confElements[j].getAttribute(ATTR_TYPE); >+ Object processor; >+ try { >+ processor = confElements[j].createExecutableExtension(ATTR_PROCESSOR); >+ } catch (CoreException e) { >+ BidiComplexActivator.logError("BiDi types: unable to create processor for " + type, e); //$NON-NLS-1$ >+ continue; >+ } >+ types.put(type, processor); >+ factories.put(type, confElements[j]); >+ } >+ } >+ } >+ >+ public void added(IExtension[] extensions) { >+ types = null; >+ factories = null; >+ } >+ >+ public void removed(IExtension[] extensions) { >+ types = null; >+ factories = null; >+ } >+ >+ public void added(IExtensionPoint[] extensionPoints) { >+ types = null; >+ factories = null; >+ } >+ >+ public void removed(IExtensionPoint[] extensionPoints) { >+ types = null; >+ factories = null; >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/BiDiActivator.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/BiDiActivator.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/BiDiActivator.java >--- src/org/eclipse/equinox/bidi/internal/complexp/BiDiActivator.java 3 Feb 2010 20:01:02 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,62 +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.internal.complexp; >- >-import org.eclipse.osgi.framework.log.FrameworkLog; >-import org.eclipse.osgi.framework.log.FrameworkLogEntry; >-import org.osgi.framework.BundleActivator; >-import org.osgi.framework.BundleContext; >-import org.osgi.util.tracker.ServiceTracker; >- >-public class BiDiActivator implements BundleActivator { >- >- private ServiceTracker logTracker = null; >- private BundleContext bundleContext; >- >- private static BiDiActivator instance; >- >- public BiDiActivator() { >- instance = this; // there is only one bundle activator >- } >- >- public void start(BundleContext context) throws Exception { >- bundleContext = context; >- instance = this; >- } >- >- public void stop(BundleContext context) throws Exception { >- if (logTracker != null) { >- logTracker.close(); >- logTracker = null; >- } >- bundleContext = null; >- } >- >- private FrameworkLog getFrameworkLog() { >- if (logTracker == null) { >- logTracker = new ServiceTracker(bundleContext, FrameworkLog.class.getName(), null); >- logTracker.open(); >- } >- return (FrameworkLog) logTracker.getService(); >- } >- >- static public void logError(String message, Exception e) { >- FrameworkLog frameworkLog = instance.getFrameworkLog(); >- if (frameworkLog != null) { >- frameworkLog.log(new FrameworkLogEntry("org.eclipse.equinox.bidi", FrameworkLogEntry.ERROR, 1, message, 0, e, null)); //$NON-NLS-1$ >- return; >- } >- System.err.println(message); >- if (e != null) >- e.printStackTrace(); >- } >- >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/BiDiTypesCollector.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/BiDiTypesCollector.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/BiDiTypesCollector.java >--- src/org/eclipse/equinox/bidi/internal/complexp/BiDiTypesCollector.java 3 Feb 2010 20:01:02 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,129 +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.internal.complexp; >- >-import java.util.HashMap; >-import java.util.Map; >-import org.eclipse.core.runtime.*; >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >- >-public class BiDiTypesCollector implements IRegistryEventListener { >- >- private static final String EXT_POINT = "org.eclipse.equinox.bidi.bidiTypes"; //$NON-NLS-1$ >- >- private static final String CE_NAME = "typeDescription"; //$NON-NLS-1$ >- private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ >- private static final String ATTR_PROCESSOR = "class"; //$NON-NLS-1$ >- >- private Map types; >- private Map factories; >- >- static private BiDiTypesCollector instance = new BiDiTypesCollector(); >- >- private BiDiTypesCollector() { >- IExtensionRegistry registry = RegistryFactory.getRegistry(); >- registry.addListener(this, EXT_POINT); >- } >- >- static public BiDiTypesCollector getInstance() { >- return instance; >- } >- >- public String[] getTypes() { >- if (types == null) >- read(); >- int size = types.size(); >- String[] result = new String[size]; >- types.keySet().toArray(result); >- return result; >- } >- >- public IComplExpProcessor getProcessor(String type) { >- if (types == null) >- read(); >- Object processor = types.get(type); >- if (processor instanceof IComplExpProcessor) >- return (IComplExpProcessor) processor; >- return null; >- } >- >- public IComplExpProcessor makeProcessor(String type) { >- if (factories == null) >- read(); >- IConfigurationElement ce = (IConfigurationElement) factories.get(type); >- if (ce == null) >- return null; >- Object processor; >- try { >- processor = ce.createExecutableExtension(ATTR_PROCESSOR); >- } catch (CoreException e) { >- BiDiActivator.logError("BiDi types: unable to create processor for " + type, e); //$NON-NLS-1$ >- return null; >- } >- if (processor instanceof IComplExpProcessor) >- return (IComplExpProcessor) processor; >- return null; >- } >- >- private void read() { >- if (types == null) >- types = new HashMap(); >- else >- types.clear(); >- >- if (factories == null) >- factories = new HashMap(); >- else >- factories.clear(); >- >- IExtensionRegistry registry = RegistryFactory.getRegistry(); >- IExtensionPoint extPoint = registry.getExtensionPoint(EXT_POINT); >- IExtension[] extensions = extPoint.getExtensions(); >- >- for (int i = 0; i < extensions.length; i++) { >- IConfigurationElement[] confElements = extensions[i].getConfigurationElements(); >- for (int j = 0; j < confElements.length; j++) { >- if (CE_NAME != confElements[j].getName()) >- BiDiActivator.logError("BiDi types: unexpected element name " + confElements[j].getName(), new IllegalArgumentException()); //$NON-NLS-1$ >- String type = confElements[j].getAttribute(ATTR_TYPE); >- Object processor; >- try { >- processor = confElements[j].createExecutableExtension(ATTR_PROCESSOR); >- } catch (CoreException e) { >- BiDiActivator.logError("BiDi types: unable to create processor for " + type, e); //$NON-NLS-1$ >- continue; >- } >- types.put(type, processor); >- factories.put(type, confElements[j]); >- } >- } >- } >- >- public void added(IExtension[] extensions) { >- types = null; >- factories = null; >- } >- >- public void removed(IExtension[] extensions) { >- types = null; >- factories = null; >- } >- >- public void added(IExtensionPoint[] extensionPoints) { >- types = null; >- factories = null; >- } >- >- public void removed(IExtensionPoint[] extensionPoints) { >- types = null; >- factories = null; >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpBasic.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpBasic.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/ComplExpBasic.java >--- src/org/eclipse/equinox/bidi/internal/complexp/ComplExpBasic.java 12 Apr 2010 18:51:18 -0000 1.5 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,989 +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.internal.complexp; >- >-import org.eclipse.equinox.bidi.complexp.*; >- >-/** >- * <code>ComplExpBasic</code> is a >- * complex expression processor for simple types of complex expressions. >- * Normally, a group of <q>operators</q> is specified when creating a new >- * instance. >- * <i>Lean</i> text which is submitted to this processor is divided into >- * segments by the operators. The processor adds directional formatting >- * characters into the lean text to generate a <i>full</i> text where >- * operators and text segments will be presented in left-to-right sequence. >- * >- * @see IComplExpProcessor >- * >- * @author Matitiahu Allouche >- */ >-public class ComplExpBasic implements IComplExpProcessor { >- >- final private static String EMPTY_STRING = ""; //$NON-NLS-1$ >- >- /** >- * Flag specifying that a specific instance of complex expression should >- * assume that the GUI is mirrored (globally going from right to left). >- * This flag overrides the default flag <code>mirroredDefault</code> >- * for the parent complex expression instance. >- * @see #assumeMirrored >- * @see #isMirrored >- * @see ComplExpUtil#isMirroredDefault() >- */ >- protected boolean mirrored = ComplExpUtil.isMirroredDefault(); >- >- /** >- * Orientation that should be assumed for the text component where the >- * complex expression will be displayed. It can be specified using >- * {@link #assumeOrientation}. >- * It must be one of the values >- * {@link IComplExpProcessor#ORIENT_LTR ORIENT_LTR}, >- * {@link IComplExpProcessor#ORIENT_LTR ORIENT_RTL}, >- * {@link IComplExpProcessor#ORIENT_CONTEXTUAL_LTR ORIENT_CONTEXTUAL_LTR} or >- * {@link IComplExpProcessor#ORIENT_CONTEXTUAL_RTL ORIENT_CONTEXTUAL_RTL}. >- * {@link IComplExpProcessor#ORIENT_UNKNOWN ORIENT_UNKNOWN}. >- * {@link IComplExpProcessor#ORIENT_IGNORE ORIENT_IGNORE}. >- * The default is <code>ORIENT_LTR</code>. >- * <p> >- * The orientation affects the addition of directional formatting >- * characters as prefix and/or suffix when generating the <i>full</i> >- * text of the complex expression. >- * >- * @see #assumeOrientation >- * @see #recallOrientation >- * @see #leanToFullText >- */ >- protected int orientation; >- >- /** >- * Type of the complex expression processor specified when calling >- * {@link ComplExpFactory#create(String)}. >- */ >- protected String type; >- >- /** >- * Base direction of the complex expression. This is an array such that >- * <ul> >- * <li><code>direction[0][0]</code> represents the base direction >- * for Arabic when the GUI is not mirrored. >- * <li><code>direction[0][1]</code> represents the base direction >- * for Arabic when the GUI is mirrored. >- * <li><code>direction[1][0]</code> represents the base direction >- * for Hebrew when the GUI is not mirrored. >- * <li><code>direction[1][1]</code> represents the base direction >- * for Hebrew when the GUI is mirrored. >- * </ul> >- * Each of the elements in the array must be one of the values >- * {@link IComplExpProcessor#DIRECTION_LTR DIRECTION_LTR}, >- * {@link IComplExpProcessor#DIRECTION_LTR DIRECTION_RTL}. >- * The default is <code>DIRECTION_LTR</code>. >- * >- * @see #setDirection(int) setDirection >- * @see #getDirection getDirection >- */ >- protected int[][] direction = new int[2][2]; >- >- /** >- * This field represents the final state achieved in a previous call to >- * {@link IComplExpProcessor#leanToFullText leanToFullText} or >- * {@link IComplExpProcessor#fullToLeanText fullToLeanText}, >- * {@link IComplExpProcessor#leanBidiCharOffsets(java.lang.String text)} or >- * {@link IComplExpProcessor#leanBidiCharOffsets(java.lang.String text, int initState)}. >- * The <code>state</code> is an opaque value which makes sense only >- * within calls to a same complex expression processor. >- * The only externalized value is >- * {@link IComplExpProcessor#STATE_NOTHING_GOING} which means that >- * there is nothing to remember from the last call. >- * <p> >- * <code>state</code> should be used only for complex expressions >- * which span more than one line, when the user makes a separate call to >- * <code>leanToFullText</code>, <code>fullToLeanText</code> or >- * <code>leanBidiCharOffsets</code> 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. >- * <p> >- * If a line within a complex expression has already been processed by >- * <code>leanToFullText</code> and the <i>lean</i> version of that line has >- * not changed, and its initial state has not changed either, the user >- * can be sure that the <i>full</i> version of that line is also >- * identical to the result of the previous processing. >- * >- * @see IComplExpProcessor#getFinalState >- * @see IComplExpProcessor#leanToFullText(String text, int initState) >- * @see IComplExpProcessor#fullToLeanText(String text, int initState) >- * @see IComplExpProcessor#leanBidiCharOffsets(String text, int initState) >- */ >- protected int state = STATE_NOTHING_GOING; >- >- private boolean ignoreArabic, ignoreHebrew; >- >- public static final byte B = Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR; >- public static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT; >- public static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT; >- public static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC; >- public static final byte AN = Character.DIRECTIONALITY_ARABIC_NUMBER; >- public static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER; >- public static final char LRM = 0x200E; >- public static final char RLM = 0x200F; >- public static final char LRE = 0x202A; >- public static final char RLE = 0x202B; >- public static final char PDF = 0x202C; >- public static final char[] MARKS = {LRM, RLM}; >- public static final char[] EMBEDS = {LRE, RLE}; >- public static final byte[] STRONGS = {L, R}; >- public static final int PREFIX_LENGTH = 2; >- public static final int SUFFIX_LENGTH = 2; >- public static final int FIXES_LENGTH = PREFIX_LENGTH + SUFFIX_LENGTH; >- >- private byte curStrong = -1; >- private char curMark; >- private char curEmbed; >- private int prefixLength; >- char[] operators; >- int[] locations; >- int specialsCount; >- private String leanText; >- private int[] offsets; >- private int count; >- // For positions where it has been looked up, the entry will receive >- // the Character directionality + 2 (so that 0 indicates that the >- // the directionality has not been looked up yet. >- private byte[] dirProps; >- // current UI orientation (after resolution if contextual) >- private int curOrient = -1; >- // Current expression base direction (after resolution if depending on >- // script and/or on GUI mirroring (0=LTR, 1=RTL)) >- private int curDirection = -1; >- >- /** >- * Constructor specifying operators. The processor will add directional >- * formatting characters to <i>lean</i> text to generate a <i>full</i> >- * text so that the operators and the segments of text between operators >- * are displayed from left to right, while each segment is displayed >- * according to the <a href="http://www.unicode.org/reports/tr9/">UBA</a>. >- * >- * @param operators string grouping one-character operators which >- * separate the text of the complex expression into segments. >- */ >- public ComplExpBasic(String operators) { >- this.operators = operators.toCharArray(); >- locations = new int[this.operators.length]; >- } >- >- public void setOperators(String operators) { >- this.operators = operators.toCharArray(); >- locations = new int[this.operators.length + specialsCount]; >- } >- >- public String getOperators() { >- return new String(operators); >- } >- >- /** >- * Constructor specifying operators and a number of special cases. >- * In <code>ComplExpBasic</code> the special cases are implemented as >- * doing nothing. Subclasses of <code>ComplExpBasic</code> may override >- * methods <code>indexOfSpecial</code> and <code>processSpecial</code> >- * to provide specific handling for the special cases. >- * Examples of special cases are comments, literals, or anything which >- * is not identified by a one-character operator. >- * <p> >- * Independently of the special cases, the processor will add directional >- * formatting characters to <i>lean</i> text to generate a <i>full</i> >- * text so that the operators and the segments of text between operators >- * are displayed from left to right, while each segment is displayed >- * according to the <a href="http://www.unicode.org/reports/tr9/">UBA</a>. >- * >- * @param operators string grouping one-character operators which >- * separate the text of the complex expression into segments. >- * >- * @param specialsCount number of special cases supported by this >- * class. Handling of the special cases is implemented with >- * methods <code>indexOfSpecial</code> and >- * <code>processSpecial</code>. >- * >- * @see #indexOfSpecial indexOfSpecial >- * @see #processSpecial processSpecial >- */ >- public ComplExpBasic(String operators, int specialsCount) { >- this.operators = operators.toCharArray(); >- this.specialsCount = specialsCount; >- locations = new int[this.operators.length + specialsCount]; >- } >- >- public void selectBidiScript(boolean arabic, boolean hebrew) { >- ignoreArabic = !arabic; >- ignoreHebrew = !hebrew; >- } >- >- public boolean handlesArabicScript() { >- return !ignoreArabic; >- } >- >- public boolean handlesHebrewScript() { >- return !ignoreHebrew; >- } >- >- long computeNextLocation(int curPos) { >- int operCount = operators.length; >- int len = leanText.length(); >- int nextLocation = len; >- int idxLocation = 0; >- // Start with special sequences to give them precedence over simple >- // operators. This may apply to cases like slash+asterisk versus slash. >- for (int i = 0; i < specialsCount; i++) { >- int loc = locations[operCount + i]; >- if (loc < curPos) { >- loc = indexOfSpecial(i, leanText, curPos); >- if (loc < 0) >- loc = len; >- locations[operCount + i] = loc; >- } >- if (loc < nextLocation) { >- nextLocation = loc; >- idxLocation = operCount + i; >- } >- } >- for (int i = 0; i < operCount; i++) { >- int loc = locations[i]; >- if (loc < curPos) { >- loc = leanText.indexOf(operators[i], curPos); >- if (loc < 0) >- loc = len; >- locations[i] = loc; >- } >- if (loc < nextLocation) { >- nextLocation = loc; >- idxLocation = i; >- } >- } >- return nextLocation + (((long) idxLocation) << 32); >- } >- >- /** >- * This method is called repeatedly by <code>leanToFullText</code> to >- * locate all special cases specified in the constructor >- * (see {@link #ComplExpBasic(String operators, int specialsCount)}), >- * varying <code>whichSpecial</code> from zero to >- * <code>specialsCount - 1</code>. It is meant to be overridden in >- * subclasses of <code>ComplExpBasic</code>. >- * Those subclasses may use methods >- * {@link #getDirProp getDirProp}, >- * {@link #setDirProp setDirProp} and >- * {@link #insertMark insertMark} within <code>indexOfSpecial</code>. >- * >- * @param whichSpecial number of the special case to locate. The meaning >- * of this number is internal to the class implementing >- * <code>indexOfSpecial</code>. >- * >- * @param srcText text of the complex expression before addition of any >- * directional formatting characters. >- * >- * @param fromIndex the index within <code>srcText</code> 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 after >- * <code>fromIndex</code>. 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). >- * If no occurrence is found, the method must return -1. >- * <p> >- * In <code>ComplExpBasic</code> this method always returns -1. >- * >- */ >- protected int indexOfSpecial(int whichSpecial, String srcText, int fromIndex) { >- // This method must be overridden by all subclasses with special cases. >- return -1; >- } >- >- /** >- * This method is called by <code>leanToFullText</code> >- * when a special case occurrence is located by >- * {@link #indexOfSpecial indexOfSpecial}. >- * It is meant to be overridden in subclasses of <code>ComplExpBasic</code>. >- * Those subclasses may use methods >- * {@link #getDirProp getDirProp}, >- * {@link #setDirProp setDirProp} and >- * {@link #insertMark insertMark} within <code>processSpecial</code>. >- * <p> >- * If a special processing cannot be completed within a current call to >- * <code>processSpecial</code> (for instance, a comment has been started >- * in the current line but its end appears in a following line), >- * <code>processSpecial</code> should put in the {@link #state} >- * member of the class instance a number which characterizes this >- * situation. On a later call to >- * {@link IComplExpProcessor#leanToFullText(String text, int initState)} >- * specifying that state value, <code>processSpecial</code> will be >- * called with that value for parameter <code>whichSpecial</code> and >- * <code>-1</code> for parameter <code>operLocation</code> 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 <code>indexOfSpecial</code>. >- * In calls to <code>leanToFullText</code> or >- * <code>fullToLeanText</code> specifying an <code>initState</code> >- * parameter, <code>processSpecial</code> is called when initializing >- * the processing with the value of <code>whichSpecial</code> >- * equal to <code>initState</code> and the value of >- * <code>operLocation</code> equal to <code>-1</code>. >- * >- * @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. >- * <p> >- * In <code>ComplExpBasic</code> this method always returns >- * <code>operLocation + 1</code> (but it should never be called). >- * >- */ >- protected int processSpecial(int whichSpecial, String srcText, int operLocation) { >- // This method must be overridden by all subclasses with any special case. >- return operLocation + 1; >- } >- >- private int getCurOrient() { >- if (curOrient >= 0) >- return curOrient; >- >- if ((orientation & ORIENT_CONTEXTUAL_LTR) == 0) { >- // absolute orientation >- curOrient = orientation; >- return curOrient; >- } >- // contextual orientation >- int len = leanText.length(); >- byte dirProp; >- for (int i = 0; i < len; i++) { >- dirProp = dirProps[i]; >- if (dirProp == 0) { >- dirProp = Character.getDirectionality(leanText.charAt(i)); >- if (dirProp == B) // B char resolves to L or R depending on orientation >- continue; >- dirProps[i] = (byte) (dirProp + 2); >- } else { >- dirProp -= 2; >- } >- if (dirProp == L) { >- curOrient = ORIENT_LTR; >- return curOrient; >- } >- if (dirProp == R || dirProp == AL) { >- curOrient = ORIENT_RTL; >- return curOrient; >- } >- } >- curOrient = orientation & 1; >- return curOrient; >- } >- >- public int getCurDirection() { >- if (curDirection >= 0) >- return curDirection; >- >- curStrong = -1; >- int idx2 = mirrored ? 1 : 0; >- // same direction for Arabic and Hebrew? >- if (direction[0][idx2] == direction[1][idx2]) { >- curDirection = direction[0][idx2]; >- return curDirection; >- } >- // check if Arabic or Hebrew letter comes first >- int len = leanText.length(); >- byte dirProp; >- for (int i = 0; i < len; i++) { >- dirProp = getDirProp(i); >- if (dirProp == AL) { >- curDirection = direction[0][idx2]; >- return curDirection; >- } >- if (dirProp == R) { >- curDirection = direction[1][idx2]; >- return curDirection; >- } >- } >- // found no Arabic or Hebrew character >- curDirection = DIRECTION_LTR; >- return curDirection; >- } >- >- private void setMarkAndFixes() { >- int dir = getCurDirection(); >- if (curStrong == STRONGS[dir]) >- return; >- curStrong = STRONGS[dir]; >- curMark = MARKS[dir]; >- curEmbed = EMBEDS[dir]; >- } >- >- /** >- * This method can be called from within {@link #indexOfSpecial indexOfSpecial} >- * or {@link #processSpecial processSpecial} in subclasses of >- * <code>ComplExpBasic</code> to retrieve the bidirectional class of >- * characters in <code>leanText</code>. >- * >- * @param index position of the character in <code>leanText</code>. >- * >- * @return the bidirectional class of the character. It is one of the >- * values which can be returned by >- * <code>java.lang.Character#getDirectionality</code>. >- * However, it is recommended to use <code>getDirProp</code> >- * rather than <code>java.lang.Character.getDirectionality</code> >- * since <code>getDirProp</code> manages a cache of character >- * properties and so can be more efficient than calling the >- * java.lang.Character method. >- * >- */ >- protected byte getDirProp(int index) { >- byte dirProp = dirProps[index]; >- if (dirProp == 0) { >- dirProp = Character.getDirectionality(leanText.charAt(index)); >- if (dirProp == B) >- dirProp = getCurOrient() == ORIENT_RTL ? R : L; >- dirProps[index] = (byte) (dirProp + 2); >- return dirProp; >- } >- return (byte) (dirProp - 2); >- } >- >- /** >- * This method can be called from within {@link #indexOfSpecial indexOfSpecial} >- * or {@link #processSpecial processSpecial} in subclasses of >- * <code>ComplExpBasic</code> to set or override the bidirectional >- * class of characters in <code>leanText</code>. >- * >- * @param index position of the character in <code>leanText</code>. >- * >- * @param dirProp bidirectional class of the character. It is one of the >- * values which can be returned by >- * <code>java.lang.Character.getDirectionality</code>. >- * >- */ >- protected void setDirProp(int index, byte dirProp) { >- dirProps[index] = (byte) (dirProp + 2); >- } >- >- /** >- * This method can be called from within >- * {@link #processSpecial processSpecial} in subclasses of >- * <code>ComplExpBasic</code> 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 <code>leanText</code> preceding and following >- * the operator itself. >- * >- * @param operLocation offset of the operator in <code>leanText</code>. >- * >- */ >- protected void processOperator(int operLocation) { >- int len = leanText.length(); >- boolean doneAN = false; >- >- if (getCurDirection() == DIRECTION_RTL) { >- // the expression base direction is RTL >- for (int i = operLocation - 1; i >= 0; i--) { >- byte dirProp = getDirProp(i); >- if (dirProp == R || dirProp == AL) >- return; >- >- if (dirProp == L) { >- for (int j = operLocation; j < len; j++) { >- dirProp = getDirProp(j); >- if (dirProp == R || dirProp == AL) >- return; >- if (dirProp == L || dirProp == EN) { >- insertMark(operLocation); >- return; >- } >- } >- return; >- } >- } >- return; >- } >- >- // the expression base direction is LTR >- if (ignoreArabic) { >- if (ignoreHebrew) /* process neither Arabic nor Hebrew */ >- return; >- /* process Hebrew, not Arabic */ >- for (int i = operLocation - 1; i >= 0; i--) { >- byte dirProp = getDirProp(i); >- if (dirProp == L) >- return; >- if (dirProp == R) { >- for (int j = operLocation; j < len; j++) { >- dirProp = getDirProp(j); >- if (dirProp == L) >- return; >- if (dirProp == R || dirProp == EN) { >- insertMark(operLocation); >- return; >- } >- } >- return; >- } >- } >- } else { >- if (ignoreHebrew) { /* process Arabic, not Hebrew */ >- for (int i = operLocation - 1; i >= 0; i--) { >- byte dirProp = getDirProp(i); >- if (dirProp == L) >- return; >- if (dirProp == AL) { >- for (int j = operLocation; j < len; j++) { >- dirProp = getDirProp(j); >- if (dirProp == L) >- return; >- if (dirProp == EN || dirProp == AL || dirProp == AN) { >- insertMark(operLocation); >- return; >- } >- } >- return; >- } >- if (dirProp == AN && !doneAN) { >- for (int j = operLocation; j < len; j++) { >- dirProp = getDirProp(j); >- if (dirProp == L) >- return; >- if (dirProp == AL || dirProp == AN) { >- insertMark(operLocation); >- return; >- } >- } >- doneAN = true; >- } >- } >- } else { /* process Arabic and Hebrew */ >- for (int i = operLocation - 1; i >= 0; i--) { >- byte dirProp = getDirProp(i); >- if (dirProp == L) >- return; >- if (dirProp == R || dirProp == AL) { >- for (int j = operLocation; j < len; j++) { >- dirProp = getDirProp(j); >- if (dirProp == L) >- return; >- if (dirProp == R || dirProp == EN || dirProp == AL || dirProp == AN) { >- insertMark(operLocation); >- return; >- } >- } >- return; >- } >- if (dirProp == AN && !doneAN) { >- for (int j = operLocation; j < len; j++) { >- dirProp = getDirProp(j); >- if (dirProp == L) >- return; >- if (dirProp == AL || dirProp == AN || dirProp == R) { >- insertMark(operLocation); >- return; >- } >- } >- doneAN = true; >- } >- } >- } >- } >- } >- >- public int getFinalState() { >- return state; >- } >- >- public String leanToFullText(String text) { >- return leanToFullText(text, STATE_NOTHING_GOING); >- } >- >- public String leanToFullText(String text, int initState) { >- if (text.length() == 0) { >- prefixLength = 0; >- count = 0; >- return text; >- } >- leanToFullTextNofix(text, initState); >- return addMarks(true); >- } >- >- void leanToFullTextNofix(String text, int initState) { >- int operCount = operators.length; >- int curPos = 0; >- int len = text.length(); >- int nextLocation, idxLocation; >- leanText = text; >- offsets = new int[20]; >- count = 0; >- dirProps = new byte[len]; >- curOrient = -1; >- curDirection = -1; >- // initialize locations >- int k = locations.length; >- for (int i = 0; i < k; i++) { >- locations[i] = -1; >- } >- state = STATE_NOTHING_GOING; >- if (initState != STATE_NOTHING_GOING) >- curPos = processSpecial(initState, leanText, -1); >- >- while (true) { >- long res = computeNextLocation(curPos); >- nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */ >- if (nextLocation >= len) >- break; >- idxLocation = (int) (res >> 32); /* high word */ >- if (idxLocation < operCount) { >- processOperator(nextLocation); >- curPos = nextLocation + 1; >- } else { >- curPos = processSpecial(idxLocation - operCount, leanText, nextLocation); >- } >- } >- } >- >- public int[] leanBidiCharOffsets(String text) { >- return leanBidiCharOffsets(text, STATE_NOTHING_GOING); >- } >- >- public int[] leanBidiCharOffsets(String text, int initState) { >- leanToFullTextNofix(text, initState); >- return leanBidiCharOffsets(); >- } >- >- public int[] leanBidiCharOffsets() { >- int[] result = new int[count]; >- System.arraycopy(offsets, 0, result, 0, count); >- return result; >- } >- >- public int[] fullBidiCharOffsets() { >- int lim = count; >- if (prefixLength > 0) { >- if (prefixLength == 1) >- lim++; >- else >- lim += FIXES_LENGTH; >- } >- int[] fullOffsets = new int[lim]; >- for (int i = 0; i < prefixLength; i++) { >- fullOffsets[i] = i; >- } >- int added = prefixLength; >- for (int i = 0; i < count; i++) { >- fullOffsets[prefixLength + i] = offsets[i] + added; >- added++; >- } >- if (prefixLength > 1) { >- int len = leanText.length(); >- fullOffsets[lim - 2] = len + lim - 2; >- fullOffsets[lim - 1] = len + lim - 1; >- } >- return fullOffsets; >- } >- >- public String fullToLeanText(String text) { >- return fullToLeanText(text, STATE_NOTHING_GOING); >- } >- >- public String fullToLeanText(String text, int initState) { >- int i; // TBD this variable is used for multiple unrelated tasks >- setMarkAndFixes(); >- // remove any prefix and leading mark >- int lenText = text.length(); >- for (i = 0; i < lenText; i++) { >- char c = text.charAt(i); >- if (c != curEmbed && c != curMark) >- break; >- } >- if (i > 0) { >- text = text.substring(i); >- lenText = text.length(); >- } >- // remove any suffix and trailing mark >- for (i = lenText - 1; i >= 0; i--) { >- char c = text.charAt(i); >- if (c != PDF && c != curMark) >- break; >- } >- if (i < 0) { >- leanText = EMPTY_STRING; >- prefixLength = 0; >- count = 0; >- return leanText; >- } >- if (i < (lenText - 1)) { >- text = text.substring(0, i + 1); >- lenText = text.length(); >- } >- char[] chars = text.toCharArray(); >- // remove marks from chars >- int cnt = 0; >- for (i = 0; i < lenText; i++) { >- char c = chars[i]; >- if (c == curMark) >- cnt++; >- else if (cnt > 0) >- chars[i - cnt] = c; >- } >- String lean = new String(chars, 0, lenText - cnt); >- leanToFullTextNofix(lean, initState); >- String full = addMarks(false); /* only marks, no prefix/suffix */ >- if (full.equals(text)) >- return lean; >- >- // There are some marks in full which are not in text and/or vice versa. >- // We need to add to lean any mark appearing in text and not in full. >- // The completed lean can never be longer than text itself. >- char[] newChars = new char[lenText]; >- char cFull, cText; >- int idxFull, idxText, idxLean, markPos, newCharsPos; >- int lenFull = full.length(); >- idxFull = idxText = idxLean = newCharsPos = 0; >- while (idxText < lenText && idxFull < lenFull) { >- cFull = full.charAt(idxFull); >- cText = text.charAt(idxText); >- if (cFull == cText) { /* chars are equal, proceed */ >- idxText++; >- idxFull++; >- continue; >- } >- if (cFull == curMark) { /* extra Mark in full text */ >- idxFull++; >- continue; >- } >- if (cText == curMark) { /* extra Mark in source full text */ >- idxText++; >- // idxText-2 always >= 0 since leading Marks were removed from text >- if (text.charAt(idxText - 2) == curMark) >- continue; // ignore successive Marks in text after the first one >- markPos = fullToLeanPos(idxFull); >- // copy from chars (== lean) to newChars until here >- for (i = idxLean; i < markPos; i++) { >- newChars[newCharsPos++] = chars[i]; >- } >- idxLean = markPos; >- newChars[newCharsPos++] = curMark; >- continue; >- } >- // we should never get here (extra char which is not a Mark) >- throw new IllegalStateException("Internal error: extra character not a Mark."); //$NON-NLS-1$ >- } >- if (idxText < lenText) /* full ended before text - this should never happen */ >- throw new IllegalStateException("Internal error: unexpected EOL."); //$NON-NLS-1$ >- >- // copy the last part of chars to newChars >- for (i = idxLean; i < lean.length(); i++) { >- newChars[newCharsPos++] = chars[i]; >- } >- lean = new String(newChars, 0, newCharsPos); >- leanText = lean; >- return lean; >- } >- >- public int leanToFullPos(int pos) { >- int added = prefixLength; >- for (int i = 0; i < count; i++) { >- if (offsets[i] <= pos) >- added++; >- else >- return pos + added; >- } >- return pos + added; >- } >- >- public int fullToLeanPos(int pos) { >- int len = leanText.length(); >- int added = 0; >- pos -= prefixLength; >- for (int i = 0; i < count; i++) { >- if ((offsets[i] + added) < pos) >- added++; >- else >- break; >- } >- pos -= added; >- if (pos < 0) >- pos = 0; >- else if (pos > len) >- pos = len; >- return pos; >- } >- >- /** >- * This method can be called from within {@link #indexOfSpecial} or >- * {@link #processSpecial} in subclasses of <code>ComplExpBasic</code> >- * to specify that a mark character must be added before the character >- * at the specified position of the <i>lean</i> text when generating the >- * <i>full</i> 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 <i>full</i> text. >- * >- * @param offset position of the character in <code>leanText</code>. >- * It must be a non-negative number smaller than the length >- * of the <i>lean</i> text. >- * For the benefit of efficiency, it is better to insert >- * multiple marks in ascending order of the offsets. >- * >- */ >- protected void insertMark(int offset) { >- int index = count - 1; // index of greatest member <= offset >- // look up after which member the new offset should be inserted >- while (index >= 0) { >- int wrkOffset = offsets[index]; >- if (offset > wrkOffset) >- break; >- if (offset == wrkOffset) >- return; // avoid duplicates >- index--; >- } >- index++; // index now points at where to insert >- // check if we have an available slot for new member >- if (count >= (offsets.length - 1)) { >- int[] newOffsets = new int[offsets.length * 2]; >- System.arraycopy(offsets, 0, newOffsets, 0, count); >- offsets = newOffsets; >- } >- >- int length = count - index; // number of members to move up >- if (length > 0) // shift right all members greater than offset >- System.arraycopy(offsets, index, offsets, index + 1, length); >- >- offsets[index] = offset; >- count++; >- // if the offset is 0, adding a mark does not change anything >- if (offset < 1) >- return; >- >- byte dirProp = getDirProp(offset); >- // if the current char is a strong one or a digit, we change the >- // dirProp of the previous char to account for the inserted mark >- if (dirProp == L || dirProp == R || dirProp == AL || dirProp == EN || dirProp == AN) >- index = offset - 1; >- else >- // if the current char is a neutral, we change its own dirProp >- index = offset; >- setMarkAndFixes(); >- setDirProp(index, curStrong); >- } >- >- private String addMarks(boolean addFixes) { >- // add prefix/suffix only if addFixes is true >- if ((count == 0) && (!addFixes || (getCurOrient() == getCurDirection()) || (curOrient == ORIENT_IGNORE))) { >- prefixLength = 0; >- return leanText; >- } >- int len = leanText.length(); >- int newLen = len + count; >- if (addFixes && ((getCurOrient() != getCurDirection()) || (curOrient == ORIENT_UNKNOWN))) { >- if ((orientation & ORIENT_CONTEXTUAL_LTR) == 0) { >- prefixLength = PREFIX_LENGTH; >- newLen += FIXES_LENGTH; >- } else { /* contextual orientation */ >- prefixLength = 1; >- newLen++; /* +1 for a mark char */ >- } >- } else { >- prefixLength = 0; >- } >- char[] fullChars = new char[newLen]; >- // add a dummy offset as fence >- offsets[count] = len; >- int added = prefixLength; >- // add marks at offsets >- setMarkAndFixes(); >- for (int i = 0, j = 0; i < len; i++) { >- char c = leanText.charAt(i); >- if (i == offsets[j]) { >- fullChars[i + added] = curMark; >- added++; >- j++; >- } >- fullChars[i + added] = c; >- } >- if (prefixLength > 0) { /* add prefix/suffix ? */ >- if (prefixLength == 1) { /* contextual orientation */ >- fullChars[0] = curMark; >- } else { >- // When the orientation is RTL, we need to add EMBED at the >- // start of the text and PDF at its end. >- // However, because of a bug in Windows' handling of LRE/PDF, >- // we add EMBED_PREFIX at the start and EMBED_SUFFIX at the end. >- fullChars[0] = curEmbed; >- fullChars[1] = curMark; >- fullChars[newLen - 1] = PDF; >- fullChars[newLen - 2] = curMark; >- } >- } >- return new String(fullChars); >- } >- >- public void assumeMirrored(boolean shouldBeMirrored) { >- mirrored = shouldBeMirrored; >- curDirection = -1; >- } >- >- public boolean isMirrored() { >- return mirrored; >- } >- >- public void assumeOrientation(int componentOrientation) { >- if (componentOrientation < ORIENT_LTR || componentOrientation > ORIENT_IGNORE) >- orientation = ORIENT_UNKNOWN; // TBD should throw new IllegalArgumentException()? >- else >- orientation = componentOrientation; >- } >- >- public int recallOrientation() { >- return orientation; >- } >- >- public void setArabicDirection(int not_mirrored, int mirrored) { >- direction[0][0] = not_mirrored & 1; >- direction[0][1] = mirrored & 1; >- curDirection = -1; >- } >- >- public void setArabicDirection(int direction) { >- setArabicDirection(direction, direction); >- } >- >- public void setHebrewDirection(int not_mirrored, int mirrored) { >- direction[1][0] = not_mirrored & 1; >- direction[1][1] = mirrored & 1; >- curDirection = -1; >- } >- >- public void setHebrewDirection(int direction) { >- setHebrewDirection(direction, direction); >- } >- >- public void setDirection(int not_mirrored, int mirrored) { >- setArabicDirection(not_mirrored, mirrored); >- setHebrewDirection(not_mirrored, mirrored); >- } >- >- public void setDirection(int direction) { >- setDirection(direction, direction); >- } >- >- public int[][] getDirection() { >- return direction; >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelims.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelims.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelims.java >--- src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelims.java 17 Mar 2010 17:53:41 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,75 +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.internal.complexp; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >- >-/** >- * <code>ComplExpDelims</code> is a processor for complex expressions >- * composed of text segments separated by operators where the text segments >- * may include delimited parts within which operators are treated like >- * regular characters. >- * >- * @see IComplExpProcessor >- * @see ComplExpBasic >- * >- * @author Matitiahu Allouche >- */ >-public class ComplExpDelims extends ComplExpBasic { >- char[] delims; >- >- /** >- * Constructor for a complex expressions processor with support for >- * operators and delimiters. >- * >- * @param operators string grouping one-character operators which >- * separate the text of the complex expression into segments. >- * >- * @param delims delimiters implemented in this class instance. >- * This parameter is a string which must include an even >- * number of characters. The first 2 characters of a string >- * constitute a pair, the next 2 characters are a second pair, etc... >- * In each pair, the first character is a start delimiter and >- * the second character is an end delimiter. In the <i>lean</i> >- * text, any part starting with a start delimiter and ending with >- * the corresponding end delimiter is a delimited part. Within a >- * delimited part, operators are treated like regular characters, >- * which means that they do not define new segments. >- */ >- public ComplExpDelims(String operators, String delims) { >- super(operators, delims.length() / 2); >- this.delims = delims.toCharArray(); >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int indexOfSpecial(int whichSpecial, String srcText, int fromIndex) { >- char delim = delims[whichSpecial * 2]; >- >- return srcText.indexOf(delim, fromIndex); >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int processSpecial(int whichSpecial, String srcText, int operLocation) { >- processOperator(operLocation); >- int loc = operLocation + 1; >- char delim = delims[(whichSpecial * 2) + 1]; >- loc = srcText.indexOf(delim, loc); >- if (loc < 0) >- return srcText.length(); >- return loc + 1; >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelimsEsc.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelimsEsc.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelimsEsc.java >--- src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDelimsEsc.java 17 Mar 2010 17:53:41 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,82 +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.internal.complexp; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >- >-/** >- * <code>ComplExpDelims</code> is a processor for complex expressions >- * composed of text segments separated by operators where the text segments >- * may include delimited parts within which operators are treated like >- * regular characters and the delimiters may be escaped. >- * This is similar to {@link ComplExpDelims} except >- * that delimiters can be escaped using the backslash character. >- * <ul> >- * <li>Two consecutive backslashes in a delimited part are treated like >- * regular characters.</li> >- * <li>An ending delimiter preceded by an odd number of backslashes is >- * treated like a regular character of a delimited part.</li> >- * </ul> >- * >- * @see IComplExpProcessor >- * @see ComplExpBasic >- * >- * @author Matitiahu Allouche >- */ >-public class ComplExpDelimsEsc extends ComplExpDelims { >- /** >- * Constructor for a complex expressions processor with support for >- * operators and delimiters which can be escaped. >- * >- * @param operators string grouping one-character operators which >- * separate the text of the complex expression into segments. >- * >- * @param delims delimiters implemented in this class instance. >- * This parameter is a string which must include an even >- * number of characters. The first 2 characters of a string >- * constitute a pair, the next 2 characters are a second pair, etc... >- * In each pair, the first character is a start delimiter and >- * the second character is an end delimiter. In the <i>lean</i> >- * text, any part starting with a start delimiter and ending with >- * the corresponding end delimiter is a delimited part. Within a >- * delimited part, operators are treated like regular characters, >- * which means that they do not define new segments.<br> >- * <br> >- * Note however that an ending delimiter preceded by an odd >- * number of backslashes is considered as a regular character >- * and does not mark the termination of a delimited part. >- */ >- public ComplExpDelimsEsc(String operators, String delims) { >- super(operators, delims); >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int processSpecial(int whichSpecial, String srcText, int operLocation) { >- processOperator(operLocation); >- int loc = operLocation + 1; >- char delim = delims[(whichSpecial * 2) + 1]; >- while (true) { >- loc = srcText.indexOf(delim, loc); >- if (loc < 0) >- return srcText.length(); >- int cnt = 0; >- for (int i = loc - 1; srcText.charAt(i) == '\\'; i--) { >- cnt++; >- } >- loc++; >- if ((cnt & 1) == 0) >- return loc; >- } >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDoNothing.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDoNothing.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDoNothing.java >--- src/org/eclipse/equinox/bidi/internal/complexp/ComplExpDoNothing.java 24 Feb 2010 14:59:37 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,265 +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.internal.complexp; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >- >-/** >- * This class is a minimal processor which implements the >- * <code>IComplExpProcessor</code> interface but does no real processing. >- * Since it is optimized for minimal overhead, it 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. >- * >- * @author Matitiahu Allouche >- */ >-// TBD is this needed? >-public class ComplExpDoNothing implements IComplExpProcessor { >- >- private static final String EMPTY_STRING = ""; //$NON-NLS-1$ >- private static final int[] EMPTY_INT_ARRAY = new int[0]; >- private static final int[][] ALL_LTR = new int[][] { {DIRECTION_LTR, DIRECTION_LTR}, {DIRECTION_LTR, DIRECTION_LTR}}; >- >- /** >- * Allocate a <code>ComplExpDoNothing</code> processor instance. >- * Such a processor does not modify text submitted to it, and can be >- * used as a place holder when the text to process is not a known >- * complex expression. >- */ >- public ComplExpDoNothing() { >- return; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> >- * this method does nothing. >- */ >- public void setOperators(String operators) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> >- * this method returns a zero-length string. >- */ >- public String getOperators() { >- return EMPTY_STRING; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> >- * this method does nothing. >- */ >- public void selectBidiScript(boolean arabic, boolean hebrew) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> >- * this method always returns <code>false</code>. >- */ >- public boolean handlesArabicScript() { >- return false; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> >- * this method always returns <code>false</code>. >- */ >- public boolean handlesHebrewScript() { >- return false; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a string identical to the <code>text</code> parameter. >- */ >- public String leanToFullText(String text) { >- return text; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a string identical to the <code>text</code> parameter. >- */ >- public String leanToFullText(String text, int initState) { >- return text; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a zero length array. >- */ >- public int[] leanBidiCharOffsets(String text) { >- return EMPTY_INT_ARRAY; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a zero length array. >- */ >- public int[] leanBidiCharOffsets(String text, int initState) { >- return EMPTY_INT_ARRAY; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a zero length array. >- */ >- public int[] leanBidiCharOffsets() { >- return EMPTY_INT_ARRAY; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a zero length array. >- */ >- public int[] fullBidiCharOffsets() { >- return EMPTY_INT_ARRAY; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a string identical to the <code>text</code> parameter. >- */ >- public String fullToLeanText(String text) { >- return text; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns a string identical to the <code>text</code> parameter. >- */ >- public String fullToLeanText(String text, int initState) { >- return text; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns value {@link #STATE_NOTHING_GOING}. >- */ >- public int getFinalState() { >- return STATE_NOTHING_GOING; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns an index identical to the <code>pos</code> parameter. >- */ >- public int leanToFullPos(int pos) { >- return pos; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns an index identical to the <code>pos</code> parameter. >- */ >- public int fullToLeanPos(int pos) { >- return pos; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void assumeMirrored(boolean mirrored) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * always returns <code>false</code>. >- */ >- public boolean isMirrored() { >- return false; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void assumeOrientation(int orientation) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * always returns <code>ORIENT_LTR</code>. >- */ >- public int recallOrientation() { >- return ORIENT_LTR; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void setArabicDirection(int not_mirrored, int mirrored) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void setArabicDirection(int direction) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void setHebrewDirection(int not_mirrored, int mirrored) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void setHebrewDirection(int direction) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void setDirection(int not_mirrored, int mirrored) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * does nothing. >- */ >- public void setDirection(int direction) { >- // empty >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns all directions as <code>DIRECTION_LTR</code>. >- */ >- public int[][] getDirection() { >- return ALL_LTR; >- } >- >- /** >- * For class <code>ComplExpDoNothing</code> this method >- * returns <code>DIRECTION_LTR</code>. >- */ >- public int getCurDirection() { >- return DIRECTION_LTR; >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpSingle.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/ComplExpSingle.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/ComplExpSingle.java >--- src/org/eclipse/equinox/bidi/internal/complexp/ComplExpSingle.java 17 Mar 2010 17:53:41 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,65 +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.internal.complexp; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >- >-/** >- * <code>ComplExpSingle</code> is a processor for complex expressions >- * composed of two parts separated by an operator. >- * The first occurrence of the operator delimits the end of the first part >- * and the start of the second part. Further occurrences of the operator, >- * if any, are treated like regular characters of the second text part. >- * The processor makes sure that the expression be presented in the form >- * (assuming that the equal sign is the operator): >- * <pre> >- * part1=part2 >- * </pre> >- * >- * @see IComplExpProcessor >- * @see ComplExpBasic >- * >- * @author Matitiahu Allouche >- */ >-public class ComplExpSingle extends ComplExpBasic { >- char separator; >- >- /** >- * Constructor for a complex expressions processor with support for one >- * operator. >- * >- * @param operators string including at least one character. The >- * first character of the string is the operator which divides >- * the expression into 2 parts. >- * >- */ >- public ComplExpSingle(String operators) { >- super(operators, 1); >- separator = operators.charAt(0); >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int indexOfSpecial(int whichSpecial, String srcText, int fromIndex) { >- return srcText.indexOf(separator, fromIndex); >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int processSpecial(int whichSpecial, String srcText, int operLocation) { >- processOperator(operLocation); >- return srcText.length(); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpComma.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpComma.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpComma.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpComma.java 3 Feb 2010 20:01:01 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,25 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * Processor adapted to processing comma-delimited lists, such as: >- * <pre> >- * part1,part2,part3 >- * </pre> >- */ >-public class ComplExpComma extends ComplExpBasic { >- public ComplExpComma() { >- super(","); //$NON-NLS-1$ >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpEmail.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpEmail.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpEmail.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpEmail.java 3 Feb 2010 20:01:01 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,22 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpDelimsEsc; >- >-/** >- * Processor adapted to processing e-mail addresses. >- */ >-public class ComplExpEmail extends ComplExpDelimsEsc { >- public ComplExpEmail() { >- super("<>.:,;@", "()\"\""); //$NON-NLS-1$ //$NON-NLS-2$ >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpFile.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpFile.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpFile.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpFile.java 3 Feb 2010 20:01:01 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,22 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * Processor adapted to processing directory and file paths. >- */ >-public class ComplExpFile extends ComplExpBasic { >- public ComplExpFile() { >- super(":/\\."); //$NON-NLS-1$ >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpJava.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpJava.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpJava.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpJava.java 12 Apr 2010 18:51:17 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,117 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * <code>ComplExpJava</code> is a processor for complex expressions >- * composed of Java statements. Such a complex expression may span >- * multiple lines. >- * <p> >- * In applications like an editor where parts of the text might be modified >- * while other parts are not, the user may want to call >- * {@link IComplExpProcessor#leanToFullText leanToFullText} >- * separately on each line and save the initial state of each line (this is >- * the final state of the previous line which can be retrieved using >- * {@link IComplExpProcessor#getFinalState getFinalState}. If both the content >- * of a line and its initial state have not changed, the user can be sure that >- * the last <i>full</i> text computed for this line has not changed either. >- * >- * @see IComplExpProcessor >- * @author Matitiahu Allouche >- */ >-public class ComplExpJava extends ComplExpBasic { >- private static final byte WS = Character.DIRECTIONALITY_WHITESPACE; >- static final String operators = "[](){}.+-<>=~!&*/%^|?:,;\t"; //$NON-NLS-1$ >- static String lineSep; >- >- /** >- * Constructor for a complex expressions processor with support for >- * Java statements. >- */ >- public ComplExpJava() { >- super(operators, 4); >- // TBD use bundle properties >- if (lineSep == null) >- lineSep = System.getProperty("line.separator", "\n"); //$NON-NLS-1$//$NON-NLS-2$ >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int indexOfSpecial(int whichSpecial, String srcText, int fromIndex) { >- switch (whichSpecial) { >- case 0 : /* space */ >- return srcText.indexOf(' ', fromIndex); >- case 1 : /* literal */ >- return srcText.indexOf('"', fromIndex); >- case 2 : /* slash-aster comment */ >- return srcText.indexOf("/*", fromIndex); //$NON-NLS-1$ >- case 3 : /* slash-slash comment */ >- return srcText.indexOf("//", fromIndex); //$NON-NLS-1$ >- } >- // we should never get here >- return -1; >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int processSpecial(int whichSpecial, String srcText, int operLocation) { >- int loc, cnt, i; >- >- processOperator(operLocation); >- switch (whichSpecial) { >- case 0 : /* space */ >- operLocation++; >- while (operLocation < srcText.length() && srcText.charAt(operLocation) == ' ') { >- setDirProp(operLocation, WS); >- operLocation++; >- } >- return operLocation; >- case 1 : /* literal */ >- loc = operLocation + 1; >- while (true) { >- loc = srcText.indexOf('"', loc); >- if (loc < 0) >- return srcText.length(); >- for (cnt = 0, i = loc - 1; srcText.charAt(i) == '\\'; i--) { >- cnt++; >- } >- loc++; >- if ((cnt & 1) == 0) >- return loc; >- } >- case 2 : /* slash-aster comment */ >- if (operLocation < 0) >- loc = 0; // initial state from previous line >- else >- loc = operLocation + 2; // skip the opening slash-aster >- loc = srcText.indexOf("*/", loc); //$NON-NLS-1$ >- if (loc < 0) { >- state = 2; >- return srcText.length(); >- } >- return loc + 2; >- case 3 : /* slash-slash comment */ >- loc = srcText.indexOf(lineSep, operLocation + 2); >- if (loc < 0) >- return srcText.length(); >- return loc + lineSep.length(); >- } >- // we should never get here >- return operLocation + 1; >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpMath.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpMath.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpMath.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpMath.java 3 Feb 2010 20:01:01 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,24 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * Processor adapted to processing arithmetic expressions with right-to-left >- * base direction. >- */ >-public class ComplExpMath extends ComplExpBasic { >- public ComplExpMath() { >- super("+-/*()="); //$NON-NLS-1$ >- setDirection(DIRECTION_RTL); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpProperty.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpProperty.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpProperty.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpProperty.java 3 Feb 2010 20:01:00 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,28 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpSingle; >- >-/** >- * Processor adapted to processing property file statements. >- * It expects the following string format: >- * <pre> >- * name=value >- * </pre> >- */ >-public class ComplExpProperty extends ComplExpSingle { >- >- public ComplExpProperty() { >- super("="); //$NON-NLS-1$ >- } >- >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpRegex.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpRegex.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpRegex.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpRegex.java 12 Apr 2010 18:51:17 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,201 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * <code>ComplExpRegex</code> is a processor for regular expressions. >- * Such expressions may span multiple lines. >- * <p> >- * In applications like an editor where parts of the text might be modified >- * while other parts are not, the user may want to call >- * {@link IComplExpProcessor#leanToFullText leanToFullText} >- * separately on each line and save the initial state of each line (this is >- * the final state of the previous line which can be retrieved using >- * {@link IComplExpProcessor#getFinalState getFinalState}. If both the content >- * of a line and its initial state have not changed, the user can be sure that >- * the last <i>full</i> text computed for this line has not changed either. >- * >- * @see IComplExpProcessor >- * @author Matitiahu Allouche >- */ >-public class ComplExpRegex extends ComplExpBasic { >- static final String operators = ""; //$NON-NLS-1$ >- static final String[] startStrings = {"(?#", /* 0 *//* comment (?#...) *///$NON-NLS-1$ >- "(?<", /* 1 *//* named group (?<name> *///$NON-NLS-1$ >- "(?'", /* 2 *//* named group (?'name' *///$NON-NLS-1$ >- "(?(<", /* 3 *//* conditional named back reference (?(<name>) *///$NON-NLS-1$ >- "(?('", /* 4 *//* conditional named back reference (?('name') *///$NON-NLS-1$ >- "(?(", /* 5 *//* conditional named back reference (?(name) *///$NON-NLS-1$ >- "(?&", /* 6 *//* named parentheses reference (?&name) *///$NON-NLS-1$ >- "(?P<", /* 7 *//* named group (?P<name> *///$NON-NLS-1$ >- "\\k<", /* 8 *//* named back reference \k<name> *///$NON-NLS-1$ >- "\\k'", /* 9 *//* named back reference \k'name' *///$NON-NLS-1$ >- "\\k{", /* 10 *//* named back reference \k{name} *///$NON-NLS-1$ >- "(?P=", /* 11 *//* named back reference (?P=name) *///$NON-NLS-1$ >- "\\g{", /* 12 *//* named back reference \g{name} *///$NON-NLS-1$ >- "\\g<", /* 13 *//* subroutine call \g<name> *///$NON-NLS-1$ >- "\\g'", /* 14 *//* subroutine call \g'name' *///$NON-NLS-1$ >- "(?(R&", /* 15 *//* named back reference recursion (?(R&name) *///$NON-NLS-1$ >- "\\Q" /* 16 *//* quoted sequence \Q...\E *///$NON-NLS-1$ >- }; >- static final char[] endChars = { >- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 >- ')', '>', '\'', ')', ')', ')', ')', '>', '>', '\'', '}', ')', '}', '>', '\'', ')'}; >- static final int numberOfStrings = startStrings.length; >- static final int maxSpecial = numberOfStrings + 1; >- >- /** >- * Constructor for a complex expressions processor with support for >- * regular expressions. >- */ >- public ComplExpRegex() { >- super(operators, maxSpecial); >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int indexOfSpecial(int whichSpecial, String srcText, int fromIndex) { >- byte dirProp; >- >- if (whichSpecial < numberOfStrings) { >- /* 0 *//* comment (?#...) */ >- /* 1 *//* named group (?<name> */ >- /* 2 *//* named group (?'name' */ >- /* 3 *//* conditional named back reference (?(name) */ >- /* 4 *//* conditional named back reference (?(<name>) */ >- /* 5 *//* conditional named back reference (?('name') */ >- /* 6 *//* named parentheses reference (?&name) */ >- /* 7 *//* named group (?P<name> */ >- /* 8 *//* named back reference \k<name> */ >- /* 9 *//* named back reference \k'name' */ >- /* 10 *//* named back reference \k{name} */ >- /* 11 *//* named back reference (?P=name) */ >- /* 12 *//* named back reference \g{name} */ >- /* 13 *//* subroutine call \g<name> */ >- /* 14 *//* subroutine call \g'name' */ >- /* 15 *//* named back reference recursion (?(R&name) */ >- /* 16 *//* quoted sequence \Q...\E */ >- return srcText.indexOf(startStrings[whichSpecial], fromIndex); >- } >- // look for R, AL, AN, EN which are potentially needing a mark >- for (; fromIndex < srcText.length(); fromIndex++) { >- // there never is a need for a mark before the first char >- if (fromIndex <= 0) >- continue; >- >- dirProp = getDirProp(fromIndex); >- // R and AL will always be examined using processOperator() >- if (dirProp == R || dirProp == AL) >- return fromIndex; >- >- if (dirProp == EN || dirProp == AN) { >- // no need for a mark after the first digit in a number >- if (getDirProp(fromIndex - 1) == dirProp) >- continue; >- >- for (int i = fromIndex - 1; i >= 0; i--) { >- dirProp = getDirProp(i); >- // after a L char, no need for a mark >- if (dirProp == L) >- continue; >- >- // digit after R or AL or AN need a mark, except for EN >- // following AN, but this is a contrived case, so we >- // don't check for it (and calling processOperator() >- // for it will do no harm) >- if (dirProp == R || dirProp == AL || dirProp == AN) >- return fromIndex; >- } >- continue; >- } >- } >- return -1; >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int processSpecial(int whichSpecial, String srcText, int operLocation) { >- int loc; >- >- switch (whichSpecial) { >- case 0 : /* comment (?#...) */ >- if (operLocation < 0) { >- // initial state from previous line >- loc = 0; >- } else { >- processOperator(operLocation); >- // skip the opening "(?#" >- loc = operLocation + 3; >- } >- loc = srcText.indexOf(')', loc); >- if (loc < 0) { >- state = whichSpecial; >- return srcText.length(); >- } >- return loc + 1; >- case 1 : /* named group (?<name> */ >- case 2 : /* named group (?'name' */ >- case 3 : /* conditional named back reference (?(name) */ >- case 4 : /* conditional named back reference (?(<name>) */ >- case 5 : /* conditional named back reference (?('name') */ >- case 6 : /* named parentheses reference (?&name) */ >- processOperator(operLocation); >- // no need for calling processOperator() for the following cases >- // since the starting string contains a L char >- case 7 : /* named group (?P<name> */ >- case 8 : /* named back reference \k<name> */ >- case 9 : /* named back reference \k'name' */ >- case 10 : /* named back reference \k{name} */ >- case 11 : /* named back reference (?P=name) */ >- case 12 : /* named back reference \g{name} */ >- case 13 : /* subroutine call \g<name> */ >- case 14 : /* subroutine call \g'name' */ >- case 15 : /* named back reference recursion (?(R&name) */ >- // skip the opening string >- loc = operLocation + startStrings[whichSpecial].length(); >- // look for ending character >- loc = srcText.indexOf(endChars[whichSpecial], loc); >- if (loc < 0) >- return srcText.length(); >- return loc + 1; >- case 16 : /* quoted sequence \Q...\E */ >- if (operLocation < 0) { >- // initial state from previous line >- loc = 0; >- } else { >- processOperator(operLocation); >- // skip the opening "\Q" >- loc = operLocation + 2; >- } >- loc = srcText.indexOf("\\E", loc); //$NON-NLS-1$ >- if (loc < 0) { >- state = whichSpecial; >- return srcText.length(); >- } >- // set the dirProp for the "E" >- setDirProp(loc + 1, L); >- return loc + 2; >- case 17 : /* R, AL, AN, EN */ >- processOperator(operLocation); >- return operLocation + 1; >- >- } >- // we should never get here >- return srcText.length(); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSql.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSql.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSql.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSql.java 12 Apr 2010 18:51:17 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,136 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * <code>ComplExpSql</code> is a processor for complex expressions >- * composed of SQL statements. Such a complex expression may span >- * multiple lines. >- * <p> >- * In applications like an editor where parts of the text might be modified >- * while other parts are not, the user may want to call >- * {@link IComplExpProcessor#leanToFullText leanToFullText} >- * separately on each line and save the initial state of each line (this is >- * the final state of the previous line which can be retrieved using >- * {@link IComplExpProcessor#getFinalState getFinalState}. If both the content >- * of a line and its initial state have not changed, the user can be sure that >- * the last <i>full</i> text computed for this line has not changed either. >- * >- * @see IComplExpProcessor >- * @author Matitiahu Allouche >- */ >-public class ComplExpSql extends ComplExpBasic { >- private static final byte WS = Character.DIRECTIONALITY_WHITESPACE; >- static final String operators = "\t!#%&()*+,-./:;<=>?|[]{}"; //$NON-NLS-1$ >- static String lineSep; >- >- /** >- * Constructor for a complex expressions processor with support for >- * SQL statements. >- */ >- public ComplExpSql() { >- super(operators, 5); >- // TBD use bundle properties >- if (lineSep == null) >- lineSep = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int indexOfSpecial(int whichSpecial, String srcText, int fromIndex) { >- switch (whichSpecial) { >- case 0 : /* space */ >- return srcText.indexOf(" ", fromIndex); //$NON-NLS-1$ >- case 1 : /* literal */ >- return srcText.indexOf('\'', fromIndex); >- case 2 : /* delimited identifier */ >- return srcText.indexOf('"', fromIndex); >- case 3 : /* slash-aster comment */ >- return srcText.indexOf("/*", fromIndex); //$NON-NLS-1$ >- case 4 : /* hyphen-hyphen comment */ >- return srcText.indexOf("--", fromIndex); //$NON-NLS-1$ >- } >- // we should never get here >- return -1; >- } >- >- /** >- * This method is not supposed to be invoked directly by users of this >- * class. It may be overridden by subclasses of this class. >- */ >- protected int processSpecial(int whichSpecial, String srcText, int operLocation) { >- int loc; >- >- processOperator(operLocation); >- switch (whichSpecial) { >- case 0 : /* space */ >- operLocation++; >- while (operLocation < srcText.length() && srcText.charAt(operLocation) == ' ') { >- setDirProp(operLocation, WS); >- operLocation++; >- } >- return operLocation; >- case 1 : /* literal */ >- loc = operLocation + 1; >- while (true) { >- loc = srcText.indexOf('\'', loc); >- if (loc < 0) { >- state = whichSpecial; >- return srcText.length(); >- } >- if ((loc + 1) < srcText.length() && srcText.charAt(loc + 1) == '\'') { >- loc += 2; >- continue; >- } >- return loc + 1; >- } >- case 2 : /* delimited identifier */ >- loc = operLocation + 1; >- while (true) { >- loc = srcText.indexOf('"', loc); >- if (loc < 0) >- return srcText.length(); >- >- if ((loc + 1) < srcText.length() && srcText.charAt(loc + 1) == '"') { >- loc += 2; >- continue; >- } >- return loc + 1; >- } >- case 3 : /* slash-aster comment */ >- if (operLocation < 0) >- loc = 0; // initial state from previous line >- else >- loc = operLocation + 2; // skip the opening slash-aster >- loc = srcText.indexOf("*/", loc); //$NON-NLS-1$ >- if (loc < 0) { >- state = whichSpecial; >- return srcText.length(); >- } >- // we need to call processOperator since text may follow the >- // end of comment immediately without even a space >- processOperator(loc); >- return loc + 2; >- case 4 : /* hyphen-hyphen comment */ >- loc = srcText.indexOf(lineSep, operLocation + 2); >- if (loc < 0) >- return srcText.length(); >- return loc + lineSep.length(); >- } >- // we should never get here >- return srcText.length(); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSystem.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSystem.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSystem.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpSystem.java 3 Feb 2010 20:01:00 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,27 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpSingle; >- >-/** >- * Processor adapted to processing expressions with the following string format: >- * <pre> >- * system(user) >- * </pre> >- */ >-public class ComplExpSystem extends ComplExpSingle { >- >- public ComplExpSystem() { >- super("("); //$NON-NLS-1$ >- } >- >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpURL.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpURL.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpURL.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpURL.java 3 Feb 2010 20:01:01 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,22 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * Processor adapted to processing URLs. >- */ >-public class ComplExpURL extends ComplExpBasic { >- public ComplExpURL() { >- super(":?#/@.[]"); //$NON-NLS-1$ >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpUnderscore.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpUnderscore.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpUnderscore.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpUnderscore.java 3 Feb 2010 20:01:00 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,27 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpBasic; >- >-/** >- * Processor adapted to processing compound names. >- * This type covers names made of one or more parts, separated by underscores: >- * <pre> >- * part1_part2_part3 >- * </pre> >- */ >-public class ComplExpUnderscore extends ComplExpBasic { >- public ComplExpUnderscore() { >- super("_"); //$NON-NLS-1$ >- } >- >-} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpXPath.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpXPath.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpXPath.java >--- src/org/eclipse/equinox/bidi/internal/complexp/consumable/ComplExpXPath.java 3 Feb 2010 20:01:00 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,22 +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.internal.complexp.consumable; >- >-import org.eclipse.equinox.bidi.internal.complexp.ComplExpDelims; >- >-/** >- * Processor adapted to processing XPath expressions. >- */ >-public class ComplExpXPath extends ComplExpDelims { >- public ComplExpXPath() { >- super(" /[]<>=!:@.|()+-*", "''\"\""); //$NON-NLS-1$ //$NON-NLS-2$ >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexComma.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexComma.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexComma.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexComma.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,35 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * Processor adapted to processing comma-delimited lists, such as: >+ * <pre> >+ * part1,part2,part3 >+ * </pre> >+ */ >+public class BidiComplexComma extends BidiComplexProcessor { >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures(",", 0, -1, -1, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with one operator (comma), no special cases, >+ * LTR direction for Arabic and Hebrew, and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexEmail.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexEmail.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexEmail.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexEmail.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,45 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.internal.BidiComplexDelimsEsc; >+ >+/** >+ * Processor adapted to processing e-mail addresses. >+ */ >+public class BidiComplexEmail extends BidiComplexDelimsEsc { >+ static final int LTR = BidiComplexFeatures.DIR_LTR; >+ static final int RTL = BidiComplexFeatures.DIR_RTL; >+ static final BidiComplexFeatures MIRRORED = new BidiComplexFeatures("<>.:,;@", 2, RTL, LTR, false, false); //$NON-NLS-1$ >+ static final BidiComplexFeatures NOT_MIRRORED = new BidiComplexFeatures("<>.:,;@", 2, LTR, LTR, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with operators "<>.:,;@", 2 special cases, >+ * LTR direction for Arabic when the GUI is not mirrored, >+ * RTL direction for Arabic when the GUI is mirrored, >+ * LTR direction for Hebrew in all cases, >+ * and support for both Arabic and Hebrew. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return env.mirrored ? MIRRORED : NOT_MIRRORED; >+ } >+ >+ /** >+ * @return parentheses and quotation marks as delimiters. >+ */ >+ protected String getDelimiters() { >+ return "()\"\""; //$NON-NLS-1$ >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexFile.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexFile.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexFile.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexFile.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,32 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * Processor adapted to processing directory and file paths. >+ */ >+public class BidiComplexFile extends BidiComplexProcessor { >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures(":/\\.", 0, -1, -1, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with operators ":/\.", no special cases, >+ * LTR direction for Arabic and Hebrew, and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexJava.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexJava.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexJava.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexJava.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,128 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * <code>BidiComplexJava</code> is a processor for complex expressions >+ * composed of Java statements. Such a complex expression may span >+ * multiple lines. >+ * <p> >+ * In applications like an editor where parts of the text might be modified >+ * while other parts are not, the user may want to call >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * separately on each line and save the initial state of each line (this is >+ * the final state of the previous line which can be retrieved using >+ * {@link BidiComplexHelper#getFinalState getFinalState}. If both the content >+ * of a line and its initial state have not changed, the user can be sure that >+ * the last <i>full</i> text computed for this line has not changed either. >+ * >+ * @see BidiComplexHelper >+ * >+ * @author Matitiahu Allouche >+ */ >+public class BidiComplexJava extends BidiComplexProcessor { >+ private static final byte WS = Character.DIRECTIONALITY_WHITESPACE; >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures("[](){}.+-<>=~!&*/%^|?:,;\t", 4, -1, -1, false, false); //$NON-NLS-1$ >+ static final String lineSep = BidiComplexEnvironment.getLineSep(); >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with operators "[](){}.+-<>=~!&/*%^|?:,;\t", >+ * 4 special cases, LTR direction for Arabic and Hebrew, >+ * and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+ /** >+ * This method looks for occurrences of 4 special strings: >+ * <ol> >+ * <li>spaces</li> >+ * <li>literals starting with quotation mark</li> >+ * <li>comments starting with slash-asterisk</li> >+ * <li>comments starting with slash-slash</li> >+ * </ol> >+ */ >+ public int indexOfSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int fromIndex) { >+ switch (caseNumber) { >+ case 0 : /* space */ >+ return srcText.indexOf(' ', fromIndex); >+ case 1 : /* literal */ >+ return srcText.indexOf('"', fromIndex); >+ case 2 : /* slash-aster comment */ >+ return srcText.indexOf("/*", fromIndex); //$NON-NLS-1$ >+ case 3 : /* slash-slash comment */ >+ return srcText.indexOf("//", fromIndex); //$NON-NLS-1$ >+ } >+ // we should never get here >+ return -1; >+ } >+ >+ /** >+ * This method processes the 4 special cases as follows. >+ * <ol> >+ * <li>skip the run of spaces</li> >+ * <li>look for a matching quotation mark and skip until after it</li> >+ * <li>skip until after the closing asterisk-slash</li> >+ * <li>skip until after a line separator</li> >+ * </ol> >+ */ >+ public int processSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int operLocation) { >+ int location, counter, i; >+ >+ helper.processOperator(operLocation); >+ switch (caseNumber) { >+ case 0 : /* space */ >+ operLocation++; >+ while (operLocation < srcText.length() && srcText.charAt(operLocation) == ' ') { >+ helper.setDirProp(operLocation, WS); >+ operLocation++; >+ } >+ return operLocation; >+ case 1 : /* literal */ >+ location = operLocation + 1; >+ while (true) { >+ location = srcText.indexOf('"', location); >+ if (location < 0) >+ return srcText.length(); >+ for (counter = 0, i = location - 1; srcText.charAt(i) == '\\'; i--) { >+ counter++; >+ } >+ location++; >+ if ((counter & 1) == 0) >+ return location; >+ } >+ case 2 : /* slash-aster comment */ >+ if (operLocation < 0) >+ location = 0; // initial state from previous line >+ else >+ location = operLocation + 2; // skip the opening slash-aster >+ location = srcText.indexOf("*/", location); //$NON-NLS-1$ >+ if (location < 0) { >+ helper.setFinalState(2); >+ return srcText.length(); >+ } >+ return location + 2; >+ case 3 : /* slash-slash comment */ >+ location = srcText.indexOf(lineSep, operLocation + 2); >+ if (location < 0) >+ return srcText.length(); >+ return location + lineSep.length(); >+ } >+ // we should never get here >+ return srcText.length(); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexMath.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexMath.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexMath.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexMath.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,34 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * Processor adapted to processing arithmetic expressions with right-to-left >+ * base direction. >+ */ >+public class BidiComplexMath extends BidiComplexProcessor { >+ static final int RTL = BidiComplexFeatures.DIR_RTL; >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures("+-/*()=", 0, RTL, RTL, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with operators "+-/*()=", no special cases, >+ * RTL direction for Arabic and Hebrew, and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexProperty.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexProperty.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexProperty.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexProperty.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,36 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.internal.BidiComplexSingle; >+ >+/** >+ * Processor adapted to processing property file statements. >+ * It expects the following string format: >+ * <pre> >+ * name=value >+ * </pre> >+ */ >+public class BidiComplexProperty extends BidiComplexSingle { >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures("=", 1, -1, -1, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with one operator (equal sign), 1 special case, >+ * LTR direction for Arabic and Hebrew, and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexRegex.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexRegex.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexRegex.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexRegex.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,216 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * <code>BidiComplexRegex</code> is a processor for regular expressions. >+ * Such expressions may span multiple lines. >+ * <p> >+ * In applications like an editor where parts of the text might be modified >+ * while other parts are not, the user may want to call >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * separately on each line and save the initial state of each line (this is >+ * the final state of the previous line which can be retrieved using >+ * {@link BidiComplexHelper#getFinalState getFinalState}. If both the content >+ * of a line and its initial state have not changed, the user can be sure that >+ * the last <i>full</i> text computed for this line has not changed either. >+ * >+ * @see BidiComplexHelper >+ * >+ * @author Matitiahu Allouche >+ */ >+public class BidiComplexRegex extends BidiComplexProcessor { >+ static final String[] startStrings = {"(?#", /* 0 *//* comment (?#...) *///$NON-NLS-1$ >+ "(?<", /* 1 *//* named group (?<name> *///$NON-NLS-1$ >+ "(?'", /* 2 *//* named group (?'name' *///$NON-NLS-1$ >+ "(?(<", /* 3 *//* conditional named back reference (?(<name>) *///$NON-NLS-1$ >+ "(?('", /* 4 *//* conditional named back reference (?('name') *///$NON-NLS-1$ >+ "(?(", /* 5 *//* conditional named back reference (?(name) *///$NON-NLS-1$ >+ "(?&", /* 6 *//* named parentheses reference (?&name) *///$NON-NLS-1$ >+ "(?P<", /* 7 *//* named group (?P<name> *///$NON-NLS-1$ >+ "\\k<", /* 8 *//* named back reference \k<name> *///$NON-NLS-1$ >+ "\\k'", /* 9 *//* named back reference \k'name' *///$NON-NLS-1$ >+ "\\k{", /* 10 *//* named back reference \k{name} *///$NON-NLS-1$ >+ "(?P=", /* 11 *//* named back reference (?P=name) *///$NON-NLS-1$ >+ "\\g{", /* 12 *//* named back reference \g{name} *///$NON-NLS-1$ >+ "\\g<", /* 13 *//* subroutine call \g<name> *///$NON-NLS-1$ >+ "\\g'", /* 14 *//* subroutine call \g'name' *///$NON-NLS-1$ >+ "(?(R&", /* 15 *//* named back reference recursion (?(R&name) *///$NON-NLS-1$ >+ "\\Q" /* 16 *//* quoted sequence \Q...\E *///$NON-NLS-1$ >+ }; >+ static final char[] endChars = { >+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 >+ ')', '>', '\'', ')', ')', ')', ')', '>', '>', '\'', '}', ')', '}', '>', '\'', ')'}; >+ static final int numberOfStrings = startStrings.length; >+ static final int maxSpecial = numberOfStrings + 1; >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures(null, maxSpecial, -1, -1, false, false); >+ static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT; >+ static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT; >+ static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC; >+ static final byte AN = Character.DIRECTIONALITY_ARABIC_NUMBER; >+ static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER; >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with no operators , special cases for each kind of >+ * regular expression syntactic string, >+ * LTR direction for Arabic and Hebrew, and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+ /** >+ * This method locates occurrences of the syntactic strings and of >+ * R, AL, EN, AN characters. >+ */ >+ public int indexOfSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int fromIndex) { >+ // In this method, L, R, AL, AN and EN represent bidi categories >+ // as defined in the Unicode Bidirectional Algorithm >+ // ( http://www.unicode.org/reports/tr9/ ). >+ // L represents the category Left to Right character. >+ // R represents the category Right to Left character. >+ // AL represents the category Arabic Letter. >+ // AN represents the category Arabic Number. >+ // EN represents the category European Number. >+ byte dirProp; >+ >+ if (caseNumber < numberOfStrings) { >+ /* 0 *//* comment (?#...) */ >+ /* 1 *//* named group (?<name> */ >+ /* 2 *//* named group (?'name' */ >+ /* 3 *//* conditional named back reference (?(name) */ >+ /* 4 *//* conditional named back reference (?(<name>) */ >+ /* 5 *//* conditional named back reference (?('name') */ >+ /* 6 *//* named parentheses reference (?&name) */ >+ /* 7 *//* named group (?P<name> */ >+ /* 8 *//* named back reference \k<name> */ >+ /* 9 *//* named back reference \k'name' */ >+ /* 10 *//* named back reference \k{name} */ >+ /* 11 *//* named back reference (?P=name) */ >+ /* 12 *//* named back reference \g{name} */ >+ /* 13 *//* subroutine call \g<name> */ >+ /* 14 *//* subroutine call \g'name' */ >+ /* 15 *//* named back reference recursion (?(R&name) */ >+ /* 16 *//* quoted sequence \Q...\E */ >+ return srcText.indexOf(startStrings[caseNumber], fromIndex); >+ } >+ // there never is a need for a mark before the first char >+ if (fromIndex <= 0) >+ fromIndex = 1; >+ // look for R, AL, AN, EN which are potentially needing a mark >+ for (; fromIndex < srcText.length(); fromIndex++) { >+ dirProp = helper.getDirProp(fromIndex); >+ // R and AL will always be examined using processOperator() >+ if (dirProp == R || dirProp == AL) >+ return fromIndex; >+ >+ if (dirProp == EN || dirProp == AN) { >+ // no need for a mark after the first digit in a number >+ if (helper.getDirProp(fromIndex - 1) == dirProp) >+ continue; >+ >+ for (int i = fromIndex - 1; i >= 0; i--) { >+ dirProp = helper.getDirProp(i); >+ // after a L char, no need for a mark >+ if (dirProp == L) >+ continue; >+ >+ // digit after R or AL or AN need a mark, except for EN >+ // following AN, but this is a contrived case, so we >+ // don't check for it (and calling processOperator() >+ // for it will do no harm) >+ if (dirProp == R || dirProp == AL || dirProp == AN) >+ return fromIndex; >+ } >+ continue; >+ } >+ } >+ return -1; >+ } >+ >+ /** >+ * This method process the special cases. >+ */ >+ public int processSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int operLocation) { >+ int location; >+ >+ switch (caseNumber) { >+ case 0 : /* comment (?#...) */ >+ if (operLocation < 0) { >+ // initial state from previous line >+ location = 0; >+ } else { >+ helper.processOperator(operLocation); >+ // skip the opening "(?#" >+ location = operLocation + 3; >+ } >+ location = srcText.indexOf(')', location); >+ if (location < 0) { >+ helper.setFinalState(caseNumber); >+ return srcText.length(); >+ } >+ return location + 1; >+ case 1 : /* named group (?<name> */ >+ case 2 : /* named group (?'name' */ >+ case 3 : /* conditional named back reference (?(name) */ >+ case 4 : /* conditional named back reference (?(<name>) */ >+ case 5 : /* conditional named back reference (?('name') */ >+ case 6 : /* named parentheses reference (?&name) */ >+ helper.processOperator(operLocation); >+ // no need for calling processOperator() for the following cases >+ // since the starting string contains a L char >+ case 7 : /* named group (?P<name> */ >+ case 8 : /* named back reference \k<name> */ >+ case 9 : /* named back reference \k'name' */ >+ case 10 : /* named back reference \k{name} */ >+ case 11 : /* named back reference (?P=name) */ >+ case 12 : /* named back reference \g{name} */ >+ case 13 : /* subroutine call \g<name> */ >+ case 14 : /* subroutine call \g'name' */ >+ case 15 : /* named back reference recursion (?(R&name) */ >+ // skip the opening string >+ location = operLocation + startStrings[caseNumber].length(); >+ // look for ending character >+ location = srcText.indexOf(endChars[caseNumber], location); >+ if (location < 0) >+ return srcText.length(); >+ return location + 1; >+ case 16 : /* quoted sequence \Q...\E */ >+ if (operLocation < 0) { >+ // initial state from previous line >+ location = 0; >+ } else { >+ helper.processOperator(operLocation); >+ // skip the opening "\Q" >+ location = operLocation + 2; >+ } >+ location = srcText.indexOf("\\E", location); //$NON-NLS-1$ >+ if (location < 0) { >+ helper.setFinalState(caseNumber); >+ return srcText.length(); >+ } >+ // set the dirProp for the "E" to L (Left to Right character) >+ helper.setDirProp(location + 1, L); >+ return location + 2; >+ case 17 : /* R, AL, AN, EN */ >+ helper.processOperator(operLocation); >+ return operLocation + 1; >+ >+ } >+ // we should never get here >+ return srcText.length(); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSql.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSql.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSql.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSql.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,149 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * <code>BidiComplexSql</code> is a processor for complex expressions >+ * composed of SQL statements. Such a complex expression may span >+ * multiple lines. >+ * <p> >+ * In applications like an editor where parts of the text might be modified >+ * while other parts are not, the user may want to call >+ * {@link BidiComplexHelper#leanToFullText leanToFullText} >+ * separately on each line and save the initial state of each line (this is >+ * the final state of the previous line which can be retrieved using >+ * {@link BidiComplexHelper#getFinalState getFinalState}. If both the content >+ * of a line and its initial state have not changed, the user can be sure that >+ * the last <i>full</i> text computed for this line has not changed either. >+ * >+ * @see BidiComplexHelper >+ * >+ * @author Matitiahu Allouche >+ */ >+public class BidiComplexSql extends BidiComplexProcessor { >+ private static final byte WS = Character.DIRECTIONALITY_WHITESPACE; >+ static final String operators = "\t!#%&()*+,-./:;<=>?|[]{}"; //$NON-NLS-1$ >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures(operators, 5, -1, -1, false, false); >+ static final String lineSep = BidiComplexEnvironment.getLineSep(); >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with operators "\t!#%&()*+,-./:;<=>?|[]{}", 5 special cases, >+ * LTR direction for Arabic and Hebrew, and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+ /** >+ * This method looks for occurrences of 5 special strings: >+ * <ol> >+ * <li>spaces</li> >+ * <li>literals starting with apostrophe</li> >+ * <li>identifiers starting with quotation mark</li> >+ * <li>comments starting with slash-asterisk</li> >+ * <li>comments starting with hyphen-hyphen</li> >+ * </ol> >+ */ >+ public int indexOfSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int fromIndex) { >+ switch (caseNumber) { >+ case 0 : /* space */ >+ return srcText.indexOf(" ", fromIndex); //$NON-NLS-1$ >+ case 1 : /* literal */ >+ return srcText.indexOf('\'', fromIndex); >+ case 2 : /* delimited identifier */ >+ return srcText.indexOf('"', fromIndex); >+ case 3 : /* slash-aster comment */ >+ return srcText.indexOf("/*", fromIndex); //$NON-NLS-1$ >+ case 4 : /* hyphen-hyphen comment */ >+ return srcText.indexOf("--", fromIndex); //$NON-NLS-1$ >+ } >+ // we should never get here >+ return -1; >+ } >+ >+ /** >+ * This method processes the 5 special cases as follows. >+ * <ol> >+ * <li>skip the run of spaces</li> >+ * <li>look for a matching apostrophe and skip until after it</li> >+ * <li>look for a matching quotation mark and skip until after it</li> >+ * <li>skip until after the closing asterisk-slash</li> >+ * <li>skip until after a line separator</li> >+ * </ol> >+ */ >+ public int processSpecial(BidiComplexHelper helper, int caseNumber, String srcText, int operLocation) { >+ int location; >+ >+ helper.processOperator(operLocation); >+ switch (caseNumber) { >+ case 0 : /* space */ >+ operLocation++; >+ while (operLocation < srcText.length() && srcText.charAt(operLocation) == ' ') { >+ helper.setDirProp(operLocation, WS); >+ operLocation++; >+ } >+ return operLocation; >+ case 1 : /* literal */ >+ location = operLocation + 1; >+ while (true) { >+ location = srcText.indexOf('\'', location); >+ if (location < 0) { >+ helper.setFinalState(caseNumber); >+ return srcText.length(); >+ } >+ if ((location + 1) < srcText.length() && srcText.charAt(location + 1) == '\'') { >+ location += 2; >+ continue; >+ } >+ return location + 1; >+ } >+ case 2 : /* delimited identifier */ >+ location = operLocation + 1; >+ while (true) { >+ location = srcText.indexOf('"', location); >+ if (location < 0) >+ return srcText.length(); >+ >+ if ((location + 1) < srcText.length() && srcText.charAt(location + 1) == '"') { >+ location += 2; >+ continue; >+ } >+ return location + 1; >+ } >+ case 3 : /* slash-aster comment */ >+ if (operLocation < 0) >+ location = 0; // initial state from previous line >+ else >+ location = operLocation + 2; // skip the opening slash-aster >+ location = srcText.indexOf("*/", location); //$NON-NLS-1$ >+ if (location < 0) { >+ helper.setFinalState(caseNumber); >+ return srcText.length(); >+ } >+ // we need to call processOperator since text may follow the >+ // end of comment immediately without even a space >+ helper.processOperator(location); >+ return location + 2; >+ case 4 : /* hyphen-hyphen comment */ >+ location = srcText.indexOf(lineSep, operLocation + 2); >+ if (location < 0) >+ return srcText.length(); >+ return location + lineSep.length(); >+ } >+ // we should never get here >+ return srcText.length(); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSystem.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSystem.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSystem.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexSystem.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,35 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.internal.BidiComplexSingle; >+ >+/** >+ * Processor adapted to processing expressions with the following string format: >+ * <pre> >+ * system(user) >+ * </pre> >+ */ >+public class BidiComplexSystem extends BidiComplexSingle { >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures("(", 0, -1, -1, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with one operator (opening parhenthesis), >+ * no special cases, LTR direction for Arabic and Hebrew, >+ * and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexURL.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexURL.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexURL.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexURL.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,33 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * Processor adapted to processing URLs. >+ */ >+public class BidiComplexURL extends BidiComplexProcessor { >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures(":?#/@.[]", 0, -1, -1, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with operators ":?#/@.[]", >+ * no special cases, LTR direction for Arabic and Hebrew, >+ * and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexUnderscore.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexUnderscore.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexUnderscore.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexUnderscore.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,37 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+ >+/** >+ * Processor adapted to processing compound names. >+ * This type covers names made of one or more parts, separated by underscores: >+ * <pre> >+ * part1_part2_part3 >+ * </pre> >+ */ >+public class BidiComplexUnderscore extends BidiComplexProcessor { >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures("_", 0, -1, -1, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with one operator (underscore), >+ * no special cases, LTR direction for Arabic and Hebrew, >+ * and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexXPath.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexXPath.java >diff -N src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexXPath.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/consumable/BidiComplexXPath.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,40 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.consumable; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.internal.BidiComplexDelims; >+ >+/** >+ * Processor adapted to processing XPath expressions. >+ */ >+public class BidiComplexXPath extends BidiComplexDelims { >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures(" /[]<>=!:@.|()+-*", 2, -1, -1, false, false); //$NON-NLS-1$ >+ >+ /** >+ * This method retrieves the features specific to this processor. >+ * >+ * @return features with operators " /[]<>=!:@.|()+-*", >+ * 2 special cases, LTR direction for Arabic and Hebrew, >+ * and support for both. >+ */ >+ public BidiComplexFeatures init(BidiComplexHelper helper, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+ /** >+ * @return parentheses apostrophe and quotation mark as delimiters. >+ */ >+ protected String getDelimiters() { >+ return "''\"\""; //$NON-NLS-1$ >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/package.html >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/package.html >diff -N src/org/eclipse/equinox/bidi/package.html >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/package.html 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,180 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> >+<html> >+<head> >+<META name="Author" content="Matitiahu Allouche"> >+</head> >+<body bgcolor="white"> >+ >+This package provides interfaces and classes for >+processing complex expressions. >+ >+ >+<h2>Introduction to Complex Expressions</h2> >+<p> >+Bidirectional text offers interesting challenges to presentation systems. >+For plain text, the Unicode Bidirectional Algorithm >+(<a href="http://www.unicode.org/reports/tr9/">UBA</a>) >+generally specifies satisfactorily how to reorder bidirectional text for >+display. This algorithm is implemented in Java's presentation system.</p> >+<p> >+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 >+when displaying such structured text.</p> >+<p> >+The general idea in handling complex expressions is to add directional >+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 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.</p> >+<p> >+In this package, text without directional formatting characters is >+called <b><i>lean</i></b> text while the text with added directional >+formatting characters is called <b><i>full</i></b> text.</p> >+<p> >+The class {@link >+<a href="BidiComplexHelper.html"><b>BidiComplexHelper</b></a>} >+is the main tool for processing complex expressions. It facilitates >+handling several types of complex expressions, each type being handled >+by a specific >+{@link <a href="custom\IBidiComplexProcessor.html"><b><i>processor</i></b></a>} :</p> >+<ul> >+ <li>property (name=value)</li> >+ <li>compound name (xxx_yy_zzzz)</li> >+ <li>comma delimited list</li> >+ <li>system(user)</li> >+ <li>directory and file path</li> >+ <li>e-mail address</li> >+ <li>URL</li> >+ <li>regular expression</li> >+ <li>Xpath</li> >+ <li>Java code</li> >+ <li>SQL statements</li> >+ <li>RTL arithmetic expressions</li> >+</ul> >+<p> >+Other classes and one interface in this package may be used to >+complement and facilitate the action of >+{@link <a href="BidiComplexHelper.html">BidiComplexHelper</a>}: >+<ul> >+ <li>{@link <a href="BidiComplexEnvironment.html">BidiComplexEnvironment</a>} >+ which regroups details about the environment</li> >+ <li>{@link <a href="BidiComplexFeatures.html">BidiComplexFeatures</a>} >+ which allows viewing and manipulating some factors which affect >+ a complex expression processor's behavior</li> >+ <li>{@link <a href="BidiComplexUtil.html">BidiComplexUtil</a>} >+ 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 use other classes of this package. However, the other classes allow >+ more precise control and possibly better performance.</li> >+ <li>{@link <a href="IBidiComplexExpressionTypes.html">IBidiComplexExpressionTypes</a>} >+ is an interface which contains only literals identifying the various types >+ of complex expressions currently supported.</li> >+ <li>{@link <a href="BidiComplexStringRecord.html">BidiComplexStringRecord</a>} >+ which allows to record strings which are complex expressions with their >+ type, so that another module can check if a given string has been recorded >+ as a complex expression and retrieve its type.</li> >+</ul> >+<p> >+{@link <a href="BidiComplexHelper.html">BidiComplexHelper</a>} and the >+other classes and interface mentioned above are intended for users who >+need to process complex expressions for which there already exist >+processors. >+<p> >+Developers who want to develop new processors to support types of complex >+expressions not currently supported can use the following components of the >+package {@link <a href="custom\package-summary.html"> >+org.eclipse.equinox.bidi.custom</a>}: >+<ul> >+ <li>{@link <a href="custom\IBidiComplexProcessor.html">IBidiComplexProcessor</a>} >+ is an interface specifying which methods a processor must provide.</li> >+ <li>{@link <a href="custom\BidiComplexProcessor.html">BidiComplexProcessor</a>} >+ is a generic processor which can be used as superclass for specific >+ processors.</li> >+ <li>{@link <a href="custom\BidiComplexStringProcessor.html">BidiComplexStringProcessor</a>} >+ is a class which allows retrieval of the defined processor types and of the >+ corresponding processors.</li> >+</ul> >+<p> >+There are two other packages associated with the current one: >+<ul> >+ <li>{@link <a href="internal\package-summary.html"> >+ org.eclipse.equinox.bidi.internal</a>}</li> >+ <li>{@link <a href="internal\consumable\package-summary.html"> >+ org.eclipse.equinox.bidi.internal.consumable</a>}</li> >+</ul> >+The tools in the first package can serve as example of how to develop >+processors for currently unsupported types of complex expressions.<br> >+The latter package contains classes for the processors implementing >+the currently supported types of complex expressions. >+<p> >+However, users wishing to process the currently supported types of >+complex expressions typically don't need to interact with these >+two packages. >+ >+<p> </p> >+ >+<h2>Abbreviations used in the documentation of this package</h2> >+ >+<dl> >+<dt><b>UBA</b><dd>Unicode Bidirectional Algorithm >+ >+<dt><b>Bidi</b><dd>Bidirectional >+ >+<dt><b>GUI</b><dd>Graphical User Interface >+ >+<dt><b>UI</b><dd>User Interface >+ >+<dt><b>LTR</b><dd>Left to Right >+ >+<dt><b>RTL</b><dd>Right to Left >+ >+<dt><b>LRM</b><dd>Left-to-Right Mark >+ >+<dt><b>RLM</b><dd>Right-to-Left Mark >+ >+<dt><b>LRE</b><dd>Left-to-Right Embedding >+ >+<dt><b>RLE</b><dd>Right-to-Left Embedding >+ >+<dt><b>PDF</b><dd>Pop Directional Formatting >+</dl> >+ >+<p> </p> >+ >+<h2>Known Limitations</h2> >+ >+<p>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 key points merit special >+attention:</p> >+ >+<ul> >+<li>Implementations of the UBA on various platforms (e.g., Windows and >+Linux) are very similar but nevertheless have known differences. Those >+differences are minor and will not have a visible effect in most cases. >+However there might be cases in which the same bidi text on two >+platforms might look different. These differences will surface in Java >+applications when they use the platform visual components for their UI >+(e.g., AWT, SWT).</li> >+ >+<li>It is assumed that the presentation engine supports LRE, RLE and >+PDF directional formatting characters.</li> >+ >+<li>Because some presentation engines are not strictly conformant to the >+UBA, the implementation of complex expressions in this package adds LRM >+or RLM characters in association with LRE, RLE or PDF in cases where >+this would not be needed if the presentation engine was fully conformant >+to the UBA. Such added marks will not have harmful effects on >+conformant presentation engines and will help less conformant engines to >+achieve the desired presentation.</li> >+</ul> >+ >+</body> >+</html> >#P org.eclipse.equinox.bidi.tests >Index: .settings/org.eclipse.jdt.core.prefs >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi.tests/.settings/org.eclipse.jdt.core.prefs,v >retrieving revision 1.1 >diff -u -r1.1 org.eclipse.jdt.core.prefs >--- .settings/org.eclipse.jdt.core.prefs 3 Feb 2010 20:08:12 -0000 1.1 >+++ .settings/org.eclipse.jdt.core.prefs 9 Feb 2011 21:27:34 -0000 >@@ -1,7 +1,350 @@ >-#Wed Feb 03 11:32:36 EST 2010 >+#Wed Feb 09 14:41:33 EST 2011 > eclipse.preferences.version=1 >+org.eclipse.jdt.core.builder.cleanOutputFolder=clean >+org.eclipse.jdt.core.builder.duplicateResourceTask=warning >+org.eclipse.jdt.core.builder.invalidClasspath=abort >+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch >+org.eclipse.jdt.core.circularClasspath=error >+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled >+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled >+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled > org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 >+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve > org.eclipse.jdt.core.compiler.compliance=1.4 >+org.eclipse.jdt.core.compiler.debug.lineNumber=generate >+org.eclipse.jdt.core.compiler.debug.localVariable=generate >+org.eclipse.jdt.core.compiler.debug.sourceFile=generate >+org.eclipse.jdt.core.compiler.doc.comment.support=enabled >+org.eclipse.jdt.core.compiler.maxProblemPerUnit=1000 >+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning > org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning >+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore >+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning >+org.eclipse.jdt.core.compiler.problem.deadCode=warning >+org.eclipse.jdt.core.compiler.problem.deprecation=warning >+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled >+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled >+org.eclipse.jdt.core.compiler.problem.discouragedReference=error >+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning > org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning >+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore >+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled >+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning >+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore >+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning >+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error >+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning >+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled >+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning >+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore >+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning >+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error >+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private >+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning >+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning >+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore >+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error >+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore >+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled >+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public >+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore >+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled >+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public >+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore >+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled >+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning >+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore >+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning >+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning >+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore >+org.eclipse.jdt.core.compiler.problem.nullReference=warning >+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning >+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore >+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning >+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore >+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning >+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore >+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore >+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled >+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning >+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled >+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled >+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning >+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning >+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning >+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning >+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning >+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning >+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning >+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore >+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning >+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled >+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled >+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled >+org.eclipse.jdt.core.compiler.problem.unusedImport=error >+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning >+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning >+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore >+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore >+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled >+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled >+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled >+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error >+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning >+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning > org.eclipse.jdt.core.compiler.source=1.3 >+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_assignment=0 >+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 >+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 >+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 >+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 >+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 >+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 >+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 >+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 >+org.eclipse.jdt.core.formatter.blank_lines_after_package=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_field=0 >+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 >+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_method=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_package=0 >+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 >+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 >+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false >+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false >+org.eclipse.jdt.core.formatter.comment.format_block_comments=false >+org.eclipse.jdt.core.formatter.comment.format_header=false >+org.eclipse.jdt.core.formatter.comment.format_html=true >+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false >+org.eclipse.jdt.core.formatter.comment.format_line_comments=false >+org.eclipse.jdt.core.formatter.comment.format_source_code=true >+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false >+org.eclipse.jdt.core.formatter.comment.indent_root_tags=false >+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert >+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert >+org.eclipse.jdt.core.formatter.comment.line_length=80 >+org.eclipse.jdt.core.formatter.compact_else_if=true >+org.eclipse.jdt.core.formatter.continuation_indentation=2 >+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 >+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true >+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true >+org.eclipse.jdt.core.formatter.indent_empty_lines=false >+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true >+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true >+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true >+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true >+org.eclipse.jdt.core.formatter.indentation.size=4 >+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert >+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert >+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert >+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert >+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert >+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false >+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false >+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false >+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false >+org.eclipse.jdt.core.formatter.lineSplit=800 >+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false >+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false >+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 >+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 >+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false >+org.eclipse.jdt.core.formatter.tabulation.char=tab >+org.eclipse.jdt.core.formatter.tabulation.size=4 >+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false >+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true >+org.eclipse.jdt.core.incompatibleJDKLevel=ignore >+org.eclipse.jdt.core.incompleteClasspath=error >Index: .settings/org.eclipse.jdt.ui.prefs >=================================================================== >RCS file: .settings/org.eclipse.jdt.ui.prefs >diff -N .settings/org.eclipse.jdt.ui.prefs >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ .settings/org.eclipse.jdt.ui.prefs 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,58 @@ >+#Tue Aug 21 11:27:48 CDT 2007 >+eclipse.preferences.version=1 >+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true >+formatter_profile=_core >+formatter_settings_version=11 >+internal.default.compliance=user >+org.eclipse.jdt.ui.ignorelowercasenames=true >+org.eclipse.jdt.ui.importorder=; >+org.eclipse.jdt.ui.ondemandthreshold=3 >+org.eclipse.jdt.ui.staticondemandthreshold=99 >+sp_cleanup.add_default_serial_version_id=true >+sp_cleanup.add_generated_serial_version_id=false >+sp_cleanup.add_missing_annotations=true >+sp_cleanup.add_missing_deprecated_annotations=true >+sp_cleanup.add_missing_nls_tags=false >+sp_cleanup.add_missing_override_annotations=true >+sp_cleanup.add_serial_version_id=false >+sp_cleanup.always_use_blocks=true >+sp_cleanup.always_use_parentheses_in_expressions=false >+sp_cleanup.always_use_this_for_non_static_field_access=false >+sp_cleanup.always_use_this_for_non_static_method_access=false >+sp_cleanup.convert_to_enhanced_for_loop=false >+sp_cleanup.correct_indentation=false >+sp_cleanup.format_source_code=true >+sp_cleanup.make_local_variable_final=false >+sp_cleanup.make_parameters_final=false >+sp_cleanup.make_private_fields_final=true >+sp_cleanup.make_variable_declarations_final=true >+sp_cleanup.never_use_blocks=false >+sp_cleanup.never_use_parentheses_in_expressions=true >+sp_cleanup.on_save_use_additional_actions=false >+sp_cleanup.organize_imports=true >+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false >+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true >+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true >+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false >+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false >+sp_cleanup.remove_private_constructors=true >+sp_cleanup.remove_trailing_whitespaces=false >+sp_cleanup.remove_trailing_whitespaces_all=true >+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false >+sp_cleanup.remove_unnecessary_casts=true >+sp_cleanup.remove_unnecessary_nls_tags=false >+sp_cleanup.remove_unused_imports=false >+sp_cleanup.remove_unused_local_variables=false >+sp_cleanup.remove_unused_private_fields=true >+sp_cleanup.remove_unused_private_members=false >+sp_cleanup.remove_unused_private_methods=true >+sp_cleanup.remove_unused_private_types=true >+sp_cleanup.sort_members=false >+sp_cleanup.sort_members_all=false >+sp_cleanup.use_blocks=false >+sp_cleanup.use_blocks_only_for_return_and_throw=false >+sp_cleanup.use_parentheses_in_expressions=false >+sp_cleanup.use_this_for_non_static_field_access=false >+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true >+sp_cleanup.use_this_for_non_static_method_access=false >+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi.tests/plugin.xml,v >retrieving revision 1.1 >diff -u -r1.1 plugin.xml >--- plugin.xml 3 Feb 2010 20:08:12 -0000 1.1 >+++ plugin.xml 9 Feb 2011 21:27:34 -0000 >@@ -5,7 +5,7 @@ > id="id2" > point="org.eclipse.equinox.bidi.bidiTypes"> > <typeDescription >- class="org.eclipse.equinox.bidi.internal.tests.ComplExpTest" >+ class="org.eclipse.equinox.bidi.internal.tests.BidiComplexTest" > description="Test" > type="test"> > </typeDescription> >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensibilityTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensibilityTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensibilityTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensibilityTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,65 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.BidiComplexHelper; >+import org.eclipse.equinox.bidi.custom.BidiComplexStringProcessor; >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+ >+/** >+ * Tests contribution of BiDi processors. >+ */ >+public class BidiComplexExtensibilityTest extends BidiComplexTestBase { >+ >+ public void testBaseContributions() { >+ String[] types = BidiComplexStringProcessor.getKnownTypes(); >+ assertNotNull(types); >+ assertTrue(types.length > 0); >+ >+ // check one of the types that we know should be there >+ assertTrue(isTypePresent(types, "regex")); >+ >+ IBidiComplexProcessor processor = BidiComplexStringProcessor.getProcessor("regex"); >+ assertNotNull(processor); >+ } >+ >+ public void testOtherContributions() { >+ String[] types = BidiComplexStringProcessor.getKnownTypes(); >+ assertNotNull(types); >+ assertTrue(types.length > 0); >+ >+ // check the type added by the test bundle >+ assertTrue(isTypePresent(types, "test")); >+ >+ IBidiComplexProcessor processor = BidiComplexStringProcessor.getProcessor("test"); >+ assertNotNull(processor); >+ >+ processor = BidiComplexStringProcessor.getProcessor("badtest"); >+ assertNull(processor); >+ >+ BidiComplexHelper helper = new BidiComplexHelper("test"); >+ String data, lean, full, model; >+ data = "ABC.DEF:HOST-COM=HELLO"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "ABC@.DEF@:HOST@-COM@=HELLO"; >+ assertEquals("Test 'test' plugin", model, toPseudo(full)); >+ } >+ >+ private boolean isTypePresent(String[] types, String type) { >+ for (int i = 0; i < types.length; i++) { >+ if (type.equalsIgnoreCase(types[i])) >+ return true; >+ } >+ return false; >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensionsTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensionsTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensionsTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexExtensionsTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,186 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.*; >+ >+/** >+ * Tests all plug-in extensions >+ */ >+ >+public class BidiComplexExtensionsTest extends BidiComplexTestBase { >+ >+ static int state = BidiComplexHelper.STATE_NOTHING_GOING; >+ >+ private void doTest1(BidiComplexHelper complexp, String label, String data, String result) { >+ String full; >+ full = complexp.leanToFullText(toUT16(data), state); >+ state = complexp.getFinalState(); >+ assertEquals(label + " data = " + data, result, toPseudo(full)); >+ } >+ >+ private void doTest2(BidiComplexHelper complexp, String label, String data, String result) { >+ String full; >+ full = complexp.leanToFullText(data, state); >+ state = complexp.getFinalState(); >+ assertEquals(label + " data = " + data, result, toPseudo(full)); >+ } >+ >+ public void testExtensions() { >+ >+ BidiComplexHelper helper; >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "Comma #1", "ab,cd, AB, CD, EFG", "ab,cd, AB@, CD@, EFG"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.EMAIL); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "Email #1", "abc.DEF:GHI", "abc.DEF@:GHI"); >+ doTest1(helper, "Email #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI @\"A.B\"@:JK "); >+ doTest1(helper, "Email #3", "DEF,GHI (A,B);JK ", "DEF@,GHI @(A,B)@;JK "); >+ doTest1(helper, "Email #4", "DEF.GHI (A.B :JK ", "DEF@.GHI @(A.B :JK "); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.FILE); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "File #1", "c:\\A\\B\\FILE.EXT", "c:\\A@\\B@\\FILE@.EXT"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.JAVA); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "Java #1", "A = B + C;", "A@ = B@ + C;"); >+ doTest1(helper, "Java #2", "A = B + C;", "A@ = B@ + C;"); >+ doTest1(helper, "Java #3", "A = \"B+C\"+D;", "A@ = \"B+C\"@+D;"); >+ doTest1(helper, "Java #4", "A = \"B+C+D;", "A@ = \"B+C+D;"); >+ doTest1(helper, "Java #5", "A = \"B\\\"C\"+D;", "A@ = \"B\\\"C\"@+D;"); >+ doTest1(helper, "Java #6", "A = /*B+C*/ D;", "A@ = /*B+C*/@ D;"); >+ doTest1(helper, "Java #7", "A = /*B+C* D;", "A@ = /*B+C* D;"); >+ doTest1(helper, "Java #8", "X+Y+Z */ B; ", "X+Y+Z */@ B; "); >+ doTest1(helper, "Java #9", "A = //B+C* D;", "A@ = //B+C* D;"); >+ doTest1(helper, "Java #10", "A = //B+C`|D+E;", "A@ = //B+C`|D@+E;"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.PROPERTY); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "Property #0", "NAME,VAL1,VAL2", "NAME,VAL1,VAL2"); >+ doTest1(helper, "Property #1", "NAME=VAL1,VAL2", "NAME@=VAL1,VAL2"); >+ doTest1(helper, "Property #2", "NAME=VAL1,VAL2=VAL3", "NAME@=VAL1,VAL2=VAL3"); >+ >+ String data; >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.REGEXP); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ data = toUT16("ABC(?") + "#" + toUT16("DEF)GHI"); >+ doTest2(helper, "Regex #0.0", data, "A@B@C@(?#DEF)@G@H@I"); >+ data = toUT16("ABC(?") + "#" + toUT16("DEF"); >+ doTest2(helper, "Regex #0.1", data, "A@B@C@(?#DEF"); >+ doTest1(helper, "Regex #0.2", "GHI)JKL", "GHI)@J@K@L"); >+ data = toUT16("ABC(?") + "<" + toUT16("DEF") + ">" + toUT16("GHI"); >+ doTest2(helper, "Regex #1", data, "A@B@C@(?<DEF>@G@H@I"); >+ doTest1(helper, "Regex #2.0", "ABC(?'DEF'GHI", "A@B@C@(?'DEF'@G@H@I"); >+ doTest1(helper, "Regex #2.1", "ABC(?'DEFGHI", "A@B@C@(?'DEFGHI"); >+ data = toUT16("ABC(?(") + "<" + toUT16("DEF") + ">" + toUT16(")GHI"); >+ doTest2(helper, "Regex #3", data, "A@B@C@(?(<DEF>)@G@H@I"); >+ doTest1(helper, "Regex #4", "ABC(?('DEF')GHI", "A@B@C@(?('DEF')@G@H@I"); >+ doTest1(helper, "Regex #5", "ABC(?(DEF)GHI", "A@B@C@(?(DEF)@G@H@I"); >+ data = toUT16("ABC(?") + "&" + toUT16("DEF)GHI"); >+ doTest2(helper, "Regex #6", data, "A@B@C@(?&DEF)@G@H@I"); >+ data = toUT16("ABC(?") + "P<" + toUT16("DEF") + ">" + toUT16("GHI"); >+ doTest2(helper, "Regex #7", data, "A@B@C(?p<DEF>@G@H@I"); >+ data = toUT16("ABC\\k") + "<" + toUT16("DEF") + ">" + toUT16("GHI"); >+ doTest2(helper, "Regex #8", data, "A@B@C\\k<DEF>@G@H@I"); >+ doTest1(helper, "Regex #9", "ABC\\k'DEF'GHI", "A@B@C\\k'DEF'@G@H@I"); >+ doTest1(helper, "Regex #10", "ABC\\k{DEF}GHI", "A@B@C\\k{DEF}@G@H@I"); >+ data = toUT16("ABC(?") + "P=" + toUT16("DEF)GHI"); >+ doTest2(helper, "Regex #11", data, "A@B@C(?p=DEF)@G@H@I"); >+ doTest1(helper, "Regex #12", "ABC\\g{DEF}GHI", "A@B@C\\g{DEF}@G@H@I"); >+ data = toUT16("ABC\\g") + "<" + toUT16("DEF") + ">" + toUT16("GHI"); >+ doTest2(helper, "Regex #13", data, "A@B@C\\g<DEF>@G@H@I"); >+ doTest1(helper, "Regex #14", "ABC\\g'DEF'GHI", "A@B@C\\g'DEF'@G@H@I"); >+ data = toUT16("ABC(?(") + "R&" + toUT16("DEF)GHI"); >+ doTest2(helper, "Regex #15", data, "A@B@C(?(r&DEF)@G@H@I"); >+ data = toUT16("ABC") + "\\Q" + toUT16("DEF") + "\\E" + toUT16("GHI"); >+ doTest2(helper, "Regex #16.0", data, "A@B@C\\qDEF\\eG@H@I"); >+ data = toUT16("ABC") + "\\Q" + toUT16("DEF"); >+ doTest2(helper, "Regex #16.1", data, "A@B@C\\qDEF"); >+ data = toUT16("GHI") + "\\E" + toUT16("JKL"); >+ doTest2(helper, "Regex #16.2", data, "GHI\\eJ@K@L"); >+ doTest1(helper, "Regex #17.0", "abc[d-h]ijk", "abc[d-h]ijk"); >+ doTest1(helper, "Regex #17.1", "aBc[d-H]iJk", "aBc[d-H]iJk"); >+ doTest1(helper, "Regex #17.2", "aB*[!-H]iJ2", "aB*[!-@H]iJ@2"); >+ doTest1(helper, "Regex #17.3", "aB*[1-2]J3", "aB*[@1-2]J@3"); >+ doTest1(helper, "Regex #17.4", "aB*[5-6]J3", "aB*[@5-@6]@J@3"); >+ doTest1(helper, "Regex #17.5", "a*[5-6]J3", "a*[5-@6]@J@3"); >+ doTest1(helper, "Regex #17.6", "aB*123", "aB*@123"); >+ doTest1(helper, "Regex #17.7", "aB*567", "aB*@567"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.SQL); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "SQL #0", "abc GHI", "abc GHI"); >+ doTest1(helper, "SQL #1", "abc DEF GHI", "abc DEF@ GHI"); >+ doTest1(helper, "SQL #2", "ABC, DEF, GHI", "ABC@, DEF@, GHI"); >+ doTest1(helper, "SQL #3", "ABC'DEF GHI' JKL,MN", "ABC@'DEF GHI'@ JKL@,MN"); >+ doTest1(helper, "SQL #4.0", "ABC'DEF GHI JKL", "ABC@'DEF GHI JKL"); >+ doTest1(helper, "SQL #4.1", "MNO PQ' RS,TUV", "MNO PQ'@ RS@,TUV"); >+ doTest1(helper, "SQL #5", "ABC\"DEF GHI\" JKL,MN", "ABC@\"DEF GHI\"@ JKL@,MN"); >+ doTest1(helper, "SQL #6", "ABC\"DEF GHI JKL", "ABC@\"DEF GHI JKL"); >+ doTest1(helper, "SQL #7", "ABC/*DEF GHI*/ JKL,MN", "ABC@/*DEF GHI@*/ JKL@,MN"); >+ doTest1(helper, "SQL #8.0", "ABC/*DEF GHI JKL", "ABC@/*DEF GHI JKL"); >+ doTest1(helper, "SQL #8.1", "MNO PQ*/RS,TUV", "MNO PQ@*/RS@,TUV"); >+ doTest1(helper, "SQL #9", "ABC--DEF GHI JKL", "ABC@--DEF GHI JKL"); >+ doTest1(helper, "SQL #10", "ABC--DEF--GHI,JKL", "ABC@--DEF--GHI,JKL"); >+ doTest1(helper, "SQL #11", "ABC'DEF '' G I' JKL,MN", "ABC@'DEF '' G I'@ JKL@,MN"); >+ doTest1(helper, "SQL #12", "ABC\"DEF \"\" G I\" JKL,MN", "ABC@\"DEF \"\" G I\"@ JKL@,MN"); >+ doTest1(helper, "SQL #13", "ABC--DEF GHI`|JKL MN", "ABC@--DEF GHI`|JKL@ MN"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.SYSTEM_USER); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "System #1", "HOST(JACK)", "HOST@(JACK)"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.UNDERSCORE); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "Underscore #1", "A_B_C_d_e_F_G", "A@_B@_C_d_e_F@_G"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.URL); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "URL #1", "WWW.DOMAIN.COM/DIR1/DIR2/dir3/DIR4", "WWW@.DOMAIN@.COM@/DIR1@/DIR2/dir3/DIR4"); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.XPATH); >+ assertNotNull(helper); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ doTest1(helper, "Xpath #1", "abc(DEF)GHI", "abc(DEF@)GHI"); >+ doTest1(helper, "Xpath #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI@ \"A.B\"@:JK "); >+ doTest1(helper, "Xpath #3", "DEF!GHI 'A!B'=JK ", "DEF@!GHI@ 'A!B'@=JK "); >+ doTest1(helper, "Xpath #4", "DEF.GHI 'A.B :JK ", "DEF@.GHI@ 'A.B :JK "); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.EMAIL); >+ state = BidiComplexHelper.STATE_NOTHING_GOING; >+ BidiComplexFeatures f1 = helper.getFeatures(); >+ assertEquals("<>.:,;@", f1.operators); >+ BidiComplexFeatures f2 = new BidiComplexFeatures("+-*/", f1.specialsCount, f1.dirArabic, f1.dirHebrew, f1.ignoreArabic, f1.ignoreHebrew); >+ helper.setFeatures(f2); >+ doTest1(helper, "DelimsEsc #1", "abc+DEF-GHI", "abc+DEF@-GHI"); >+ doTest1(helper, "DelimsEsc #2", "DEF-GHI (A*B)/JK ", "DEF@-GHI @(A*B)@/JK "); >+ doTest1(helper, "DelimsEsc #3", "DEF-GHI (A*B)/JK ", "DEF@-GHI @(A*B)@/JK "); >+ doTest1(helper, "DelimsEsc #4", "DEF-GHI (A*B\\)*C) /JK ", "DEF@-GHI @(A*B\\)*C) @/JK "); >+ doTest1(helper, "DelimsEsc #5", "DEF-GHI (A\\\\\\)*C) /JK ", "DEF@-GHI @(A\\\\\\)*C) @/JK "); >+ doTest1(helper, "DelimsEsc #6", "DEF-GHI (A\\\\)*C /JK ", "DEF@-GHI @(A\\\\)@*C @/JK "); >+ doTest1(helper, "DelimsEsc #7", "DEF-GHI (A\\)*C /JK ", "DEF@-GHI @(A\\)*C /JK "); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexFullToLeanTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexFullToLeanTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexFullToLeanTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexFullToLeanTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,160 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.*; >+ >+/** >+ * Tests fullToLean method >+ */ >+ >+public class BidiComplexFullToLeanTest extends BidiComplexTestBase { >+ >+ static final BidiComplexEnvironment envLTR = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_LTR); >+ >+ static final BidiComplexEnvironment envRTL = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_RTL); >+ >+ private BidiComplexHelper helper; >+ >+ protected void setUp() throws Exception { >+ super.setUp(); >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ } >+ >+ static int[] getpos(BidiComplexHelper complexp, boolean leanToFull) { >+ int[] pos = new int[5]; >+ >+ if (leanToFull) { >+ pos[0] = complexp.leanToFullPos(0); >+ pos[1] = complexp.leanToFullPos(4); >+ pos[2] = complexp.leanToFullPos(7); >+ pos[3] = complexp.leanToFullPos(10); >+ pos[4] = complexp.leanToFullPos(30); >+ } else { >+ pos[0] = complexp.fullToLeanPos(0); >+ pos[1] = complexp.fullToLeanPos(4); >+ pos[2] = complexp.fullToLeanPos(7); >+ pos[3] = complexp.fullToLeanPos(10); >+ pos[4] = complexp.fullToLeanPos(30); >+ } >+ return pos; >+ } >+ >+ private void doTest1(String msg, String data, String leanLTR, String fullLTR, int[] l2fPosLTR, int[] f2lPosLTR, String leanRTL, String fullRTL, int[] l2fPosRTL, int[] f2lPosRTL) { >+ String text, full, lean, label; >+ int[] pos; >+ >+ text = toUT16(data); >+ helper.setEnvironment(envLTR); >+ lean = helper.fullToLeanText(text); >+ assertEquals(msg + "LTR lean", leanLTR, toPseudo(lean)); >+ full = helper.leanToFullText(lean); >+ assertEquals(msg + "LTR full", fullLTR, toPseudo(full)); >+ pos = getpos(helper, true); >+ label = msg + "leanToFullPos() LTR, expected=" + array_display(l2fPosLTR) + " result=" + array_display(pos); >+ assertTrue(label, arrays_equal(l2fPosLTR, pos)); >+ pos = getpos(helper, false); >+ label = msg + "fullToLeanPos() LTR, expected=" + array_display(f2lPosLTR) + " result=" + array_display(pos); >+ assertTrue(label, arrays_equal(f2lPosLTR, pos)); >+ helper.setEnvironment(envRTL); >+ lean = helper.fullToLeanText(text); >+ assertEquals(msg + "RTL lean", leanRTL, toPseudo(lean)); >+ full = helper.leanToFullText(lean); >+ assertEquals(msg + "RTL full", fullRTL, toPseudo(full)); >+ pos = getpos(helper, true); >+ label = msg + "leanToFullPos() RTL, expected=" + array_display(l2fPosRTL) + " result=" + array_display(pos); >+ assertTrue(label, arrays_equal(l2fPosRTL, pos)); >+ pos = getpos(helper, false); >+ label = msg + "fullToLeanPos() RTL, expected=" + array_display(f2lPosRTL) + " result=" + array_display(pos); >+ assertTrue(label, arrays_equal(f2lPosRTL, pos)); >+ } >+ >+ private void doTest2(String msg) { >+ String text, data, full, lean, model; >+ int state, state2, state3; >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.SQL); >+ helper.setEnvironment(envLTR); >+ data = "update \"AB_CDE\" set \"COL1\"@='01', \"COL2\"@='02' /* GH IJK"; >+ text = toUT16(data); >+ lean = helper.fullToLeanText(text); >+ state = helper.getFinalState(); >+ model = "update \"AB_CDE\" set \"COL1\"='01', \"COL2\"='02' /* GH IJK"; >+ assertEquals(msg + "LTR lean", model, toPseudo(lean)); >+ full = helper.leanToFullText(lean); >+ assertEquals(msg + "LTR full", data, toPseudo(full)); >+ assertEquals(msg + "state from leanToFullText", helper.getFinalState(), state); >+ data = "THIS IS A COMMENT LINE"; >+ text = toUT16(data); >+ lean = helper.fullToLeanText(text, state); >+ state2 = helper.getFinalState(); >+ model = "THIS IS A COMMENT LINE"; >+ assertEquals(msg + "LTR lean2", model, toPseudo(lean)); >+ full = helper.leanToFullText(lean, state); >+ assertEquals(msg + "LTR full2", data, toPseudo(full)); >+ assertEquals(msg + "state from leanToFullText2", helper.getFinalState(), state2); >+ data = "SOME MORE */ where \"COL3\"@=123"; >+ text = toUT16(data); >+ lean = helper.fullToLeanText(text, state2); >+ state3 = helper.getFinalState(); >+ model = "SOME MORE */ where \"COL3\"=123"; >+ assertEquals(msg + "LTR lean3", model, toPseudo(lean)); >+ full = helper.leanToFullText(lean, state2); >+ assertEquals(msg + "LTR full3", data, toPseudo(full)); >+ assertEquals(msg + "state from leanToFullText3", helper.getFinalState(), state3); >+ } >+ >+ public void testFullToLean() { >+ >+ doTest1("testFullToLean #1 - ", "", "", "", new int[] {0, 4, 7, 10, 30}, new int[] {0, 0, 0, 0, 0}, "", "", new int[] {0, 4, 7, 10, 30}, new int[] {0, 0, 0, 0, 0}); >+ doTest1("testFullToLean #01 - ", "1.abc", "1.abc", "1.abc", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 5, 5, 5}, "1.abc", ">@1.abc@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 5, 5}); >+ doTest1("testFullToLean #02 - ", "2.abc,def", "2.abc,def", "2.abc,def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 9, 9}, "2.abc,def", ">@2.abc,def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 9}); >+ doTest1("testFullToLean #03 - ", "@a.3.bc,def", "a.3.bc,def", "a.3.bc,def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 10, 10}, "a.3.bc,def", ">@a.3.bc,def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 10}); >+ doTest1("testFullToLean #04 - ", "@@a.4.bc,def", "a.4.bc,def", "a.4.bc,def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 10, 10}, "a.4.bc,def", ">@a.4.bc,def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 10}); >+ doTest1("testFullToLean #05 - ", "@5.abc,def", "5.abc,def", "5.abc,def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 9, 9}, "5.abc,def", ">@5.abc,def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 9}); >+ doTest1("testFullToLean #06 - ", "@@6.abc,def", "6.abc,def", "6.abc,def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 9, 9}, "6.abc,def", ">@6.abc,def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 9}); >+ doTest1("testFullToLean #07 - ", "7abc,@def", "7abc,@def", "7abc,@def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 9, 9}, "7abc,@def", ">@7abc,@def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 9}); >+ doTest1("testFullToLean #08 - ", "8abc,@@def", "8abc,@def", "8abc,@def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 9, 9}, "8abc,@def", ">@8abc,@def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 9}); >+ doTest1("testFullToLean #09 - ", "9abc,def@", "9abc,def", "9abc,def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 8, 8}, "9abc,def", ">@9abc,def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 8}); >+ doTest1("testFullToLean #10 - ", "10abc,def@@", "10abc,def", "10abc,def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 9, 9}, "10abc,def", ">@10abc,def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 9}); >+ doTest1("testFullToLean #11 - ", "@a.11.bc,@def@", "a.11.bc,@def", "a.11.bc,@def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 10, 12}, "a.11.bc,@def", ">@a.11.bc,@def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 12}); >+ doTest1("testFullToLean #12 - ", "@@a.12.bc,@@def@@", "a.12.bc,@def", "a.12.bc,@def", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 10, 12}, "a.12.bc,@def", ">@a.12.bc,@def@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 12}); >+ doTest1("testFullToLean #13 - ", "13ABC", "13ABC", "13ABC", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 5, 5, 5}, "13ABC", ">@13ABC@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 5, 5}); >+ doTest1("testFullToLean #14 - ", "14ABC,DE", "14ABC,DE", "14ABC@,DE", new int[] {0, 4, 8, 11, 31}, new int[] {0, 4, 6, 8, 8}, "14ABC,DE", ">@14ABC@,DE@^", new int[] {2, 6, 10, 13, 33}, new int[] {0, 2, 5, 7, 8}); >+ doTest1("testFullToLean #15 - ", "15ABC@,DE", "15ABC,DE", "15ABC@,DE", new int[] {0, 4, 8, 11, 31}, new int[] {0, 4, 6, 8, 8}, "15ABC,DE", ">@15ABC@,DE@^", new int[] {2, 6, 10, 13, 33}, new int[] {0, 2, 5, 7, 8}); >+ doTest1("testFullToLean #16 - ", "16ABC@@,DE", "16ABC,DE", "16ABC@,DE", new int[] {0, 4, 8, 11, 31}, new int[] {0, 4, 6, 8, 8}, "16ABC,DE", ">@16ABC@,DE@^", new int[] {2, 6, 10, 13, 33}, new int[] {0, 2, 5, 7, 8}); >+ doTest1("testFullToLean #17 - ", "17ABC,@@DE", "17ABC,@DE", "17ABC,@DE", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 9, 9}, "17ABC,@DE", ">@17ABC,@DE@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 9}); >+ doTest1("testFullToLean #18 - ", "18ABC,DE,FGH", "18ABC,DE,FGH", "18ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "18ABC,DE,FGH", ">@18ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #19 - ", "19ABC@,DE@,FGH", "19ABC,DE,FGH", "19ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "19ABC,DE,FGH", ">@19ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #20 - ", "20ABC,@DE,@FGH", "20ABC,@DE,@FGH", "20ABC,@DE,@FGH", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 10, 14}, "20ABC,@DE,@FGH", ">@20ABC,@DE,@FGH@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 14}); >+ doTest1("testFullToLean #21 - ", "21ABC@@,DE@@,FGH", "21ABC,DE,FGH", "21ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "21ABC,DE,FGH", ">@21ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #22 - ", "22ABC,@@DE,@@FGH", "22ABC,@DE,@FGH", "22ABC,@DE,@FGH", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 10, 14}, "22ABC,@DE,@FGH", ">@22ABC,@DE,@FGH@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 14}); >+ doTest1("testFullToLean #23 - ", ">@23abc@^", "23abc", "23abc", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 5, 5, 5}, "23abc", ">@23abc@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 5, 5}); >+ doTest1("testFullToLean #24 - ", "24abc@^", "24abc", "24abc", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 5, 5, 5}, "24abc", ">@24abc@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 5, 5}); >+ doTest1("testFullToLean #25 - ", ">@25abc", "25abc", "25abc", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 5, 5, 5}, "25abc", ">@25abc@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 5, 5}); >+ doTest1("testFullToLean #26 - ", "26AB,CD@EF,GHI", "26AB,CD@EF,GHI", "26AB@,CD@EF@,GHI", new int[] {0, 5, 8, 12, 32}, new int[] {0, 4, 6, 9, 14}, "26AB,CD@EF,GHI", ">@26AB@,CD@EF@,GHI@^", new int[] {2, 7, 10, 14, 34}, new int[] {0, 2, 4, 7, 14}); >+ doTest1("testFullToLean #27 - ", "27AB,CD@123ef,GHI", "27AB,CD@123ef,GHI", "27AB@,CD@123ef,GHI", new int[] {0, 5, 8, 11, 31}, new int[] {0, 4, 6, 9, 17}, "27AB,CD@123ef,GHI", ">@27AB@,CD@123ef,GHI@^", new int[] {2, 7, 10, 13, 33}, new int[] {0, 2, 4, 7, 17}); >+ doTest1("testFullToLean #28 - ", ">28ABC@,DE@,FGH^", "28ABC,DE,FGH", "28ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "28ABC,DE,FGH", ">@28ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #29 - ", ">>29ABC@,DE@,FGH^^", "29ABC,DE,FGH", "29ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "29ABC,DE,FGH", ">@29ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #30 - ", ">30AB>C^@,DE@,FGH^", "30AB>C^,DE,FGH", "30AB>C^@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 7, 9, 14}, "30AB>C^,DE,FGH", ">@30AB>C^@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 14}); >+ doTest1("testFullToLean #31 - ", ">31AB>C@,DE@,FGH^^", "31AB>C,DE,FGH", "31AB>C@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 9, 13}, "31AB>C,DE,FGH", ">@31AB>C@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 13}); >+ doTest1("testFullToLean #32 - ", ">@32ABC@,DE@,FGH@^", "32ABC,DE,FGH", "32ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "32ABC,DE,FGH", ">@32ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #33 - ", "@33ABC@,DE@,FGH@^", "33ABC,DE,FGH", "33ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "33ABC,DE,FGH", ">@33ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #34 - ", ">@34ABC@,DE@,FGH@", "34ABC,DE,FGH", "34ABC@,DE@,FGH", new int[] {0, 4, 8, 12, 32}, new int[] {0, 4, 6, 8, 12}, "34ABC,DE,FGH", ">@34ABC@,DE@,FGH@^", new int[] {2, 6, 10, 14, 34}, new int[] {0, 2, 5, 7, 12}); >+ doTest1("testFullToLean #35 - ", "35ABC@@DE@@@GH@", "35ABC@DE@GH", "35ABC@DE@GH", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 10, 11}, "35ABC@DE@GH", ">@35ABC@DE@GH@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 11}); >+ doTest1("testFullToLean #36 - ", "36ABC@@DE@@@@@@", "36ABC@DE", "36ABC@DE", new int[] {0, 4, 7, 10, 30}, new int[] {0, 4, 7, 8, 8}, "36ABC@DE", ">@36ABC@DE@^", new int[] {2, 6, 9, 12, 32}, new int[] {0, 2, 5, 8, 8}); >+ doTest1("testFullToLean #37 - ", ">>>@@@@@^^^", "", "", new int[] {0, 4, 7, 10, 30}, new int[] {0, 0, 0, 0, 0}, "", "", new int[] {0, 4, 7, 10, 30}, new int[] {0, 0, 0, 0, 0}); >+ >+ // test fullToLeanText with initial state >+ doTest2("testFullToLean #38 - "); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMathTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMathTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMathTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMathTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,55 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.*; >+ >+/** >+ * Tests RTL arithmetic >+ */ >+public class BidiComplexMathTest extends BidiComplexTestBase { >+ >+ static final BidiComplexEnvironment envLTR = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_LTR); >+ >+ static final BidiComplexEnvironment envRTL = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_RTL); >+ >+ private BidiComplexHelper helper; >+ >+ protected void setUp() throws Exception { >+ super.setUp(); >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.RTL_ARITHMETIC); >+ } >+ >+ private void verifyOneLine(String msg, String data, String resLTR, String resRTL) { >+ String lean = toUT16(data); >+ helper.setEnvironment(envLTR); >+ String fullLTR = helper.leanToFullText(lean); >+ assertEquals(msg + " LTR - ", resLTR, toPseudo(fullLTR)); >+ >+ helper.setEnvironment(envRTL); >+ String fullRTL = helper.leanToFullText(lean); >+ assertEquals(msg + " RTL - ", resRTL, toPseudo(fullRTL)); >+ } >+ >+ public void testRTLarithmetic() { >+ verifyOneLine("Math #0", "", "", ""); >+ verifyOneLine("Math #1", "1+abc", "<&1+abc&^", "1+abc"); >+ verifyOneLine("Math #2", "2+abc-def", "<&2+abc&-def&^", "2+abc&-def"); >+ verifyOneLine("Math #3", "a+3*bc/def", "<&a&+3*bc&/def&^", "a&+3*bc&/def"); >+ verifyOneLine("Math #4", "4+abc/def", "<&4+abc&/def&^", "4+abc&/def"); >+ verifyOneLine("Math #5", "13ABC", "<&13ABC&^", "13ABC"); >+ verifyOneLine("Math #6", "14ABC-DE", "<&14ABC-DE&^", "14ABC-DE"); >+ verifyOneLine("Math #7", "15ABC+DE", "<&15ABC+DE&^", "15ABC+DE"); >+ verifyOneLine("Math #8", "16ABC*DE", "<&16ABC*DE&^", "16ABC*DE"); >+ verifyOneLine("Math #9", "17ABC/DE", "<&17ABC/DE&^", "17ABC/DE"); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMethodsTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMethodsTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMethodsTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexMethodsTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,366 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.*; >+ >+/** >+ * Tests most public methods of BidiComplexHelper >+ */ >+ >+public class BidiComplexMethodsTest extends BidiComplexTestBase { >+ >+ final static int LTR = BidiComplexFeatures.DIR_LTR; >+ >+ final static int RTL = BidiComplexFeatures.DIR_RTL; >+ >+ final static BidiComplexEnvironment envLTR = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_LTR); >+ >+ final static BidiComplexEnvironment envRTL = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_RTL); >+ >+ final static BidiComplexEnvironment envRTLMIR = new BidiComplexEnvironment(null, true, BidiComplexEnvironment.ORIENT_RTL); >+ >+ final static BidiComplexEnvironment envIGN = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_IGNORE); >+ >+ final static BidiComplexEnvironment envCLR = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_CONTEXTUAL_LTR); >+ >+ final static BidiComplexEnvironment envCRL = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_CONTEXTUAL_RTL); >+ >+ final static BidiComplexEnvironment envERR = new BidiComplexEnvironment(null, false, 9999); >+ >+ BidiComplexHelper helper; >+ >+ private void doTestTools() { >+ >+ // This method tests utility methods used by the JUnits >+ String data = "56789ABCDEFGHIJKLMNOPQRSTUVWXYZ~#@&><^|`"; >+ String text = toUT16(data); >+ String dat2 = toPseudo(text); >+ assertEquals(data, dat2); >+ >+ text = toPseudo(data); >+ assertEquals("56789abcdefghijklmnopqrstuvwxyz~#@&><^|`", text); >+ >+ int[] arrayA = new int[] {1, 2}; >+ int[] arrayB = new int[] {3, 4, 5}; >+ assertFalse(arrays_equal(arrayA, arrayB)); >+ >+ assertTrue(arrays_equal(arrayA, arrayA)); >+ >+ arrayB = new int[] {3, 4}; >+ assertFalse(arrays_equal(arrayA, arrayB)); >+ >+ text = array_display(null); >+ assertEquals("null", text); >+ } >+ >+ private void doTestState() { >+ String data, lean, full, model; >+ int state; >+ >+ data = "A=B+C;/* D=E+F;"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "A@=B@+C@;/* D=E+F;"; >+ assertEquals("full1", model, toPseudo(full)); >+ state = helper.getFinalState(); >+ data = "A=B+C; D=E+F;"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean, state); >+ model = "A=B+C; D=E+F;"; >+ assertEquals("full2", model, toPseudo(full)); >+ state = helper.getFinalState(); >+ data = "A=B+C;*/ D=E+F;"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean, state); >+ model = "A=B+C;*/@ D@=E@+F;"; >+ assertEquals("full3", model, toPseudo(full)); >+ } >+ >+ private void doTestOrientation() { >+ int orient; >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ orient = helper.getEnvironment().orientation; >+ assertEquals("orient #1", BidiComplexEnvironment.ORIENT_LTR, orient); >+ >+ helper.setEnvironment(envIGN); >+ orient = helper.getEnvironment().orientation; >+ assertEquals("orient #2", BidiComplexEnvironment.ORIENT_IGNORE, orient); >+ >+ helper.setEnvironment(envCRL); >+ orient = helper.getEnvironment().orientation; >+ helper.leanToFullText("--!**"); >+ assertEquals("orient #3", BidiComplexEnvironment.ORIENT_CONTEXTUAL_RTL, orient); >+ >+ helper.setEnvironment(envERR); >+ orient = helper.getEnvironment().orientation; >+ helper.leanToFullText("--!**"); >+ assertEquals("orient #4", BidiComplexEnvironment.ORIENT_UNKNOWN, orient); >+ } >+ >+ private void doTestOrient(BidiComplexFeatures f, String label, String data, String resLTR, String resRTL, String resCon) { >+ String full, lean; >+ >+ lean = toUT16(data); >+ helper.setEnvironment(envLTR); >+ helper.setFeatures(f); >+ full = helper.leanToFullText(lean); >+ assertEquals(label + "LTR full", resLTR, toPseudo(full)); >+ helper.setEnvironment(envRTL); >+ helper.setFeatures(f); >+ full = helper.leanToFullText(lean); >+ assertEquals("label + RTL full", resRTL, toPseudo(full)); >+ helper.setEnvironment(envCRL); >+ helper.setFeatures(f); >+ full = helper.leanToFullText(lean); >+ assertEquals(label + "CON full", resCon, toPseudo(full)); >+ } >+ >+ private void doTestScripts() { >+ BidiComplexFeatures f2, f1 = helper.getFeatures(); >+ boolean flag; >+ flag = f1.ignoreArabic; >+ assertFalse("Ignores Arabic 1", flag); >+ flag = f1.ignoreHebrew; >+ assertFalse("Ignores Hebrew 1", flag); >+ >+ f2 = new BidiComplexFeatures(f1.operators, 0, -1, -1, true, true); >+ flag = f2.ignoreArabic; >+ assertTrue("Ignores Arabic 2", flag); >+ flag = f2.ignoreHebrew; >+ assertTrue("Ignores Hebrew 2", flag); >+ doTestOrient(f2, "Scripts #1 ", "BCD,EF", "BCD,EF", ">@BCD,EF@^", "@BCD,EF"); >+ f2 = new BidiComplexFeatures(f1.operators, 0, -1, -1, false, true); >+ flag = f2.ignoreArabic; >+ assertFalse("Ignores Arabic 3", flag); >+ flag = f2.ignoreHebrew; >+ assertTrue("Ignores Hebrew 3", flag); >+ doTestOrient(f2, "Scripts #2 ", "d,EF", "d,EF", ">@d,EF@^", "d,EF"); >+ doTestOrient(f2, "Scripts #3 ", "#,eF", "#,eF", ">@#,eF@^", "@#,eF"); >+ doTestOrient(f2, "Scripts #4 ", "#,12", "#@,12", ">@#@,12@^", "@#@,12"); >+ doTestOrient(f2, "Scripts #5 ", "#,##", "#@,##", ">@#@,##@^", "@#@,##"); >+ doTestOrient(f2, "Scripts #6 ", "#,89", "#@,89", ">@#@,89@^", "@#@,89"); >+ doTestOrient(f2, "Scripts #7 ", "#,ef", "#,ef", ">@#,ef@^", "@#,ef"); >+ doTestOrient(f2, "Scripts #8 ", "#,", "#,", ">@#,@^", "@#,"); >+ doTestOrient(f2, "Scripts #9 ", "9,ef", "9,ef", ">@9,ef@^", "9,ef"); >+ doTestOrient(f2, "Scripts #10 ", "9,##", "9@,##", ">@9@,##@^", "9@,##"); >+ doTestOrient(f2, "Scripts #11 ", "7,89", "7@,89", ">@7@,89@^", "7@,89"); >+ doTestOrient(f2, "Scripts #12 ", "7,EF", "7,EF", ">@7,EF@^", "@7,EF"); >+ doTestOrient(f2, "Scripts #13 ", "BCD,EF", "BCD,EF", ">@BCD,EF@^", "@BCD,EF"); >+ >+ f2 = new BidiComplexFeatures(f1.operators, 0, -1, -1, true, false); >+ flag = f2.ignoreArabic; >+ assertTrue("Ignores Arabic 4", flag); >+ flag = f2.ignoreHebrew; >+ assertFalse("Ignores Hebrew 4", flag); >+ doTestOrient(f2, "Scripts #14 ", "BCd,EF", "BCd,EF", ">@BCd,EF@^", "@BCd,EF"); >+ doTestOrient(f2, "Scripts #15 ", "BCD,eF", "BCD,eF", ">@BCD,eF@^", "@BCD,eF"); >+ doTestOrient(f2, "Scripts #16 ", "BCD,EF", "BCD@,EF", ">@BCD@,EF@^", "@BCD@,EF"); >+ doTestOrient(f2, "Scripts #17 ", "BCD,12", "BCD@,12", ">@BCD@,12@^", "@BCD@,12"); >+ doTestOrient(f2, "Scripts #18 ", "BCD,", "BCD,", ">@BCD,@^", "@BCD,"); >+ >+ f2 = new BidiComplexFeatures(f1.operators, 0, -1, -1, false, false); >+ doTestOrient(f2, "Scripts #19 ", "123,45|67", "123,45|67", ">@123,45|67@^", "@123,45|67"); >+ doTestOrient(f2, "Scripts #20 ", "5,e", "5,e", ">@5,e@^", "5,e"); >+ doTestOrient(f2, "Scripts #21 ", "5,#", "5@,#", ">@5@,#@^", "5@,#"); >+ doTestOrient(f2, "Scripts #22 ", "5,6", "5@,6", ">@5@,6@^", "5@,6"); >+ doTestOrient(f2, "Scripts #23 ", "5,D", "5@,D", ">@5@,D@^", "5@,D"); >+ doTestOrient(f2, "Scripts #24 ", "5,--", "5,--", ">@5,--@^", "@5,--"); >+ } >+ >+ private void doTestLeanOffsets() { >+ String lean, data, label; >+ int state; >+ int[] offsets; >+ int[] model; >+ >+ data = "A=B+C;/* D=E+F;"; >+ lean = toUT16(data); >+ helper.leanToFullText(lean); >+ offsets = helper.leanBidiCharOffsets(); >+ model = new int[] {1, 3, 5}; >+ label = "leanBidiCharOffsets() #1 expected=" + array_display(model) + " result=" + array_display(offsets); >+ assertTrue(label, arrays_equal(model, offsets)); >+ state = helper.getFinalState(); >+ data = "A=B+C;*/ D=E+F;"; >+ lean = toUT16(data); >+ helper.leanToFullText(lean, state); >+ offsets = helper.leanBidiCharOffsets(); >+ model = new int[] {8, 10, 12}; >+ label = "leanBidiCharOffsets() #2 expected=" + array_display(model) + " result=" + array_display(offsets); >+ assertTrue(label, arrays_equal(model, offsets)); >+ offsets = helper.leanBidiCharOffsets(); >+ model = new int[] {8, 10, 12}; >+ label = "leanBidiCharOffsets() #3 expected=" + array_display(model) + " result=" + array_display(offsets); >+ assertTrue(label, arrays_equal(model, offsets)); >+ } >+ >+ private void doTestFullOffsets(String label, String data, int[] resLTR, int[] resRTL, int[] resCon) { >+ String full, lean, msg; >+ int[] offsets; >+ >+ lean = toUT16(data); >+ helper.setEnvironment(envLTR); >+ full = helper.leanToFullText(lean); >+ // the following line avoids a compiler warning about full never being >+ // read >+ full += ""; >+ offsets = helper.fullBidiCharOffsets(); >+ msg = label + "LTR expected=" + array_display(resLTR) + " result=" + array_display(offsets); >+ assertTrue(msg, arrays_equal(resLTR, offsets)); >+ helper.setEnvironment(envRTL); >+ full = helper.leanToFullText(lean); >+ offsets = helper.fullBidiCharOffsets(); >+ msg = label + "RTL expected=" + array_display(resRTL) + " result=" + array_display(offsets); >+ assertTrue(msg, arrays_equal(resRTL, offsets)); >+ helper.setEnvironment(envCLR); >+ full = helper.leanToFullText(lean); >+ offsets = helper.fullBidiCharOffsets(); >+ msg = label + "CON expected=" + array_display(resCon) + " result=" + array_display(offsets); >+ assertTrue(msg, arrays_equal(resCon, offsets)); >+ } >+ >+ private void doTestMirrored() { >+ boolean mirrored; >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ mirrored = helper.getEnvironment().mirrored; >+ assertFalse("mirrored #1", mirrored); >+ BidiComplexEnvironment env = new BidiComplexEnvironment(null, true, BidiComplexEnvironment.ORIENT_LTR); >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED, env); >+ mirrored = helper.getEnvironment().mirrored; >+ assertTrue("mirrored #2", mirrored); >+ } >+ >+ private void doTestDirection() { >+ String data, lean, full, model, msg; >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ BidiComplexFeatures f1 = helper.getFeatures(); >+ msg = "TestDirection #1"; >+ assertTrue(msg, f1.dirArabic == LTR && f1.dirHebrew == LTR); >+ >+ BidiComplexFeatures f2 = new BidiComplexFeatures(f1.operators, 0, RTL, RTL, false, false); >+ helper.setFeatures(f2); >+ f1 = helper.getFeatures(); >+ msg = "TestDirection #2"; >+ assertTrue(msg, f1.dirArabic == RTL && f1.dirHebrew == RTL); >+ >+ BidiComplexEnvironment environment = new BidiComplexEnvironment(null, false, BidiComplexEnvironment.ORIENT_LTR); >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.EMAIL, environment); >+ f1 = helper.getFeatures(); >+ msg = "TestDirection #3"; >+ assertTrue(msg, f1.dirArabic == LTR && f1.dirHebrew == LTR); >+ data = "#ABC.#DEF:HOST.com"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "#ABC@.#DEF@:HOST.com"; >+ assertEquals("TestDirection #9 full", model, toPseudo(full)); >+ >+ data = "ABC.DEF:HOST.com"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "ABC@.DEF@:HOST.com"; >+ assertEquals("TestDirection #10 full", model, toPseudo(full)); >+ >+ environment = new BidiComplexEnvironment(null, true, BidiComplexEnvironment.ORIENT_LTR); >+ helper.setEnvironment(environment); >+ f1 = helper.getFeatures(); >+ msg = "TestDirection #10.5"; >+ assertTrue(msg, f1.dirArabic == RTL && f1.dirHebrew == LTR); >+ data = "#ABC.#DEF:HOST.com"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "<&#ABC.#DEF:HOST.com&^"; >+ assertEquals("TestDirection #11 full", model, toPseudo(full)); >+ >+ data = "#ABc.#DEF:HOSt.COM"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "<&#ABc.#DEF:HOSt.COM&^"; >+ assertEquals("TestDirection #12 full", model, toPseudo(full)); >+ >+ data = "#ABc.#DEF:HOSt."; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "<&#ABc.#DEF:HOSt.&^"; >+ assertEquals("TestDirection #13 full", model, toPseudo(full)); >+ >+ data = "ABC.DEF:HOST.com"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "ABC@.DEF@:HOST.com"; >+ assertEquals("TestDirection #14 full", model, toPseudo(full)); >+ >+ data = "--.---:----"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "--.---:----"; >+ assertEquals("TestDirection #15 full", model, toPseudo(full)); >+ >+ data = "ABC.|DEF:HOST.com"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "ABC.|DEF@:HOST.com"; >+ assertEquals("TestDirection #16 full", model, toPseudo(full)); >+ >+ helper.setEnvironment(envRTLMIR); >+ data = "#ABc.|#DEF:HOST.com"; >+ lean = toUT16(data); >+ full = helper.leanToFullText(lean); >+ model = "#ABc.|#DEF:HOST.com"; >+ assertEquals("TestDirection #17 full", model, toPseudo(full)); >+ assertEquals("Test curDirection", RTL, helper.getCurDirection()); >+ } >+ >+ public void testMethods() { >+ >+ doTestTools(); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.JAVA); >+ doTestState(); >+ >+ doTestOrientation(); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ BidiComplexFeatures f2 = helper.getFeatures(); >+ doTestOrient(f2, "Methods #1 ", "", "", "", ""); >+ doTestOrient(f2, "Methods #2 ", "abc", "abc", ">@abc@^", "abc"); >+ doTestOrient(f2, "Methods #3 ", "ABC", "ABC", ">@ABC@^", "@ABC"); >+ doTestOrient(f2, "Methods #4 ", "bcd,ef", "bcd,ef", ">@bcd,ef@^", "bcd,ef"); >+ doTestOrient(f2, "Methods #5 ", "BCD,EF", "BCD@,EF", ">@BCD@,EF@^", "@BCD@,EF"); >+ doTestOrient(f2, "Methods #6 ", "cde,FG", "cde,FG", ">@cde,FG@^", "cde,FG"); >+ doTestOrient(f2, "Methods #7 ", "CDE,fg", "CDE,fg", ">@CDE,fg@^", "@CDE,fg"); >+ doTestOrient(f2, "Methods #8 ", "12..def,GH", "12..def,GH", ">@12..def,GH@^", "12..def,GH"); >+ doTestOrient(f2, "Methods #9 ", "34..DEF,gh", "34..DEF,gh", ">@34..DEF,gh@^", "@34..DEF,gh"); >+ >+ doTestScripts(); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.JAVA); >+ doTestLeanOffsets(); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ doTestFullOffsets("TestFullOffsets ", "BCD,EF,G", new int[] {3, 7}, new int[] {0, 1, 5, 9, 12, 13}, new int[] {0, 4, 8}); >+ >+ doTestMirrored(); >+ >+ doTestDirection(); >+ >+ helper = new BidiComplexHelper(IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ String data = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"; >+ String lean = toUT16(data); >+ String full = helper.leanToFullText(lean); >+ String model = "A@,B@,C@,D@,E@,F@,G@,H@,I@,J@,K@,L@,M@,N@,O@,P@,Q@,R@,S@,T@,U@,V@,W@,X@,Y@,Z"; >+ assertEquals("many inserts", model, toPseudo(full)); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexNullProcessorTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexNullProcessorTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexNullProcessorTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexNullProcessorTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,59 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.*; >+ >+/** >+ * Tests RTL arithmetic >+ */ >+public class BidiComplexNullProcessorTest extends BidiComplexTestBase { >+ >+ static final int[] EMPTY_INT_ARRAY = new int[0]; >+ >+ private BidiComplexHelper helper; >+ >+ protected void setUp() throws Exception { >+ super.setUp(); >+ helper = new BidiComplexHelper(); >+ } >+ >+ public void testNullProcessor() { >+ String full = helper.leanToFullText("abc"); >+ assertEquals("leanToFullText", "abc", full); >+ full = helper.leanToFullText("abc", 3); >+ assertEquals("leanToFullText with state", "abc", full); >+ int[] offsets = helper.leanBidiCharOffsets(); >+ assertTrue("leanBidiCharOffsets", arrays_equal(offsets, EMPTY_INT_ARRAY)); >+ offsets = helper.fullBidiCharOffsets(); >+ assertTrue("fullBidiCharOffsets", arrays_equal(offsets, EMPTY_INT_ARRAY)); >+ String lean = helper.fullToLeanText("abc"); >+ assertEquals("fullToLeanText", "abc", lean); >+ lean = helper.fullToLeanText("abc", 3); >+ assertEquals("fullToLeanText with state", "abc", lean); >+ int state = helper.getFinalState(); >+ assertEquals("getFinalState", BidiComplexHelper.STATE_NOTHING_GOING, state); >+ int pos = helper.leanToFullPos(13); >+ assertEquals("leanToFullPos", 13, pos); >+ pos = helper.fullToLeanPos(15); >+ assertEquals("fullToLeanPos", 15, pos); >+ assertEquals("getDirProp", Character.DIRECTIONALITY_UNDEFINED, helper.getDirProp(123)); >+ int direction = helper.getCurDirection(); >+ assertEquals("getCurDirection", BidiComplexFeatures.DIR_LTR, direction); >+ BidiComplexEnvironment env = helper.getEnvironment(); >+ assertEquals("getEnvironment", BidiComplexEnvironment.DEFAULT, env); >+ helper.setEnvironment(env); >+ BidiComplexFeatures features = helper.getFeatures(); >+ assertEquals("getFeatures", BidiComplexFeatures.DEFAULT, features); >+ helper.setFeatures(features); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexSomeMoreTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexSomeMoreTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexSomeMoreTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexSomeMoreTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,100 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.BidiComplexProcessor; >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+ >+/** >+ * Tests some weird cases >+ */ >+ >+public class BidiComplexSomeMoreTest extends BidiComplexTestBase { >+ >+ final static BidiComplexEnvironment env1 = new BidiComplexEnvironment("en_US", false, BidiComplexEnvironment.ORIENT_LTR); >+ >+ final static BidiComplexEnvironment env2 = new BidiComplexEnvironment("he", false, BidiComplexEnvironment.ORIENT_LTR); >+ >+ final static BidiComplexFeatures features = new BidiComplexFeatures(null, 1, -1, -1, false, false); >+ >+ BidiComplexHelper helper; >+ >+ class Processor1 extends BidiComplexProcessor { >+ >+ public BidiComplexFeatures init(BidiComplexHelper caller, BidiComplexEnvironment env) { >+ return features; >+ } >+ >+ public int indexOfSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int fromIndex) { >+ return fromIndex; >+ } >+ >+ public int processSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int operLocation) { >+ int len = srcText.length(); >+ for (int i = len - 1; i >= 0; i--) { >+ caller.insertMark(i); >+ caller.insertMark(i); >+ } >+ return len; >+ } >+ } >+ >+ class Processor2 extends BidiComplexProcessor { >+ >+ public BidiComplexFeatures init(BidiComplexHelper caller, BidiComplexEnvironment env) { >+ return features; >+ } >+ } >+ >+ class Processor3 extends BidiComplexProcessor { >+ >+ public BidiComplexFeatures init(BidiComplexHelper caller, BidiComplexEnvironment env) { >+ return features; >+ } >+ >+ public int indexOfSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int fromIndex) { >+ return 0; >+ } >+ } >+ >+ public void testSomeMore() { >+ assertFalse(env1.isBidi()); >+ assertTrue(env2.isBidi()); >+ >+ IBidiComplexProcessor processor = new Processor1(); >+ helper = new BidiComplexHelper(processor, env1); >+ String full = toPseudo(helper.leanToFullText("abcd")); >+ assertEquals("@a@b@c@d", full); >+ >+ processor = new Processor2(); >+ helper = new BidiComplexHelper(processor, env1); >+ boolean catchFlag = false; >+ try { >+ full = toPseudo(helper.leanToFullText("abcd")); >+ } catch (IllegalStateException e) { >+ catchFlag = true; >+ } >+ assertTrue("Catch missing indexOfSpecial", catchFlag); >+ >+ processor = new Processor3(); >+ helper = new BidiComplexHelper(processor, env1); >+ catchFlag = false; >+ try { >+ full = toPseudo(helper.leanToFullText("abcd")); >+ } catch (IllegalStateException e) { >+ catchFlag = true; >+ } >+ assertTrue("Catch missing processSpecial", catchFlag); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,36 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import org.eclipse.equinox.bidi.*; >+import org.eclipse.equinox.bidi.custom.IBidiComplexProcessor; >+ >+public class BidiComplexTest implements IBidiComplexProcessor { >+ >+ static final BidiComplexFeatures FEATURES = new BidiComplexFeatures("-=.:", 0, -1, -1, false, false); >+ >+ public BidiComplexFeatures init(BidiComplexHelper caller, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+ public BidiComplexFeatures updateEnvironment(BidiComplexHelper caller, BidiComplexEnvironment env) { >+ return FEATURES; >+ } >+ >+ public int indexOfSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int fromIndex) { >+ throw new IllegalStateException(); >+ } >+ >+ public int processSpecial(BidiComplexHelper caller, int caseNumber, String srcText, int operLocation) { >+ throw new IllegalStateException(); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTestBase.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTestBase.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTestBase.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexTestBase.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,123 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import junit.framework.TestCase; >+ >+/** >+ * Base functionality for the processor tests. >+ */ >+public class BidiComplexTestBase extends TestCase { >+ >+ static final private char LRM = 0x200E; >+ >+ static final private char RLM = 0x200F; >+ >+ static final private char LRE = 0x202A; >+ >+ static final private char RLE = 0x202B; >+ >+ static final private char PDF = 0x202C; >+ >+ public static String toPseudo(String text) { >+ char[] chars = text.toCharArray(); >+ int len = chars.length; >+ >+ for (int i = 0; i < len; i++) { >+ char c = chars[i]; >+ if (c >= 'A' && c <= 'Z') >+ chars[i] = (char) (c + 'a' - 'A'); >+ else if (c >= 0x05D0 && c < 0x05EA) >+ chars[i] = (char) (c + 'A' - 0x05D0); >+ else if (c == 0x05EA) >+ chars[i] = '~'; >+ else if (c == 0x0644) >+ chars[i] = '#'; >+ else if (c >= 0x0665 && c <= 0x0669) >+ chars[i] = (char) (c + '5' - 0x0665); >+ else if (c == LRM) >+ chars[i] = '@'; >+ else if (c == RLM) >+ chars[i] = '&'; >+ else if (c == LRE) >+ chars[i] = '>'; >+ else if (c == RLE) >+ chars[i] = '<'; >+ else if (c == PDF) >+ chars[i] = '^'; >+ else if (c == '\n') >+ chars[i] = '|'; >+ else if (c == '\r') >+ chars[i] = '`'; >+ } >+ return new String(chars); >+ } >+ >+ public static String toUT16(String text) { >+ char[] chars = text.toCharArray(); >+ int len = chars.length; >+ >+ for (int i = 0; i < len; i++) { >+ char c = chars[i]; >+ if (c >= '5' && c <= '9') >+ chars[i] = (char) (0x0665 + c - '5'); >+ else if (c >= 'A' && c <= 'Z') >+ chars[i] = (char) (0x05D0 + c - 'A'); >+ else if (c == '~') >+ chars[i] = (char) (0x05EA); >+ else if (c == '#') >+ chars[i] = (char) (0x0644); >+ else if (c == '@') >+ chars[i] = LRM; >+ else if (c == '&') >+ chars[i] = RLM; >+ else if (c == '>') >+ chars[i] = LRE; >+ else if (c == '<') >+ chars[i] = RLE; >+ else if (c == '^') >+ chars[i] = PDF; >+ else if (c == '|') >+ chars[i] = '\n'; >+ else if (c == '`') >+ chars[i] = '\r'; >+ } >+ return new String(chars); >+ } >+ >+ static String array_display(int[] array) { >+ if (array == null) { >+ return "null"; >+ } >+ StringBuffer sb = new StringBuffer(50); >+ int len = array.length; >+ for (int i = 0; i < len; i++) { >+ sb.append(array[i]); >+ sb.append(' '); >+ } >+ return sb.toString(); >+ } >+ >+ static boolean arrays_equal(int[] one, int[] two) { >+ int len = one.length; >+ if (len != two.length) { >+ return false; >+ } >+ for (int i = 0; i < len; i++) { >+ if (one[i] != two[i]) { >+ return false; >+ } >+ } >+ return true; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexUtilTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/BidiComplexUtilTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/BidiComplexUtilTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/tests/BidiComplexUtilTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,138 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.internal.tests; >+ >+import java.util.Locale; >+import org.eclipse.equinox.bidi.BidiComplexUtil; >+import org.eclipse.equinox.bidi.IBidiComplexExpressionTypes; >+ >+/** >+ * Tests methods in BidiComplexUtil >+ */ >+ >+public class BidiComplexUtilTest extends BidiComplexTestBase { >+ >+ private static final String HEBREW = "iw"; >+ >+ private static final String HEBREW2 = "he"; >+ >+ private static final String ARABIC = "ar"; >+ >+ private static final String FARSI = "fa"; >+ >+ private static final String URDU = "ur"; >+ >+ private Locale locale; >+ >+ protected void setUp() throws Exception { >+ super.setUp(); >+ locale = Locale.getDefault(); >+ } >+ >+ protected void tearDown() { >+ Locale.setDefault(locale); >+ } >+ >+ private void doTest1(String data, String result) { >+ Locale.setDefault(Locale.ENGLISH); >+ String full = BidiComplexUtil.process(toUT16(data)); >+ assertEquals("Util #1 full EN - ", data, toPseudo(full)); >+ Locale.setDefault(new Locale(HEBREW2)); >+ full = BidiComplexUtil.process(toUT16(data)); >+ assertEquals("Util #1 full HE - ", result, toPseudo(full)); >+ Locale.setDefault(new Locale(ARABIC)); >+ full = BidiComplexUtil.process(toUT16(data)); >+ assertEquals("Util #1 full AR - ", result, toPseudo(full)); >+ Locale.setDefault(new Locale(FARSI)); >+ full = BidiComplexUtil.process(toUT16(data)); >+ assertEquals("Util #1 full FA - ", result, toPseudo(full)); >+ Locale.setDefault(new Locale(URDU)); >+ full = BidiComplexUtil.process(toUT16(data)); >+ assertEquals("Util #1 full UR - ", result, toPseudo(full)); >+ Locale.setDefault(new Locale(HEBREW)); >+ full = BidiComplexUtil.process(toUT16(data)); >+ String ful2 = BidiComplexUtil.process(toUT16(data), null); >+ assertEquals("Util #1 full - ", result, toPseudo(full)); >+ assertEquals("Util #1 ful2 - ", result, toPseudo(ful2)); >+ String lean = BidiComplexUtil.deprocess(full); >+ assertEquals("Util #1 lean - ", data, toPseudo(lean)); >+ } >+ >+ private void doTest2(String msg, String data, String result) { >+ doTest2(msg, data, result, data); >+ } >+ >+ private void doTest2(String msg, String data, String result, String resLean) { >+ String full = BidiComplexUtil.process(toUT16(data), "*"); >+ assertEquals(msg + "full", result, toPseudo(full)); >+ String lean = BidiComplexUtil.deprocess(full); >+ assertEquals(msg + "lean", resLean, toPseudo(lean)); >+ } >+ >+ private void doTest3(String msg, String data, String result) { >+ doTest3(msg, data, result, data); >+ } >+ >+ private void doTest3(String msg, String data, String result, String resLean) { >+ String full = BidiComplexUtil.processTyped(toUT16(data), IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ assertEquals(msg + "full", result, toPseudo(full)); >+ String lean = BidiComplexUtil.deprocess(full, IBidiComplexExpressionTypes.COMMA_DELIMITED); >+ assertEquals(msg + "lean", resLean, toPseudo(lean)); >+ } >+ >+ private void doTest4(String msg, String data, int[] offsets, int direction, boolean affix, String result) { >+ String txt = msg + "text=" + data + "\n offsets=" + array_display(offsets) + "\n direction=" + direction + "\n affix=" + affix; >+ String lean = toUT16(data); >+ String full = BidiComplexUtil.insertMarks(lean, offsets, direction, affix); >+ assertEquals(txt, result, toPseudo(full)); >+ } >+ >+ public void testBidiComplexUtil() { >+ >+ // Test process() and deprocess() with default delimiters >+ doTest1("ABC/DEF/G", ">@ABC@/DEF@/G@^"); >+ // Test process() and deprocess() with specified delimiters >+ doTest2("Util #2.1 - ", "", ""); >+ doTest2("Util #2.2 - ", ">@ABC@^", ">@ABC@^", "ABC"); >+ doTest2("Util #2.3 - ", "abc", "abc"); >+ doTest2("Util #2.4 - ", "!abc", ">@!abc@^"); >+ doTest2("Util #2.5 - ", "abc!", ">@abc!@^"); >+ doTest2("Util #2.6 - ", "ABC*DEF*G", ">@ABC@*DEF@*G@^"); >+ // Test process() and deprocess() with specified expression type >+ doTest3("Util #3.1 - ", "ABC,DEF,G", ">@ABC@,DEF@,G@^"); >+ doTest3("Util #3.2 - ", "", ""); >+ doTest3("Util #3.3 - ", ">@DEF@^", ">@DEF@^", "DEF"); >+ boolean catchFlag = false; >+ try { >+ BidiComplexUtil.deprocess(toUT16("ABC,DE"), "wrong_type"); >+ } catch (IllegalArgumentException e) { >+ catchFlag = true; >+ } >+ assertTrue("Catch invalid type on deprocess", catchFlag); >+ catchFlag = false; >+ try { >+ BidiComplexUtil.processTyped("abc", "wrong_type"); >+ } catch (IllegalArgumentException e) { >+ catchFlag = true; >+ } >+ assertTrue("Catch invalid type on process", catchFlag); >+ // Test insertMarks() >+ doTest4("Util #4.1 - ", "ABCDEFG", new int[] {3, 6}, 0, false, "ABC@DEF@G"); >+ doTest4("Util #4.2 - ", "ABCDEFG", new int[] {3, 6}, 0, true, ">@ABC@DEF@G@^"); >+ doTest4("Util #4.3 - ", "ABCDEFG", new int[] {3, 6}, 1, false, "ABC&DEF&G"); >+ doTest4("Util #4.4 - ", "ABCDEFG", new int[] {3, 6}, 1, true, "<&ABC&DEF&G&^"); >+ doTest4("Util #4.5 - ", "", new int[] {3, 6}, 0, false, ""); >+ doTest4("Util #4.6 - ", "", new int[] {3, 6}, 0, true, ""); >+ doTest4("Util #4.7 - ", "ABCDEFG", null, 1, false, "ABCDEFG"); >+ doTest4("Util #4.8 - ", "ABCDEFG", null, 1, true, "<&ABCDEFG&^"); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/tests/ComplExpMathTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/ComplExpMathTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/ComplExpMathTest.java >--- src/org/eclipse/equinox/bidi/internal/tests/ComplExpMathTest.java 17 Mar 2010 17:53:44 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,55 +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.internal.tests; >- >-import org.eclipse.equinox.bidi.complexp.IBiDiProcessor; >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.complexp.StringProcessor; >- >-/** >- * Tests RTL arithmetic >- */ >-public class ComplExpMathTest extends ComplExpTestBase { >- >- private IComplExpProcessor processor; >- >- protected void setUp() throws Exception { >- super.setUp(); >- processor = StringProcessor.getProcessor(IBiDiProcessor.RTL_ARITHMETIC); >- } >- >- private void verifyOneLine(String msg, String data, String resLTR, >- String resRTL) { >- String lean = toUT16(data); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- String fullLTR = processor.leanToFullText(lean); >- assertEquals(msg + " LTR - ", resLTR, toPseudo(fullLTR)); >- >- processor.assumeOrientation(IComplExpProcessor.ORIENT_RTL); >- String fullRTL = processor.leanToFullText(lean); >- assertEquals(msg + " RTL - ", resRTL, toPseudo(fullRTL)); >- } >- >- public void testRTLarithmetic() { >- verifyOneLine("Math #0", "", "", ""); >- verifyOneLine("Math #1", "1+abc", "<&1+abc&^", "1+abc"); >- verifyOneLine("Math #2", "2+abc-def", "<&2+abc&-def&^", "2+abc&-def"); >- verifyOneLine("Math #3", "a+3*bc/def", "<&a&+3*bc&/def&^", >- "a&+3*bc&/def"); >- verifyOneLine("Math #4", "4+abc/def", "<&4+abc&/def&^", "4+abc&/def"); >- verifyOneLine("Math #5", "13ABC", "<&13ABC&^", "13ABC"); >- verifyOneLine("Math #6", "14ABC-DE", "<&14ABC-DE&^", "14ABC-DE"); >- verifyOneLine("Math #7", "15ABC+DE", "<&15ABC+DE&^", "15ABC+DE"); >- verifyOneLine("Math #8", "16ABC*DE", "<&16ABC*DE&^", "16ABC*DE"); >- verifyOneLine("Math #9", "17ABC/DE", "<&17ABC/DE&^", "17ABC/DE"); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/tests/ComplExpTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/ComplExpTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/ComplExpTest.java >--- src/org/eclipse/equinox/bidi/internal/tests/ComplExpTest.java 17 Mar 2010 17:53:43 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,136 +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.internal.tests; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >- >-public class ComplExpTest implements IComplExpProcessor { >- >- private static final int[] EMPTY_INT_ARRAY = new int[0]; >- private static final int[][] ALL_LTR = new int[][] { >- { DIRECTION_LTR, DIRECTION_LTR }, { DIRECTION_LTR, DIRECTION_LTR } }; >- >- public ComplExpTest() { >- return; >- } >- >- public void setOperators(String operators) { >- // empty >- } >- >- public String getOperators() { >- return ""; >- } >- >- public void selectBidiScript(boolean arabic, boolean hebrew) { >- // empty >- } >- >- public boolean handlesArabicScript() { >- return false; >- } >- >- public boolean handlesHebrewScript() { >- return false; >- } >- >- public String leanToFullText(String text) { >- return text; >- } >- >- public String leanToFullText(String text, int initState) { >- return text; >- } >- >- public int[] leanBidiCharOffsets(String text) { >- return EMPTY_INT_ARRAY; >- } >- >- public int[] leanBidiCharOffsets(String text, int initState) { >- return EMPTY_INT_ARRAY; >- } >- >- public int[] leanBidiCharOffsets() { >- return EMPTY_INT_ARRAY; >- } >- >- public int[] fullBidiCharOffsets() { >- return EMPTY_INT_ARRAY; >- } >- >- public String fullToLeanText(String text) { >- return text; >- } >- >- public String fullToLeanText(String text, int initState) { >- return text; >- } >- >- public int getFinalState() { >- return STATE_NOTHING_GOING; >- } >- >- public int leanToFullPos(int pos) { >- return pos; >- } >- >- public int fullToLeanPos(int pos) { >- return pos; >- } >- >- public void assumeMirrored(boolean mirrored) { >- // empty >- } >- >- public boolean isMirrored() { >- return false; >- } >- >- public void assumeOrientation(int orientation) { >- // empty >- } >- >- public int recallOrientation() { >- return ORIENT_LTR; >- } >- >- public void setArabicDirection(int not_mirrored, int mirrored) { >- // empty >- } >- >- public void setArabicDirection(int direction) { >- // empty >- } >- >- public void setHebrewDirection(int not_mirrored, int mirrored) { >- // empty >- } >- >- public void setHebrewDirection(int direction) { >- // empty >- } >- >- public void setDirection(int not_mirrored, int mirrored) { >- // empty >- } >- >- public void setDirection(int direction) { >- // empty >- } >- >- public int[][] getDirection() { >- return ALL_LTR; >- } >- >- public int getCurDirection() { >- return DIRECTION_LTR; >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/tests/ComplExpTestBase.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/ComplExpTestBase.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/ComplExpTestBase.java >--- src/org/eclipse/equinox/bidi/internal/tests/ComplExpTestBase.java 17 Mar 2010 17:53:44 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,156 +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.internal.tests; >- >-import junit.framework.TestCase; >- >-/** >- * Base functionality for the processor tests. >- */ >-public class ComplExpTestBase extends TestCase { >- >- static final private char LRM = 0x200E; >- static final private char RLM = 0x200F; >- static final private char LRE = 0x202A; >- static final private char RLE = 0x202B; >- static final private char PDF = 0x202C; >- >- protected String toPseudo(String text) { >- char[] chars = text.toCharArray(); >- int len = chars.length; >- >- for (int i = 0; i < len; i++) { >- char c = chars[i]; >- if (c >= 'A' && c <= 'Z') >- chars[i] = (char) (c + 'a' - 'A'); >- else if (c >= 0x05D0 && c < 0x05EA) >- chars[i] = (char) (c + 'A' - 0x05D0); >- else if (c == 0x05EA) >- chars[i] = '~'; >- else if (c == 0x0644) >- chars[i] = '#'; >- else if (c >= 0x0665 && c <= 0x0669) >- chars[i] = (char) (c + '5' - 0x0665); >- else if (c == LRM) >- chars[i] = '@'; >- else if (c == RLM) >- chars[i] = '&'; >- else if (c == LRE) >- chars[i] = '>'; >- else if (c == RLE) >- chars[i] = '<'; >- else if (c == PDF) >- chars[i] = '^'; >- else if (c == '\n') >- chars[i] = '|'; >- else if (c == '\r') >- chars[i] = '`'; >- } >- return new String(chars); >- } >- >- protected String toUT16(String text) { >- char[] chars = text.toCharArray(); >- int len = chars.length; >- >- for (int i = 0; i < len; i++) { >- char c = chars[i]; >- if (c >= '5' && c <= '9') >- chars[i] = (char) (0x0665 + c - '5'); >- else if (c >= 'A' && c <= 'Z') >- chars[i] = (char) (0x05D0 + c - 'A'); >- else if (c == '~') >- chars[i] = (char) (0x05EA); >- else if (c == '#') >- chars[i] = (char) (0x0644); >- else if (c == '@') >- chars[i] = LRM; >- else if (c == '&') >- chars[i] = RLM; >- else if (c == '>') >- chars[i] = LRE; >- else if (c == '<') >- chars[i] = RLE; >- else if (c == '^') >- chars[i] = PDF; >- else if (c == '|') >- chars[i] = '\n'; >- else if (c == '`') >- chars[i] = '\r'; >- } >- return new String(chars); >- } >- >- static String array_display(int[] array) { >- if (array == null) { >- return "null"; >- } >- StringBuffer sb = new StringBuffer(50); >- int len = array.length; >- for (int i = 0; i < len; i++) { >- sb.append(array[i]); >- sb.append(' '); >- } >- return sb.toString(); >- } >- >- static boolean arrays_equal(int[] one, int[] two) { >- int len = one.length; >- if (len != two.length) { >- return false; >- } >- for (int i = 0; i < len; i++) { >- if (one[i] != two[i]) { >- return false; >- } >- } >- return true; >- } >- >- static boolean arrays2_equal(int[][] one, int[][] two) { >- int dim1, dim2; >- dim1 = one.length; >- if (dim1 != two.length) { >- return false; >- } >- for (int i = 0; i < dim1; i++) { >- dim2 = one[i].length; >- if (dim2 != two[i].length) { >- return false; >- } >- for (int j = 0; j < dim2; j++) { >- if (one[i][j] != two[i][j]) { >- return false; >- } >- } >- } >- return true; >- } >- >- static String array2_display(int[][] array) { >- int dim1, dim2; >- if (array == null) { >- return "null"; >- } >- StringBuffer sb = new StringBuffer(50); >- dim1 = array.length; >- for (int i = 0; i < dim1; i++) { >- dim2 = array[i].length; >- for (int j = 0; j < dim2; j++) { >- sb.append(array[i][j]); >- sb.append(' '); >- } >- } >- return sb.toString(); >- } >- >-} >Index: src/org/eclipse/equinox/bidi/internal/tests/ComplExpUtilTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/ComplExpUtilTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/ComplExpUtilTest.java >--- src/org/eclipse/equinox/bidi/internal/tests/ComplExpUtilTest.java 17 Mar 2010 17:53:44 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,131 +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.internal.tests; >- >-import org.eclipse.equinox.bidi.complexp.*; >-import java.util.Locale; >- >-/** >- * Tests methods in ComplExpUtil >- */ >- >-public class ComplExpUtilTest extends ComplExpTestBase { >- >- private static final String HEBREW = "iw"; >- private static final String HEBREW2 = "he"; >- private static final String ARABIC = "ar"; >- private static final String FARSI = "fa"; >- private static final String URDU = "ur"; >- private Locale locale; >- >- protected void setUp() throws Exception { >- super.setUp(); >- locale = Locale.getDefault(); >- } >- >- protected void tearDown() { >- Locale.setDefault(locale); >- } >- >- private void doTest1(String data, String result) { >- Locale.setDefault(Locale.ENGLISH); >- String full = ComplExpUtil.process(toUT16(data)); >- assertEquals("Util #1 full EN - ", data, toPseudo(full)); >- Locale.setDefault(new Locale(HEBREW2)); >- full = ComplExpUtil.process(toUT16(data)); >- assertEquals("Util #1 full HE - ", result, toPseudo(full)); >- Locale.setDefault(new Locale(ARABIC)); >- full = ComplExpUtil.process(toUT16(data)); >- assertEquals("Util #1 full AR - ", result, toPseudo(full)); >- Locale.setDefault(new Locale(FARSI)); >- full = ComplExpUtil.process(toUT16(data)); >- assertEquals("Util #1 full FA - ", result, toPseudo(full)); >- Locale.setDefault(new Locale(URDU)); >- full = ComplExpUtil.process(toUT16(data)); >- assertEquals("Util #1 full UR - ", result, toPseudo(full)); >- Locale.setDefault(new Locale(HEBREW)); >- full = ComplExpUtil.process(toUT16(data)); >- String ful2 = ComplExpUtil.process(toUT16(data), null); >- assertEquals("Util #1 full - ", result, toPseudo(full)); >- assertEquals("Util #1 ful2 - ", result, toPseudo(ful2)); >- String lean = ComplExpUtil.deprocess(full); >- assertEquals("Util #1 lean - ", data, toPseudo(lean)); >- } >- >- private void doTest2(String msg, String data, String result) { >- doTest2(msg, data, result, data); >- } >- >- private void doTest2(String msg, String data, String result, String resLean) { >- String full = ComplExpUtil.process(toUT16(data), "*"); >- assertEquals(msg + "full", result, toPseudo(full)); >- String lean = ComplExpUtil.deprocess(full); >- assertEquals(msg + "lean", resLean, toPseudo(lean)); >- } >- >- private void doTest3(String msg, String data, String result) { >- doTest3(msg, data, result, data); >- } >- >- private void doTest3(String msg, String data, String result, String resLean) { >- String full = ComplExpUtil.processTyped(toUT16(data), >- IBiDiProcessor.COMMA_DELIMITED); >- assertEquals(msg + "full", result, toPseudo(full)); >- String lean = ComplExpUtil.deprocess(full, >- IBiDiProcessor.COMMA_DELIMITED); >- assertEquals(msg + "lean", resLean, toPseudo(lean)); >- } >- >- private void doTest4(String msg, String data, int[] offsets, int direction, >- boolean affix, String result) { >- String txt = msg + "text=" + data + "\n offsets=" >- + array_display(offsets) + "\n direction=" + direction >- + "\n affix=" + affix; >- String lean = toUT16(data); >- String full = ComplExpUtil.insertMarks(lean, offsets, direction, affix); >- assertEquals(txt, result, toPseudo(full)); >- } >- >- public void testComplExpUtil() { >- >- // Test process() and deprocess() with default delimiters >- doTest1("ABC/DEF/G", ">@ABC@/DEF@/G@^"); >- // Test process() and deprocess() with specified delimiters >- doTest2("Util #2.1 - ", "", ""); >- doTest2("Util #2.2 - ", ">@ABC@^", ">@ABC@^", "ABC"); >- doTest2("Util #2.3 - ", "abc", "abc"); >- doTest2("Util #2.4 - ", "!abc", ">@!abc@^"); >- doTest2("Util #2.5 - ", "abc!", ">@abc!@^"); >- doTest2("Util #2.6 - ", "ABC*DEF*G", ">@ABC@*DEF@*G@^"); >- // Test process() and deprocess() with specified expression type >- doTest3("Util #3.1 - ", "ABC,DEF,G", ">@ABC@,DEF@,G@^"); >- doTest3("Util #3.2 - ", "", ""); >- doTest3("Util #3.3 - ", ">@DEF@^", ">@DEF@^", "DEF"); >- String str = ComplExpUtil.deprocess(toUT16("ABC,DE"), "wrong_type"); >- assertEquals("deprocess(9999)", "ABC,DE", toPseudo(str)); >- str = ComplExpUtil.process("abc", "wrong_type"); >- assertEquals("invalid type", "abc", toPseudo(str)); >- // Test insertMarks() >- doTest4("Util #4.1 - ", "ABCDEFG", new int[] { 3, 6 }, 0, false, >- "ABC@DEF@G"); >- doTest4("Util #4.2 - ", "ABCDEFG", new int[] { 3, 6 }, 0, true, >- ">@ABC@DEF@G@^"); >- doTest4("Util #4.3 - ", "ABCDEFG", new int[] { 3, 6 }, 1, false, >- "ABC&DEF&G"); >- doTest4("Util #4.4 - ", "ABCDEFG", new int[] { 3, 6 }, 1, true, >- "<&ABC&DEF&G&^"); >- doTest4("Util #4.5 - ", "", new int[] { 3, 6 }, 0, false, ""); >- doTest4("Util #4.6 - ", "", new int[] { 3, 6 }, 0, true, ""); >- doTest4("Util #4.7 - ", "ABCDEFG", null, 1, false, "ABCDEFG"); >- doTest4("Util #4.8 - ", "ABCDEFG", null, 1, true, "<&ABCDEFG&^"); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/tests/ExtensibilityTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/ExtensibilityTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/ExtensibilityTest.java >--- src/org/eclipse/equinox/bidi/internal/tests/ExtensibilityTest.java 17 Mar 2010 17:53:44 -0000 1.5 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,55 +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.internal.tests; >- >-import junit.framework.TestCase; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.complexp.StringProcessor; >- >-/** >- * Tests contribution of BiDi processors. >- */ >-public class ExtensibilityTest extends TestCase { >- >- public void testBaseContributions() { >- String[] types = StringProcessor.getKnownTypes(); >- assertNotNull(types); >- assertTrue(types.length > 0); >- >- // check one of the types that we know should be there >- assertTrue(isTypePresent(types, "regex")); >- >- IComplExpProcessor processor = StringProcessor.getProcessor("regex"); >- assertNotNull(processor); >- } >- >- public void testOtherContributions() { >- String[] types = StringProcessor.getKnownTypes(); >- assertNotNull(types); >- assertTrue(types.length > 0); >- >- // check the type added by the test bundle >- assertTrue(isTypePresent(types, "test")); >- >- IComplExpProcessor processor = StringProcessor.getProcessor("test"); >- assertNotNull(processor); >- } >- >- private boolean isTypePresent(String[] types, String type) { >- for (int i = 0; i < types.length; i++) { >- if (type.equalsIgnoreCase(types[i])) >- return true; >- } >- return false; >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/tests/ExtensionsTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/ExtensionsTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/ExtensionsTest.java >--- src/org/eclipse/equinox/bidi/internal/tests/ExtensionsTest.java 17 Mar 2010 17:53:44 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,210 +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.internal.tests; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.complexp.StringProcessor; >-import org.eclipse.equinox.bidi.complexp.IBiDiProcessor; >- >-/** >- * Tests all plug-in extensions >- */ >- >-public class ExtensionsTest extends ComplExpTestBase { >- >- static int state = IComplExpProcessor.STATE_NOTHING_GOING; >- >- private void doTest1(IComplExpProcessor complexp, String label, >- String data, String result) { >- String full; >- full = complexp.leanToFullText(toUT16(data), state); >- state = complexp.getFinalState(); >- assertEquals(label + " data = " + data, result, toPseudo(full)); >- } >- >- private void doTest2(IComplExpProcessor complexp, String label, >- String data, String result) { >- String full; >- full = complexp.leanToFullText(data, state); >- state = complexp.getFinalState(); >- assertEquals(label + " data = " + data, result, toPseudo(full)); >- } >- >- public void testExtensions() { >- >- IComplExpProcessor ce; >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "Comma #1", "ab,cd, AB, CD, EFG", "ab,cd, AB@, CD@, EFG"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.EMAIL); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "Email #1", "abc.DEF:GHI", "abc.DEF@:GHI"); >- doTest1(ce, "Email #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI @\"A.B\"@:JK "); >- doTest1(ce, "Email #3", "DEF,GHI (A,B);JK ", "DEF@,GHI @(A,B)@;JK "); >- doTest1(ce, "Email #4", "DEF.GHI (A.B :JK ", "DEF@.GHI @(A.B :JK "); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.FILE); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "File #1", "c:\\A\\B\\FILE.EXT", "c:\\A@\\B@\\FILE@.EXT"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.JAVA); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "Java #1", "A = B + C;", "A@ = B@ + C;"); >- doTest1(ce, "Java #2", "A = B + C;", "A@ = B@ + C;"); >- doTest1(ce, "Java #3", "A = \"B+C\"+D;", "A@ = \"B+C\"@+D;"); >- doTest1(ce, "Java #4", "A = \"B+C+D;", "A@ = \"B+C+D;"); >- doTest1(ce, "Java #5", "A = \"B\\\"C\"+D;", "A@ = \"B\\\"C\"@+D;"); >- doTest1(ce, "Java #6", "A = /*B+C*/ D;", "A@ = /*B+C*/@ D;"); >- doTest1(ce, "Java #7", "A = /*B+C* D;", "A@ = /*B+C* D;"); >- doTest1(ce, "Java #8", "X+Y+Z */ B; ", "X+Y+Z */@ B; "); >- doTest1(ce, "Java #9", "A = //B+C* D;", "A@ = //B+C* D;"); >- doTest1(ce, "Java #10", "A = //B+C`|D+E;", "A@ = //B+C`|D@+E;"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.PROPERTY); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "Property #0", "NAME,VAL1,VAL2", "NAME,VAL1,VAL2"); >- doTest1(ce, "Property #1", "NAME=VAL1,VAL2", "NAME@=VAL1,VAL2"); >- doTest1(ce, "Property #2", "NAME=VAL1,VAL2=VAL3", >- "NAME@=VAL1,VAL2=VAL3"); >- >- String data; >- ce = StringProcessor.getProcessor(IBiDiProcessor.REGEXP); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- data = toUT16("ABC(?") + "#" + toUT16("DEF)GHI"); >- doTest2(ce, "Regex #0.0", data, "A@B@C@(?#DEF)@G@H@I"); >- data = toUT16("ABC(?") + "#" + toUT16("DEF"); >- doTest2(ce, "Regex #0.1", data, "A@B@C@(?#DEF"); >- doTest1(ce, "Regex #0.2", "GHI)JKL", "GHI)@J@K@L"); >- data = toUT16("ABC(?") + "<" + toUT16("DEF") + ">" + toUT16("GHI"); >- doTest2(ce, "Regex #1", data, "A@B@C@(?<DEF>@G@H@I"); >- doTest1(ce, "Regex #2.0", "ABC(?'DEF'GHI", "A@B@C@(?'DEF'@G@H@I"); >- doTest1(ce, "Regex #2.1", "ABC(?'DEFGHI", "A@B@C@(?'DEFGHI"); >- data = toUT16("ABC(?(") + "<" + toUT16("DEF") + ">" + toUT16(")GHI"); >- doTest2(ce, "Regex #3", data, "A@B@C@(?(<DEF>)@G@H@I"); >- doTest1(ce, "Regex #4", "ABC(?('DEF')GHI", "A@B@C@(?('DEF')@G@H@I"); >- doTest1(ce, "Regex #5", "ABC(?(DEF)GHI", "A@B@C@(?(DEF)@G@H@I"); >- data = toUT16("ABC(?") + "&" + toUT16("DEF)GHI"); >- doTest2(ce, "Regex #6", data, "A@B@C@(?&DEF)@G@H@I"); >- data = toUT16("ABC(?") + "P<" + toUT16("DEF") + ">" + toUT16("GHI"); >- doTest2(ce, "Regex #7", data, "A@B@C(?p<DEF>@G@H@I"); >- data = toUT16("ABC\\k") + "<" + toUT16("DEF") + ">" + toUT16("GHI"); >- doTest2(ce, "Regex #8", data, "A@B@C\\k<DEF>@G@H@I"); >- doTest1(ce, "Regex #9", "ABC\\k'DEF'GHI", "A@B@C\\k'DEF'@G@H@I"); >- doTest1(ce, "Regex #10", "ABC\\k{DEF}GHI", "A@B@C\\k{DEF}@G@H@I"); >- data = toUT16("ABC(?") + "P=" + toUT16("DEF)GHI"); >- doTest2(ce, "Regex #11", data, "A@B@C(?p=DEF)@G@H@I"); >- doTest1(ce, "Regex #12", "ABC\\g{DEF}GHI", "A@B@C\\g{DEF}@G@H@I"); >- data = toUT16("ABC\\g") + "<" + toUT16("DEF") + ">" + toUT16("GHI"); >- doTest2(ce, "Regex #13", data, "A@B@C\\g<DEF>@G@H@I"); >- doTest1(ce, "Regex #14", "ABC\\g'DEF'GHI", "A@B@C\\g'DEF'@G@H@I"); >- data = toUT16("ABC(?(") + "R&" + toUT16("DEF)GHI"); >- doTest2(ce, "Regex #15", data, "A@B@C(?(r&DEF)@G@H@I"); >- data = toUT16("ABC") + "\\Q" + toUT16("DEF") + "\\E" + toUT16("GHI"); >- doTest2(ce, "Regex #16.0", data, "A@B@C\\qDEF\\eG@H@I"); >- data = toUT16("ABC") + "\\Q" + toUT16("DEF"); >- doTest2(ce, "Regex #16.1", data, "A@B@C\\qDEF"); >- data = toUT16("GHI") + "\\E" + toUT16("JKL"); >- doTest2(ce, "Regex #16.2", data, "GHI\\eJ@K@L"); >- doTest1(ce, "Regex #17.0", "abc[d-h]ijk", "abc[d-h]ijk"); >- doTest1(ce, "Regex #17.1", "aBc[d-H]iJk", "aBc[d-H]iJk"); >- doTest1(ce, "Regex #17.2", "aB*[!-H]iJ2", "aB*[!-@H]iJ@2"); >- doTest1(ce, "Regex #17.3", "aB*[1-2]J3", "aB*[@1-2]J@3"); >- doTest1(ce, "Regex #17.4", "aB*[5-6]J3", "aB*[@5-@6]@J@3"); >- doTest1(ce, "Regex #17.5", "a*[5-6]J3", "a*[5-@6]@J@3"); >- doTest1(ce, "Regex #17.6", "aB*123", "aB*@123"); >- doTest1(ce, "Regex #17.7", "aB*567", "aB*@567"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.SQL); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "SQL #0", "abc GHI", "abc GHI"); >- doTest1(ce, "SQL #1", "abc DEF GHI", "abc DEF@ GHI"); >- doTest1(ce, "SQL #2", "ABC, DEF, GHI", "ABC@, DEF@, GHI"); >- doTest1(ce, "SQL #3", "ABC'DEF GHI' JKL,MN", "ABC@'DEF GHI'@ JKL@,MN"); >- doTest1(ce, "SQL #4.0", "ABC'DEF GHI JKL", "ABC@'DEF GHI JKL"); >- doTest1(ce, "SQL #4.1", "MNO PQ' RS,TUV", "MNO PQ'@ RS@,TUV"); >- doTest1(ce, "SQL #5", "ABC\"DEF GHI\" JKL,MN", >- "ABC@\"DEF GHI\"@ JKL@,MN"); >- doTest1(ce, "SQL #6", "ABC\"DEF GHI JKL", "ABC@\"DEF GHI JKL"); >- doTest1(ce, "SQL #7", "ABC/*DEF GHI*/ JKL,MN", >- "ABC@/*DEF GHI@*/ JKL@,MN"); >- doTest1(ce, "SQL #8.0", "ABC/*DEF GHI JKL", "ABC@/*DEF GHI JKL"); >- doTest1(ce, "SQL #8.1", "MNO PQ*/RS,TUV", "MNO PQ@*/RS@,TUV"); >- doTest1(ce, "SQL #9", "ABC--DEF GHI JKL", "ABC@--DEF GHI JKL"); >- doTest1(ce, "SQL #10", "ABC--DEF--GHI,JKL", "ABC@--DEF--GHI,JKL"); >- doTest1(ce, "SQL #11", "ABC'DEF '' G I' JKL,MN", >- "ABC@'DEF '' G I'@ JKL@,MN"); >- doTest1(ce, "SQL #12", "ABC\"DEF \"\" G I\" JKL,MN", >- "ABC@\"DEF \"\" G I\"@ JKL@,MN"); >- doTest1(ce, "SQL #13", "ABC--DEF GHI`|JKL MN", "ABC@--DEF GHI`|JKL@ MN"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.SYSTEM_USER); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "System #1", "HOST(JACK)", "HOST@(JACK)"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.UNDERSCORE); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "Underscore #1", "A_B_C_d_e_F_G", "A@_B@_C_d_e_F@_G"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.URL); >- assertNotNull(ce); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- doTest1(ce, "URL #1", "WWW.DOMAIN.COM/DIR1/DIR2/dir3/DIR4", >- "WWW@.DOMAIN@.COM@/DIR1@/DIR2/dir3/DIR4"); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.XPATH); >- assertNotNull(ce); >- ce.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- doTest1(ce, "Xpath #1", "abc(DEF)GHI", "abc(DEF@)GHI"); >- doTest1(ce, "Xpath #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI@ \"A.B\"@:JK "); >- doTest1(ce, "Xpath #3", "DEF!GHI 'A!B'=JK ", "DEF@!GHI@ 'A!B'@=JK "); >- doTest1(ce, "Xpath #4", "DEF.GHI 'A.B :JK ", "DEF@.GHI@ 'A.B :JK "); >- >- ce = StringProcessor.getProcessor(IBiDiProcessor.EMAIL); >- state = IComplExpProcessor.STATE_NOTHING_GOING; >- String operators = ce.getOperators(); >- assertEquals("<>.:,;@", operators); >- ce.setOperators("+-*/"); >- doTest1(ce, "DelimsEsc #1", "abc+DEF-GHI", "abc+DEF@-GHI"); >- doTest1(ce, "DelimsEsc #2", "DEF-GHI (A*B)/JK ", "DEF@-GHI @(A*B)@/JK "); >- doTest1(ce, "DelimsEsc #3", "DEF-GHI (A*B)/JK ", "DEF@-GHI @(A*B)@/JK "); >- doTest1(ce, "DelimsEsc #4", "DEF-GHI (A*B\\)*C) /JK ", >- "DEF@-GHI @(A*B\\)*C) @/JK "); >- doTest1(ce, "DelimsEsc #5", "DEF-GHI (A\\\\\\)*C) /JK ", >- "DEF@-GHI @(A\\\\\\)*C) @/JK "); >- doTest1(ce, "DelimsEsc #6", "DEF-GHI (A\\\\)*C /JK ", >- "DEF@-GHI @(A\\\\)@*C @/JK "); >- doTest1(ce, "DelimsEsc #7", "DEF-GHI (A\\)*C /JK ", >- "DEF@-GHI @(A\\)*C /JK "); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/tests/FullToLeanTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/FullToLeanTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/FullToLeanTest.java >--- src/org/eclipse/equinox/bidi/internal/tests/FullToLeanTest.java 17 Mar 2010 17:53:44 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,284 +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.internal.tests; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.complexp.StringProcessor; >-import org.eclipse.equinox.bidi.complexp.IBiDiProcessor; >- >-/** >- * Tests fullToLean method >- */ >- >-public class FullToLeanTest extends ComplExpTestBase { >- >- private IComplExpProcessor processor; >- >- protected void setUp() throws Exception { >- super.setUp(); >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- } >- >- static int[] getpos(IComplExpProcessor complexp, boolean leanToFull) { >- int[] pos = new int[5]; >- >- if (leanToFull) { >- pos[0] = complexp.leanToFullPos(0); >- pos[1] = complexp.leanToFullPos(4); >- pos[2] = complexp.leanToFullPos(7); >- pos[3] = complexp.leanToFullPos(10); >- pos[4] = complexp.leanToFullPos(30); >- } else { >- pos[0] = complexp.fullToLeanPos(0); >- pos[1] = complexp.fullToLeanPos(4); >- pos[2] = complexp.fullToLeanPos(7); >- pos[3] = complexp.fullToLeanPos(10); >- pos[4] = complexp.fullToLeanPos(30); >- } >- return pos; >- } >- >- private void doTest1(String msg, String data, String leanLTR, >- String fullLTR, int[] l2fPosLTR, int[] f2lPosLTR, String leanRTL, >- String fullRTL, int[] l2fPosRTL, int[] f2lPosRTL) { >- String text, full, lean, label; >- int[] pos; >- >- text = toUT16(data); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- lean = processor.fullToLeanText(text); >- assertEquals(msg + "LTR lean", leanLTR, toPseudo(lean)); >- full = processor.leanToFullText(lean); >- assertEquals(msg + "LTR full", fullLTR, toPseudo(full)); >- pos = getpos(processor, true); >- label = msg + "leanToFullPos() LTR, expected=" >- + array_display(l2fPosLTR) + " result=" + array_display(pos); >- assertTrue(label, arrays_equal(l2fPosLTR, pos)); >- pos = getpos(processor, false); >- label = msg + "fullToLeanPos() LTR, expected=" >- + array_display(f2lPosLTR) + " result=" + array_display(pos); >- assertTrue(label, arrays_equal(f2lPosLTR, pos)); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_RTL); >- lean = processor.fullToLeanText(text); >- assertEquals(msg + "RTL lean", leanRTL, toPseudo(lean)); >- full = processor.leanToFullText(lean); >- assertEquals(msg + "RTL full", fullRTL, toPseudo(full)); >- pos = getpos(processor, true); >- label = msg + "leanToFullPos() RTL, expected=" >- + array_display(l2fPosRTL) + " result=" + array_display(pos); >- assertTrue(label, arrays_equal(l2fPosRTL, pos)); >- pos = getpos(processor, false); >- label = msg + "fullToLeanPos() RTL, expected=" >- + array_display(f2lPosRTL) + " result=" + array_display(pos); >- assertTrue(label, arrays_equal(f2lPosRTL, pos)); >- } >- >- private void doTest2(String msg) { >- String text, data, full, lean, model; >- int state, state2, state3; >- >- processor = StringProcessor.getProcessor(IBiDiProcessor.SQL); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- data = "update \"AB_CDE\" set \"COL1\"@='01', \"COL2\"@='02' /* GH IJK"; >- text = toUT16(data); >- lean = processor.fullToLeanText(text); >- state = processor.getFinalState(); >- model = "update \"AB_CDE\" set \"COL1\"='01', \"COL2\"='02' /* GH IJK"; >- assertEquals(msg + "LTR lean", model, toPseudo(lean)); >- full = processor.leanToFullText(lean); >- assertEquals(msg + "LTR full", data, toPseudo(full)); >- assertEquals(msg + "state from leanToFullText", processor >- .getFinalState(), state); >- data = "THIS IS A COMMENT LINE"; >- text = toUT16(data); >- lean = processor.fullToLeanText(text, state); >- state2 = processor.getFinalState(); >- model = "THIS IS A COMMENT LINE"; >- assertEquals(msg + "LTR lean2", model, toPseudo(lean)); >- full = processor.leanToFullText(lean, state); >- assertEquals(msg + "LTR full2", data, toPseudo(full)); >- assertEquals(msg + "state from leanToFullText2", processor >- .getFinalState(), state2); >- data = "SOME MORE */ where \"COL3\"@=123"; >- text = toUT16(data); >- lean = processor.fullToLeanText(text, state2); >- state3 = processor.getFinalState(); >- model = "SOME MORE */ where \"COL3\"=123"; >- assertEquals(msg + "LTR lean3", model, toPseudo(lean)); >- full = processor.leanToFullText(lean, state2); >- assertEquals(msg + "LTR full3", data, toPseudo(full)); >- assertEquals(msg + "state from leanToFullText3", processor >- .getFinalState(), state3); >- } >- >- public void testFullToLean() { >- >- doTest1("testFullToLean #1 - ", "", "", "", >- new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 0, 0, 0, 0 }, "", >- "", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 0, 0, 0, 0 }); >- doTest1("testFullToLean #01 - ", "1.abc", "1.abc", "1.abc", new int[] { >- 0, 4, 7, 10, 30 }, new int[] { 0, 4, 5, 5, 5 }, "1.abc", >- ">@1.abc@^", new int[] { 2, 6, 9, 12, 32 }, new int[] { 0, 2, >- 5, 5, 5 }); >- doTest1("testFullToLean #02 - ", "2.abc,def", "2.abc,def", "2.abc,def", >- new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, 7, 9, 9 }, >- "2.abc,def", ">@2.abc,def@^", new int[] { 2, 6, 9, 12, 32 }, >- new int[] { 0, 2, 5, 8, 9 }); >- doTest1("testFullToLean #03 - ", "@a.3.bc,def", "a.3.bc,def", >- "a.3.bc,def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 10, 10 }, "a.3.bc,def", ">@a.3.bc,def@^", new int[] { >- 2, 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 10 }); >- doTest1("testFullToLean #04 - ", "@@a.4.bc,def", "a.4.bc,def", >- "a.4.bc,def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 10, 10 }, "a.4.bc,def", ">@a.4.bc,def@^", new int[] { >- 2, 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 10 }); >- doTest1("testFullToLean #05 - ", "@5.abc,def", "5.abc,def", >- "5.abc,def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 9, 9 }, "5.abc,def", ">@5.abc,def@^", new int[] { 2, >- 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 9 }); >- doTest1("testFullToLean #06 - ", "@@6.abc,def", "6.abc,def", >- "6.abc,def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 9, 9 }, "6.abc,def", ">@6.abc,def@^", new int[] { 2, >- 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 9 }); >- doTest1("testFullToLean #07 - ", "7abc,@def", "7abc,@def", "7abc,@def", >- new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, 7, 9, 9 }, >- "7abc,@def", ">@7abc,@def@^", new int[] { 2, 6, 9, 12, 32 }, >- new int[] { 0, 2, 5, 8, 9 }); >- doTest1("testFullToLean #08 - ", "8abc,@@def", "8abc,@def", >- "8abc,@def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 9, 9 }, "8abc,@def", ">@8abc,@def@^", new int[] { 2, >- 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 9 }); >- doTest1("testFullToLean #09 - ", "9abc,def@", "9abc,def", "9abc,def", >- new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, 7, 8, 8 }, >- "9abc,def", ">@9abc,def@^", new int[] { 2, 6, 9, 12, 32 }, >- new int[] { 0, 2, 5, 8, 8 }); >- doTest1("testFullToLean #10 - ", "10abc,def@@", "10abc,def", >- "10abc,def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 9, 9 }, "10abc,def", ">@10abc,def@^", new int[] { 2, >- 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 9 }); >- doTest1("testFullToLean #11 - ", "@a.11.bc,@def@", "a.11.bc,@def", >- "a.11.bc,@def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, >- 4, 7, 10, 12 }, "a.11.bc,@def", ">@a.11.bc,@def@^", >- new int[] { 2, 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 12 }); >- doTest1("testFullToLean #12 - ", "@@a.12.bc,@@def@@", "a.12.bc,@def", >- "a.12.bc,@def", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, >- 4, 7, 10, 12 }, "a.12.bc,@def", ">@a.12.bc,@def@^", >- new int[] { 2, 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 12 }); >- doTest1("testFullToLean #13 - ", "13ABC", "13ABC", "13ABC", new int[] { >- 0, 4, 7, 10, 30 }, new int[] { 0, 4, 5, 5, 5 }, "13ABC", >- ">@13ABC@^", new int[] { 2, 6, 9, 12, 32 }, new int[] { 0, 2, >- 5, 5, 5 }); >- doTest1("testFullToLean #14 - ", "14ABC,DE", "14ABC,DE", "14ABC@,DE", >- new int[] { 0, 4, 8, 11, 31 }, new int[] { 0, 4, 6, 8, 8 }, >- "14ABC,DE", ">@14ABC@,DE@^", new int[] { 2, 6, 10, 13, 33 }, >- new int[] { 0, 2, 5, 7, 8 }); >- doTest1("testFullToLean #15 - ", "15ABC@,DE", "15ABC,DE", "15ABC@,DE", >- new int[] { 0, 4, 8, 11, 31 }, new int[] { 0, 4, 6, 8, 8 }, >- "15ABC,DE", ">@15ABC@,DE@^", new int[] { 2, 6, 10, 13, 33 }, >- new int[] { 0, 2, 5, 7, 8 }); >- doTest1("testFullToLean #16 - ", "16ABC@@,DE", "16ABC,DE", "16ABC@,DE", >- new int[] { 0, 4, 8, 11, 31 }, new int[] { 0, 4, 6, 8, 8 }, >- "16ABC,DE", ">@16ABC@,DE@^", new int[] { 2, 6, 10, 13, 33 }, >- new int[] { 0, 2, 5, 7, 8 }); >- doTest1("testFullToLean #17 - ", "17ABC,@@DE", "17ABC,@DE", >- "17ABC,@DE", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 9, 9 }, "17ABC,@DE", ">@17ABC,@DE@^", new int[] { 2, >- 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 9 }); >- doTest1("testFullToLean #18 - ", "18ABC,DE,FGH", "18ABC,DE,FGH", >- "18ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "18ABC,DE,FGH", ">@18ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #19 - ", "19ABC@,DE@,FGH", "19ABC,DE,FGH", >- "19ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "19ABC,DE,FGH", ">@19ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #20 - ", "20ABC,@DE,@FGH", "20ABC,@DE,@FGH", >- "20ABC,@DE,@FGH", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, >- 4, 7, 10, 14 }, "20ABC,@DE,@FGH", ">@20ABC,@DE,@FGH@^", >- new int[] { 2, 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 14 }); >- doTest1("testFullToLean #21 - ", "21ABC@@,DE@@,FGH", "21ABC,DE,FGH", >- "21ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "21ABC,DE,FGH", ">@21ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #22 - ", "22ABC,@@DE,@@FGH", "22ABC,@DE,@FGH", >- "22ABC,@DE,@FGH", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, >- 4, 7, 10, 14 }, "22ABC,@DE,@FGH", ">@22ABC,@DE,@FGH@^", >- new int[] { 2, 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 14 }); >- doTest1("testFullToLean #23 - ", ">@23abc@^", "23abc", "23abc", >- new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, 5, 5, 5 }, >- "23abc", ">@23abc@^", new int[] { 2, 6, 9, 12, 32 }, new int[] { >- 0, 2, 5, 5, 5 }); >- doTest1("testFullToLean #24 - ", "24abc@^", "24abc", "24abc", >- new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, 5, 5, 5 }, >- "24abc", ">@24abc@^", new int[] { 2, 6, 9, 12, 32 }, new int[] { >- 0, 2, 5, 5, 5 }); >- doTest1("testFullToLean #25 - ", ">@25abc", "25abc", "25abc", >- new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, 5, 5, 5 }, >- "25abc", ">@25abc@^", new int[] { 2, 6, 9, 12, 32 }, new int[] { >- 0, 2, 5, 5, 5 }); >- doTest1("testFullToLean #26 - ", "26AB,CD@EF,GHI", "26AB,CD@EF,GHI", >- "26AB@,CD@EF@,GHI", new int[] { 0, 5, 8, 12, 32 }, new int[] { >- 0, 4, 6, 9, 14 }, "26AB,CD@EF,GHI", >- ">@26AB@,CD@EF@,GHI@^", new int[] { 2, 7, 10, 14, 34 }, >- new int[] { 0, 2, 4, 7, 14 }); >- doTest1("testFullToLean #27 - ", "27AB,CD@123ef,GHI", >- "27AB,CD@123ef,GHI", "27AB@,CD@123ef,GHI", new int[] { 0, 5, 8, >- 11, 31 }, new int[] { 0, 4, 6, 9, 17 }, >- "27AB,CD@123ef,GHI", ">@27AB@,CD@123ef,GHI@^", new int[] { 2, >- 7, 10, 13, 33 }, new int[] { 0, 2, 4, 7, 17 }); >- doTest1("testFullToLean #28 - ", ">28ABC@,DE@,FGH^", "28ABC,DE,FGH", >- "28ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "28ABC,DE,FGH", ">@28ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #29 - ", ">>29ABC@,DE@,FGH^^", "29ABC,DE,FGH", >- "29ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "29ABC,DE,FGH", ">@29ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #30 - ", ">30AB>C^@,DE@,FGH^", >- "30AB>C^,DE,FGH", "30AB>C^@,DE@,FGH", new int[] { 0, 4, 8, 12, >- 32 }, new int[] { 0, 4, 7, 9, 14 }, "30AB>C^,DE,FGH", >- ">@30AB>C^@,DE@,FGH@^", new int[] { 2, 6, 10, 14, 34 }, >- new int[] { 0, 2, 5, 7, 14 }); >- doTest1("testFullToLean #31 - ", ">31AB>C@,DE@,FGH^^", "31AB>C,DE,FGH", >- "31AB>C@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { >- 0, 4, 6, 9, 13 }, "31AB>C,DE,FGH", >- ">@31AB>C@,DE@,FGH@^", new int[] { 2, 6, 10, 14, 34 }, >- new int[] { 0, 2, 5, 7, 13 }); >- doTest1("testFullToLean #32 - ", ">@32ABC@,DE@,FGH@^", "32ABC,DE,FGH", >- "32ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "32ABC,DE,FGH", ">@32ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #33 - ", "@33ABC@,DE@,FGH@^", "33ABC,DE,FGH", >- "33ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "33ABC,DE,FGH", ">@33ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #34 - ", ">@34ABC@,DE@,FGH@", "34ABC,DE,FGH", >- "34ABC@,DE@,FGH", new int[] { 0, 4, 8, 12, 32 }, new int[] { 0, >- 4, 6, 8, 12 }, "34ABC,DE,FGH", ">@34ABC@,DE@,FGH@^", >- new int[] { 2, 6, 10, 14, 34 }, new int[] { 0, 2, 5, 7, 12 }); >- doTest1("testFullToLean #35 - ", "35ABC@@DE@@@GH@", "35ABC@DE@GH", >- "35ABC@DE@GH", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, >- 7, 10, 11 }, "35ABC@DE@GH", ">@35ABC@DE@GH@^", >- new int[] { 2, 6, 9, 12, 32 }, new int[] { 0, 2, 5, 8, 11 }); >- doTest1("testFullToLean #36 - ", "36ABC@@DE@@@@@@", "36ABC@DE", >- "36ABC@DE", new int[] { 0, 4, 7, 10, 30 }, new int[] { 0, 4, 7, >- 8, 8 }, "36ABC@DE", ">@36ABC@DE@^", new int[] { 2, 6, >- 9, 12, 32 }, new int[] { 0, 2, 5, 8, 8 }); >- doTest1("testFullToLean #37 - ", ">>>@@@@@^^^", "", "", new int[] { 0, >- 4, 7, 10, 30 }, new int[] { 0, 0, 0, 0, 0 }, "", "", new int[] { >- 0, 4, 7, 10, 30 }, new int[] { 0, 0, 0, 0, 0 }); >- >- // test fullToLeanText with initial state >- doTest2("testFullToLean #38 - "); >- } >-} >Index: src/org/eclipse/equinox/bidi/internal/tests/MethodsTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/tests/MethodsTest.java >diff -N src/org/eclipse/equinox/bidi/internal/tests/MethodsTest.java >--- src/org/eclipse/equinox/bidi/internal/tests/MethodsTest.java 17 Mar 2010 17:53:44 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,438 +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.internal.tests; >- >-import org.eclipse.equinox.bidi.complexp.IComplExpProcessor; >-import org.eclipse.equinox.bidi.complexp.IBiDiProcessor; >-import org.eclipse.equinox.bidi.complexp.StringProcessor; >-import org.eclipse.equinox.bidi.complexp.ComplExpUtil; >- >-/** >- * Tests most public methods of ComplExpBasic >- */ >- >-public class MethodsTest extends ComplExpTestBase { >- >- final static int LTR = IComplExpProcessor.DIRECTION_LTR; >- final static int RTL = IComplExpProcessor.DIRECTION_RTL; >- >- IComplExpProcessor processor; >- >- private void doTestTools() { >- >- // This method tests utility methods used by the JUnits >- String data = "56789ABCDEFGHIJKLMNOPQRSTUVWXYZ~#@&><^|`"; >- String text = toUT16(data); >- String dat2 = toPseudo(text); >- assertEquals(data, dat2); >- >- text = toPseudo(data); >- assertEquals("56789abcdefghijklmnopqrstuvwxyz~#@&><^|`", text); >- >- int[] arA = new int[] { 1, 2 }; >- int[] arB = new int[] { 3, 4, 5 }; >- assertFalse(arrays_equal(arA, arB)); >- >- assertTrue(arrays_equal(arA, arA)); >- >- arB = new int[] { 3, 4 }; >- assertFalse(arrays_equal(arA, arB)); >- >- int[][] ar2A = new int[][] { { 1 }, { 1, 2 }, { 1, 2, 3 } }; >- int[][] ar2B = new int[][] { { 1 }, { 1, 2 } }; >- assertTrue(arrays2_equal(ar2A, ar2A)); >- >- assertFalse(arrays2_equal(ar2A, ar2B)); >- >- ar2B = new int[][] { { 1 }, { 1, 2 }, { 1, 2, 3, 4 } }; >- assertFalse(arrays2_equal(ar2A, ar2B)); >- >- ar2B = new int[][] { { 1 }, { 1, 2 }, { 1, 2, 4 } }; >- assertFalse(arrays2_equal(ar2A, ar2B)); >- >- text = array_display(null); >- assertEquals("null", text); >- >- text = array2_display(null); >- assertEquals("null", text); >- } >- >- private void doTestState() { >- String data, lean, full, model; >- int state; >- >- data = "A=B+C;/* D=E+F;"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "A@=B@+C@;/* D=E+F;"; >- assertEquals("full1", model, toPseudo(full)); >- state = processor.getFinalState(); >- data = "A=B+C; D=E+F;"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean, state); >- model = "A=B+C; D=E+F;"; >- assertEquals("full2", model, toPseudo(full)); >- state = processor.getFinalState(); >- data = "A=B+C;*/ D=E+F;"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean, state); >- model = "A=B+C;*/@ D@=E@+F;"; >- assertEquals("full3", model, toPseudo(full)); >- } >- >- private void doTestOrientation() { >- int orient; >- >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- orient = processor.recallOrientation(); >- // TBD: the following test cannot succeed with the current >- // implementation. >- // it will need allocating separate data for each processor use. >- // assertEquals("orient #1", IComplExpProcessor.ORIENT_LTR, orient); >- >- processor.assumeOrientation(IComplExpProcessor.ORIENT_IGNORE); >- orient = processor.recallOrientation(); >- assertEquals("orient #2", IComplExpProcessor.ORIENT_IGNORE, orient); >- >- processor.assumeOrientation(IComplExpProcessor.ORIENT_CONTEXTUAL_RTL); >- orient = processor.recallOrientation(); >- processor.leanToFullText("--!**"); >- assertEquals("orient #3", IComplExpProcessor.ORIENT_CONTEXTUAL_RTL, >- orient); >- >- processor.assumeOrientation(9999); >- orient = processor.recallOrientation(); >- processor.leanToFullText("--!**"); >- assertEquals("orient #4", IComplExpProcessor.ORIENT_UNKNOWN, orient); >- } >- >- private void doTestOrient(String label, String data, String resLTR, >- String resRTL, String resCon) { >- String full, lean; >- >- lean = toUT16(data); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- full = processor.leanToFullText(lean); >- assertEquals(label + "LTR full", resLTR, toPseudo(full)); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_RTL); >- full = processor.leanToFullText(lean); >- assertEquals("label + RTL full", resRTL, toPseudo(full)); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_CONTEXTUAL_RTL); >- full = processor.leanToFullText(lean); >- assertEquals(label + "CON full", resCon, toPseudo(full)); >- } >- >- private void doTestScripts() { >- boolean flag; >- flag = processor.handlesArabicScript(); >- assertTrue("Handles Arabic 1", flag); >- flag = processor.handlesHebrewScript(); >- assertTrue("Handles Hebrew 1", flag); >- >- processor.selectBidiScript(false, false); >- flag = processor.handlesArabicScript(); >- assertFalse("Handles Arabic 2", flag); >- flag = processor.handlesHebrewScript(); >- assertFalse("Handles Hebrew 2", flag); >- doTestOrient("Scripts #1 ", "BCD,EF", "BCD,EF", ">@BCD,EF@^", "@BCD,EF"); >- processor.selectBidiScript(true, false); >- flag = processor.handlesArabicScript(); >- assertTrue("Handles Arabic 3", flag); >- flag = processor.handlesHebrewScript(); >- assertFalse("Handles Hebrew 3", flag); >- doTestOrient("Scripts #2 ", "d,EF", "d,EF", ">@d,EF@^", "d,EF"); >- doTestOrient("Scripts #3 ", "#,eF", "#,eF", ">@#,eF@^", "@#,eF"); >- doTestOrient("Scripts #4 ", "#,12", "#@,12", ">@#@,12@^", "@#@,12"); >- doTestOrient("Scripts #5 ", "#,##", "#@,##", ">@#@,##@^", "@#@,##"); >- doTestOrient("Scripts #6 ", "#,89", "#@,89", ">@#@,89@^", "@#@,89"); >- doTestOrient("Scripts #7 ", "#,ef", "#,ef", ">@#,ef@^", "@#,ef"); >- doTestOrient("Scripts #8 ", "#,", "#,", ">@#,@^", "@#,"); >- doTestOrient("Scripts #9 ", "9,ef", "9,ef", ">@9,ef@^", "9,ef"); >- doTestOrient("Scripts #10 ", "9,##", "9@,##", ">@9@,##@^", "9@,##"); >- doTestOrient("Scripts #11 ", "7,89", "7@,89", ">@7@,89@^", "7@,89"); >- doTestOrient("Scripts #12 ", "7,EF", "7,EF", ">@7,EF@^", "@7,EF"); >- doTestOrient("Scripts #13 ", "BCD,EF", "BCD,EF", ">@BCD,EF@^", >- "@BCD,EF"); >- >- processor.selectBidiScript(false, true); >- flag = processor.handlesArabicScript(); >- assertFalse("Handles Arabic 4", flag); >- flag = processor.handlesHebrewScript(); >- assertTrue("Handles Hebrew 4", flag); >- doTestOrient("Scripts #14 ", "BCd,EF", "BCd,EF", ">@BCd,EF@^", >- "@BCd,EF"); >- doTestOrient("Scripts #15 ", "BCD,eF", "BCD,eF", ">@BCD,eF@^", >- "@BCD,eF"); >- doTestOrient("Scripts #16 ", "BCD,EF", "BCD@,EF", ">@BCD@,EF@^", >- "@BCD@,EF"); >- doTestOrient("Scripts #17 ", "BCD,12", "BCD@,12", ">@BCD@,12@^", >- "@BCD@,12"); >- doTestOrient("Scripts #18 ", "BCD,", "BCD,", ">@BCD,@^", "@BCD,"); >- >- processor.selectBidiScript(true, true); >- doTestOrient("Scripts #19 ", "123,45|67", "123,45|67", ">@123,45|67@^", >- "@123,45|67"); >- doTestOrient("Scripts #20 ", "5,e", "5,e", ">@5,e@^", "5,e"); >- doTestOrient("Scripts #21 ", "5,#", "5@,#", ">@5@,#@^", "5@,#"); >- doTestOrient("Scripts #22 ", "5,6", "5@,6", ">@5@,6@^", "5@,6"); >- doTestOrient("Scripts #23 ", "5,D", "5@,D", ">@5@,D@^", "5@,D"); >- doTestOrient("Scripts #24 ", "5,--", "5,--", ">@5,--@^", "@5,--"); >- } >- >- private void doTestLeanOffsets() { >- String lean, data, label; >- int state; >- int[] offsets; >- int[] model; >- >- data = "A=B+C;/* D=E+F;"; >- lean = toUT16(data); >- offsets = processor.leanBidiCharOffsets(lean); >- model = new int[] { 1, 3, 5 }; >- label = "leanBidiCharOffsets() #1 expected=" + array_display(model) >- + " result=" + array_display(offsets); >- assertTrue(label, arrays_equal(model, offsets)); >- state = processor.getFinalState(); >- data = "A=B+C;*/ D=E+F;"; >- lean = toUT16(data); >- offsets = processor.leanBidiCharOffsets(lean, state); >- model = new int[] { 8, 10, 12 }; >- label = "leanBidiCharOffsets() #2 expected=" + array_display(model) >- + " result=" + array_display(offsets); >- assertTrue(label, arrays_equal(model, offsets)); >- offsets = processor.leanBidiCharOffsets(); >- model = new int[] { 8, 10, 12 }; >- label = "leanBidiCharOffsets() #3 expected=" + array_display(model) >- + " result=" + array_display(offsets); >- assertTrue(label, arrays_equal(model, offsets)); >- } >- >- private void doTestFullOffsets(String label, String data, int[] resLTR, >- int[] resRTL, int[] resCon) { >- String full, lean, msg; >- int[] offsets; >- >- lean = toUT16(data); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- full = processor.leanToFullText(lean); >- // the following line avoids a compiler warning about full never being >- // read >- full += ""; >- offsets = processor.fullBidiCharOffsets(); >- msg = label + "LTR expected=" + array_display(resLTR) + " result=" >- + array_display(offsets); >- assertTrue(msg, arrays_equal(resLTR, offsets)); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_RTL); >- full = processor.leanToFullText(lean); >- offsets = processor.fullBidiCharOffsets(); >- msg = label + "RTL expected=" + array_display(resRTL) + " result=" >- + array_display(offsets); >- assertTrue(msg, arrays_equal(resRTL, offsets)); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_CONTEXTUAL_LTR); >- full = processor.leanToFullText(lean); >- offsets = processor.fullBidiCharOffsets(); >- msg = label + "CON expected=" + array_display(resCon) + " result=" >- + array_display(offsets); >- assertTrue(msg, arrays_equal(resCon, offsets)); >- } >- >- private void doTestMirrored() { >- boolean mirrored; >- >- mirrored = ComplExpUtil.isMirroredDefault(); >- assertFalse("mirrored #1", mirrored); >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- mirrored = processor.isMirrored(); >- assertFalse("mirrored #2", mirrored); >- ComplExpUtil.assumeMirroredDefault(true); >- mirrored = ComplExpUtil.isMirroredDefault(); >- assertTrue("mirrored #3", mirrored); >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- mirrored = processor.isMirrored(); >- // TBD: the following test cannot succeed with the current >- // implementation. >- // it will need allocating separate data for each processor use. >- // assertTrue("mirrored #4", mirrored); >- processor.assumeMirrored(false); >- mirrored = processor.isMirrored(); >- assertFalse("mirrored #5", mirrored); >- } >- >- private void doTestDirection() { >- int[][] dir; >- int[][] modir; >- String data, lean, full, model, msg; >- >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- dir = processor.getDirection(); >- modir = new int[][] { { LTR, LTR }, { LTR, LTR } }; >- msg = "TestDirection #1 expected=" + array2_display(modir) + " result=" >- + array2_display(dir); >- assertTrue(msg, arrays2_equal(modir, dir)); >- >- processor.setDirection(RTL); >- dir = processor.getDirection(); >- modir = new int[][] { { RTL, RTL }, { RTL, RTL } }; >- msg = "TestDirection #2 expected=" + array2_display(modir) + " result=" >- + array2_display(dir); >- assertTrue(msg, arrays2_equal(modir, dir)); >- >- processor.setDirection(LTR, RTL); >- dir = processor.getDirection(); >- modir = new int[][] { { LTR, RTL }, { LTR, RTL } }; >- msg = "TestDirection #3 expected=" + array2_display(modir) + " result=" >- + array2_display(dir); >- assertTrue(msg, arrays2_equal(modir, dir)); >- >- processor.setArabicDirection(RTL); >- dir = processor.getDirection(); >- modir = new int[][] { { RTL, RTL }, { LTR, RTL } }; >- msg = "TestDirection #4 expected=" + array2_display(modir) + " result=" >- + array2_display(dir); >- assertTrue(msg, arrays2_equal(modir, dir)); >- >- processor.setArabicDirection(RTL, LTR); >- dir = processor.getDirection(); >- modir = new int[][] { { RTL, LTR }, { LTR, RTL } }; >- msg = "TestDirection #5 expected=" + array2_display(modir) + " result=" >- + array2_display(dir); >- assertTrue(msg, arrays2_equal(modir, dir)); >- >- processor.setHebrewDirection(RTL); >- dir = processor.getDirection(); >- modir = new int[][] { { RTL, LTR }, { RTL, RTL } }; >- msg = "TestDirection #6 expected=" + array2_display(modir) + " result=" >- + array2_display(dir); >- assertTrue(msg, arrays2_equal(modir, dir)); >- >- processor.setHebrewDirection(RTL, LTR); >- dir = processor.getDirection(); >- modir = new int[][] { { RTL, LTR }, { RTL, LTR } }; >- msg = "TestDirection #7 expected=" + array2_display(modir) + " result=" >- + array2_display(dir); >- assertTrue(msg, arrays2_equal(modir, dir)); >- >- processor = StringProcessor.getProcessor(IBiDiProcessor.EMAIL); >- processor.assumeMirrored(false); >- processor.setArabicDirection(LTR, RTL); >- processor.setHebrewDirection(LTR, LTR); >- data = "#ABC.#DEF:HOST.com"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "#ABC@.#DEF@:HOST.com"; >- assertEquals("TestDirection #9 full", model, toPseudo(full)); >- >- data = "ABC.DEF:HOST.com"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "ABC@.DEF@:HOST.com"; >- assertEquals("TestDirection #10 full", model, toPseudo(full)); >- >- processor.assumeMirrored(true); >- data = "#ABC.#DEF:HOST.com"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "<&#ABC.#DEF:HOST.com&^"; >- assertEquals("TestDirection #11 full", model, toPseudo(full)); >- >- data = "#ABc.#DEF:HOSt.COM"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "<&#ABc.#DEF:HOSt.COM&^"; >- assertEquals("TestDirection #12 full", model, toPseudo(full)); >- >- data = "#ABc.#DEF:HOSt."; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "<&#ABc.#DEF:HOSt.&^"; >- assertEquals("TestDirection #13 full", model, toPseudo(full)); >- >- data = "ABC.DEF:HOST.com"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "ABC@.DEF@:HOST.com"; >- assertEquals("TestDirection #14 full", model, toPseudo(full)); >- >- data = "--.---:----"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "--.---:----"; >- assertEquals("TestDirection #15 full", model, toPseudo(full)); >- >- data = "ABC.|DEF:HOST.com"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "ABC.|DEF@:HOST.com"; >- assertEquals("TestDirection #16 full", model, toPseudo(full)); >- >- processor.assumeOrientation(IComplExpProcessor.ORIENT_RTL); >- data = "#ABc.|#DEF:HOST.com"; >- lean = toUT16(data); >- full = processor.leanToFullText(lean); >- model = "#ABc.|#DEF:HOST.com"; >- assertEquals("TestDirection #17 full", model, toPseudo(full)); >- } >- >- public void testMethods() { >- >- doTestTools(); >- >- processor = StringProcessor.getProcessor(IBiDiProcessor.JAVA); >- doTestState(); >- >- doTestOrientation(); >- >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- doTestOrient("Methods #1 ", "", "", "", ""); >- doTestOrient("Methods #2 ", "abc", "abc", ">@abc@^", "abc"); >- doTestOrient("Methods #3 ", "ABC", "ABC", ">@ABC@^", "@ABC"); >- doTestOrient("Methods #4 ", "bcd,ef", "bcd,ef", ">@bcd,ef@^", "bcd,ef"); >- doTestOrient("Methods #5 ", "BCD,EF", "BCD@,EF", ">@BCD@,EF@^", >- "@BCD@,EF"); >- doTestOrient("Methods #6 ", "cde,FG", "cde,FG", ">@cde,FG@^", "cde,FG"); >- doTestOrient("Methods #7 ", "CDE,fg", "CDE,fg", ">@CDE,fg@^", "@CDE,fg"); >- doTestOrient("Methods #8 ", "12..def,GH", "12..def,GH", >- ">@12..def,GH@^", "12..def,GH"); >- doTestOrient("Methods #9 ", "34..DEF,gh", "34..DEF,gh", >- ">@34..DEF,gh@^", "@34..DEF,gh"); >- >- doTestScripts(); >- >- processor = StringProcessor.getProcessor(IBiDiProcessor.JAVA); >- doTestLeanOffsets(); >- >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- doTestFullOffsets("TestFullOffsets ", "BCD,EF,G", new int[] { 3, 7 }, >- new int[] { 0, 1, 5, 9, 12, 13 }, new int[] { 0, 4, 8 }); >- >- doTestMirrored(); >- >- doTestDirection(); >- >- processor = StringProcessor >- .getProcessor(IBiDiProcessor.COMMA_DELIMITED); >- processor.assumeOrientation(IComplExpProcessor.ORIENT_LTR); >- processor.setDirection(LTR); >- String data = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"; >- String lean = toUT16(data); >- String full = processor.leanToFullText(lean); >- String model = "A@,B@,C@,D@,E@,F@,G@,H@,I@,J@,K@,L@,M@,N@,O@,P@,Q@,R@,S@,T@,U@,V@,W@,X@,Y@,Z"; >- assertEquals("many inserts", model, toPseudo(full)); >- >- } >-} >Index: src/org/eclipse/equinox/bidi/tests/BiDiTestSuite.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/tests/BiDiTestSuite.java >diff -N src/org/eclipse/equinox/bidi/tests/BiDiTestSuite.java >--- src/org/eclipse/equinox/bidi/tests/BiDiTestSuite.java 17 Mar 2010 17:53:43 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,34 +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.tests; >- >-import org.eclipse.equinox.bidi.internal.tests.*; >- >-import junit.framework.Test; >-import junit.framework.TestSuite; >- >-public class BiDiTestSuite extends TestSuite { >- public static Test suite() { >- return new BiDiTestSuite(); >- } >- >- public BiDiTestSuite() { >- addTestSuite(ExtensibilityTest.class); >- addTestSuite(MethodsTest.class); >- // addTestSuite(TestDoNothing.class); >- addTestSuite(FullToLeanTest.class); >- addTestSuite(ComplExpMathTest.class); >- // TBD: TestSubclass >- addTestSuite(ExtensionsTest.class); >- addTestSuite(ComplExpUtilTest.class); >- } >-} >Index: src/org/eclipse/equinox/bidi/tests/BidiComplexTestSuite.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/tests/BidiComplexTestSuite.java >diff -N src/org/eclipse/equinox/bidi/tests/BidiComplexTestSuite.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/tests/BidiComplexTestSuite.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,33 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 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.tests; >+ >+import junit.framework.Test; >+import junit.framework.TestSuite; >+import org.eclipse.equinox.bidi.internal.tests.*; >+ >+public class BidiComplexTestSuite extends TestSuite { >+ public static Test suite() { >+ return new BidiComplexTestSuite(); >+ } >+ >+ public BidiComplexTestSuite() { >+ addTestSuite(BidiComplexExtensibilityTest.class); >+ addTestSuite(BidiComplexMethodsTest.class); >+ addTestSuite(BidiComplexNullProcessorTest.class); >+ addTestSuite(BidiComplexFullToLeanTest.class); >+ addTestSuite(BidiComplexExtensionsTest.class); >+ addTestSuite(BidiComplexMathTest.class); >+ addTestSuite(BidiComplexSomeMoreTest.class); >+ addTestSuite(BidiComplexUtilTest.class); >+ } >+} >\ No newline at end of file
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 183164
:
148967
|
157821
|
158092
|
158531
|
160015
|
160017
|
160081
|
160698
|
160858
|
162228
|
162229
|
164476
|
186038
|
186054
|
186488
|
186490
|
188406
|
188407
|
188408
| 188627 |
194078
|
194079
|
195082
|
195084
|
196575
|
196576
|
199068
|
199070
|
199113
|
199855
|
200008
|
200389
|
200629
|
200630
|
200631
|
200742
|
200743
|
200803
|
200805
|
200905
|
200907
|
201464
|
201465
|
201467
|
201468
|
201469
|
201470
|
201676
|
201677
|
201785
|
201787
|
202172
|
202173
|
205767
|
205768
|
206588
|
210657