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 186038 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]
Patch generating new version of complex expression package
patch_bidi_20110104.txt (text/plain), 238.99 KB, created by
Matitiahu Allouche
on 2011-01-04 13:42:38 EST
(
hide
)
Description:
Patch generating new version of complex expression package
Filename:
MIME Type:
Creator:
Matitiahu Allouche
Created:
2011-01-04 13:42:38 EST
Size:
238.99 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.equinox.bidi >Index: src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java >diff -N src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java >--- src/org/eclipse/equinox/bidi/complexp/ComplExpFactory.java 3 Feb 2010 20:00:59 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,48 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2010 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- ******************************************************************************/ >-package org.eclipse.equinox.bidi.complexp; >- >-import org.eclipse.equinox.bidi.internal.complexp.BiDiTypesCollector; >- >-/** >- * @noinstantiate This class is not intended to be instantiated by clients. >- */ >-// TBD do we really want to provide individual instances of the text processors? >-final public class ComplExpFactory implements IBiDiProcessor { >- >- /** >- * Factory method to create a new instance of the bi-directional text >- * processor for the specified text type. This method may return <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/CxpEnv.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/CxpEnv.java >diff -N src/org/eclipse/equinox/bidi/complexp/CxpEnv.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/complexp/CxpEnv.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,301 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.equinox.bidi.complexp; >+ >+import java.util.Locale; >+ >+/** >+ * This class defines certain details of the environment within which >+ * complex expressions are processed. >+ * <p> >+ * All public fields in this class are <code>final</code>, i.e. cannot be >+ * changed after creating an instance. >+ * <p> >+ * A <code>CxpEnv</code> instance can be associated with a <code>CxpHelper</code> >+ * instance either when creating the >+ * {@link CxpHelper#CxpHelper(java.lang.String, CxpEnv) CxpHelper} instance >+ * or using the {@link CxpHelper#setEnvironment setEnvironment} method. >+ * >+ * <h2>Code Samples</h2> >+ * <p>Example 1 (set all environment parameters) >+ * <pre> >+ * >+ * CxpEnv myEnv = new CxpEnv("he_IL", true, CxpEnv.ORIENT_RTL); >+ * CxpHelper myHelper = new CxpHelper(IProcessorTypes.FILE, myEnv); >+ * >+ * </pre> >+ * <p>Example 2 (change only the orientation) >+ * <pre> >+ * >+ * CxpEnv env1 = myHelper.getEnvironment(); >+ * CxpEnv env2 = new CxpEnv(env1.language, env1.mirrored, CxpEnv.ORIENT_UNKNOWN); >+ * myHelper.setEnvironment(env2); >+ * >+ * </pre> >+ * <p> >+ * This class also provides a number of convenience methods related to the environment. >+ * <p> </p> >+ * @see CxpHelper#CxpHelper(String, CxpEnv) >+ * @see CxpHelper#CxpHelper(ICxpProcessor, CxpEnv) >+ * @see CxpHelper#getEnvironment CxpHelper.getEnvironment >+ * @see CxpHelper#setEnvironment CxpHelper.setEnvironment >+ * @see ICxpProcessor#init ICxpProcessor.init >+ * @see ICxpProcessor#init2 ICxpProcessor.init2 >+ * >+ * @author Matitiahu Allouche >+ */ >+public class CxpEnv { >+ >+ /** >+ * Constant specifying that the orientation of the GUI component >+ * where a complex expression will be displayed is LTR. >+ * It can appear as <code>orientation</code> argument for >+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the >+ * {@link CxpEnv#orientation} member of <code>CxpEnv</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 CxpEnv#CxpEnv CxpEnv constructor} and as value for the >+ * {@link CxpEnv#orientation} member of <code>CxpEnv</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 CxpEnv#CxpEnv CxpEnv constructor} and as value for the >+ * {@link CxpEnv#orientation} member of <code>CxpEnv</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 CxpEnv#CxpEnv CxpEnv constructor} and as value for the >+ * {@link CxpEnv#orientation} member of <code>CxpEnv</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 CxpHelper#leanToFullText leanToFullText}. >+ * It can appear as <code>orientation</code> argument for >+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the >+ * {@link CxpEnv#orientation} member of <code>CxpEnv</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 CxpHelper#leanToFullText leanToFullText}. >+ * It can appear as <code>orientation</code> argument for >+ * {@link CxpEnv#CxpEnv CxpEnv constructor} and as value for the >+ * {@link CxpEnv#orientation} member of <code>CxpEnv</code>. >+ */ >+ public static final int ORIENT_IGNORE = 5; >+ >+ /** >+ * Pre-defined <code>CxpEnv</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 CxpEnv DEFAULT = new CxpEnv(null, false, ORIENT_LTR); >+ >+ /** >+ * This string is a 2-letters code representing a language as defined by >+ * ISO-639. If left as <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 CxpHelper#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 CxpHelper#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 CxpHelper#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 CxpHelper#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 CxpHelper#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 CxpHelper#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 CxpHelper#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 defLocale; >+ static String defLanguage; >+ static boolean defBidi; >+ boolean bidiFlag; >+ >+ /** >+ * Constructor >+ * >+ * @param lang represents the language to be used in this environment. >+ * It should be specified as a 2-letters code as defined by >+ * ISO-639.<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 CxpEnv(String lang, boolean mirrored, int orientation) { >+ if (lang == null) { >+ language = null; >+ } else { >+ if (lang.length() > 2) { >+ language = lang.substring(0, 2); >+ } else { >+ language = lang; >+ } >+ bidiFlag = isBidiLanguage(language); >+ } >+ this.mirrored = mirrored; >+ this.orientation = orientation >= ORIENT_LTR && orientation <= ORIENT_IGNORE ? orientation : ORIENT_UNKNOWN; >+ } >+ >+ /** >+ * Check whether the current language uses a >+ * bidi script (Arabic, Hebrew, Farsi or Urdu). >+ * >+ * @return <code>true</code> if the current language uses a bidi script. >+ * The language may have been set explicitly when creating the >+ * <code>CxpEnv</code> instance, or it may have defaulted to >+ * the language of the current default locale. >+ * @see #CxpEnv CxpEnv >+ */ >+ public boolean isBidi() { >+ // TBD use OSGi service >+ if (defLanguage != null && defLocale.equals(Locale.getDefault())) >+ return defBidi; >+ >+ if (language == null) { >+ // TBD use OSGi service >+ defLocale = Locale.getDefault(); >+ defLanguage = defLocale.getLanguage(); >+ defBidi = isBidiLanguage(defLanguage); >+ return defBidi; >+ } >+ >+ return bidiFlag; >+ } >+ >+ static boolean isBidiLanguage(String lang) { >+ return "iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || "fa".equals(lang) || "ur".equals(lang); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ >+ } >+ >+ static String lineSep; >+ >+ /** >+ * Retrieve the string which represents a line separator in this environment. >+ * >+ * @return the string which is used as line separator (e.g. CRLF). >+ */ >+ public static String getLineSep() { >+ // TBD use bundle properties >+ if (lineSep == null) >+ lineSep = System.getProperty("line.separator", "\n"); //$NON-NLS-1$//$NON-NLS-2$ >+ return lineSep; >+ } >+ >+ static String osName; >+ static boolean flagOS; >+ >+ /** >+ * Check if the current OS is supported by the complex expression packages. >+ * >+ * @return <code>true</code> if the current OS is supported. >+ */ >+ public static boolean isSupportedOS() { >+ if (osName == null) { >+ // TBD use bundle properties >+ osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ >+ flagOS = osName.startsWith("windows") || osName.startsWith("linux"); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ return flagOS; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java >diff -N src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/complexp/CxpFeatures.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,188 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.equinox.bidi.complexp; >+ >+/** >+ * This class defines features of a complex expression processor. >+ * <p> >+ * All public fields in this class are <code>final</code>, i.e. cannot be >+ * changed after creating an instance. >+ * <p> >+ * A <code>CxpFeatures</code> instance can be associated with a >+ * <code>CxpHelper</code> instance using >+ * the {@link CxpHelper#setFeatures setFeatures} method. >+ * >+ * <h2>Code Samples</h2> >+ * <p>Example 1 (set all features) >+ * <pre> >+ * >+ * CxpFeatures myFeatures = new CxpFeatures("+-=", 0, -1, -1, false, false); >+ * CxpHelper myHelper = new CxpHelper(IProcessorTypes.FILE, myEnv); >+ * myHelper.setFeatures(myFeatures); >+ * >+ * </pre> >+ * <p>Example 2 (change only the operators) >+ * <pre> >+ * >+ * CxpFeatures f1 = myHelper.getFeatures(); >+ * CxpFeatures f2 = new CxpFeatures("[]|()", f1.specialsCount, >+ * f1.dirArabic, f1.dirHebrew, >+ * f1.ignoreArabic, f1.ignoreHebrew); >+ * myHelper.setFeatures(f2); >+ * >+ * </pre> >+ * >+ * @see CxpHelper#getFeatures CxpHelper.getFeatures >+ * @see CxpHelper#setFeatures CxpHelper.setFeatures >+ * @see ICxpProcessor#init ICxpProcessor.init >+ * @see ICxpProcessor#init2 ICxpProcessor.init2 >+ * >+ * @author Matitiahu Allouche >+ */ >+public class CxpFeatures { >+ >+ /** >+ * Constant specifying that the base direction of a complex expression is LTR. >+ * The base direction may depend on whether the GUI is >+ * {@link CxpEnv#mirrored mirrored} and may >+ * may be different for Arabic and for Hebrew. >+ * This constant can appear as <code>dirArabic</code> >+ * or <code>dirHebrew</code> argument for >+ * {@link CxpFeatures#CxpFeatures CxpFeatures constructor} and as value >+ * for the {@link #dirArabic} or {@link #dirHebrew} members of >+ * <code>CxpFeatures</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 CxpEnv#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 CxpFeatures#CxpFeatures CxpFeatures constructor} and as value >+ * for the {@link #dirArabic} or {@link #dirHebrew} members of >+ * <code>CxpFeatures</code>. >+ */ >+ public static final int DIR_RTL = 1; >+ >+ /** >+ * Pre-defined <code>CxpFeatures</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 CxpHelper#CxpHelper() CxpHelper} >+ * instantiated with no arguments. >+ */ >+ public static final CxpFeatures DEFAULT = new CxpFeatures(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 ICxpProcessor#indexOfSpecial indexOfSpecial} and >+ * {@link ICxpProcessor#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 CxpFeatures(String operators, int specialsCount, int dirArabic, int dirHebrew, boolean ignoreArabic, boolean ignoreHebrew) { >+ >+ this.operators = operators == null ? "" : operators; //$NON-NLS-1$ >+ this.specialsCount = specialsCount; >+ this.dirArabic = dirArabic == DIR_LTR || dirArabic == DIR_RTL ? dirArabic : DIR_LTR; >+ this.dirHebrew = dirHebrew == DIR_LTR || dirHebrew == DIR_RTL ? dirHebrew : DIR_LTR; >+ this.ignoreArabic = ignoreArabic; >+ this.ignoreHebrew = ignoreHebrew; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/complexp/CxpHelper.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/CxpHelper.java >diff -N src/org/eclipse/equinox/bidi/complexp/CxpHelper.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/complexp/CxpHelper.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,570 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.equinox.bidi.complexp; >+ >+import org.eclipse.equinox.bidi.internal.complexp.CxpDoer; >+ >+/** >+ * This class acts as a mediator between applications and complex >+ * expression processors. >+ * The purpose of complex expression processors is to add directional >+ * formatting characters to ensure correct display. >+ * This class shields applications from the >+ * intricacies of complex expression processors. >+ * <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 CxpHelper 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> >+ * >+ * CxpHelper helper = new CxpHelper(IProcessorTypes.FILE); >+ * String leanText = "D:\\\u05d0\u05d1\\\u05d2\\\u05d3.ext"; >+ * String fullText = helper.leanToFullText(leanText); >+ * System.out.println("full text = " + fullText); >+ * >+ * </pre> >+ * This class provides a user-oriented API but does not provides >+ * an actual implementation. The real work is done by the class >+ * {@link CxpDoer}. Users of the API need not be concerned by, and >+ * should not depend upon, details of the implementation by >+ * <code>CxpDoer</code>. >+ * >+ * @author Matitiahu Allouche >+ * >+ */ >+public class CxpHelper { >+ /** >+ * 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 CxpDoer} instance which accomplishes >+ * most of the work. This member should be accessed only by >+ * complex expression processors (implementing {@link ICxpProcessor}). >+ */ >+ public CxpDoer ced; >+ >+ /** >+ * Create a <code>CxpHelper</code> instance which does nothing tangible >+ * but does it quickly. We will call it a <i>no-op helper</i>. >+ * The {@link #CxpHelper() no-op helper} does not modify text submitted to it, and can be >+ * used when it is known that no complex expression processing >+ * is needed, for instance because no bidi text is expected. With this >+ * helper, the cost of invoking the complex expression API is minimal. >+ */ >+ public CxpHelper() { >+ // let ced stay null >+ } >+ >+ /** >+ * Create a <code>CxpHelper</code> instance to process expressions >+ * of type <code>type</code> with a >+ * {@link CxpEnv#DEFAULT DEFAULT} environment. >+ * >+ * @param type represents the type of the complex expression. It must >+ * be one of the values in {@link IProcessorTypes}, or a type >+ * added in a plug-in extension. >+ * >+ * @throws IllegalArgumentException if the <code>type</code> is not >+ * supported. >+ */ >+ public CxpHelper(String type) { >+ this(type, null); >+ } >+ >+ /** >+ * Create a <code>CxpHelper</code> instance to process expressions >+ * of type <code>type</code> operating under the environment >+ * {@link CxpEnv env}. >+ * >+ * @param type represents the type of the complex expression. It must >+ * be one of the values in {@link IProcessorTypes}, or a type >+ * added in a plug-in extension. >+ * >+ * @param env represents the environment where the complex expression >+ * will be displayed. It is better to specify the environment >+ * when instantiating a <code>CxpHelper</code> than to specify >+ * it later using {@link #setEnvironment setEnvironment}.<br> >+ * <code>null</code> can be specified here for a >+ * {@link CxpEnv#DEFAULT DEFAULT} environment. >+ * >+ * @throws IllegalArgumentException if the <code>type</code> is not >+ * supported. >+ */ >+ public CxpHelper(String type, CxpEnv env) { >+ ICxpProcessor proc = StringProcessor.getProcessor(type); >+ if (proc == null) { >+ throw new IllegalArgumentException("Invalid processor type!"); //$NON-NLS-1$ >+ } >+ ced = new CxpDoer(this, proc, env); >+ } >+ >+ /** >+ * Create a <code>CxpHelper</code> instance to process complex >+ * expressions by means of a given processor <code>proc</code>, >+ * operating under the environment {@link CxpEnv env}. >+ * >+ * @param proc is a complex expression processor. >+ * >+ * @param env represents the environment where the complex expression >+ * will be displayed. It is better to specify the environment >+ * when instantiating a <code>CxpHelper</code> than to specify >+ * it later using {@link #setEnvironment setEnvironment}.<br> >+ * <code>null</code> can be specified here for a >+ * {@link CxpEnv#DEFAULT DEFAULT} environment. >+ */ >+ public CxpHelper(ICxpProcessor proc, CxpEnv env) { >+ ced = new CxpDoer(this, proc, env); >+ } >+ >+ /** Add directional formatting characters to a complex expression >+ * to ensure correct presentation. >+ * >+ * @param text is the text of the complex expression. >+ * >+ * @return the complex expression with directional formatting >+ * characters added at proper locations to ensure correct >+ * presentation.<br> >+ * The {@link #CxpHelper() 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 #CxpHelper() no-op helper} returns <code>text</code>. >+ * >+ * @see #getFinalState getFinalState >+ */ >+ public String leanToFullText(String text, int initState) { >+ if (ced == null) >+ return text; >+ return ced.leanToFullText(text, initState); >+ } >+ >+ /** >+ * Given a complex expression, get the offsets of characters before >+ * which directional formatting characters must be added in order to >+ * ensure correct presentation. >+ * Only LRMs (for an expression with LTR base direction) and RLMs (for >+ * an expression with RTL base direction) are considered. Leading and >+ * trailing LRE, RLE and PDF which might be prefixed or suffixed >+ * depending on the {@link CxpEnv#orientation orientation} of the >+ * GUI component used for display are not reflected in this method. >+ * <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 #CxpHelper() no-op helper} returns an array of 0 elements. >+ */ >+ public int[] leanBidiCharOffsets() { >+ if (ced == null) >+ return EMPTY_INT_ARRAY; >+ return ced.leanBidiCharOffsets(); >+ } >+ >+ /** >+ * Get the offsets of characters in the <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 CxpEnv#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 #CxpHelper() no-op helper} returns an array of 0 elements. >+ */ >+ public int[] fullBidiCharOffsets() { >+ if (ced == null) >+ return EMPTY_INT_ARRAY; >+ return ced.fullBidiCharOffsets(); >+ } >+ >+ /** >+ * Remove directional formatting characters which were added to a >+ * complex expression to ensure correct presentation. >+ * >+ * @param text is the text of the complex expression including >+ * directional formatting characters. >+ * >+ * @return the complex expression without directional formatting >+ * characters which might have been added by processing it >+ * with {@link #leanToFullText leanToFullText}.<br> >+ * The {@link #CxpHelper() 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 #CxpHelper() no-op helper} returns <code>text</code> >+ * >+ * @see #getFinalState getFinalState >+ */ >+ public String fullToLeanText(String text, int initState) { >+ if (ced == null) >+ return text; >+ return ced.fullToLeanText(text, initState); >+ } >+ >+ /** >+ * Retrieve the final state achieved in a previous call to >+ * {@link #leanToFullText leanToFullText} or >+ * {@link #fullToLeanText fullToLeanText}. >+ * This state is an opaque value which is meaningful only >+ * within calls to the same complex expression processor. >+ * The only externalized value is >+ * {@link #STATE_NOTHING_GOING} which means that >+ * there is nothing to remember from the last call. >+ * <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 #CxpHelper() no-op helper} returns {@link #STATE_NOTHING_GOING}. >+ */ >+ public int getFinalState() { >+ if (ced == null) >+ return STATE_NOTHING_GOING; >+ return ced.getFinalState(); >+ } >+ >+ /** >+ * After transforming a <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. >+ * 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 #CxpHelper() no-op helper} returns <code>pos</code>. >+ */ >+ public int leanToFullPos(int pos) { >+ if (ced == null) >+ return pos; >+ return ced.leanToFullPos(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. >+ * 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>pos</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 #CxpHelper() no-op helper} returns <code>pos</code>. >+ */ >+ public int fullToLeanPos(int pos) { >+ if (ced == null) >+ return pos; >+ return ced.fullToLeanPos(pos); >+ } >+ >+ /** >+ * Get the base direction of the complex expression last >+ * submitted to {@link #leanToFullText leanToFullText}. >+ * This base direction may depend on >+ * whether the expression contains Arabic or Hebrew words >+ * (if it contains both, the first Arabic or Hebrew letter in the >+ * expression determines which is the governing script) and on >+ * whether the GUI is {@link CxpEnv#mirrored mirrored}. >+ * >+ * @return the base direction of the last submitted complex >+ * expression. It must be one of the values >+ * {@link CxpFeatures#DIR_LTR} or {@link CxpFeatures#DIR_RTL}.<br> >+ * The {@link #CxpHelper() no-op helper} returns <code>DIR_LTR</code>. >+ */ >+ public int getCurDirection() { >+ if (ced == null) >+ return CxpFeatures.DIR_LTR; >+ return ced.getCurDirection(); >+ } >+ >+ /** >+ * Get the current environment under which the <code>CxpHelper</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 #CxpHelper() no-op helper} returns a {@link CxpEnv#DEFAULT DEFAULT} >+ * environment. >+ * >+ * @see #setEnvironment setEnvironment >+ */ >+ public CxpEnv getEnvironment() { >+ if (ced == null) >+ return CxpEnv.DEFAULT; >+ return ced.getEnvironment(); >+ } >+ >+ /** >+ * Specify the environment under which the <code>CxpHelper</code> >+ * must operate. >+ * <p> >+ * <b>Note</b> that calling this method causes the processor >+ * associated with this instance of <code>CxpHelper</code> >+ * to re-initialize its features. The effect of a previous call >+ * to {@link #setFeatures(CxpFeatures) setFeatures} is lost.<br> >+ * The {@link #CxpHelper() no-op helper} does nothing. >+ * >+ * @see #getEnvironment getEnvironment >+ * @see ICxpProcessor#init2 ICxpProcessor.init2 >+ */ >+ public void setEnvironment(CxpEnv environment) { >+ if (ced == null) { >+ return; // do nothing >+ } >+ ced.setEnvironment(environment); >+ } >+ >+ /** >+ * Get the current features of the processor associated with this >+ * <code>CxpHelper</code> instance. >+ * >+ * @return the current features.<br> >+ * The {@link #CxpHelper() no-op helper} returns {@link CxpFeatures#DEFAULT DEFAULT} >+ * features. >+ * >+ * @see #setFeatures setFeatures >+ */ >+ public CxpFeatures getFeatures() { >+ if (ced == null) >+ return CxpFeatures.DEFAULT; >+ return ced.getFeatures(); >+ } >+ >+ /** >+ * Specify the features to be applied to the processor associated with this >+ * <code>CxpHelper</code> instance. >+ * Note that the value of {@link CxpFeatures#specialsCount specialsCount} >+ * cannot be changed (the new value will be ignored).<br> >+ * The {@link #CxpHelper() no-op helper} does nothing. >+ * >+ * @see #getFeatures getFeatures >+ */ >+ public void setFeatures(CxpFeatures features) { >+ if (ced == null) { >+ return; // do nothing >+ } >+ ced.setFeatures(features); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link ICxpProcessor#processSpecial processSpecial} in implementations >+ * of {@link ICxpProcessor} to retrieve the bidirectional class of >+ * characters in the <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 #CxpHelper() no-op helper} returns >+ * <code>Character.DIRECTIONALITY_UNDEFINED</code>. >+ */ >+ public byte getDirProp(int index) { >+ if (ced == null) >+ return Character.DIRECTIONALITY_UNDEFINED; >+ return ced.getDirProp(index); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link ICxpProcessor#processSpecial processSpecial} in implementations >+ * of {@link ICxpProcessor} to set or override the bidirectional >+ * class of characters in the <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 #CxpHelper() no-op helper} does nothing. >+ */ >+ public void setDirProp(int index, byte dirProp) { >+ if (ced != null) >+ ced.getDirProp(index); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link ICxpProcessor#processSpecial processSpecial} in implementations >+ * of {@link ICxpProcessor} >+ * to specify that a mark character must be added before the character >+ * at the specified position of the <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 #CxpHelper() no-op helper} does nothing. >+ */ >+ public void insertMark(int offset) { >+ if (ced != null) >+ ced.insertMark(offset); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link ICxpProcessor#processSpecial processSpecial} in >+ * implementations of {@link ICxpProcessor} to add a >+ * directional mark before an >+ * operator if needed for correct display, depending on the >+ * base direction of the expression and on the class of the >+ * characters in the <i>lean</i> text preceding and following >+ * the operator itself.<br> >+ * The {@link #CxpHelper() 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 (ced != null) >+ ced.processOperator(operLocation); >+ } >+ >+ /** >+ * This method can be called from within >+ * {@link ICxpProcessor#indexOfSpecial indexOfSpecial} or >+ * {@link ICxpProcessor#processSpecial processSpecial} in >+ * implementations of {@link ICxpProcessor} to >+ * set the final state which should be used for the next call to >+ * {@link #leanToFullText(java.lang.String, int)}.<br> >+ * The {@link #CxpHelper() no-op helper} does nothing. >+ */ >+ public void setFinalState(int newState) { >+ if (ced != null) >+ ced.setFinalState(newState); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java >diff -N src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/complexp/CxpProcessor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,97 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.equinox.bidi.complexp; >+ >+import org.eclipse.equinox.bidi.internal.complexp.CxpDoer; >+ >+/** >+ * Generic processor which can be used as superclass (base class) >+ * for specific complex expression processors. >+ * <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 #init2 init2} methods. >+ * Both methods have a {@link CxpHelper} argument named <code>ceh</code>. >+ * All calls to methods of <code>CxpProcessor</code> have a >+ * <code>ceh</code> argument. >+ * If a processor needs to retain some data across invocations, it may >+ * access the field {@link CxpDoer#procData ceh.ced.procData}. >+ * It is guaranteed that this field will not be modified by any code >+ * except the processor itself.</li> >+ * <li>The behavior of a processor is governed by 3 factors: >+ * <ul> >+ * <li>The {@link CxpFeatures#operators operators} field of its >+ * {@link CxpFeatures 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 CxpFeatures#dirArabic direction}. >+ * <li>The counter {@link CxpFeatures#specialsCount specialsCount} >+ * determines how many special cases need to be handled by >+ * code specific to that processor. >+ * </ul> >+ * >+ * @author Matitiahu Allouche >+ */ >+public class CxpProcessor implements ICxpProcessor { >+ >+ /** >+ * In <code>CxpProcessor</code> this method returns a >+ * {@link CxpFeatures#DEFAULT DEFAULT} value which >+ * directs the processor to do nothing. >+ */ >+ public CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return CxpFeatures.DEFAULT; >+ } >+ >+ /** >+ * In <code>CxpProcessor</code> this method simply calls the >+ * {@link #init init} method. If this is good enough, i.e. >+ * if the {@link CxpFeatures features} of the processor are >+ * determined identically for initialization and after a >+ * change in the {@link CxpEnv environment}, subclasses of >+ * <code>CxpProcessor</code> don't need to override this >+ * method. >+ */ >+ public CxpFeatures init2(CxpHelper ceh, CxpEnv env) { >+ return init(ceh, env); >+ } >+ >+ /** >+ * In <code>CxpProcessor</code> this method throws an >+ * <code>IllegalStateException</code>. This is appropriate behavior >+ * (and does not need to be overridden) for processors whose >+ * {@link CxpFeatures#specialsCount specialsCount} is zero, which >+ * means that <code>indexOfSpecial</code> should never be called >+ * for them. >+ */ >+ public int indexOfSpecial(CxpHelper ceh, int whichSpecial, String srcText, int fromIndex) { >+ // This method must be overridden by all subclasses with special cases. >+ throw new IllegalStateException(); >+ } >+ >+ /** >+ * In <code>CxpProcessor</code> this method throws an >+ * <code>IllegalStateException</code>. This is appropriate behavior >+ * (and does not need to be overridden) for processors whose >+ * {@link CxpFeatures#specialsCount specialsCount} is zero, which >+ * means that <code>processSpecial</code> should never be called >+ * for them. >+ */ >+ public int processSpecial(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) { >+ // This method must be overridden by all subclasses with any special case. >+ throw new IllegalStateException(); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/complexp/CxpUtil.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/CxpUtil.java >diff -N src/org/eclipse/equinox/bidi/complexp/CxpUtil.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/complexp/CxpUtil.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,313 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.equinox.bidi.complexp; >+ >+/** >+ * This class provides a number of convenience functions facilitating the >+ * processing of complex expressions. >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * @noinstantiate This class is not intended to be instantiated by clients. >+ * >+ * @author Matitiahu Allouche >+ */ >+final public class CxpUtil { >+ >+ /** >+ * prevent instantiation >+ */ >+ private CxpUtil() { >+ // empty >+ } >+ >+ /** This is a convenience method which can add directional marks in a given >+ * text before the characters specified in the given array of offsets, >+ * and can add a prefix and/or a suffix of directional formatting characters. >+ * This can be used for instance after obtaining offsets by calling >+ * {@link CxpHelper#leanBidiCharOffsets() leanBidiCharOffsets} in order to >+ * produce a <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 CxpFeatures#DIR_LTR} or >+ * {@link CxpFeatures#DIR_RTL}. >+ * >+ * @param affix specifies if a prefix and a suffix should be added to >+ * the result to make sure that the <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 == CxpFeatures.DIR_LTR) { >+ curMark = LRM; >+ curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$ >+ curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$ >+ } else { >+ curMark = RLM; >+ curPrefix = "\u202b\u200f"; /* RLE+RLM *///$NON-NLS-1$ >+ curSuffix = "\u200f\u202c"; /* RLM+PDF *///$NON-NLS-1$ >+ } >+ // add marks at offsets >+ if ((offsets != null) && (offsets.length > 0)) { >+ int offLen = offsets.length; >+ fullChars = new char[textLen + offLen]; >+ int added = 0; >+ for (int i = 0, j = 0; i < textLen; i++) { >+ c = text.charAt(i); >+ if ((j < offLen) && (i == offsets[j])) { >+ fullChars[i + added] = curMark; >+ added++; >+ j++; >+ } >+ fullChars[i + added] = c; >+ } >+ full = new String(fullChars); >+ } else { >+ full = text; >+ } >+ if (affix) >+ return curPrefix + full + curSuffix; >+ return full; >+ } >+ >+ /*************************************************************************/ >+ /* */ >+ /* The following code is provided for compatibility with TextProcessor */ >+ /* */ >+ /*************************************************************************/ >+ >+ // The default set of delimiters to use to segment a string. >+ private static final String defaultDelimiters = ".:/\\"; //$NON-NLS-1$ >+ // left to right mark >+ private static final char LRM = '\u200e'; >+ // left to right mark >+ private static final char RLM = '\u200f'; >+ // left to right embedding >+ private static final char LRE = '\u202a'; >+ // right to left embedding >+ private static final char RLE = '\u202b'; >+ // pop directional format >+ private static final char PDF = '\u202c'; >+ >+ static boolean isProcessingNeeded() { >+ if (!CxpEnv.isSupportedOS()) >+ return false; >+ return CxpEnv.DEFAULT.isBidi(); >+ } >+ >+ /** >+ * Process the given text and return a string with appropriate >+ * directional formatting characters if the locale is a bidi locale. >+ * This is equivalent to calling >+ * {@link #process(String str, String delimiters)} with the default >+ * set of delimiters (dot, colon, slash, backslash). >+ * >+ * @param str the text to be processed. >+ * >+ * @return the processed string. >+ */ >+ public static String process(String str) { >+ return process(str, defaultDelimiters); >+ } >+ >+ /** >+ * Process a string that has a particular semantic meaning to render >+ * it correctly on bidi locales. This is done by adding directional >+ * formatting characters so that presentation using the Unicode >+ * Bidirectional Algorithm will provide the expected result. >+ * The text is segmented according to the provided delimiters. >+ * Each segment has the Unicode Bidi Algorithm applied to it, >+ * but as a whole, the string is oriented left to right. >+ * <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 >+ CxpEnv env = new CxpEnv(null, false, CxpEnv.ORIENT_UNKNOWN); >+ CxpHelper helper = new CxpHelper(new CxpProcessor(), env); >+ helper.setFeatures(new CxpFeatures(delimiters, 0, -1, -1, false, false)); >+ return helper.leanToFullText(str); >+ } >+ >+ /** >+ * Process a string that has a particular semantic meaning to render >+ * it correctly on bidi locales. This is done by adding directional >+ * formatting characters so that presentation using the Unicode >+ * Bidirectional Algorithm will provide the expected result.. >+ * The text is segmented according to the syntax specified in the >+ * <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 IProcessorTypes} 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 >+ CxpEnv env = new CxpEnv(null, false, CxpEnv.ORIENT_UNKNOWN); >+ CxpHelper helper = new CxpHelper(type, env); >+ return helper.leanToFullText(str); >+ } >+ >+ /** >+ * Remove directional formatting characters in the given string that >+ * were inserted by one of the {@link #process process} methods. >+ * >+ * @param str string with directional characters to remove. >+ * >+ * @return string with no directional formatting characters. >+ */ >+ public static String deprocess(String str) { >+ if ((str == null) || (str.length() <= 1) || !isProcessingNeeded()) >+ return str; >+ >+ StringBuffer buf = new StringBuffer(); >+ int strLen = str.length(); >+ for (int i = 0; i < strLen; i++) { >+ char c = str.charAt(i); >+ switch (c) { >+ case LRM : >+ continue; >+ case LRE : >+ continue; >+ case PDF : >+ continue; >+ default : >+ buf.append(c); >+ } >+ } >+ return buf.toString(); >+ } >+ >+ /** >+ * Remove directional formatting characters in the given string that >+ * were inserted by the {@link #processTyped processTyped} method. >+ * >+ * @param str string with directional characters to remove. >+ * >+ * @param type type of the complex expression as specified when >+ * calling {@link #processTyped processTyped}. >+ * >+ * @return string with no directional formatting characters. >+ */ >+ public static String deprocess(String str, String type) { >+ if ((str == null) || (str.length() <= 1) || !isProcessingNeeded()) >+ return str; >+ >+ // make sure that LRE/PDF are added around the string >+ CxpEnv env = new CxpEnv(null, false, CxpEnv.ORIENT_UNKNOWN); >+ CxpHelper helper = new CxpHelper(type, env); >+ return helper.fullToLeanText(str); >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java >diff -N src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java >--- src/org/eclipse/equinox/bidi/complexp/IBiDiProcessor.java 3 Feb 2010 20:00:59 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,106 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2010 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- ******************************************************************************/ >-package org.eclipse.equinox.bidi.complexp; >- >-/** >- * Bi-directional processors supplied in this bundle. >- * >- * @noextend This interface is not intended to be extended by clients. >- */ >-public interface IBiDiProcessor { >- >- /** >- * Constant indicating a type of complex expression processor adapted >- * to processing property file statements. It expects the following >- * string format: >- * <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/ICxpProcessor.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/ICxpProcessor.java >diff -N src/org/eclipse/equinox/bidi/complexp/ICxpProcessor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/complexp/ICxpProcessor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,149 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.equinox.bidi.complexp; >+ >+import org.eclipse.equinox.bidi.internal.complexp.CxpDoer; >+ >+/** >+ * Interface for all complex expression processors. >+ * For guidelines about implementation, see >+ * {@link CxpProcessor}. >+ * >+ * @author Matitiahu Allouche >+ */ >+public interface ICxpProcessor { >+ >+ /** >+ * Do whatever initializations are needed and return the >+ * {@link CxpFeatures} characterizing the processor. >+ * >+ * @param env the current environment, which may affect the >+ * initializations. >+ * >+ * @param ceh <code>CxpHelper</code> instance which called this method. >+ * This allows access to the field >+ * {@link CxpDoer#procData ceh.ced.procData} where >+ * the processor can keep whatever data it needs. >+ * >+ * @return the features in use for this processor. >+ */ >+ public abstract CxpFeatures init(CxpHelper ceh, CxpEnv env); >+ >+ /** >+ * Do whatever renewed initializations are needed after a >+ * change in the environment and return the possibly updated >+ * {@link CxpFeatures} characterizing the processor. >+ * >+ * @param env the updated environment, which may affect the >+ * initializations. >+ * >+ * @param ceh <code>CxpHelper</code> instance which called this method. >+ * This allows access to the field >+ * {@link CxpDoer#procData ceh.ced.procData} where >+ * the processor can keep whatever data it needs. >+ * >+ * @return the features to use for this processor. >+ */ >+ public CxpFeatures init2(CxpHelper ceh, CxpEnv env); >+ >+ /** >+ * Locate occurrences of special strings within a complex expression >+ * and return their indexes one after the other in successive calls. >+ * <p> >+ * This method is called repeatedly from the code implementing >+ * {@link CxpHelper#leanToFullText leanToFullText} if the field >+ * {@link CxpFeatures#specialsCount specialsCount} returned when >+ * {@link #init initializing} the processor is greater than zero. >+ * <p> >+ * The code implementing this method may use the following methods >+ * in {@link CxpHelper}: >+ * <ul> >+ * <li>{@link CxpHelper#getDirProp getDirProp}</li> >+ * <li>{@link CxpHelper#setDirProp setDirProp}</li> >+ * <li>{@link CxpHelper#insertMark insertMark}</li> >+ * <li>{@link CxpHelper#processOperator processOperator}</li> >+ * <li>{@link CxpHelper#setFinalState setFinalState}</li> >+ * </ul> >+ * >+ * @param whichSpecial 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(CxpHelper ceh, int whichSpecial, String srcText, int fromIndex); >+ >+ /** >+ * This method is called by {@link CxpHelper#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 CxpHelper}: >+ * <ul> >+ * <li>{@link CxpHelper#getDirProp getDirProp}</li> >+ * <li>{@link CxpHelper#setDirProp setDirProp}</li> >+ * <li>{@link CxpHelper#insertMark insertMark}</li> >+ * <li>{@link CxpHelper#processOperator processOperator}</li> >+ * <li>{@link CxpHelper#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 CxpHelper#setFinalState setFinalState}. >+ * The meaning of this state is internal to the processor. >+ * On a later call to >+ * {@link CxpHelper#leanToFullText(String text, int initState)} >+ * specifying that state value, <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 >+ * {@link #indexOfSpecial indexOfSpecial}. In calls to >+ * {@link CxpHelper#leanToFullText(String text, int initState)} or >+ * {@link CxpHelper#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>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. >+ * <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(CxpHelper ceh, int whichSpecial, String srcText, int operLocation); >+ >+} >Index: src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java >diff -N src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/complexp/IProcessorTypes.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,106 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.equinox.bidi.complexp; >+ >+/** >+ * Bidirectional processors supplied in this bundle. >+ * >+ * @noextend This interface is not intended to be extended by clients. >+ */ >+public interface IProcessorTypes { >+ >+ /** >+ * Constant indicating a type of complex expression processor adapted >+ * to processing property file statements. It expects the following >+ * string format: >+ * <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/StringProcessor.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/complexp/StringProcessor.java,v >retrieving revision 1.1 >diff -u -r1.1 StringProcessor.java >--- src/org/eclipse/equinox/bidi/complexp/StringProcessor.java 3 Feb 2010 20:00:59 -0000 1.1 >+++ src/org/eclipse/equinox/bidi/complexp/StringProcessor.java 4 Jan 2011 18:03:21 -0000 >@@ -10,22 +10,31 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.complexp; > >-import org.eclipse.equinox.bidi.internal.complexp.BiDiTypesCollector; >+import org.eclipse.equinox.bidi.internal.complexp.BidiTypesCollector; > > /** >- * The API part for the TextProcessor replacement. >+ * This class provides access to registered complex expression processors. > */ >-// TBD processors currently are not thread-safe (ComplExpBasic has class variables containing >-// parsing state). This means that either: >-// a) a new instance of the processor needs to be created for every call; >-// b) processors have to be made thread-safe. > public class StringProcessor { >+ /** >+ * Retrieve all registered types of complex expression processors. >+ * >+ * @return an array of strings, each string identifying a type of >+ * complex expression processor. >+ */ >+ static public String[] getKnownTypes() { >+ return BidiTypesCollector.getInstance().getTypes(); >+ } > >- static public String[] getKnownTypes() { >- return BiDiTypesCollector.getInstance().getTypes(); >- } >- >- static public IComplExpProcessor getProcessor(String type) { >- return BiDiTypesCollector.getInstance().getProcessor(type); >- } >+ /** >+ * Get access to a complex expression processor of a given type. >+ * >+ * @param type string identifying a type of processor >+ * >+ * @return a reference to an instance of a processor of the >+ * required type. If the type is unknown, return <code>null</code>. >+ */ >+ static public ICxpProcessor getProcessor(String type) { >+ return BidiTypesCollector.getInstance().getProcessor(type); >+ } > } >Index: src/org/eclipse/equinox/bidi/complexp/package.html >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/components/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/complexp/package.html,v >retrieving revision 1.1 >diff -u -r1.1 package.html >--- src/org/eclipse/equinox/bidi/complexp/package.html 2 Feb 2010 21:55:25 -0000 1.1 >+++ src/org/eclipse/equinox/bidi/complexp/package.html 4 Jan 2011 18:03:21 -0000 >@@ -5,7 +5,7 @@ > </head> > <body bgcolor="white"> > >-This package provides an interface and implementing classes for >+This package provides interfaces and classes for > processing complex expressions. > > >@@ -14,10 +14,10 @@ > Bidirectional text offers interesting challenges to presentation systems. > For plain text, the Unicode Bidirectional Algorithm > (<a href="http://www.unicode.org/reports/tr9/">UBA</a>) >-generally specifies satisfactorily how to reorder Bidirectional text for >+generally specifies satisfactorily how to reorder bidirectional text for > display. This algorithm is implemented in Java's presentation system.</p> > <p> >-However, all Bidirectional text is not necessarily plain text. There >+However, all bidirectional text is not necessarily plain text. There > are also instances of text structured to follow a given syntax, which > should be reflected in the display order. The general algorithm, which > has no awareness of these special cases, often gives incorrect results >@@ -27,37 +27,22 @@ > formatting characters at proper locations in the text to supplement the > standard algorithm, so that the final result is correctly displayed > using the UBA. >-A class which handles complex expressions is thus a transformation >-engine which receives text without directional formatting characters >-as input and produces as output the same text with added directional >-formatting characters, hopefully in the minimum quantity which is >-sufficient to ensure correct display, considering the type of complex >-expression involved.</p> >+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> >-{@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: >+The class {@link <a href="CxpHelper.html"><b>CxpHelper</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="ICxpProcessor.html"><b><i>processor</i></b></a>} :</p> > <ul> > <li>property (name=value)</li> > <li>compound name (xxx_yy_zzzz)</li> >@@ -73,20 +58,57 @@ > <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> >+Other classes and one interface in this package may be used to >+complement and facilitate the action of >+{@link <a href="CxpHelper.html">CxpHelper</a>}: >+<ul> >+ <li>{@link <a href="CxpEnv.html">CxpEnv</a>} which regroups >+ details about the environment</li> >+ <li>{@link <a href="CxpFeatures.html">CxpFeatures</a>} which allows viewing >+ and manipulating some factors which affect >+ a complex expression processor's behavior</li> >+ <li>{@link <a href="CxpUtil.html">CxpUtil</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="IProcessorTypes.html">IProcessorTypes</a>} is an >+ interface which contains only literals identifying the various types >+ of complex expressions currently supported.</li> >+</ul> >+<p> >+{@link <a href="CxpHelper.html">CxpHelper</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 >+present package: >+<ul> >+ <li>{@link <a href="ICxpProcessor.html">ICxpProcessor</a>} is an interface >+ specifying which methods a processor must provide.</li> >+ <li>{@link <a href="CxpProcessor.html">CxpProcessor</a>} is a generic >+ processor which can be used as superclass for specific processors. >+ <li>{@link <a href="StringProcessor.html">StringProcessor</a>} is a class >+ which allows retrieval of the defined processor types and of the >+ corresponding processors. >+</ul> > <p> >+There are two other packages associated with the current one: >+<ul> >+ <li>{@link <a href="..\internal\complexp\package-summary.html"> >+ org.eclipse.equinox.bidi.internal.complexp</a>}</li> >+ <li>{@link <a href="..\internal\complexp\consumable\package-summary.html"> >+ org.eclipse.equinox.bidi.internal.complexp.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> > >@@ -121,15 +143,15 @@ > <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 >+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 >+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> >@@ -146,13 +168,5 @@ > 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/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/BidiActivator.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/BidiActivator.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/BidiActivator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/BidiActivator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,62 @@ >+/******************************************************************************* >+ * 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 >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/BidiTypesCollector.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,111 @@ >+/******************************************************************************* >+ * 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.ICxpProcessor; >+ >+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 ICxpProcessor getProcessor(String type) { >+ if (types == null) >+ read(); >+ Object processor = types.get(type); >+ if (processor instanceof ICxpProcessor) >+ return (ICxpProcessor) 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/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/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/CxpDelims.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/CxpDelims.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/CxpDelims.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/CxpDelims.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,61 @@ >+/******************************************************************************* >+ * 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.CxpHelper; >+import org.eclipse.equinox.bidi.complexp.CxpProcessor; >+ >+/** >+ * <code>CxpDelims</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 CxpDelims extends CxpProcessor { >+ >+ /** >+ * This method locates occurrences of start delimiters. >+ */ >+ public int indexOfSpecial(CxpHelper ceh, int whichSpecial, String srcText, int fromIndex) { >+ char delim = getDelimiters().charAt(whichSpecial * 2); >+ return srcText.indexOf(delim, fromIndex); >+ } >+ >+ /** >+ * This method skips until after the matching end delimiter. >+ */ >+ public int processSpecial(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) { >+ ceh.processOperator(operLocation); >+ int loc = operLocation + 1; >+ char delim = getDelimiters().charAt((whichSpecial * 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/complexp/CxpDelimsEsc.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/CxpDelimsEsc.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/CxpDelimsEsc.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/CxpDelimsEsc.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,55 @@ >+/******************************************************************************* >+ * 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.CxpHelper; >+ >+/** >+ * <code>CxpDelims</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 CxpDelims} 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 CxpDelimsEsc extends CxpDelims { >+ >+ /** >+ * This method skips until after the matching end delimiter, >+ * ignoring possibly escaped end delimiters. >+ */ >+ public int processSpecial(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) { >+ ceh.processOperator(operLocation); >+ int loc = operLocation + 1; >+ char delim = getDelimiters().charAt((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/CxpDoer.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/CxpDoer.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/CxpDoer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/CxpDoer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,712 @@ >+/******************************************************************************* >+ * 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>CxpDoer</code> provides the code which implements the API in >+ * {@link CxpHelper}. All its public methods are shadows of similarly >+ * signed methods of <code>CxpHelper</code>, and their documentation >+ * is by reference to the methods in <code>CxpHelper</code>. >+ * >+ * @author Matitiahu Allouche >+ */ >+public class CxpDoer { >+ >+ 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; >+ >+ CxpHelper ceh; >+ >+ CxpEnv env; >+ >+ ICxpProcessor proc; >+ >+ /** >+ * This field is reserved for use of the complex expression >+ * processor associated with this instance of <code>CxpDoer</code>. >+ * The processor can keep here a reference to an object that it >+ * has sole control of. >+ */ >+ public Object procData; >+ >+ /** >+ * Features of the associated processor. >+ * >+ */ >+ public CxpFeatures cef; >+ >+ int state = CxpHelper.STATE_NOTHING_GOING; >+ >+ byte curStrong = -1; >+ char curMark; >+ char curEmbed; >+ int prefixLength; >+ int[] locations; >+ int specialsCount; >+ String leanText; >+ int[] offsets; >+ 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 CxpHelper#CxpHelper(ICxpProcessor proc, CxpEnv env) >+ */ >+ public CxpDoer(CxpHelper caller, ICxpProcessor proc, CxpEnv env) { >+ ceh = caller; >+ if (env == null) { >+ this.env = CxpEnv.DEFAULT; >+ } else { >+ this.env = env; >+ } >+ this.proc = proc; >+ cef = proc.init(ceh, this.env); >+ // keep private copy of specialsCount to avoid later modification >+ specialsCount = cef.specialsCount; >+ locations = new int[cef.operators.length() + specialsCount]; >+ } >+ >+ long computeNextLocation(int curPos) { >+ int operCount = cef.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 = proc.indexOfSpecial(ceh, 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(cef.operators.charAt(i), curPos); >+ if (loc < 0) >+ loc = len; >+ locations[i] = loc; >+ } >+ if (loc < nextLocation) { >+ nextLocation = loc; >+ idxLocation = i; >+ } >+ } >+ return nextLocation + (((long) idxLocation) << 32); >+ } >+ >+ int getCurOrient() { >+ if (curOrient >= 0) >+ return curOrient; >+ >+ if ((env.orientation & CxpEnv.ORIENT_CONTEXTUAL_LTR) == 0) { >+ // absolute orientation >+ curOrient = env.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 = CxpEnv.ORIENT_LTR; >+ return curOrient; >+ } >+ if (dirProp == R || dirProp == AL) { >+ curOrient = CxpEnv.ORIENT_RTL; >+ return curOrient; >+ } >+ } >+ curOrient = env.orientation & 1; >+ return curOrient; >+ } >+ >+ /** >+ * @see CxpHelper#getCurDirection >+ */ >+ public int getCurDirection() { >+ if (curDirection >= 0) >+ return curDirection; >+ >+ curStrong = -1; >+ // same direction for Arabic and Hebrew? >+ if (cef.dirArabic == cef.dirHebrew) { >+ curDirection = cef.dirArabic; >+ 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 = cef.dirArabic; >+ return curDirection; >+ } >+ if (dirProp == R) { >+ curDirection = cef.dirHebrew; >+ return curDirection; >+ } >+ } >+ // found no Arabic or Hebrew character >+ curDirection = CxpFeatures.DIR_LTR; >+ return curDirection; >+ } >+ >+ void setMarkAndFixes() { >+ int dir = getCurDirection(); >+ if (curStrong == STRONGS[dir]) >+ return; >+ curStrong = STRONGS[dir]; >+ curMark = MARKS[dir]; >+ curEmbed = EMBEDS[dir]; >+ } >+ >+ /** >+ * @see CxpHelper#getDirProp(int index) >+ */ >+ public byte getDirProp(int index) { >+ byte dirProp = dirProps[index]; >+ if (dirProp == 0) { >+ dirProp = Character.getDirectionality(leanText.charAt(index)); >+ if (dirProp == B) >+ dirProp = getCurOrient() == CxpEnv.ORIENT_RTL ? R : L; >+ dirProps[index] = (byte) (dirProp + 2); >+ return dirProp; >+ } >+ return (byte) (dirProp - 2); >+ } >+ >+ /** >+ * @see CxpHelper#setDirProp(int index, byte dirProp) >+ */ >+ public void setDirProp(int index, byte dirProp) { >+ dirProps[index] = (byte) (dirProp + 2); >+ } >+ >+ /** >+ * @see CxpHelper#processOperator(int operLocation) >+ */ >+ public void processOperator(int operLocation) { >+ int len = leanText.length(); >+ boolean doneAN = false; >+ >+ if (getCurDirection() == CxpFeatures.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 (cef.ignoreArabic) { >+ if (cef.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 (cef.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 CxpHelper#getFinalState() >+ */ >+ public int getFinalState() { >+ return state; >+ } >+ >+ /** >+ * @see CxpHelper#setFinalState(int newState) >+ */ >+ public void setFinalState(int newState) { >+ state = newState; >+ } >+ >+ /** >+ * @see CxpHelper#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 = cef.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 = CxpHelper.STATE_NOTHING_GOING; >+ if (initState != CxpHelper.STATE_NOTHING_GOING) >+ curPos = proc.processSpecial(ceh, 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 = proc.processSpecial(ceh, idxLocation - operCount, leanText, nextLocation); >+ } >+ } >+ } >+ >+ /** >+ * @see CxpHelper#leanBidiCharOffsets() >+ */ >+ public int[] leanBidiCharOffsets() { >+ int[] result = new int[count]; >+ System.arraycopy(offsets, 0, result, 0, count); >+ return result; >+ } >+ >+ /** >+ * @see CxpHelper#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 CxpHelper#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 CxpHelper#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 CxpHelper#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 CxpHelper#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 >+ 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 == CxpEnv.ORIENT_IGNORE))) { >+ prefixLength = 0; >+ return leanText; >+ } >+ int len = leanText.length(); >+ int newLen = len + count; >+ if (addFixes && ((getCurOrient() != getCurDirection()) || (curOrient == CxpEnv.ORIENT_UNKNOWN))) { >+ if ((env.orientation & CxpEnv.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 CxpHelper#getEnvironment() >+ */ >+ public CxpEnv getEnvironment() { >+ return env; >+ } >+ >+ /** >+ * @see CxpHelper#setEnvironment(CxpEnv environment) >+ */ >+ public void setEnvironment(CxpEnv environment) { >+ env = environment; >+ cef = proc.init2(ceh, env); >+ specialsCount = cef.specialsCount; >+ } >+ >+ /** >+ * @see CxpHelper#getFeatures() >+ */ >+ public CxpFeatures getFeatures() { >+ return cef; >+ } >+ >+ /** >+ * @see CxpHelper#setFeatures(CxpFeatures features) >+ */ >+ public void setFeatures(CxpFeatures features) { >+ if (features.operators.length() > cef.operators.length()) >+ locations = new int[features.operators.length() + specialsCount]; >+ cef = features; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/CxpSingle.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/CxpSingle.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/CxpSingle.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/CxpSingle.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,51 @@ >+/******************************************************************************* >+ * 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>CxpSingle</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 CxpFeatures#operators operators} >+ * field in the {@link CxpFeatures features} >+ * of this processor should contain exactly one character. >+ * Additional characters will be ignored. >+ * >+ * @author Matitiahu Allouche >+ */ >+public abstract class CxpSingle extends CxpProcessor { >+ >+ /** >+ * This method locates occurrences of the operator. >+ */ >+ public int indexOfSpecial(CxpHelper ceh, int whichSpecial, String srcText, int fromIndex) { >+ return srcText.indexOf(ceh.ced.cef.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(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) { >+ ceh.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/complexp/consumable/CxpComma.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpComma.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpComma.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpComma.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,34 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * Processor adapted to processing comma-delimited lists, such as: >+ * <pre> >+ * part1,part2,part3 >+ * </pre> >+ */ >+public class CxpComma extends CxpProcessor { >+ static final CxpFeatures FEATURES = new CxpFeatures(",", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpEmail.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpEmail.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpEmail.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpEmail.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,45 @@ >+/******************************************************************************* >+ * 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.*; >+import org.eclipse.equinox.bidi.internal.complexp.CxpDelimsEsc; >+ >+/** >+ * Processor adapted to processing e-mail addresses. >+ */ >+public class CxpEmail extends CxpDelimsEsc { >+ static final int LTR = CxpFeatures.DIR_LTR; >+ static final int RTL = CxpFeatures.DIR_RTL; >+ static final CxpFeatures MIRRORED = new CxpFeatures("<>.:,;@", 2, RTL, LTR, false, false); //$NON-NLS-1$ >+ static final CxpFeatures NOT_MIRRORED = new CxpFeatures("<>.:,;@", 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 CxpFeatures init(CxpHelper ceh, CxpEnv 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/complexp/consumable/CxpFile.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpFile.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpFile.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpFile.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,31 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * Processor adapted to processing directory and file paths. >+ */ >+public class CxpFile extends CxpProcessor { >+ static final CxpFeatures FEATURES = new CxpFeatures(":/\\.", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpJava.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpJava.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpJava.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpJava.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,127 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * <code>CxpJava</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 CxpHelper#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 CxpHelper#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 CxpHelper >+ * >+ * @author Matitiahu Allouche >+ */ >+public class CxpJava extends CxpProcessor { >+ private static final byte WS = Character.DIRECTIONALITY_WHITESPACE; >+ static final CxpFeatures FEATURES = new CxpFeatures("[](){}.+-<>=~!&*/%^|?:,;\t", 4, -1, -1, false, false); //$NON-NLS-1$ >+ static final String lineSep = CxpEnv.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 CxpFeatures init(CxpHelper ceh, CxpEnv 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(CxpHelper ceh, 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 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(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) { >+ int loc, cnt, i; >+ >+ ceh.processOperator(operLocation); >+ switch (whichSpecial) { >+ case 0 : /* space */ >+ operLocation++; >+ while (operLocation < srcText.length() && srcText.charAt(operLocation) == ' ') { >+ ceh.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) { >+ ceh.setFinalState(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 srcText.length(); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpMath.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpMath.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpMath.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpMath.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,33 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * Processor adapted to processing arithmetic expressions with right-to-left >+ * base direction. >+ */ >+public class CxpMath extends CxpProcessor { >+ static final int RTL = CxpFeatures.DIR_RTL; >+ static final CxpFeatures FEATURES = new CxpFeatures("+-/*()=", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpProperty.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpProperty.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpProperty.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpProperty.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,36 @@ >+/******************************************************************************* >+ * 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.*; >+import org.eclipse.equinox.bidi.internal.complexp.CxpSingle; >+ >+/** >+ * Processor adapted to processing property file statements. >+ * It expects the following string format: >+ * <pre> >+ * name=value >+ * </pre> >+ */ >+public class CxpProperty extends CxpSingle { >+ static final CxpFeatures FEATURES = new CxpFeatures("=", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpRegex.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpRegex.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpRegex.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpRegex.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,207 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * <code>CxpRegex</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 CxpHelper#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 CxpHelper#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 CxpHelper >+ * >+ * @author Matitiahu Allouche >+ */ >+public class CxpRegex extends CxpProcessor { >+ 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 CxpFeatures FEATURES = new CxpFeatures(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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+ /** >+ * This method locates occurrences of the syntactic strings and of >+ * R, AL, EN, AN characters. >+ */ >+ public int indexOfSpecial(CxpHelper ceh, 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); >+ } >+ // 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 = ceh.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 (ceh.getDirProp(fromIndex - 1) == dirProp) >+ continue; >+ >+ for (int i = fromIndex - 1; i >= 0; i--) { >+ dirProp = ceh.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(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) { >+ int loc; >+ >+ switch (whichSpecial) { >+ case 0 : /* comment (?#...) */ >+ if (operLocation < 0) { >+ // initial state from previous line >+ loc = 0; >+ } else { >+ ceh.processOperator(operLocation); >+ // skip the opening "(?#" >+ loc = operLocation + 3; >+ } >+ loc = srcText.indexOf(')', loc); >+ if (loc < 0) { >+ ceh.setFinalState(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) */ >+ ceh.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 { >+ ceh.processOperator(operLocation); >+ // skip the opening "\Q" >+ loc = operLocation + 2; >+ } >+ loc = srcText.indexOf("\\E", loc); //$NON-NLS-1$ >+ if (loc < 0) { >+ ceh.setFinalState(whichSpecial); >+ return srcText.length(); >+ } >+ // set the dirProp for the "E" >+ ceh.setDirProp(loc + 1, L); >+ return loc + 2; >+ case 17 : /* R, AL, AN, EN */ >+ ceh.processOperator(operLocation); >+ return operLocation + 1; >+ >+ } >+ // we should never get here >+ return srcText.length(); >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpSql.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpSql.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpSql.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpSql.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,148 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * <code>CxpSql</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 CxpHelper#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 CxpHelper#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 CxpHelper >+ * >+ * @author Matitiahu Allouche >+ */ >+public class CxpSql extends CxpProcessor { >+ private static final byte WS = Character.DIRECTIONALITY_WHITESPACE; >+ static final String operators = "\t!#%&()*+,-./:;<=>?|[]{}"; //$NON-NLS-1$ >+ static final CxpFeatures FEATURES = new CxpFeatures(operators, 5, -1, -1, false, false); >+ static final String lineSep = CxpEnv.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 CxpFeatures init(CxpHelper ceh, CxpEnv 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(CxpHelper ceh, 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 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(CxpHelper ceh, int whichSpecial, String srcText, int operLocation) { >+ int loc; >+ >+ ceh.processOperator(operLocation); >+ switch (whichSpecial) { >+ case 0 : /* space */ >+ operLocation++; >+ while (operLocation < srcText.length() && srcText.charAt(operLocation) == ' ') { >+ ceh.setDirProp(operLocation, WS); >+ operLocation++; >+ } >+ return operLocation; >+ case 1 : /* literal */ >+ loc = operLocation + 1; >+ while (true) { >+ loc = srcText.indexOf('\'', loc); >+ if (loc < 0) { >+ ceh.setFinalState(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) { >+ ceh.setFinalState(whichSpecial); >+ return srcText.length(); >+ } >+ // we need to call processOperator since text may follow the >+ // end of comment immediately without even a space >+ ceh.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/CxpSystem.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpSystem.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpSystem.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpSystem.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,35 @@ >+/******************************************************************************* >+ * 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.*; >+import org.eclipse.equinox.bidi.internal.complexp.CxpSingle; >+ >+/** >+ * Processor adapted to processing expressions with the following string format: >+ * <pre> >+ * system(user) >+ * </pre> >+ */ >+public class CxpSystem extends CxpSingle { >+ static final CxpFeatures FEATURES = new CxpFeatures("(", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpURL.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpURL.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpURL.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpURL.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,32 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * Processor adapted to processing URLs. >+ */ >+public class CxpURL extends CxpProcessor { >+ static final CxpFeatures FEATURES = new CxpFeatures(":?#/@.[]", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpUnderscore.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpUnderscore.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpUnderscore.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpUnderscore.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,36 @@ >+/******************************************************************************* >+ * 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.*; >+ >+/** >+ * 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 CxpUnderscore extends CxpProcessor { >+ static final CxpFeatures FEATURES = new CxpFeatures("_", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpXPath.java >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpXPath.java >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpXPath.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/CxpXPath.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,40 @@ >+/******************************************************************************* >+ * 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.*; >+import org.eclipse.equinox.bidi.internal.complexp.CxpDelims; >+ >+/** >+ * Processor adapted to processing XPath expressions. >+ */ >+public class CxpXPath extends CxpDelims { >+ static final CxpFeatures FEATURES = new CxpFeatures(" /[]<>=!:@.|()+-*", 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 CxpFeatures init(CxpHelper ceh, CxpEnv env) { >+ return FEATURES; >+ } >+ >+ /** >+ * @return parentheses apostrophe and quotation mark as delimiters. >+ */ >+ protected String getDelimiters() { >+ return "''\"\""; //$NON-NLS-1$ >+ } >+ >+} >Index: src/org/eclipse/equinox/bidi/internal/complexp/consumable/package.html >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/consumable/package.html >diff -N src/org/eclipse/equinox/bidi/internal/complexp/consumable/package.html >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/consumable/package.html 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,14 @@ >+<!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 implementations for complex expression processors. >+More specifically, it provides implementations for all the >+complex expression processors whose types are listed in >+{@link <a href="..\..\..\complexp\IProcessorTypes.html">IProcessorTypes</a>}. >+ >+</body> >+</html> >Index: src/org/eclipse/equinox/bidi/internal/complexp/package.html >=================================================================== >RCS file: src/org/eclipse/equinox/bidi/internal/complexp/package.html >diff -N src/org/eclipse/equinox/bidi/internal/complexp/package.html >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/bidi/internal/complexp/package.html 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,12 @@ >+<!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 internal tools for the implementation >+of complex expression processors. >+ >+</body> >+</html>
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