View | Details | Raw Unified | Return to bug 183164 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.xml (-12 / +12 lines)
Lines 10-41 Link Here
10
            type="test">
10
            type="test">
11
      </typeDescription>
11
      </typeDescription>
12
     <typeDescription
12
     <typeDescription
13
            class="org.eclipse.equinox.bidi.internal.tests.TestHandler1"
13
            class="org.eclipse.equinox.bidi.internal.tests.TestProcessor1"
14
            description="Test Handler 1"
14
            description="Test processor 1"
15
            type="test.Handler1">
15
            type="test.Processor1">
16
      </typeDescription>
16
      </typeDescription>
17
      <typeDescription
17
      <typeDescription
18
            class="org.eclipse.equinox.bidi.internal.tests.TestHandler2"
18
            class="org.eclipse.equinox.bidi.internal.tests.TestProcessor2"
19
            description="Test Handler 2"
19
            description="Test processor 2"
20
            type="test.Handler2">
20
            type="test.Processor2">
21
      </typeDescription>
21
      </typeDescription>
22
      <typeDescription
22
      <typeDescription
23
            class="org.eclipse.equinox.bidi.internal.tests.TestHandler3"
23
            class="org.eclipse.equinox.bidi.internal.tests.TestProcessor3"
24
            description="Test Handler 3"
24
            description="Test processor 3"
25
            type="test.Handler3">
25
            type="test.Processor3">
26
      </typeDescription>
26
      </typeDescription>
27
      <typeDescription
27
      <typeDescription
28
            class="org.eclipse.equinox.bidi.internal.tests.TestHandlerMyCommaRL"
28
            class="org.eclipse.equinox.bidi.internal.tests.TestProcessorMyCommaRL"
29
            description="Test my comma RL"
29
            description="Test my comma RL"
30
            type="test.MyCommaRL">
30
            type="test.MyCommaRL">
31
      </typeDescription>
31
      </typeDescription>
32
       <typeDescription
32
       <typeDescription
33
            class="org.eclipse.equinox.bidi.internal.tests.TestHandlerMyCommaRR"
33
            class="org.eclipse.equinox.bidi.internal.tests.TestProcessorMyCommaRR"
34
            description="Test my comma RR"
34
            description="Test my comma RR"
35
            type="test.MyCommaRR">
35
            type="test.MyCommaRR">
36
      </typeDescription>
36
      </typeDescription>
37
      <typeDescription
37
      <typeDescription
38
            class="org.eclipse.equinox.bidi.internal.tests.TestHandlerMyCommaLL"
38
            class="org.eclipse.equinox.bidi.internal.tests.TestProcessorMyCommaLL"
39
            description="Test my comma LL"
39
            description="Test my comma LL"
40
            type="test.MyCommaLL">
40
            type="test.MyCommaLL">
41
      </typeDescription>
41
      </typeDescription>
(-)src/org/eclipse/equinox/bidi/internal/tests/STextExtensibilityTest.java (-13 / +13 lines)
Lines 11-56 Link Here
11
11
12
package org.eclipse.equinox.bidi.internal.tests;
12
package org.eclipse.equinox.bidi.internal.tests;
13
13
14
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
14
import org.eclipse.equinox.bidi.STextProcessorFactory;
15
import org.eclipse.equinox.bidi.advanced.STextExpertFactory;
15
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
16
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
16
import org.eclipse.equinox.bidi.advanced.STextExpertFactory;
17
import org.eclipse.equinox.bidi.custom.STextProcessor;
17
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
18
18
19
/**
19
/**
20
 * Tests contribution of BiDi handlers.
20
 * Tests contribution of BiDi processors.
21
 */
21
 */
22
public class STextExtensibilityTest extends STextTestBase {
22
public class STextExtensibilityTest extends STextTestBase {
23
23
24
	public void testBaseContributions() {
24
	public void testBaseContributions() {
25
		String[] types = STextTypeHandlerFactory.getAllHandlerIDs();
25
		String[] types = STextProcessorFactory.getAllProcessorIDs();
26
		assertNotNull(types);
26
		assertNotNull(types);
27
		assertTrue(types.length > 0);
27
		assertTrue(types.length > 0);
28
28
29
		// check one of the types that we know should be there
29
		// check one of the types that we know should be there
30
		assertTrue(isTypePresent(types, "regex"));
30
		assertTrue(isTypePresent(types, "regex"));
31
31
32
		STextTypeHandler handler = STextTypeHandlerFactory.getHandler("regex");
32
		STextProcessor processor = STextProcessorFactory.getProcessor("regex");
33
		assertNotNull(handler);
33
		assertNotNull(processor);
34
	}
34
	}
35
35
36
	public void testOtherContributions() {
36
	public void testOtherContributions() {
37
		String[] types = STextTypeHandlerFactory.getAllHandlerIDs();
37
		String[] types = STextProcessorFactory.getAllProcessorIDs();
38
		assertNotNull(types);
38
		assertNotNull(types);
39
		assertTrue(types.length > 0);
39
		assertTrue(types.length > 0);
40
40
41
		// check the type added by the test bundle
41
		// check the type added by the test bundle
42
		assertTrue(isTypePresent(types, "test"));
42
		assertTrue(isTypePresent(types, "test"));
43
43
44
		STextTypeHandler handler = STextTypeHandlerFactory.getHandler("test");
44
		STextProcessor processor = STextProcessorFactory.getProcessor("test");
45
		assertNotNull(handler);
45
		assertNotNull(processor);
46
46
47
		handler = STextTypeHandlerFactory.getHandler("badtest");
47
		processor = STextProcessorFactory.getProcessor("badtest");
48
		assertNull(handler);
48
		assertNull(processor);
49
49
50
		String data, lean, full, model;
50
		String data, lean, full, model;
51
		data = "ABC.DEF:HOST-COM=HELLO";
51
		data = "ABC.DEF:HOST-COM=HELLO";
52
		lean = toUT16(data);
52
		lean = toUT16(data);
53
		handler = STextTypeHandlerFactory.getHandler("test");
53
		processor = STextProcessorFactory.getProcessor("test");
54
54
55
		ISTextExpert expert = STextExpertFactory.getExpert("test");
55
		ISTextExpert expert = STextExpertFactory.getExpert("test");
56
		full = expert.leanToFullText(lean);
56
		full = expert.leanToFullText(lean);
(-)src/org/eclipse/equinox/bidi/internal/tests/STextExtensionsTest.java (-16 / +16 lines)
Lines 11-17 Link Here
11
11
12
package org.eclipse.equinox.bidi.internal.tests;
12
package org.eclipse.equinox.bidi.internal.tests;
13
13
14
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
14
import org.eclipse.equinox.bidi.STextProcessorFactory;
15
import org.eclipse.equinox.bidi.advanced.*;
15
import org.eclipse.equinox.bidi.advanced.*;
16
16
17
/**
17
/**
Lines 43-72 Link Here
43
	public void testExtensions() {
43
	public void testExtensions() {
44
		String data;
44
		String data;
45
45
46
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.COMMA_DELIMITED, env);
46
		expert = STextExpertFactory.getExpert(STextProcessorFactory.COMMA_DELIMITED, env);
47
		doTest1("Comma #1", "ab,cd, AB, CD, EFG", "ab,cd, AB@, CD@, EFG");
47
		doTest1("Comma #1", "ab,cd, AB, CD, EFG", "ab,cd, AB@, CD@, EFG");
48
48
49
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.EMAIL, env);
49
		expert = STextExpertFactory.getExpert(STextProcessorFactory.EMAIL, env);
50
		doTest1("Email #1", "abc.DEF:GHI", "abc.DEF@:GHI");
50
		doTest1("Email #1", "abc.DEF:GHI", "abc.DEF@:GHI");
51
		doTest1("Email #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI @\"A.B\"@:JK ");
51
		doTest1("Email #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI @\"A.B\"@:JK ");
52
		doTest1("Email #3", "DEF,GHI (A,B);JK ", "DEF@,GHI @(A,B)@;JK ");
52
		doTest1("Email #3", "DEF,GHI (A,B);JK ", "DEF@,GHI @(A,B)@;JK ");
53
		doTest1("Email #4", "DEF.GHI (A.B :JK ", "DEF@.GHI @(A.B :JK ");
53
		doTest1("Email #4", "DEF.GHI (A.B :JK ", "DEF@.GHI @(A.B :JK ");
54
		env = envArabic;
54
		env = envArabic;
55
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.EMAIL, env);
55
		expert = STextExpertFactory.getExpert(STextProcessorFactory.EMAIL, env);
56
		doTest1("Email #5", "#EF.GHI \"A.B\":JK ", "<&#EF.GHI \"A.B\":JK &^");
56
		doTest1("Email #5", "#EF.GHI \"A.B\":JK ", "<&#EF.GHI \"A.B\":JK &^");
57
		doTest1("Email #6", "#EF,GHI (A,B);JK ", "<&#EF,GHI (A,B);JK &^");
57
		doTest1("Email #6", "#EF,GHI (A,B);JK ", "<&#EF,GHI (A,B);JK &^");
58
		doTest1("Email #7", "#EF.GHI (A.B :JK ", "<&#EF.GHI (A.B :JK &^");
58
		doTest1("Email #7", "#EF.GHI (A.B :JK ", "<&#EF.GHI (A.B :JK &^");
59
		data = toUT16("peter.pan") + "@" + toUT16("#EF.GHI");
59
		data = toUT16("peter.pan") + "@" + toUT16("#EF.GHI");
60
		doTest2("Email #8", data, "<&peter&.pan@#EF.GHI&^");
60
		doTest2("Email #8", data, "<&peter&.pan@#EF.GHI&^");
61
		env = envHebrew;
61
		env = envHebrew;
62
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.EMAIL, env);
62
		expert = STextExpertFactory.getExpert(STextProcessorFactory.EMAIL, env);
63
		data = toUT16("peter.pan") + "@" + toUT16("DEF.GHI");
63
		data = toUT16("peter.pan") + "@" + toUT16("DEF.GHI");
64
		doTest2("Email #9", data, "peter.pan@DEF@.GHI");
64
		doTest2("Email #9", data, "peter.pan@DEF@.GHI");
65
65
66
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.FILE, env);
66
		expert = STextExpertFactory.getExpert(STextProcessorFactory.FILE, env);
67
		doTest1("File #1", "c:\\A\\B\\FILE.EXT", "c:\\A@\\B@\\FILE@.EXT");
67
		doTest1("File #1", "c:\\A\\B\\FILE.EXT", "c:\\A@\\B@\\FILE@.EXT");
68
68
69
		expert = STextExpertFactory.getPrivateExpert(STextTypeHandlerFactory.JAVA, env);
69
		expert = STextExpertFactory.getExpert(STextProcessorFactory.JAVA, env);
70
		doTest1("Java #1", "A = B + C;", "A@ = B@ + C;");
70
		doTest1("Java #1", "A = B + C;", "A@ = B@ + C;");
71
		doTest1("Java #2", "A   = B + C;", "A@   = B@ + C;");
71
		doTest1("Java #2", "A   = B + C;", "A@   = B@ + C;");
72
		doTest1("Java #3", "A = \"B+C\"+D;", "A@ = \"B+C\"@+D;");
72
		doTest1("Java #3", "A = \"B+C\"+D;", "A@ = \"B+C\"@+D;");
Lines 78-89 Link Here
78
		doTest1("Java #9", "A = //B+C* D;", "A@ = //B+C* D;");
78
		doTest1("Java #9", "A = //B+C* D;", "A@ = //B+C* D;");
79
		doTest1("Java #10", "A = //B+C`|D+E;", "A@ = //B+C`|D@+E;");
79
		doTest1("Java #10", "A = //B+C`|D+E;", "A@ = //B+C`|D@+E;");
80
80
81
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.PROPERTY, env);
81
		expert = STextExpertFactory.getExpert(STextProcessorFactory.PROPERTY, env);
82
		doTest1("Property #0", "NAME,VAL1,VAL2", "NAME,VAL1,VAL2");
82
		doTest1("Property #0", "NAME,VAL1,VAL2", "NAME,VAL1,VAL2");
83
		doTest1("Property #1", "NAME=VAL1,VAL2", "NAME@=VAL1,VAL2");
83
		doTest1("Property #1", "NAME=VAL1,VAL2", "NAME@=VAL1,VAL2");
84
		doTest1("Property #2", "NAME=VAL1,VAL2=VAL3", "NAME@=VAL1,VAL2=VAL3");
84
		doTest1("Property #2", "NAME=VAL1,VAL2=VAL3", "NAME@=VAL1,VAL2=VAL3");
85
85
86
		expert = STextExpertFactory.getPrivateExpert(STextTypeHandlerFactory.REGEXP, env);
86
		expert = STextExpertFactory.getExpert(STextProcessorFactory.REGEXP, env);
87
		data = toUT16("ABC(?") + "#" + toUT16("DEF)GHI");
87
		data = toUT16("ABC(?") + "#" + toUT16("DEF)GHI");
88
		doTest2("Regex #0.0", data, "A@B@C@(?#DEF)@G@H@I");
88
		doTest2("Regex #0.0", data, "A@B@C@(?#DEF)@G@H@I");
89
		data = toUT16("ABC(?") + "#" + toUT16("DEF");
89
		data = toUT16("ABC(?") + "#" + toUT16("DEF");
Lines 129-135 Link Here
129
		doTest1("Regex #17.7", "aB*567", "aB*@567");
129
		doTest1("Regex #17.7", "aB*567", "aB*@567");
130
130
131
		env = envArabic;
131
		env = envArabic;
132
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.REGEXP, env);
132
		expert = STextExpertFactory.getExpert(STextProcessorFactory.REGEXP, env);
133
		data = toUT16("#BC(?") + "#" + toUT16("DEF)GHI");
133
		data = toUT16("#BC(?") + "#" + toUT16("DEF)GHI");
134
		doTest2("Regex #0.0", data, "<&#BC(?#DEF)GHI&^");
134
		doTest2("Regex #0.0", data, "<&#BC(?#DEF)GHI&^");
135
		data = toUT16("#BC(?") + "#" + toUT16("DEF");
135
		data = toUT16("#BC(?") + "#" + toUT16("DEF");
Lines 167-173 Link Here
167
		doTest2("Regex #16.2", data, "<&#HI\\eJKL&^");
167
		doTest2("Regex #16.2", data, "<&#HI\\eJKL&^");
168
		env = envHebrew;
168
		env = envHebrew;
169
169
170
		expert = STextExpertFactory.getPrivateExpert(STextTypeHandlerFactory.SQL, env);
170
		expert = STextExpertFactory.getExpert(STextProcessorFactory.SQL, env);
171
		doTest1("SQL #0", "abc GHI", "abc GHI");
171
		doTest1("SQL #0", "abc GHI", "abc GHI");
172
		doTest1("SQL #1", "abc DEF   GHI", "abc DEF@   GHI");
172
		doTest1("SQL #1", "abc DEF   GHI", "abc DEF@   GHI");
173
		doTest1("SQL #2", "ABC, DEF,   GHI", "ABC@, DEF@,   GHI");
173
		doTest1("SQL #2", "ABC, DEF,   GHI", "ABC@, DEF@,   GHI");
Lines 185-206 Link Here
185
		doTest1("SQL #12", "ABC\"DEF \"\" G I\" JKL,MN", "ABC@\"DEF \"\" G I\"@ JKL@,MN");
185
		doTest1("SQL #12", "ABC\"DEF \"\" G I\" JKL,MN", "ABC@\"DEF \"\" G I\"@ JKL@,MN");
186
		doTest1("SQL #13", "ABC--DEF GHI`|JKL MN", "ABC@--DEF GHI`|JKL@ MN");
186
		doTest1("SQL #13", "ABC--DEF GHI`|JKL MN", "ABC@--DEF GHI`|JKL@ MN");
187
187
188
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.SYSTEM_USER, env);
188
		expert = STextExpertFactory.getExpert(STextProcessorFactory.SYSTEM_USER, env);
189
		doTest1("System #1", "HOST(JACK)", "HOST@(JACK)");
189
		doTest1("System #1", "HOST(JACK)", "HOST@(JACK)");
190
190
191
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.UNDERSCORE, env);
191
		expert = STextExpertFactory.getExpert(STextProcessorFactory.UNDERSCORE, env);
192
		doTest1("Underscore #1", "A_B_C_d_e_F_G", "A@_B@_C_d_e_F@_G");
192
		doTest1("Underscore #1", "A_B_C_d_e_F_G", "A@_B@_C_d_e_F@_G");
193
193
194
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.URL, env);
194
		expert = STextExpertFactory.getExpert(STextProcessorFactory.URL, env);
195
		doTest1("URL #1", "WWW.DOMAIN.COM/DIR1/DIR2/dir3/DIR4", "WWW@.DOMAIN@.COM@/DIR1@/DIR2/dir3/DIR4");
195
		doTest1("URL #1", "WWW.DOMAIN.COM/DIR1/DIR2/dir3/DIR4", "WWW@.DOMAIN@.COM@/DIR1@/DIR2/dir3/DIR4");
196
196
197
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.XPATH, env);
197
		expert = STextExpertFactory.getExpert(STextProcessorFactory.XPATH, env);
198
		doTest1("Xpath #1", "abc(DEF)GHI", "abc(DEF@)GHI");
198
		doTest1("Xpath #1", "abc(DEF)GHI", "abc(DEF@)GHI");
199
		doTest1("Xpath #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI@ \"A.B\"@:JK ");
199
		doTest1("Xpath #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI@ \"A.B\"@:JK ");
200
		doTest1("Xpath #3", "DEF!GHI 'A!B'=JK ", "DEF@!GHI@ 'A!B'@=JK ");
200
		doTest1("Xpath #3", "DEF!GHI 'A!B'=JK ", "DEF@!GHI@ 'A!B'@=JK ");
201
		doTest1("Xpath #4", "DEF.GHI 'A.B :JK ", "DEF@.GHI@ 'A.B :JK ");
201
		doTest1("Xpath #4", "DEF.GHI 'A.B :JK ", "DEF@.GHI@ 'A.B :JK ");
202
202
203
		expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.EMAIL, env);
203
		expert = STextExpertFactory.getExpert(STextProcessorFactory.EMAIL, env);
204
		doTest3("DelimsEsc #1", "abc.DEF.GHI", "abc.DEF@.GHI");
204
		doTest3("DelimsEsc #1", "abc.DEF.GHI", "abc.DEF@.GHI");
205
		doTest3("DelimsEsc #2", "DEF.GHI (A:B);JK ", "DEF@.GHI @(A:B)@;JK ");
205
		doTest3("DelimsEsc #2", "DEF.GHI (A:B);JK ", "DEF@.GHI @(A:B)@;JK ");
206
		doTest3("DelimsEsc #3", "DEF.GHI (A:B);JK ", "DEF@.GHI @(A:B)@;JK ");
206
		doTest3("DelimsEsc #3", "DEF.GHI (A:B);JK ", "DEF@.GHI @(A:B)@;JK ");
(-)src/org/eclipse/equinox/bidi/internal/tests/STextFullToLeanTest.java (-3 / +3 lines)
Lines 11-17 Link Here
11
11
12
package org.eclipse.equinox.bidi.internal.tests;
12
package org.eclipse.equinox.bidi.internal.tests;
13
13
14
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
14
import org.eclipse.equinox.bidi.STextProcessorFactory;
15
import org.eclipse.equinox.bidi.advanced.*;
15
import org.eclipse.equinox.bidi.advanced.*;
16
16
17
/**
17
/**
Lines 110-116 Link Here
110
	}
110
	}
111
111
112
	public void testFullToLean() {
112
	public void testFullToLean() {
113
		type = STextTypeHandlerFactory.COMMA_DELIMITED;
113
		type = STextProcessorFactory.COMMA_DELIMITED;
114
		doTest1("testFullToLean #1 - ", "", "", "", new int[0], new int[0], "", "", new int[0], new int[0]);
114
		doTest1("testFullToLean #1 - ", "", "", "", new int[0], new int[0], "", "", new int[0], new int[0]);
115
		int[] map1 = new int[] {0, 1, 2, 3, 4};
115
		int[] map1 = new int[] {0, 1, 2, 3, 4};
116
		int[] map2 = new int[] {2, 3, 4, 5, 6};
116
		int[] map2 = new int[] {2, 3, 4, 5, 6};
Lines 257-263 Link Here
257
		doTest1("testFullToLean #37 - ", ">>>@@@@@^^^", "", "", map1, map2, "", "", map1, map2);
257
		doTest1("testFullToLean #37 - ", ">>>@@@@@^^^", "", "", map1, map2, "", "", map1, map2);
258
258
259
		// test fullToLeanText with initial state
259
		// test fullToLeanText with initial state
260
		type = STextTypeHandlerFactory.SQL;
260
		type = STextProcessorFactory.SQL;
261
		doTest2("testFullToLean #38 - ");
261
		doTest2("testFullToLean #38 - ");
262
	}
262
	}
263
}
263
}
(-)src/org/eclipse/equinox/bidi/internal/tests/STextMathTest.java (-3 / +3 lines)
Lines 11-17 Link Here
11
11
12
package org.eclipse.equinox.bidi.internal.tests;
12
package org.eclipse.equinox.bidi.internal.tests;
13
13
14
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
14
import org.eclipse.equinox.bidi.STextProcessorFactory;
15
import org.eclipse.equinox.bidi.advanced.*;
15
import org.eclipse.equinox.bidi.advanced.*;
16
16
17
/**
17
/**
Lines 22-29 Link Here
22
	private STextEnvironment envLTR = new STextEnvironment("ar", false, STextEnvironment.ORIENT_LTR);
22
	private STextEnvironment envLTR = new STextEnvironment("ar", false, STextEnvironment.ORIENT_LTR);
23
	private STextEnvironment envRTL = new STextEnvironment("ar", false, STextEnvironment.ORIENT_RTL);
23
	private STextEnvironment envRTL = new STextEnvironment("ar", false, STextEnvironment.ORIENT_RTL);
24
24
25
	private ISTextExpert expertLTR = STextExpertFactory.getExpert(STextTypeHandlerFactory.RTL_ARITHMETIC, envLTR);
25
	private ISTextExpert expertLTR = STextExpertFactory.getExpert(STextProcessorFactory.RTL_ARITHMETIC, envLTR);
26
	private ISTextExpert expertRTL = STextExpertFactory.getExpert(STextTypeHandlerFactory.RTL_ARITHMETIC, envRTL);
26
	private ISTextExpert expertRTL = STextExpertFactory.getExpert(STextProcessorFactory.RTL_ARITHMETIC, envRTL);
27
27
28
	private void verifyOneLine(String msg, String data, String resLTR, String resRTL) {
28
	private void verifyOneLine(String msg, String data, String resLTR, String resRTL) {
29
		String lean = toUT16(data);
29
		String lean = toUT16(data);
(-)src/org/eclipse/equinox/bidi/internal/tests/STextMethodsTest.java (-30 / +25 lines)
Lines 12-18 Link Here
12
package org.eclipse.equinox.bidi.internal.tests;
12
package org.eclipse.equinox.bidi.internal.tests;
13
13
14
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.STextDirection;
15
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
15
import org.eclipse.equinox.bidi.STextProcessorFactory;
16
import org.eclipse.equinox.bidi.advanced.*;
16
import org.eclipse.equinox.bidi.advanced.*;
17
17
18
/**
18
/**
Lines 47-77 Link Here
47
47
48
	private void doTestState() {
48
	private void doTestState() {
49
		String data, lean, full, model;
49
		String data, lean, full, model;
50
		ISTextExpert expert = STextExpertFactory.getPrivateExpert(STextTypeHandlerFactory.JAVA);
50
		ISTextExpert expert = STextExpertFactory.getPrivateExpert(STextProcessorFactory.JAVA);
51
51
52
		data = "A=B+C;/* D=E+F;";
52
		data = "A=B+C;/* D=E+F;";
53
		lean = toUT16(data);
53
		lean = toUT16(data);
54
		full = expert.leanToFullText(lean);
54
		full = expert.leanToFullText(lean);
55
55
		model = "A@=B@+C@;/* D=E+F;";
56
		model = "A@=B@+C@;/* D=E+F;";
56
		assertEquals("full1", model, toPseudo(full));
57
		assertEquals("full1", model, toPseudo(full));
57
58
		data = "A=B+C; D=E+F;";
58
		data = "A=B+C; D=E+F;";
59
		lean = toUT16(data);
59
		lean = toUT16(data);
60
		full = expert.leanToFullText(lean);
60
		full = expert.leanToFullText(lean);
61
		model = data;
61
62
		model = "A=B+C; D=E+F;";
62
		assertEquals("full2", model, toPseudo(full));
63
		assertEquals("full2", model, toPseudo(full));
63
64
		data = "SOME MORE COMMENTS";
65
		lean = toUT16(data);
66
		full = expert.leanToFullText(lean);
67
		model = data;
68
		assertEquals("full3", model, toPseudo(full));
69
70
		data = "A=B+C;*/ D=E+F;";
64
		data = "A=B+C;*/ D=E+F;";
71
		lean = toUT16(data);
65
		lean = toUT16(data);
72
		full = expert.leanToFullText(lean);
66
		full = expert.leanToFullText(lean);
67
73
		model = "A=B+C;@*/ D@=E@+F;";
68
		model = "A=B+C;@*/ D@=E@+F;";
74
		assertEquals("full4", model, toPseudo(full));
69
		assertEquals("full3", model, toPseudo(full));
75
	}
70
	}
76
71
77
	private void doTestOrientation() {
72
	private void doTestOrientation() {
Lines 88-99 Link Here
88
		assertEquals("orient #4", STextEnvironment.ORIENT_UNKNOWN, orient);
83
		assertEquals("orient #4", STextEnvironment.ORIENT_UNKNOWN, orient);
89
	}
84
	}
90
85
91
	private void doTestOrient(String handlerDefID, String label, String data, String resLTR, String resRTL, String resCon) {
86
	private void doTestOrient(String processorDefID, String label, String data, String resLTR, String resRTL, String resCon) {
92
		String full, lean;
87
		String full, lean;
93
88
94
		ISTextExpert expertLTR = STextExpertFactory.getExpert(handlerDefID, envLTR);
89
		ISTextExpert expertLTR = STextExpertFactory.getExpert(processorDefID, envLTR);
95
		ISTextExpert expertRTL = STextExpertFactory.getExpert(handlerDefID, envRTL);
90
		ISTextExpert expertRTL = STextExpertFactory.getExpert(processorDefID, envRTL);
96
		ISTextExpert expertCRL = STextExpertFactory.getExpert(handlerDefID, envCRL);
91
		ISTextExpert expertCRL = STextExpertFactory.getExpert(processorDefID, envCRL);
97
92
98
		lean = toUT16(data);
93
		lean = toUT16(data);
99
		full = expertLTR.leanToFullText(lean);
94
		full = expertLTR.leanToFullText(lean);
Lines 111-117 Link Here
111
106
112
	private void doTestLeanOffsets() {
107
	private void doTestLeanOffsets() {
113
		String lean, data, label;
108
		String lean, data, label;
114
		ISTextExpert expert = STextExpertFactory.getPrivateExpert(STextTypeHandlerFactory.JAVA);
109
		ISTextExpert expert = STextExpertFactory.getExpert(STextProcessorFactory.JAVA);
115
110
116
		int[] offsets;
111
		int[] offsets;
117
		int[] model;
112
		int[] model;
Lines 133-141 Link Here
133
	private void doTestFullOffsets(String label, String data, int[] resLTR, int[] resRTL, int[] resCon) {
128
	private void doTestFullOffsets(String label, String data, int[] resLTR, int[] resRTL, int[] resCon) {
134
		String full, lean, msg;
129
		String full, lean, msg;
135
		int[] offsets;
130
		int[] offsets;
136
		ISTextExpert expertLTR = STextExpertFactory.getExpert(STextTypeHandlerFactory.COMMA_DELIMITED, envLTR);
131
		ISTextExpert expertLTR = STextExpertFactory.getExpert(STextProcessorFactory.COMMA_DELIMITED, envLTR);
137
		ISTextExpert expertRTL = STextExpertFactory.getExpert(STextTypeHandlerFactory.COMMA_DELIMITED, envRTL);
132
		ISTextExpert expertRTL = STextExpertFactory.getExpert(STextProcessorFactory.COMMA_DELIMITED, envRTL);
138
		ISTextExpert expertCLR = STextExpertFactory.getExpert(STextTypeHandlerFactory.COMMA_DELIMITED, envCLR);
133
		ISTextExpert expertCLR = STextExpertFactory.getExpert(STextProcessorFactory.COMMA_DELIMITED, envCLR);
139
134
140
		lean = toUT16(data);
135
		lean = toUT16(data);
141
		full = expertLTR.leanToFullText(lean);
136
		full = expertLTR.leanToFullText(lean);
Lines 243-257 Link Here
243
238
244
		doTestOrientation();
239
		doTestOrientation();
245
240
246
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #1 ", "", "", "", "");
241
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #1 ", "", "", "", "");
247
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #2 ", "abc", "abc", ">@abc@^", "abc");
242
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #2 ", "abc", "abc", ">@abc@^", "abc");
248
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #3 ", "ABC", "ABC", ">@ABC@^", "@ABC");
243
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #3 ", "ABC", "ABC", ">@ABC@^", "@ABC");
249
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #4 ", "bcd,ef", "bcd,ef", ">@bcd,ef@^", "bcd,ef");
244
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #4 ", "bcd,ef", "bcd,ef", ">@bcd,ef@^", "bcd,ef");
250
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #5 ", "BCD,EF", "BCD@,EF", ">@BCD@,EF@^", "@BCD@,EF");
245
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #5 ", "BCD,EF", "BCD@,EF", ">@BCD@,EF@^", "@BCD@,EF");
251
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #6 ", "cde,FG", "cde,FG", ">@cde,FG@^", "cde,FG");
246
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #6 ", "cde,FG", "cde,FG", ">@cde,FG@^", "cde,FG");
252
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #7 ", "CDE,fg", "CDE,fg", ">@CDE,fg@^", "@CDE,fg");
247
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #7 ", "CDE,fg", "CDE,fg", ">@CDE,fg@^", "@CDE,fg");
253
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #8 ", "12..def,GH", "12..def,GH", ">@12..def,GH@^", "12..def,GH");
248
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #8 ", "12..def,GH", "12..def,GH", ">@12..def,GH@^", "12..def,GH");
254
		doTestOrient(STextTypeHandlerFactory.COMMA_DELIMITED, "Methods #9 ", "34..DEF,gh", "34..DEF,gh", ">@34..DEF,gh@^", "@34..DEF,gh");
249
		doTestOrient(STextProcessorFactory.COMMA_DELIMITED, "Methods #9 ", "34..DEF,gh", "34..DEF,gh", ">@34..DEF,gh@^", "@34..DEF,gh");
255
250
256
		doTestSkipProcessing();
251
		doTestSkipProcessing();
257
252
Lines 263-269 Link Here
263
258
264
		doTestDirection();
259
		doTestDirection();
265
260
266
		ISTextExpert expert = STextExpertFactory.getExpert(STextTypeHandlerFactory.COMMA_DELIMITED);
261
		ISTextExpert expert = STextExpertFactory.getExpert(STextProcessorFactory.COMMA_DELIMITED);
267
		String data = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
262
		String data = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
268
		String lean = toUT16(data);
263
		String lean = toUT16(data);
269
		String full = expert.leanToFullText(lean);
264
		String full = expert.leanToFullText(lean);
(-)src/org/eclipse/equinox/bidi/internal/tests/STextNullProcessorTest.java (+47 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.equinox.bidi.internal.tests;
13
14
15
/**
16
 * Tests null processor
17
 */
18
public class STextNullProcessorTest extends STextTestBase {
19
20
	static final int[] EMPTY_INT_ARRAY = new int[0];
21
22
	public void testNullProcessor() {
23
		/* not needed
24
		String full = STextEngine.leanToFullText(null, null, "abc", null);
25
		assertEquals("leanToFullText", "abc", full);
26
		int[] state = new int[1];
27
		state[0] = 3;
28
		full = STextEngine.leanToFullText(null, null, "abc", state);
29
		assertEquals("leanToFullText with state", "abc", full);
30
		int[] offsets = STextEngine.leanBidiCharOffsets(null, null, "abc", null);
31
		assertEquals("leanBidiCharOffsets", 0, offsets.length);
32
		offsets = STextEngine.fullBidiCharOffsets(null, null, "abc", null);
33
		assertEquals("fullBidiCharOffsets", 0, offsets.length);
34
		String lean = STextEngine.fullToLeanText(null, null, "abc", null);
35
		assertEquals("fullToLeanText", "abc", lean);
36
		lean = STextEngine.fullToLeanText(null, null, "abc", state);
37
		assertEquals("fullToLeanText with state", "abc", lean);
38
		int[] map = STextEngine.leanToFullMap(null, null, "abc", null);
39
		int[] model = {0, 1, 2};
40
		assertEquals("leanToFullMap", array_display(model), array_display(map));
41
		map = STextEngine.fullToLeanMap(null, null, "abc", null);
42
		assertEquals("fullToLeanMap", array_display(model), array_display(map));
43
		int direction = STextEngine.getCurDirection(null, null, "abc");
44
		assertEquals("getCurDirection", STextEngine.DIR_LTR, direction);
45
		*/
46
	}
47
}
(-)src/org/eclipse/equinox/bidi/internal/tests/STextProcessorTest.java (-126 lines)
Lines 1-126 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.equinox.bidi.internal.tests;
13
14
import java.util.Locale;
15
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
16
import org.eclipse.equinox.bidi.STextProcessor;
17
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
18
19
/**
20
 * Tests methods in BidiComplexUtil
21
 */
22
23
public class STextProcessorTest extends STextTestBase {
24
25
	private static final String HEBREW = "iw";
26
27
	private static final String HEBREW2 = "he";
28
29
	private static final String ARABIC = "ar";
30
31
	private static final String FARSI = "fa";
32
33
	private static final String URDU = "ur";
34
35
	private Locale locale;
36
37
	protected void setUp() throws Exception {
38
		super.setUp();
39
		locale = Locale.getDefault();
40
	}
41
42
	protected void tearDown() {
43
		Locale.setDefault(locale);
44
	}
45
46
	private void doTest1(String data, String result) {
47
		Locale.setDefault(Locale.ENGLISH);
48
		String full = STextProcessor.process(toUT16(data));
49
		assertEquals("Util #1 full EN - ", data, toPseudo(full));
50
		Locale.setDefault(new Locale(HEBREW2));
51
		full = STextProcessor.process(toUT16(data));
52
		assertEquals("Util #1 full HE - ", result, toPseudo(full));
53
		Locale.setDefault(new Locale(ARABIC));
54
		full = STextProcessor.process(toUT16(data));
55
		assertEquals("Util #1 full AR - ", result, toPseudo(full));
56
		Locale.setDefault(new Locale(FARSI));
57
		full = STextProcessor.process(toUT16(data));
58
		assertEquals("Util #1 full FA - ", result, toPseudo(full));
59
		Locale.setDefault(new Locale(URDU));
60
		full = STextProcessor.process(toUT16(data));
61
		assertEquals("Util #1 full UR - ", result, toPseudo(full));
62
		Locale.setDefault(new Locale(HEBREW));
63
		full = STextProcessor.process(toUT16(data));
64
		String ful2 = STextProcessor.process(toUT16(data), (String) null);
65
		assertEquals("Util #1 full - ", result, toPseudo(full));
66
		assertEquals("Util #1 ful2 - ", result, toPseudo(ful2));
67
		String lean = STextProcessor.deprocess(full);
68
		assertEquals("Util #1 lean - ", data, toPseudo(lean));
69
	}
70
71
	private void doTest2(String msg, String data, String result) {
72
		doTest2(msg, data, result, data);
73
	}
74
75
	private void doTest2(String msg, String data, String result, String resLean) {
76
		String full = STextProcessor.process(toUT16(data), "*");
77
		assertEquals(msg + "full", result, toPseudo(full));
78
		String lean = STextProcessor.deprocess(full);
79
		assertEquals(msg + "lean", resLean, toPseudo(lean));
80
	}
81
82
	private void doTest3(String msg, String data, String result) {
83
		doTest3(msg, data, result, data);
84
	}
85
86
	private void doTest3(String msg, String data, String result, String resLean) {
87
		STextTypeHandler handler = STextTypeHandlerFactory.getHandler(STextTypeHandlerFactory.COMMA_DELIMITED);
88
		String full = STextProcessor.process(toUT16(data), handler);
89
		assertEquals(msg + "full", result, toPseudo(full));
90
		String lean = STextProcessor.deprocess(full, handler);
91
		assertEquals(msg + "lean", resLean, toPseudo(lean));
92
	}
93
94
	private void doTest4(String msg, String data, int[] offsets, int direction, boolean affix, String result) {
95
		String txt = msg + "text=" + data + "\n    offsets=" + array_display(offsets) + "\n    direction=" + direction + "\n    affix=" + affix;
96
		String lean = toUT16(data);
97
		String full = STextProcessor.insertMarks(lean, offsets, direction, affix);
98
		assertEquals(txt, result, toPseudo(full));
99
	}
100
101
	public void testBidiComplexUtil() {
102
103
		// Test process() and deprocess() with default delimiters
104
		doTest1("ABC/DEF/G", ">@ABC@/DEF@/G@^");
105
		// Test process() and deprocess() with specified delimiters
106
		doTest2("Util #2.1 - ", "", "");
107
		doTest2("Util #2.2 - ", ">@ABC@^", ">@ABC@^", "ABC");
108
		doTest2("Util #2.3 - ", "abc", "abc");
109
		doTest2("Util #2.4 - ", "!abc", ">@!abc@^");
110
		doTest2("Util #2.5 - ", "abc!", ">@abc!@^");
111
		doTest2("Util #2.6 - ", "ABC*DEF*G", ">@ABC@*DEF@*G@^");
112
		// Test process() and deprocess() with specified expression type
113
		doTest3("Util #3.1 - ", "ABC,DEF,G", ">@ABC@,DEF@,G@^");
114
		doTest3("Util #3.2 - ", "", "");
115
		doTest3("Util #3.3 - ", ">@DEF@^", ">@DEF@^", "DEF");
116
		// Test insertMarks()
117
		doTest4("Util #4.1 - ", "ABCDEFG", new int[] {3, 6}, 0, false, "ABC@DEF@G");
118
		doTest4("Util #4.2 - ", "ABCDEFG", new int[] {3, 6}, 0, true, ">@ABC@DEF@G@^");
119
		doTest4("Util #4.3 - ", "ABCDEFG", new int[] {3, 6}, 1, false, "ABC&DEF&G");
120
		doTest4("Util #4.4 - ", "ABCDEFG", new int[] {3, 6}, 1, true, "<&ABC&DEF&G&^");
121
		doTest4("Util #4.5 - ", "", new int[] {3, 6}, 0, false, "");
122
		doTest4("Util #4.6 - ", "", new int[] {3, 6}, 0, true, "");
123
		doTest4("Util #4.7 - ", "ABCDEFG", null, 1, false, "ABCDEFG");
124
		doTest4("Util #4.8 - ", "ABCDEFG", null, 1, true, "<&ABCDEFG&^");
125
	}
126
}
(-)src/org/eclipse/equinox/bidi/internal/tests/STextSomeMoreTest.java (-3 / +3 lines)
Lines 25-35 Link Here
25
		assertFalse(env1.isProcessingNeeded());
25
		assertFalse(env1.isProcessingNeeded());
26
		assertTrue(env2.isProcessingNeeded());
26
		assertTrue(env2.isProcessingNeeded());
27
27
28
		ISTextExpert expert1 = STextExpertFactory.getExpert("test.Handler1", env1);
28
		ISTextExpert expert1 = STextExpertFactory.getExpert("test.Processor1", env1);
29
		String full = expert1.leanToFullText("abcd");
29
		String full = expert1.leanToFullText("abcd");
30
		assertEquals("@a@b@c@d", toPseudo(full));
30
		assertEquals("@a@b@c@d", toPseudo(full));
31
31
32
		ISTextExpert expert2 = STextExpertFactory.getExpert("test.Handler2", env1);
32
		ISTextExpert expert2 = STextExpertFactory.getExpert("test.Processor2", env1);
33
		boolean catchFlag = false;
33
		boolean catchFlag = false;
34
		try {
34
		try {
35
			full = expert2.leanToFullText("abcd");
35
			full = expert2.leanToFullText("abcd");
Lines 39-45 Link Here
39
		assertTrue("Catch missing indexOfSpecial", catchFlag);
39
		assertTrue("Catch missing indexOfSpecial", catchFlag);
40
40
41
		catchFlag = false;
41
		catchFlag = false;
42
		ISTextExpert expert3 = STextExpertFactory.getExpert("test.Handler3", env1);
42
		ISTextExpert expert3 = STextExpertFactory.getExpert("test.Processor3", env1);
43
		try {
43
		try {
44
			full = expert3.leanToFullText("abcd");
44
			full = expert3.leanToFullText("abcd");
45
		} catch (IllegalStateException e) {
45
		} catch (IllegalStateException e) {
(-)src/org/eclipse/equinox/bidi/internal/tests/STextStringRecordTest.java (-17 / +17 lines)
Lines 11-18 Link Here
11
11
12
package org.eclipse.equinox.bidi.internal.tests;
12
package org.eclipse.equinox.bidi.internal.tests;
13
13
14
import org.eclipse.equinox.bidi.STextProcessorFactory;
14
import org.eclipse.equinox.bidi.STextStringRecord;
15
import org.eclipse.equinox.bidi.STextStringRecord;
15
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
16
16
17
/**
17
/**
18
 *	Tests the StringRecord class	
18
 *	Tests the StringRecord class	
Lines 24-30 Link Here
24
		// check handling of invalid arguments
24
		// check handling of invalid arguments
25
		catchFlag = false;
25
		catchFlag = false;
26
		try {
26
		try {
27
			sr = STextStringRecord.addRecord(null, 1, STextTypeHandlerFactory.EMAIL, 0, 1);
27
			sr = STextStringRecord.addRecord(null, 1, STextProcessorFactory.EMAIL, 0, 1);
28
		} catch (IllegalArgumentException e) {
28
		} catch (IllegalArgumentException e) {
29
			catchFlag = true;
29
			catchFlag = true;
30
		}
30
		}
Lines 35-72 Link Here
35
		} catch (IllegalArgumentException e) {
35
		} catch (IllegalArgumentException e) {
36
			catchFlag = true;
36
			catchFlag = true;
37
		}
37
		}
38
		assertTrue("Catch null handler argument", catchFlag);
38
		assertTrue("Catch null processor argument", catchFlag);
39
		catchFlag = false;
39
		catchFlag = false;
40
		try {
40
		try {
41
			sr = STextStringRecord.addRecord("abc", 0, STextTypeHandlerFactory.EMAIL, 0, 1);
41
			sr = STextStringRecord.addRecord("abc", 0, STextProcessorFactory.EMAIL, 0, 1);
42
		} catch (IllegalArgumentException e) {
42
		} catch (IllegalArgumentException e) {
43
			catchFlag = true;
43
			catchFlag = true;
44
		}
44
		}
45
		assertTrue("Catch invalid segment count argument", catchFlag);
45
		assertTrue("Catch invalid segment count argument", catchFlag);
46
		catchFlag = false;
46
		catchFlag = false;
47
		try {
47
		try {
48
			sr = STextStringRecord.addRecord("abc", 1, STextTypeHandlerFactory.EMAIL, -1, 1);
48
			sr = STextStringRecord.addRecord("abc", 1, STextProcessorFactory.EMAIL, -1, 1);
49
		} catch (IllegalArgumentException e) {
49
		} catch (IllegalArgumentException e) {
50
			catchFlag = true;
50
			catchFlag = true;
51
		}
51
		}
52
		assertTrue("Catch invalid start argument", catchFlag);
52
		assertTrue("Catch invalid start argument", catchFlag);
53
		catchFlag = false;
53
		catchFlag = false;
54
		try {
54
		try {
55
			sr = STextStringRecord.addRecord("abc", 1, STextTypeHandlerFactory.EMAIL, 4, 1);
55
			sr = STextStringRecord.addRecord("abc", 1, STextProcessorFactory.EMAIL, 4, 1);
56
		} catch (IllegalArgumentException e) {
56
		} catch (IllegalArgumentException e) {
57
			catchFlag = true;
57
			catchFlag = true;
58
		}
58
		}
59
		assertTrue("Catch invalid start argument", catchFlag);
59
		assertTrue("Catch invalid start argument", catchFlag);
60
		catchFlag = false;
60
		catchFlag = false;
61
		try {
61
		try {
62
			sr = STextStringRecord.addRecord("abc", 1, STextTypeHandlerFactory.EMAIL, 0, 0);
62
			sr = STextStringRecord.addRecord("abc", 1, STextProcessorFactory.EMAIL, 0, 0);
63
		} catch (IllegalArgumentException e) {
63
		} catch (IllegalArgumentException e) {
64
			catchFlag = true;
64
			catchFlag = true;
65
		}
65
		}
66
		assertTrue("Catch invalid limit argument", catchFlag);
66
		assertTrue("Catch invalid limit argument", catchFlag);
67
		catchFlag = false;
67
		catchFlag = false;
68
		try {
68
		try {
69
			sr = STextStringRecord.addRecord("abc", 1, STextTypeHandlerFactory.EMAIL, 0, 5);
69
			sr = STextStringRecord.addRecord("abc", 1, STextProcessorFactory.EMAIL, 0, 5);
70
		} catch (IllegalArgumentException e) {
70
		} catch (IllegalArgumentException e) {
71
			catchFlag = true;
71
			catchFlag = true;
72
		}
72
		}
Lines 78-84 Link Here
78
		assertEquals(null, sr);
78
		assertEquals(null, sr);
79
		for (int i = 0; i < lim; i++) {
79
		for (int i = 0; i < lim; i++) {
80
			String str = Integer.toString(i);
80
			String str = Integer.toString(i);
81
			sr = STextStringRecord.addRecord(str, 1, STextTypeHandlerFactory.EMAIL, 0, 1);
81
			sr = STextStringRecord.addRecord(str, 1, STextProcessorFactory.EMAIL, 0, 1);
82
		}
82
		}
83
		sr = STextStringRecord.getRecord(null);
83
		sr = STextStringRecord.getRecord(null);
84
		assertEquals(null, sr);
84
		assertEquals(null, sr);
Lines 96-102 Link Here
96
96
97
		for (int i = lim; i <= poolSize; i++) {
97
		for (int i = lim; i <= poolSize; i++) {
98
			String str = Integer.toString(i);
98
			String str = Integer.toString(i);
99
			sr = STextStringRecord.addRecord(str, 1, STextTypeHandlerFactory.EMAIL, 0, 1);
99
			sr = STextStringRecord.addRecord(str, 1, STextProcessorFactory.EMAIL, 0, 1);
100
		}
100
		}
101
		for (int i = 1; i <= poolSize; i++) {
101
		for (int i = 1; i <= poolSize; i++) {
102
			String str = Integer.toString(i);
102
			String str = Integer.toString(i);
Lines 105-124 Link Here
105
		}
105
		}
106
		sr = STextStringRecord.getRecord("0");
106
		sr = STextStringRecord.getRecord("0");
107
		assertEquals(null, sr);
107
		assertEquals(null, sr);
108
		sr = STextStringRecord.addRecord("thisisalongstring", 3, STextTypeHandlerFactory.EMAIL, 0, 2);
108
		sr = STextStringRecord.addRecord("thisisalongstring", 3, STextProcessorFactory.EMAIL, 0, 2);
109
		sr.addSegment(STextTypeHandlerFactory.JAVA, 4, 5);
109
		sr.addSegment(STextProcessorFactory.JAVA, 4, 5);
110
		sr.addSegment(STextTypeHandlerFactory.FILE, 6, 7);
110
		sr.addSegment(STextProcessorFactory.FILE, 6, 7);
111
		catchFlag = false;
111
		catchFlag = false;
112
		try {
112
		try {
113
			sr.addSegment(STextTypeHandlerFactory.EMAIL, 10, 13);
113
			sr.addSegment(STextProcessorFactory.EMAIL, 10, 13);
114
		} catch (IllegalStateException e) {
114
		} catch (IllegalStateException e) {
115
			catchFlag = true;
115
			catchFlag = true;
116
		}
116
		}
117
		assertTrue("Catch too many segments", catchFlag);
117
		assertTrue("Catch too many segments", catchFlag);
118
		assertEquals(3, sr.getSegmentCount());
118
		assertEquals(3, sr.getSegmentCount());
119
		assertEquals(STextTypeHandlerFactory.EMAIL, sr.getHandler(0));
119
		assertEquals(STextProcessorFactory.EMAIL, sr.getProcessor(0));
120
		assertEquals(STextTypeHandlerFactory.JAVA, sr.getHandler(1));
120
		assertEquals(STextProcessorFactory.JAVA, sr.getProcessor(1));
121
		assertEquals(STextTypeHandlerFactory.FILE, sr.getHandler(2));
121
		assertEquals(STextProcessorFactory.FILE, sr.getProcessor(2));
122
		assertEquals(0, sr.getStart(0));
122
		assertEquals(0, sr.getStart(0));
123
		assertEquals(4, sr.getStart(1));
123
		assertEquals(4, sr.getStart(1));
124
		assertEquals(6, sr.getStart(2));
124
		assertEquals(6, sr.getStart(2));
(-)src/org/eclipse/equinox/bidi/internal/tests/STextTest.java (-2 / +2 lines)
Lines 10-18 Link Here
10
 ******************************************************************************/
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
11
package org.eclipse.equinox.bidi.internal.tests;
12
12
13
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
13
import org.eclipse.equinox.bidi.custom.STextProcessor;
14
14
15
public class STextTest extends STextTypeHandler {
15
public class STextTest extends STextProcessor {
16
16
17
	public STextTest() {
17
	public STextTest() {
18
		super("-=.:");
18
		super("-=.:");
(-)src/org/eclipse/equinox/bidi/internal/tests/STextTestBase.java (-1 / +1 lines)
Lines 14-20 Link Here
14
import junit.framework.TestCase;
14
import junit.framework.TestCase;
15
15
16
/**
16
/**
17
 * Base functionality for the handler tests.
17
 * Base functionality for the processor tests.
18
 */
18
 */
19
public class STextTestBase extends TestCase {
19
public class STextTestBase extends TestCase {
20
20
(-)src/org/eclipse/equinox/bidi/internal/tests/STextUtilTest.java (+126 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.equinox.bidi.internal.tests;
13
14
import java.util.Locale;
15
import org.eclipse.equinox.bidi.STextProcessorFactory;
16
import org.eclipse.equinox.bidi.STextUtil;
17
import org.eclipse.equinox.bidi.custom.STextProcessor;
18
19
/**
20
 * Tests methods in BidiComplexUtil
21
 */
22
23
public class STextUtilTest extends STextTestBase {
24
25
	private static final String HEBREW = "iw";
26
27
	private static final String HEBREW2 = "he";
28
29
	private static final String ARABIC = "ar";
30
31
	private static final String FARSI = "fa";
32
33
	private static final String URDU = "ur";
34
35
	private Locale locale;
36
37
	protected void setUp() throws Exception {
38
		super.setUp();
39
		locale = Locale.getDefault();
40
	}
41
42
	protected void tearDown() {
43
		Locale.setDefault(locale);
44
	}
45
46
	private void doTest1(String data, String result) {
47
		Locale.setDefault(Locale.ENGLISH);
48
		String full = STextUtil.process(toUT16(data));
49
		assertEquals("Util #1 full EN - ", data, toPseudo(full));
50
		Locale.setDefault(new Locale(HEBREW2));
51
		full = STextUtil.process(toUT16(data));
52
		assertEquals("Util #1 full HE - ", result, toPseudo(full));
53
		Locale.setDefault(new Locale(ARABIC));
54
		full = STextUtil.process(toUT16(data));
55
		assertEquals("Util #1 full AR - ", result, toPseudo(full));
56
		Locale.setDefault(new Locale(FARSI));
57
		full = STextUtil.process(toUT16(data));
58
		assertEquals("Util #1 full FA - ", result, toPseudo(full));
59
		Locale.setDefault(new Locale(URDU));
60
		full = STextUtil.process(toUT16(data));
61
		assertEquals("Util #1 full UR - ", result, toPseudo(full));
62
		Locale.setDefault(new Locale(HEBREW));
63
		full = STextUtil.process(toUT16(data));
64
		String ful2 = STextUtil.process(toUT16(data), (String) null);
65
		assertEquals("Util #1 full - ", result, toPseudo(full));
66
		assertEquals("Util #1 ful2 - ", result, toPseudo(ful2));
67
		String lean = STextUtil.deprocess(full);
68
		assertEquals("Util #1 lean - ", data, toPseudo(lean));
69
	}
70
71
	private void doTest2(String msg, String data, String result) {
72
		doTest2(msg, data, result, data);
73
	}
74
75
	private void doTest2(String msg, String data, String result, String resLean) {
76
		String full = STextUtil.process(toUT16(data), "*");
77
		assertEquals(msg + "full", result, toPseudo(full));
78
		String lean = STextUtil.deprocess(full);
79
		assertEquals(msg + "lean", resLean, toPseudo(lean));
80
	}
81
82
	private void doTest3(String msg, String data, String result) {
83
		doTest3(msg, data, result, data);
84
	}
85
86
	private void doTest3(String msg, String data, String result, String resLean) {
87
		STextProcessor descriptor = STextProcessorFactory.getProcessor(STextProcessorFactory.COMMA_DELIMITED);
88
		String full = STextUtil.process(toUT16(data), descriptor);
89
		assertEquals(msg + "full", result, toPseudo(full));
90
		String lean = STextUtil.deprocess(full, descriptor);
91
		assertEquals(msg + "lean", resLean, toPseudo(lean));
92
	}
93
94
	private void doTest4(String msg, String data, int[] offsets, int direction, boolean affix, String result) {
95
		String txt = msg + "text=" + data + "\n    offsets=" + array_display(offsets) + "\n    direction=" + direction + "\n    affix=" + affix;
96
		String lean = toUT16(data);
97
		String full = STextUtil.insertMarks(lean, offsets, direction, affix);
98
		assertEquals(txt, result, toPseudo(full));
99
	}
100
101
	public void testBidiComplexUtil() {
102
103
		// Test process() and deprocess() with default delimiters
104
		doTest1("ABC/DEF/G", ">@ABC@/DEF@/G@^");
105
		// Test process() and deprocess() with specified delimiters
106
		doTest2("Util #2.1 - ", "", "");
107
		doTest2("Util #2.2 - ", ">@ABC@^", ">@ABC@^", "ABC");
108
		doTest2("Util #2.3 - ", "abc", "abc");
109
		doTest2("Util #2.4 - ", "!abc", ">@!abc@^");
110
		doTest2("Util #2.5 - ", "abc!", ">@abc!@^");
111
		doTest2("Util #2.6 - ", "ABC*DEF*G", ">@ABC@*DEF@*G@^");
112
		// Test process() and deprocess() with specified expression type
113
		doTest3("Util #3.1 - ", "ABC,DEF,G", ">@ABC@,DEF@,G@^");
114
		doTest3("Util #3.2 - ", "", "");
115
		doTest3("Util #3.3 - ", ">@DEF@^", ">@DEF@^", "DEF");
116
		// Test insertMarks()
117
		doTest4("Util #4.1 - ", "ABCDEFG", new int[] {3, 6}, 0, false, "ABC@DEF@G");
118
		doTest4("Util #4.2 - ", "ABCDEFG", new int[] {3, 6}, 0, true, ">@ABC@DEF@G@^");
119
		doTest4("Util #4.3 - ", "ABCDEFG", new int[] {3, 6}, 1, false, "ABC&DEF&G");
120
		doTest4("Util #4.4 - ", "ABCDEFG", new int[] {3, 6}, 1, true, "<&ABC&DEF&G&^");
121
		doTest4("Util #4.5 - ", "", new int[] {3, 6}, 0, false, "");
122
		doTest4("Util #4.6 - ", "", new int[] {3, 6}, 0, true, "");
123
		doTest4("Util #4.7 - ", "ABCDEFG", null, 1, false, "ABCDEFG");
124
		doTest4("Util #4.8 - ", "ABCDEFG", null, 1, true, "<&ABCDEFG&^");
125
	}
126
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestHandler1.java (-34 lines)
Lines 1-34 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.custom.*;
15
16
public class TestHandler1 extends STextTypeHandler {
17
18
	public int getSpecialsCount(STextEnvironment env) {
19
		return 1;
20
	}
21
22
	public int indexOfSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
23
		return fromIndex;
24
	}
25
26
	public int processSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
27
		int len = text.length();
28
		for (int i = len - 1; i >= 0; i--) {
29
			STextTypeHandler.insertMark(text, charTypes, offsets, i);
30
			STextTypeHandler.insertMark(text, charTypes, offsets, i);
31
		}
32
		return len;
33
	}
34
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestHandler2.java (-22 lines)
Lines 1-22 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
15
16
public class TestHandler2 extends STextTypeHandler {
17
18
	public int getSpecialsCount(STextEnvironment env) {
19
		return 1;
20
	}
21
22
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestHandler3.java (-25 lines)
Lines 1-25 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.custom.*;
15
16
public class TestHandler3 extends STextTypeHandler {
17
18
	public int getSpecialsCount(STextEnvironment env) {
19
		return 1;
20
	}
21
22
	public int indexOfSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
23
		return fromIndex;
24
	}
25
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyComma.java (-55 lines)
Lines 1-55 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
15
import org.eclipse.equinox.bidi.custom.STextCharTypes;
16
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
17
18
public class TestHandlerMyComma extends STextTypeHandler {
19
20
	private final static byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
21
	protected final static int LTR = STextDirection.DIR_LTR;
22
	protected final static int RTL = STextDirection.DIR_RTL;
23
24
	final int dirArabic;
25
	final int dirHebrew;
26
27
	public TestHandlerMyComma(int dirArabic, int dirHebrew) {
28
		this.dirArabic = dirArabic;
29
		this.dirHebrew = dirHebrew;
30
	}
31
32
	public String getSeparators(STextEnvironment environment) {
33
		return ","; //$NON-NLS-1$
34
	}
35
36
	public boolean skipProcessing(STextEnvironment environment, String text, STextCharTypes charTypes) {
37
		byte charType = charTypes.getBidiTypeAt(0);
38
		if (charType == AL)
39
			return true;
40
		return false;
41
	}
42
43
	public int getDirection(STextEnvironment environment, String text) {
44
		return getDirection(environment, text, new STextCharTypes(this, environment, text));
45
	}
46
47
	public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
48
		for (int i = 0; i < text.length(); i++) {
49
			byte charType = charTypes.getBidiTypeAt(i);
50
			if (charType == AL)
51
				return dirArabic;
52
		}
53
		return dirHebrew;
54
	}
55
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyCommaLL.java (-18 lines)
Lines 1-18 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
public class TestHandlerMyCommaLL extends TestHandlerMyComma {
14
15
	public TestHandlerMyCommaLL() {
16
		super(LTR, LTR);
17
	}
18
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyCommaRL.java (-18 lines)
Lines 1-18 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
public class TestHandlerMyCommaRL extends TestHandlerMyComma {
14
15
	public TestHandlerMyCommaRL() {
16
		super(RTL, LTR);
17
	}
18
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyCommaRR.java (-18 lines)
Lines 1-18 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
public class TestHandlerMyCommaRR extends TestHandlerMyComma {
14
15
	public TestHandlerMyCommaRR() {
16
		super(RTL, RTL);
17
	}
18
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestProcessor1.java (+34 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.custom.*;
15
16
public class TestProcessor1 extends STextProcessor {
17
18
	public int getSpecialsCount(STextEnvironment env) {
19
		return 1;
20
	}
21
22
	public int indexOfSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
23
		return fromIndex;
24
	}
25
26
	public int processSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
27
		int len = text.length();
28
		for (int i = len - 1; i >= 0; i--) {
29
			STextProcessor.insertMark(text, charTypes, offsets, i);
30
			STextProcessor.insertMark(text, charTypes, offsets, i);
31
		}
32
		return len;
33
	}
34
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestProcessor2.java (+22 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.custom.STextProcessor;
15
16
public class TestProcessor2 extends STextProcessor {
17
18
	public int getSpecialsCount(STextEnvironment env) {
19
		return 1;
20
	}
21
22
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestProcessor3.java (+25 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.custom.*;
15
16
public class TestProcessor3 extends STextProcessor {
17
18
	public int getSpecialsCount(STextEnvironment env) {
19
		return 1;
20
	}
21
22
	public int indexOfSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
23
		return fromIndex;
24
	}
25
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestProcessorMyComma.java (+55 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
15
import org.eclipse.equinox.bidi.custom.STextCharTypes;
16
import org.eclipse.equinox.bidi.custom.STextProcessor;
17
18
public class TestProcessorMyComma extends STextProcessor {
19
20
	private final static byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
21
	protected final static int LTR = STextDirection.DIR_LTR;
22
	protected final static int RTL = STextDirection.DIR_RTL;
23
24
	final int dirArabic;
25
	final int dirHebrew;
26
27
	public TestProcessorMyComma(int dirArabic, int dirHebrew) {
28
		this.dirArabic = dirArabic;
29
		this.dirHebrew = dirHebrew;
30
	}
31
32
	public String getSeparators(STextEnvironment environment) {
33
		return ","; //$NON-NLS-1$
34
	}
35
36
	public boolean skipProcessing(STextEnvironment environment, String text, STextCharTypes charTypes) {
37
		byte charType = charTypes.getBidiTypeAt(0);
38
		if (charType == AL)
39
			return true;
40
		return false;
41
	}
42
43
	public int getDirection(STextEnvironment environment, String text) {
44
		return getDirection(environment, text, new STextCharTypes(this, environment, text));
45
	}
46
47
	public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
48
		for (int i = 0; i < text.length(); i++) {
49
			byte charType = charTypes.getBidiTypeAt(i);
50
			if (charType == AL)
51
				return dirArabic;
52
		}
53
		return dirHebrew;
54
	}
55
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestProcessorMyCommaLL.java (+18 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
public class TestProcessorMyCommaLL extends TestProcessorMyComma {
14
15
	public TestProcessorMyCommaLL() {
16
		super(LTR, LTR);
17
	}
18
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestProcessorMyCommaRL.java (+18 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
public class TestProcessorMyCommaRL extends TestProcessorMyComma {
14
15
	public TestProcessorMyCommaRL() {
16
		super(RTL, LTR);
17
	}
18
}
(-)src/org/eclipse/equinox/bidi/internal/tests/TestProcessorMyCommaRR.java (+18 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.tests;
12
13
public class TestProcessorMyCommaRR extends TestProcessorMyComma {
14
15
	public TestProcessorMyCommaRR() {
16
		super(RTL, RTL);
17
	}
18
}
(-)src/org/eclipse/equinox/bidi/tests/STextTestSuite.java (-1 / +2 lines)
Lines 23-33 Link Here
23
	public STextTestSuite() {
23
	public STextTestSuite() {
24
		addTestSuite(STextExtensibilityTest.class);
24
		addTestSuite(STextExtensibilityTest.class);
25
		addTestSuite(STextMethodsTest.class);
25
		addTestSuite(STextMethodsTest.class);
26
		addTestSuite(STextNullProcessorTest.class);
26
		addTestSuite(STextFullToLeanTest.class);
27
		addTestSuite(STextFullToLeanTest.class);
27
		addTestSuite(STextExtensionsTest.class);
28
		addTestSuite(STextExtensionsTest.class);
28
		addTestSuite(STextMathTest.class);
29
		addTestSuite(STextMathTest.class);
29
		addTestSuite(STextSomeMoreTest.class);
30
		addTestSuite(STextSomeMoreTest.class);
30
		addTestSuite(STextProcessorTest.class);
31
		addTestSuite(STextUtilTest.class);
31
		addTestSuite(STextStringRecordTest.class);
32
		addTestSuite(STextStringRecordTest.class);
32
	}
33
	}
33
}
34
}
(-)src/org/eclipse/equinox/bidi/STextDirection.java (-1 / +1 lines)
Lines 12-18 Link Here
12
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
14
15
// TBD combine with STextProcessor; remove duplicates of those two constants
15
// TBD combine with STextUtil; remove duplicates of those two constants
16
public interface STextDirection {
16
public interface STextDirection {
17
17
18
	/**
18
	/**
(-)src/org/eclipse/equinox/bidi/STextProcessor.java (-269 lines)
Lines 1-269 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi;
12
13
import org.eclipse.equinox.bidi.advanced.*;
14
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
15
16
/**
17
 *  This class provides a number of convenience functions facilitating the
18
 *  processing of structured text.
19
 *
20
 *  @noextend This class is not intended to be subclassed by clients.
21
 *  @noinstantiate This class is not intended to be instantiated by clients.
22
 *
23
 *  @author Matitiahu Allouche
24
 */
25
public final class STextProcessor {
26
27
	/**
28
	 * The default set of separators used to segment a string: dot, colon, slash, backslash.
29
	 */
30
	public static final String defaultSeparators = ".:/\\"; //$NON-NLS-1$
31
32
	// left to right mark
33
	private static final char LRM = '\u200e';
34
35
	// left to right mark
36
	private static final char RLM = '\u200f';
37
38
	// left to right embedding
39
	private static final char LRE = '\u202a';
40
41
	// right to left embedding
42
	private static final char RLE = '\u202b';
43
44
	// pop directional format
45
	private static final char PDF = '\u202c';
46
47
	/**
48
	 * Prevents instantiation.
49
	 */
50
	private STextProcessor() {
51
		// empty
52
	}
53
54
	/** 
55
	 * This method adds directional marks to the given text before the characters 
56
	 * specified in the given array of offsets. It can be used to add a prefix and/or 
57
	 * a suffix of directional formatting characters.
58
	 * <p>
59
	 * The directional marks will be LRMs for structured text strings with LTR base 
60
	 * direction and RLMs for strings with RTL base direction.
61
	 * </p><p> 
62
	 * If necessary, leading and trailing directional markers (LRE, RLE and PDF) can 
63
	 * be added depending on the value of the <code>affix</code> argument.
64
	 * </p>
65
	 * @see ISTextExpert#leanBidiCharOffsets(String)
66
	 * 
67
	 * @param  text the structured text string
68
	 * @param  offsets an array of offsets to characters in <code>text</code>
69
	 *         before which an LRM or RLM will be inserted.
70
	 *         The array must be sorted in ascending order without duplicates.
71
	 *         This argument may be <code>null</code> if there are no marks to add.
72
	 * @param  direction the base direction of the structured text.
73
	 *         It must be one of the values {@link STextDirection#DIR_LTR}, or
74
	 *         {@link STextDirection#DIR_RTL}.
75
	 * @param  affix specifies if a prefix and a suffix should be added to
76
	 *         the result
77
	 * @return a string corresponding to the source <code>text</code> with
78
	 *         directional marks (LRMs or RLMs) added at the specified offsets,
79
	 *         and directional formatting characters (LRE, RLE, PDF) added
80
	 *         as prefix and suffix if so required.
81
	 */
82
	public static String insertMarks(String text, int[] offsets, int direction, boolean affix) {
83
		int textLen = text.length();
84
		if (textLen == 0)
85
			return ""; //$NON-NLS-1$
86
87
		String curPrefix, curSuffix, full;
88
		char curMark, c;
89
		char[] fullChars;
90
		if (direction == STextDirection.DIR_LTR) {
91
			curMark = LRM;
92
			curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$
93
			curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$
94
		} else {
95
			curMark = RLM;
96
			curPrefix = "\u202b\u200f"; /* RLE+RLM *///$NON-NLS-1$
97
			curSuffix = "\u200f\u202c"; /* RLM+PDF *///$NON-NLS-1$
98
		}
99
		// add marks at offsets
100
		if ((offsets != null) && (offsets.length > 0)) {
101
			int offLen = offsets.length;
102
			fullChars = new char[textLen + offLen];
103
			int added = 0;
104
			for (int i = 0, j = 0; i < textLen; i++) {
105
				c = text.charAt(i);
106
				if ((j < offLen) && (i == offsets[j])) {
107
					fullChars[i + added] = curMark;
108
					added++;
109
					j++;
110
				}
111
				fullChars[i + added] = c;
112
			}
113
			full = new String(fullChars);
114
		} else {
115
			full = text;
116
		}
117
		if (affix)
118
			return curPrefix + full + curSuffix;
119
		return full;
120
	}
121
122
	/**
123
	 *  Process the given text and return a string with appropriate
124
	 *  directional formatting characters. This is equivalent to calling
125
	 *  {@link #process(String str, String separators)} with the default
126
	 *  set of separators.
127
	 *  <p>
128
	 *  The processing adds directional formatting characters so that presentation 
129
	 *  using the Unicode Bidirectional Algorithm will provide the expected result.
130
	 *  The text is segmented according to the provided separators.
131
	 *  Each segment has the Unicode Bidi Algorithm applied to it,
132
	 *  but as a whole, the string is oriented left to right.
133
	 *  </p><p>
134
	 *  For example, a file path such as <tt>d:\myfolder\FOLDER\MYFILE.java</tt>
135
	 *  (where capital letters indicate RTL text) should render as
136
	 *  <tt>d:\myfolder\REDLOF\ELIFYM.java</tt>.
137
	 *  </p>
138
	 *  @param  str the text to be processed
139
	 *  @return the processed string
140
	 */
141
	public static String process(String str) {
142
		return process(str, defaultSeparators);
143
	}
144
145
	/**
146
	 * Process a string that has a particular semantic meaning to render
147
	 * it correctly on bidi locales. 
148
	 * @see #process(String)
149
	 * @param  str the text to process
150
	 * @param  separators separators by which the string will be segmented
151
	 * @return the processed string
152
	 */
153
	public static String process(String str, String separators) {
154
		if ((str == null) || (str.length() <= 1))
155
			return str;
156
157
		// do not process a string that has already been processed.
158
		if (str.charAt(0) == LRE && str.charAt(str.length() - 1) == PDF)
159
			return str;
160
161
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
162
		if (!env.isProcessingNeeded())
163
			return str;
164
		// do not process a string if all the following conditions are true:
165
		//  a) it has no RTL characters
166
		//  b) it starts with a LTR character
167
		//  c) it ends with a LTR character or a digit
168
		boolean isStringBidi = false;
169
		int strLength = str.length();
170
		char c;
171
		for (int i = 0; i < strLength; i++) {
172
			c = str.charAt(i);
173
			if (((c >= 0x05d0) && (c <= 0x07b1)) || ((c >= 0xfb1d) && (c <= 0xfefc))) {
174
				isStringBidi = true;
175
				break;
176
			}
177
		}
178
		while (!isStringBidi) {
179
			if (!Character.isLetter(str.charAt(0)))
180
				break;
181
			c = str.charAt(strLength - 1);
182
			if (!Character.isDigit(c) && !Character.isLetter(c))
183
				break;
184
			return str;
185
		}
186
187
		if (separators == null)
188
			separators = defaultSeparators;
189
190
		// make sure that LRE/PDF are added around the string
191
		STextTypeHandler handler = new STextTypeHandler(separators);
192
		ISTextExpert expert = STextExpertFactory.getExpert(handler, env);
193
		return expert.leanToFullText(str);
194
	}
195
196
	/**
197
	 * Processes a string that has a particular semantic meaning to render
198
	 * it correctly on bidi locales. 
199
	 * @see #process(String)
200
	 * @param  str the text to process
201
	 * @param  handler a handler instance appropriate for the type of the structured text
202
	 * @return the processed string
203
	 */
204
	public static String process(String str, STextTypeHandler handler) {
205
		if ((str == null) || (str.length() <= 1))
206
			return str;
207
208
		// do not process a string that has already been processed.
209
		char c = str.charAt(0);
210
		if (((c == LRE) || (c == RLE)) && str.charAt(str.length() - 1) == PDF)
211
			return str;
212
213
		// make sure that LRE/PDF are added around the string
214
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
215
		if (!env.isProcessingNeeded())
216
			return str;
217
		ISTextExpert expert = STextExpertFactory.getExpert(handler, env);
218
		return expert.leanToFullText(str);
219
	}
220
221
	/**
222
	 * Removes directional formatting characters in the given string.
223
	 * @param  str string with directional characters to remove
224
	 * @return string without directional formatting characters
225
	 */
226
	public static String deprocess(String str) {
227
		if ((str == null) || (str.length() <= 1))
228
			return str;
229
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
230
		if (!env.isProcessingNeeded())
231
			return str;
232
233
		StringBuffer buf = new StringBuffer();
234
		int strLen = str.length();
235
		for (int i = 0; i < strLen; i++) {
236
			char c = str.charAt(i);
237
			switch (c) {
238
				case LRM :
239
					continue;
240
				case LRE :
241
					continue;
242
				case PDF :
243
					continue;
244
				default :
245
					buf.append(c);
246
			}
247
		}
248
		return buf.toString();
249
	}
250
251
	/**
252
	 * Removes directional formatting characters in the given string.
253
	 * @param  str string with directional characters to remove
254
	 * @param  handler appropriate for the structured text
255
	 * @return string without directional formatting characters
256
	 */
257
	public static String deprocess(String str, STextTypeHandler handler) {
258
		if ((str == null) || (str.length() <= 1))
259
			return str;
260
261
		// make sure that LRE/PDF are added around the string
262
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
263
		if (!env.isProcessingNeeded())
264
			return str;
265
		ISTextExpert expert = STextExpertFactory.getExpert(handler, env);
266
		return expert.fullToLeanText(str);
267
	}
268
269
}
(-)src/org/eclipse/equinox/bidi/STextProcessorFactory.java (+120 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi;
12
13
import org.eclipse.equinox.bidi.custom.STextProcessor;
14
import org.eclipse.equinox.bidi.internal.STextTypesCollector;
15
16
/**
17
 * This class provides access to registered structured text processors.
18
 * 
19
 * @noinstantiate This class is not intended to be instantiated by clients.
20
 */
21
final public class STextProcessorFactory {
22
23
	/**
24
	 * Structured text processor for property file statements. It expects the following format:
25
	 * <pre>
26
	 *  name=value
27
	 * </pre>
28
	 */
29
	public static final String PROPERTY = "property"; //$NON-NLS-1$
30
31
	/**
32
	 * Structured text processor for compound names. It expects text to be made of one or more 
33
	 * parts separated by underscores:
34
	 * <pre>
35
	 *  part1_part2_part3
36
	 * </pre>
37
	 */
38
	public static final String UNDERSCORE = "underscore"; //$NON-NLS-1$
39
40
	/**
41
	 * Structured text processor for comma-delimited lists, such as:
42
	 * <pre>
43
	 *  part1,part2,part3
44
	 * </pre>
45
	 */
46
	public static final String COMMA_DELIMITED = "comma"; //$NON-NLS-1$
47
48
	/**
49
	 * Structured text processor for strings with the following format:
50
	 * <pre>
51
	 *  system(user)
52
	 * </pre>
53
	 */
54
	public static final String SYSTEM_USER = "system"; //$NON-NLS-1$
55
56
	/**
57
	 * Structured text processor for directory and file paths.
58
	 */
59
	public static final String FILE = "file"; //$NON-NLS-1$
60
61
	/**
62
	 * Structured text processor for e-mail addresses.
63
	 */
64
	public static final String EMAIL = "email"; //$NON-NLS-1$
65
66
	/**
67
	 * Structured text processor for URLs.
68
	 */
69
	public static final String URL = "url"; //$NON-NLS-1$
70
71
	/**
72
	 * Structured text processor for regular expressions, possibly spanning multiple lines.
73
	 */
74
	public static final String REGEXP = "regex"; //$NON-NLS-1$
75
76
	/**
77
	 * Structured text processor for XPath expressions.
78
	 */
79
	public static final String XPATH = "xpath"; //$NON-NLS-1$
80
81
	/**
82
	 * Structured text processor for Java code, possibly spanning multiple lines.
83
	 */
84
	public static final String JAVA = "java"; //$NON-NLS-1$
85
86
	/**
87
	 * Structured text processor for SQL statements, possibly spanning multiple lines.
88
	 */
89
	public static final String SQL = "sql"; //$NON-NLS-1$
90
91
	/**
92
	 *  Structured text processor for arithmetic expressions, possibly with a RTL base direction.
93
	 */
94
	public static final String RTL_ARITHMETIC = "math"; //$NON-NLS-1$
95
96
	/**
97
	 * Prevents instantiation
98
	 */
99
	private STextProcessorFactory() {
100
		// placeholder
101
	}
102
103
	/**
104
	 * Retrieve all IDs of registered structured text processors.
105
	 * @return an array of text processor IDs.
106
	 */
107
	static public String[] getAllProcessorIDs() {
108
		return STextTypesCollector.getInstance().getTypes();
109
	}
110
111
	/**
112
	 *  Obtain a structured text processor of a given type.
113
	 *  @param id string identifying processor
114
	 *  @return a processor of the required type, or <code>null</code> if the type is unknown
115
	 */
116
	static public STextProcessor getProcessor(String id) {
117
		return STextTypesCollector.getInstance().getProcessor(id);
118
	}
119
120
}
(-)src/org/eclipse/equinox/bidi/STextStringRecord.java (-24 / +24 lines)
Lines 25-31 Link Here
25
 * A string may be itself entirely a structured text, or it may contain
25
 * A string may be itself entirely a structured text, or it may contain
26
 * segments each of which is a structured text of a given type. Each such
26
 * segments each of which is a structured text of a given type. Each such
27
 * segment is identified by its starting and ending offsets within the
27
 * segment is identified by its starting and ending offsets within the
28
 * string, and by the handler which is appropriate to handle it.
28
 * string, and by the processor which is appropriate to handle it.
29
 */
29
 */
30
public class STextStringRecord {
30
public class STextStringRecord {
31
	/**
31
	/**
Lines 57-64 Link Here
57
	// reference to the recorded string
57
	// reference to the recorded string
58
	private String string;
58
	private String string;
59
59
60
	// reference to the handlers of the STT segments in the recorded string
60
	// reference to the processors of the STT segments in the recorded string
61
	private String[] handlers;
61
	private String[] processors;
62
62
63
	// reference to the boundaries of the STT segments in the recorded string
63
	// reference to the boundaries of the STT segments in the recorded string
64
	// (entries 0, 2, 4, ... are start offsets; entries 1, 3, 5, ... are
64
	// (entries 0, 2, 4, ... are start offsets; entries 1, 3, 5, ... are
Lines 74-80 Link Here
74
74
75
	/**
75
	/**
76
	 * Record a string in the pool. The caller must specify the number
76
	 * Record a string in the pool. The caller must specify the number
77
	 * of segments in the record (at least 1), and the handler, starting
77
	 * of segments in the record (at least 1), and the processor, starting
78
	 * and ending offsets for the first segment.
78
	 * and ending offsets for the first segment.
79
	 *
79
	 *
80
	 * @param  string the string to record.
80
	 * @param  string the string to record.
Lines 82-90 Link Here
82
	 * @param  segmentCount number of segments allowed in this string.
82
	 * @param  segmentCount number of segments allowed in this string.
83
	 *         This number must be >= 1.
83
	 *         This number must be >= 1.
84
	 *
84
	 *
85
	 * @param  handler the handler appropriate to handle the type
85
	 * @param  processor the processor appropriate to handle the type
86
	 *         of structured text present in the first segment.
86
	 *         of structured text present in the first segment.
87
	 *         It may be one of the pre-defined handler instances, or it may be an instance
87
	 *         It may be one of the pre-defined processor instances, or it may be an instance
88
	 *         created by a plug-in or by the application.
88
	 *         created by a plug-in or by the application.
89
	 *
89
	 *
90
	 * @param  start offset in the string of the starting character of the first
90
	 * @param  start offset in the string of the starting character of the first
Lines 102-108 Link Here
102
	 *         if <code>segmentCount</code> is less than 1.
102
	 *         if <code>segmentCount</code> is less than 1.
103
	 * @throws also the same exceptions as {@link #addSegment addSegment}.
103
	 * @throws also the same exceptions as {@link #addSegment addSegment}.
104
	 */
104
	 */
105
	public static STextStringRecord addRecord(String string, int segmentCount, String handlerID, int start, int limit) {
105
	public static STextStringRecord addRecord(String string, int segmentCount, String processorID, int start, int limit) {
106
		if (string == null)
106
		if (string == null)
107
			throw new IllegalArgumentException("The string argument must not be null!"); //$NON-NLS-1$
107
			throw new IllegalArgumentException("The string argument must not be null!"); //$NON-NLS-1$
108
		if (segmentCount < 1)
108
		if (segmentCount < 1)
Lines 124-147 Link Here
124
		}
124
		}
125
		hashArray[last] = string.hashCode();
125
		hashArray[last] = string.hashCode();
126
		for (int i = 0; i < record.usedSegmentCount; i++)
126
		for (int i = 0; i < record.usedSegmentCount; i++)
127
			record.handlers[i] = null;
127
			record.processors[i] = null;
128
		if (segmentCount > record.totalSegmentCount) {
128
		if (segmentCount > record.totalSegmentCount) {
129
			record.handlers = new String[segmentCount];
129
			record.processors = new String[segmentCount];
130
			record.boundaries = new short[segmentCount * 2];
130
			record.boundaries = new short[segmentCount * 2];
131
			record.totalSegmentCount = segmentCount;
131
			record.totalSegmentCount = segmentCount;
132
		}
132
		}
133
		record.usedSegmentCount = 0;
133
		record.usedSegmentCount = 0;
134
		record.string = string;
134
		record.string = string;
135
		record.addSegment(handlerID, start, limit);
135
		record.addSegment(processorID, start, limit);
136
		return record;
136
		return record;
137
	}
137
	}
138
138
139
	/**
139
	/**
140
	 * Add a second or further segment to a record.
140
	 * Add a second or further segment to a record.
141
	 *
141
	 *
142
	 * @param  handler the handler appropriate to handle the type
142
	 * @param  processor the processor appropriate to handle the type
143
	 *         of structured text present in this segment.
143
	 *         of structured text present in this segment.
144
	 *         It may be one of the pre-defined handler instances, or it may be an instance
144
	 *         It may be one of the pre-defined processor instances, or it may be an instance
145
	 *         created by a plug-in or by the application.
145
	 *         created by a plug-in or by the application.
146
	 *
146
	 *
147
	 * @param  start offset in the string of the starting character of the
147
	 * @param  start offset in the string of the starting character of the
Lines 151-157 Link Here
151
	 *         greater than the <code>start</code> argument and not greater
151
	 *         greater than the <code>start</code> argument and not greater
152
	 *         than the length of the string.
152
	 *         than the length of the string.
153
	 *
153
	 *
154
	 * @throws IllegalArgumentException if <code>handler</code> is null,
154
	 * @throws IllegalArgumentException if <code>processor</code> is null,
155
	 *         or if <code>start</code> or <code>limit</code> have invalid
155
	 *         or if <code>start</code> or <code>limit</code> have invalid
156
	 *         values.
156
	 *         values.
157
	 * @throws IllegalStateException if the current segment exceeds the
157
	 * @throws IllegalStateException if the current segment exceeds the
Lines 159-174 Link Here
159
	 *         in the call to {@link #addRecord addRecord} which created
159
	 *         in the call to {@link #addRecord addRecord} which created
160
	 *         the STextStringRecord instance.
160
	 *         the STextStringRecord instance.
161
	 */
161
	 */
162
	public void addSegment(String handlerID, int start, int limit) {
162
	public void addSegment(String processorID, int start, int limit) {
163
		if (handlerID == null)
163
		if (processorID == null)
164
			throw new IllegalArgumentException("The handler argument must not be null!"); //$NON-NLS-1$
164
			throw new IllegalArgumentException("The processor argument must not be null!"); //$NON-NLS-1$
165
		if (start < 0 || start >= string.length())
165
		if (start < 0 || start >= string.length())
166
			throw new IllegalArgumentException("The start position must be at least 0 and less than the length of the string!"); //$NON-NLS-1$
166
			throw new IllegalArgumentException("The start position must be at least 0 and less than the length of the string!"); //$NON-NLS-1$
167
		if (limit <= start || limit > string.length())
167
		if (limit <= start || limit > string.length())
168
			throw new IllegalArgumentException("The limit position must be greater than the start position but no greater than the length of the string!"); //$NON-NLS-1$
168
			throw new IllegalArgumentException("The limit position must be greater than the start position but no greater than the length of the string!"); //$NON-NLS-1$
169
		if (usedSegmentCount >= totalSegmentCount)
169
		if (usedSegmentCount >= totalSegmentCount)
170
			throw new IllegalStateException("All segments of the record are already used!"); //$NON-NLS-1$
170
			throw new IllegalStateException("All segments of the record are already used!"); //$NON-NLS-1$
171
		handlers[usedSegmentCount] = handlerID;
171
		processors[usedSegmentCount] = processorID;
172
		boundaries[usedSegmentCount * 2] = (short) start;
172
		boundaries[usedSegmentCount * 2] = (short) start;
173
		boundaries[usedSegmentCount * 2 + 1] = (short) limit;
173
		boundaries[usedSegmentCount * 2 + 1] = (short) limit;
174
		usedSegmentCount++;
174
		usedSegmentCount++;
Lines 184-191 Link Here
184
	 *         records this string.<br>
184
	 *         records this string.<br>
185
	 *         Once a record has been found, the number of its segments can
185
	 *         Once a record has been found, the number of its segments can
186
	 *         be retrieved using {@link #getSegmentCount getSegmentCount},
186
	 *         be retrieved using {@link #getSegmentCount getSegmentCount},
187
	 *         its handler can
187
	 *         its processor can
188
	 *         be retrieved using {@link #getHandler getHandler},
188
	 *         be retrieved using {@link #getProcessor getProcessor},
189
	 *         its starting offset can
189
	 *         its starting offset can
190
	 *         be retrieved using {@link #getStart getStart},
190
	 *         be retrieved using {@link #getStart getStart},
191
	 *         its ending offset can
191
	 *         its ending offset can
Lines 236-242 Link Here
236
	}
236
	}
237
237
238
	/**
238
	/**
239
	 * Retrieve the handler of a given segment.
239
	 * Retrieve the processor of a given segment.
240
	 *
240
	 *
241
	 * @param  segmentNumber number of the segment about which information
241
	 * @param  segmentNumber number of the segment about which information
242
	 *         is required. It must be >= 0 and less than the number of
242
	 *         is required. It must be >= 0 and less than the number of
Lines 244-250 Link Here
244
	 *         in the call to {@link #addRecord addRecord} which created
244
	 *         in the call to {@link #addRecord addRecord} which created
245
	 *         the STextStringRecord instance.
245
	 *         the STextStringRecord instance.
246
	 *
246
	 *
247
	 * @return the handler to handle the structured text in the segment
247
	 * @return the processor to handle the structured text in the segment
248
	 *         specified by <code>segmentNumber</code>.
248
	 *         specified by <code>segmentNumber</code>.
249
	 *
249
	 *
250
	 * @throws IllegalArgumentException if <code>segmentNumber</code>
250
	 * @throws IllegalArgumentException if <code>segmentNumber</code>
Lines 252-260 Link Here
252
	 *
252
	 *
253
	 * @see    #getSegmentCount
253
	 * @see    #getSegmentCount
254
	 */
254
	 */
255
	public String getHandler(int segmentNumber) {
255
	public String getProcessor(int segmentNumber) {
256
		checkSegmentNumber(segmentNumber);
256
		checkSegmentNumber(segmentNumber);
257
		return handlers[segmentNumber];
257
		return processors[segmentNumber];
258
	}
258
	}
259
259
260
	/**
260
	/**
Lines 315-321 Link Here
315
			if (record == null)
315
			if (record == null)
316
				continue;
316
				continue;
317
			record.boundaries = null;
317
			record.boundaries = null;
318
			record.handlers = null;
318
			record.processors = null;
319
			record.totalSegmentCount = 0;
319
			record.totalSegmentCount = 0;
320
			record.usedSegmentCount = 0;
320
			record.usedSegmentCount = 0;
321
			recordRefs[i].clear();
321
			recordRefs[i].clear();
(-)src/org/eclipse/equinox/bidi/STextTypeHandlerFactory.java (-120 lines)
Lines 1-120 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi;
12
13
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
14
import org.eclipse.equinox.bidi.internal.STextTypesCollector;
15
16
/**
17
 * This class provides access to registered structured text handlers.
18
 * 
19
 * @noinstantiate This class is not intended to be instantiated by clients.
20
 */
21
final public class STextTypeHandlerFactory {
22
23
	/**
24
	 * Structured text handler for property file statements. It expects the following format:
25
	 * <pre>
26
	 *  name=value
27
	 * </pre>
28
	 */
29
	public static final String PROPERTY = "property"; //$NON-NLS-1$
30
31
	/**
32
	 * Structured text handler for compound names. It expects text to be made of one or more 
33
	 * parts separated by underscores:
34
	 * <pre>
35
	 *  part1_part2_part3
36
	 * </pre>
37
	 */
38
	public static final String UNDERSCORE = "underscore"; //$NON-NLS-1$
39
40
	/**
41
	 * Structured text handler for comma-delimited lists, such as:
42
	 * <pre>
43
	 *  part1,part2,part3
44
	 * </pre>
45
	 */
46
	public static final String COMMA_DELIMITED = "comma"; //$NON-NLS-1$
47
48
	/**
49
	 * Structured text handler for strings with the following format:
50
	 * <pre>
51
	 *  system(user)
52
	 * </pre>
53
	 */
54
	public static final String SYSTEM_USER = "system"; //$NON-NLS-1$
55
56
	/**
57
	 * Structured text handler for directory and file paths.
58
	 */
59
	public static final String FILE = "file"; //$NON-NLS-1$
60
61
	/**
62
	 * Structured text handler for e-mail addresses.
63
	 */
64
	public static final String EMAIL = "email"; //$NON-NLS-1$
65
66
	/**
67
	 * Structured text handler for URLs.
68
	 */
69
	public static final String URL = "url"; //$NON-NLS-1$
70
71
	/**
72
	 * Structured text handler for regular expressions, possibly spanning multiple lines.
73
	 */
74
	public static final String REGEXP = "regex"; //$NON-NLS-1$
75
76
	/**
77
	 * Structured text handler for XPath expressions.
78
	 */
79
	public static final String XPATH = "xpath"; //$NON-NLS-1$
80
81
	/**
82
	 * Structured text handler for Java code, possibly spanning multiple lines.
83
	 */
84
	public static final String JAVA = "java"; //$NON-NLS-1$
85
86
	/**
87
	 * Structured text handler for SQL statements, possibly spanning multiple lines.
88
	 */
89
	public static final String SQL = "sql"; //$NON-NLS-1$
90
91
	/**
92
	 *  Structured text handler for arithmetic expressions, possibly with a RTL base direction.
93
	 */
94
	public static final String RTL_ARITHMETIC = "math"; //$NON-NLS-1$
95
96
	/**
97
	 * Prevents instantiation
98
	 */
99
	private STextTypeHandlerFactory() {
100
		// placeholder
101
	}
102
103
	/**
104
	 * Retrieve all IDs of registered structured text handlers.
105
	 * @return an array of text handler IDs.
106
	 */
107
	static public String[] getAllHandlerIDs() {
108
		return STextTypesCollector.getInstance().getTypes();
109
	}
110
111
	/**
112
	 *  Obtain a structured text handler of a given type.
113
	 *  @param id string identifying handler
114
	 *  @return a handler of the required type, or <code>null</code> if the type is unknown
115
	 */
116
	static public STextTypeHandler getHandler(String id) {
117
		return STextTypesCollector.getInstance().getHandler(id);
118
	}
119
120
}
(-)src/org/eclipse/equinox/bidi/STextUtil.java (+269 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi;
12
13
import org.eclipse.equinox.bidi.advanced.*;
14
import org.eclipse.equinox.bidi.custom.STextProcessor;
15
16
/**
17
 *  This class provides a number of convenience functions facilitating the
18
 *  processing of structured text.
19
 *
20
 *  @noextend This class is not intended to be subclassed by clients.
21
 *  @noinstantiate This class is not intended to be instantiated by clients.
22
 *
23
 *  @author Matitiahu Allouche
24
 */
25
public final class STextUtil {
26
27
	/**
28
	 * The default set of separators used to segment a string: dot, colon, slash, backslash.
29
	 */
30
	public static final String defaultSeparators = ".:/\\"; //$NON-NLS-1$
31
32
	// left to right mark
33
	private static final char LRM = '\u200e';
34
35
	// left to right mark
36
	private static final char RLM = '\u200f';
37
38
	// left to right embedding
39
	private static final char LRE = '\u202a';
40
41
	// right to left embedding
42
	private static final char RLE = '\u202b';
43
44
	// pop directional format
45
	private static final char PDF = '\u202c';
46
47
	/**
48
	 * Prevents instantiation.
49
	 */
50
	private STextUtil() {
51
		// empty
52
	}
53
54
	/** 
55
	 * This method adds directional marks to the given text before the characters 
56
	 * specified in the given array of offsets. It can be used to add a prefix and/or 
57
	 * a suffix of directional formatting characters.
58
	 * <p>
59
	 * The directional marks will be LRMs for structured text strings with LTR base 
60
	 * direction and RLMs for strings with RTL base direction.
61
	 * </p><p> 
62
	 * If necessary, leading and trailing directional markers (LRE, RLE and PDF) can 
63
	 * be added depending on the value of the <code>affix</code> argument.
64
	 * </p>
65
	 * @see ISTextExpert#leanBidiCharOffsets(String)
66
	 * 
67
	 * @param  text the structured text string
68
	 * @param  offsets an array of offsets to characters in <code>text</code>
69
	 *         before which an LRM or RLM will be inserted.
70
	 *         The array must be sorted in ascending order without duplicates.
71
	 *         This argument may be <code>null</code> if there are no marks to add.
72
	 * @param  direction the base direction of the structured text.
73
	 *         It must be one of the values {@link STextDirection#DIR_LTR}, or
74
	 *         {@link STextDirection#DIR_RTL}.
75
	 * @param  affix specifies if a prefix and a suffix should be added to
76
	 *         the result
77
	 * @return a string corresponding to the source <code>text</code> with
78
	 *         directional marks (LRMs or RLMs) added at the specified offsets,
79
	 *         and directional formatting characters (LRE, RLE, PDF) added
80
	 *         as prefix and suffix if so required.
81
	 */
82
	public static String insertMarks(String text, int[] offsets, int direction, boolean affix) {
83
		int textLen = text.length();
84
		if (textLen == 0)
85
			return ""; //$NON-NLS-1$
86
87
		String curPrefix, curSuffix, full;
88
		char curMark, c;
89
		char[] fullChars;
90
		if (direction == STextDirection.DIR_LTR) {
91
			curMark = LRM;
92
			curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$
93
			curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$
94
		} else {
95
			curMark = RLM;
96
			curPrefix = "\u202b\u200f"; /* RLE+RLM *///$NON-NLS-1$
97
			curSuffix = "\u200f\u202c"; /* RLM+PDF *///$NON-NLS-1$
98
		}
99
		// add marks at offsets
100
		if ((offsets != null) && (offsets.length > 0)) {
101
			int offLen = offsets.length;
102
			fullChars = new char[textLen + offLen];
103
			int added = 0;
104
			for (int i = 0, j = 0; i < textLen; i++) {
105
				c = text.charAt(i);
106
				if ((j < offLen) && (i == offsets[j])) {
107
					fullChars[i + added] = curMark;
108
					added++;
109
					j++;
110
				}
111
				fullChars[i + added] = c;
112
			}
113
			full = new String(fullChars);
114
		} else {
115
			full = text;
116
		}
117
		if (affix)
118
			return curPrefix + full + curSuffix;
119
		return full;
120
	}
121
122
	/**
123
	 *  Process the given text and return a string with appropriate
124
	 *  directional formatting characters. This is equivalent to calling
125
	 *  {@link #process(String str, String separators)} with the default
126
	 *  set of separators.
127
	 *  <p>
128
	 *  The processing adds directional formatting characters so that presentation 
129
	 *  using the Unicode Bidirectional Algorithm will provide the expected result.
130
	 *  The text is segmented according to the provided separators.
131
	 *  Each segment has the Unicode Bidi Algorithm applied to it,
132
	 *  but as a whole, the string is oriented left to right.
133
	 *  </p><p>
134
	 *  For example, a file path such as <tt>d:\myfolder\FOLDER\MYFILE.java</tt>
135
	 *  (where capital letters indicate RTL text) should render as
136
	 *  <tt>d:\myfolder\REDLOF\ELIFYM.java</tt>.
137
	 *  </p>
138
	 *  @param  str the text to be processed
139
	 *  @return the processed string
140
	 */
141
	public static String process(String str) {
142
		return process(str, defaultSeparators);
143
	}
144
145
	/**
146
	 * Process a string that has a particular semantic meaning to render
147
	 * it correctly on bidi locales. 
148
	 * @see #process(String)
149
	 * @param  str the text to process
150
	 * @param  separators separators by which the string will be segmented
151
	 * @return the processed string
152
	 */
153
	public static String process(String str, String separators) {
154
		if ((str == null) || (str.length() <= 1))
155
			return str;
156
157
		// do not process a string that has already been processed.
158
		if (str.charAt(0) == LRE && str.charAt(str.length() - 1) == PDF)
159
			return str;
160
161
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
162
		if (!env.isProcessingNeeded())
163
			return str;
164
		// do not process a string if all the following conditions are true:
165
		//  a) it has no RTL characters
166
		//  b) it starts with a LTR character
167
		//  c) it ends with a LTR character or a digit
168
		boolean isStringBidi = false;
169
		int strLength = str.length();
170
		char c;
171
		for (int i = 0; i < strLength; i++) {
172
			c = str.charAt(i);
173
			if (((c >= 0x05d0) && (c <= 0x07b1)) || ((c >= 0xfb1d) && (c <= 0xfefc))) {
174
				isStringBidi = true;
175
				break;
176
			}
177
		}
178
		while (!isStringBidi) {
179
			if (!Character.isLetter(str.charAt(0)))
180
				break;
181
			c = str.charAt(strLength - 1);
182
			if (!Character.isDigit(c) && !Character.isLetter(c))
183
				break;
184
			return str;
185
		}
186
187
		if (separators == null)
188
			separators = defaultSeparators;
189
190
		// make sure that LRE/PDF are added around the string
191
		STextProcessor processor = new STextProcessor(separators);
192
		ISTextExpert processorNew = STextExpertFactory.getExpert(processor, env);
193
		return processorNew.leanToFullText(str);
194
	}
195
196
	/**
197
	 * Processes a string that has a particular semantic meaning to render
198
	 * it correctly on bidi locales. 
199
	 * @see #process(String)
200
	 * @param  str the text to process
201
	 * @param  processor a processor instance appropriate for the type of the structured text
202
	 * @return the processed string
203
	 */
204
	public static String process(String str, STextProcessor processor) {
205
		if ((str == null) || (str.length() <= 1))
206
			return str;
207
208
		// do not process a string that has already been processed.
209
		char c = str.charAt(0);
210
		if (((c == LRE) || (c == RLE)) && str.charAt(str.length() - 1) == PDF)
211
			return str;
212
213
		// make sure that LRE/PDF are added around the string
214
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
215
		if (!env.isProcessingNeeded())
216
			return str;
217
		ISTextExpert processorNew = STextExpertFactory.getExpert(processor, env);
218
		return processorNew.leanToFullText(str);
219
	}
220
221
	/**
222
	 * Removes directional formatting characters in the given string.
223
	 * @param  str string with directional characters to remove
224
	 * @return string without directional formatting characters
225
	 */
226
	public static String deprocess(String str) {
227
		if ((str == null) || (str.length() <= 1))
228
			return str;
229
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
230
		if (!env.isProcessingNeeded())
231
			return str;
232
233
		StringBuffer buf = new StringBuffer();
234
		int strLen = str.length();
235
		for (int i = 0; i < strLen; i++) {
236
			char c = str.charAt(i);
237
			switch (c) {
238
				case LRM :
239
					continue;
240
				case LRE :
241
					continue;
242
				case PDF :
243
					continue;
244
				default :
245
					buf.append(c);
246
			}
247
		}
248
		return buf.toString();
249
	}
250
251
	/**
252
	 * Removes directional formatting characters in the given string.
253
	 * @param  str string with directional characters to remove
254
	 * @param  processor appropriate for the structured text
255
	 * @return string without directional formatting characters
256
	 */
257
	public static String deprocess(String str, STextProcessor processor) {
258
		if ((str == null) || (str.length() <= 1))
259
			return str;
260
261
		// make sure that LRE/PDF are added around the string
262
		STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
263
		if (!env.isProcessingNeeded())
264
			return str;
265
		ISTextExpert processorNew = STextExpertFactory.getExpert(processor, env);
266
		return processorNew.fullToLeanText(str);
267
	}
268
269
}
(-)src/org/eclipse/equinox/bidi/advanced/ISTextExpert.java (-17 / +17 lines)
Lines 14-23 Link Here
14
 * For a general introduction to structured text, see
14
 * For a general introduction to structured text, see
15
 * {@link <a href="package-summary.html"> the package documentation</a>}.
15
 * {@link <a href="package-summary.html"> the package documentation</a>}.
16
 * <p>
16
 * <p>
17
 * Several common handlers are included in <b>STextEngine</b>. For handlers 
17
 * Several common processors are included in <b>STextEngine</b>. For processors 
18
 * supplied by other packages, a handler instance can be obtained using the
18
 * supplied by other packages, a processor instance can be obtained using the
19
 * {@link org.eclipse.equinox.bidi.STextTypeHandlerFactory#getHandler}
19
 * {@link org.eclipse.equinox.bidi.STextProcessorFactory#getProcessor}
20
 * method for the registered handlers, or by instantiating a private handler.
20
 * method for the registered processors, or by instantiating a private processor.
21
 * </p><p>
21
 * </p><p>
22
 * Most of the methods in this class have a <code>text</code>
22
 * Most of the methods in this class have a <code>text</code>
23
 * argument which may be just a part of a larger body of text.
23
 * argument which may be just a part of a larger body of text.
Lines 100-106 Link Here
100
	 * Add directional formatting characters to a structured text
100
	 * Add directional formatting characters to a structured text
101
	 * to ensure correct presentation.
101
	 * to ensure correct presentation.
102
	 * 
102
	 * 
103
	 * @param  handler the handler applicable to the text. If <code>null</code>, 
103
	 * @param  processor the processor applicable to the text. If <code>null</code>, 
104
	 * the method returns unmodified text.
104
	 * the method returns unmodified text.
105
	 * 
105
	 * 
106
	 * @param  environment a bidi environment. If <code>null</code>, the default environment 
106
	 * @param  environment a bidi environment. If <code>null</code>, the default environment 
Lines 122-132 Link Here
122
	 * Given a <i>lean</i> string, compute the positions of each of its
122
	 * Given a <i>lean</i> string, compute the positions of each of its
123
	 * characters within the corresponding <i>full</i> string.
123
	 * characters within the corresponding <i>full</i> string.
124
	 *
124
	 *
125
	 * @param  handler designates a handler instance. If <code>null</code>, this 
125
	 * @param  processor designates a processor instance. If <code>null</code>, this 
126
	 * method returns an identity map.
126
	 * method returns an identity map.
127
	 *
127
	 *
128
	 * @param  environment specifies an environment whose characteristics may affect 
128
	 * @param  environment specifies an environment whose characteristics may affect 
129
	 * the handler's behavior. If <code>null</code>, the default environment is used.
129
	 * the processor's behavior. If <code>null</code>, the default environment is used.
130
	 *
130
	 *
131
	 * @param text is the structured text string.
131
	 * @param text is the structured text string.
132
	 *
132
	 *
Lines 151-160 Link Here
151
	 * depending on the {@link STextEnvironment#getOrientation orientation} of the
151
	 * depending on the {@link STextEnvironment#getOrientation orientation} of the
152
	 * GUI component used for display are not reflected in this method.
152
	 * GUI component used for display are not reflected in this method.
153
	 * </p>
153
	 * </p>
154
	 * @param handler designates a handler instance
154
	 * @param processor designates a processor instance
155
	 *
155
	 *
156
	 * @param  environment specifies an environment whose characteristics may affect 
156
	 * @param  environment specifies an environment whose characteristics may affect 
157
	 * the handler's behavior. If <code>null</code>, the default environment is used.
157
	 * the processor's behavior. If <code>null</code>, the default environment is used.
158
	 *
158
	 *
159
	 * @param text is the structured text string
159
	 * @param text is the structured text string
160
	 *
160
	 *
Lines 173-182 Link Here
173
	 * Remove directional formatting characters which were added to a
173
	 * Remove directional formatting characters which were added to a
174
	 * structured text string to ensure correct presentation.
174
	 * structured text string to ensure correct presentation.
175
	 *
175
	 *
176
	 * @param  handler designates a handler instance
176
	 * @param  processor designates a processor instance
177
	 *
177
	 *
178
	 * @param  environment specifies an environment whose characteristics may affect 
178
	 * @param  environment specifies an environment whose characteristics may affect 
179
	 * the handler's behavior. If <code>null</code>, the default environment is used.
179
	 * the processor's behavior. If <code>null</code>, the default environment is used.
180
	 *
180
	 *
181
	 * @param text is the structured text string including directional formatting characters.
181
	 * @param text is the structured text string including directional formatting characters.
182
	 *
182
	 *
Lines 195-204 Link Here
195
	 * Given a <i>full</i> string, compute the positions of each of its
195
	 * Given a <i>full</i> string, compute the positions of each of its
196
	 * characters within the corresponding <i>lean</i> string.
196
	 * characters within the corresponding <i>lean</i> string.
197
	 *
197
	 *
198
	 * @param  handler designates a handler instance
198
	 * @param  processor designates a processor instance
199
	 *
199
	 *
200
	 * @param  environment specifies an environment whose characteristics may affect 
200
	 * @param  environment specifies an environment whose characteristics may affect 
201
	 * the handler's behavior. If <code>null</code>, the default environment is used.
201
	 * the processor's behavior. If <code>null</code>, the default environment is used.
202
	 *
202
	 *
203
	 * @param  text is the structured text string including directional formatting characters.
203
	 * @param  text is the structured text string including directional formatting characters.
204
	 *
204
	 *
Lines 225-234 Link Here
225
	 * or suffixed depending on the {@link STextEnvironment#getOrientation orientation} 
225
	 * or suffixed depending on the {@link STextEnvironment#getOrientation orientation} 
226
	 * of the GUI component used for display.
226
	 * of the GUI component used for display.
227
	 * </p>
227
	 * </p>
228
	 * @param  handler designates a handler instance
228
	 * @param  processor designates a processor instance
229
	 *
229
	 *
230
	 * @param  environment specifies an environment whose characteristics may affect 
230
	 * @param  environment specifies an environment whose characteristics may affect 
231
	 * the handler's behavior. If <code>null</code>, the default environment is used.
231
	 * the processor's behavior. If <code>null</code>, the default environment is used.
232
	 *
232
	 *
233
	 * @param  text is the structured text string including directional formatting characters
233
	 * @param  text is the structured text string including directional formatting characters
234
	 *
234
	 *
Lines 248-257 Link Here
248
	 * whether the text contains Arabic or Hebrew words. If the text contains both, 
248
	 * whether the text contains Arabic or Hebrew words. If the text contains both, 
249
	 * the first Arabic or Hebrew letter in the text determines which is the governing script.
249
	 * the first Arabic or Hebrew letter in the text determines which is the governing script.
250
	 *
250
	 *
251
	 * @param  handler designates a handler instance
251
	 * @param  processor designates a processor instance
252
	 *
252
	 *
253
	 * @param  environment specifies an environment whose characteristics may affect 
253
	 * @param  environment specifies an environment whose characteristics may affect 
254
	 * the handler's behavior. If <code>null</code>, the default environment is used.
254
	 * the processor's behavior. If <code>null</code>, the default environment is used.
255
	 *
255
	 *
256
	 * @param  text is the structured text string
256
	 * @param  text is the structured text string
257
	 *
257
	 *
(-)src/org/eclipse/equinox/bidi/advanced/ISTextExpertStateful.java (-1 / +1 lines)
Lines 17-23 Link Here
17
	public int getState();
17
	public int getState();
18
18
19
	/**
19
	/**
20
	 * Resets non-shared expert state to initial.
20
	 * Resets non-shared processor state to initial.
21
	 */
21
	 */
22
	public void resetState();
22
	public void resetState();
23
23
(-)src/org/eclipse/equinox/bidi/advanced/STextExpertFactory.java (-30 / +31 lines)
Lines 12-20 Link Here
12
12
13
import java.util.HashMap;
13
import java.util.HashMap;
14
import java.util.Map;
14
import java.util.Map;
15
import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
15
import org.eclipse.equinox.bidi.STextProcessorFactory;
16
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
16
import org.eclipse.equinox.bidi.custom.STextProcessor;
17
import org.eclipse.equinox.bidi.internal.STextImpl;
17
import org.eclipse.equinox.bidi.internal.STextExpertImpl;
18
import org.eclipse.equinox.bidi.internal.STextExpertMultipassImpl;
18
19
19
final public class STextExpertFactory {
20
final public class STextExpertFactory {
20
21
Lines 35-83 Link Here
35
36
36
	static public ISTextExpert getExpert() {
37
	static public ISTextExpert getExpert() {
37
		if (defaultExpert == null) {
38
		if (defaultExpert == null) {
38
			STextTypeHandler handler = new STextTypeHandler(defaultSeparators);
39
			STextProcessor descriptor = new STextProcessor(defaultSeparators);
39
			defaultExpert = new STextImpl(handler, STextEnvironment.DEFAULT, null);
40
			defaultExpert = new STextExpertImpl(descriptor, STextEnvironment.DEFAULT);
40
		}
41
		}
41
		return defaultExpert;
42
		return defaultExpert;
42
	}
43
	}
43
44
44
	static public ISTextExpert getExpert(String type) {
45
	static public ISTextExpert getExpert(String type) {
45
		ISTextExpert expert;
46
		ISTextExpert processor;
46
		synchronized (sharedDefaultExperts) {
47
		synchronized (sharedDefaultExperts) {
47
			expert = (ISTextExpert) sharedDefaultExperts.get(type);
48
			processor = (ISTextExpert) sharedDefaultExperts.get(type);
48
			if (expert == null) {
49
			if (processor == null) {
49
				STextTypeHandler handler = STextTypeHandlerFactory.getHandler(type);
50
				STextProcessor descriptor = STextProcessorFactory.getProcessor(type);
50
				if (handler == null)
51
				if (descriptor == null)
51
					return null;
52
					return null;
52
				expert = new STextImpl(handler, STextEnvironment.DEFAULT, null);
53
				processor = new STextExpertImpl(descriptor, STextEnvironment.DEFAULT);
53
				sharedDefaultExperts.put(type, expert);
54
				sharedDefaultExperts.put(type, processor);
54
			}
55
			}
55
		}
56
		}
56
		return expert;
57
		return processor;
57
	}
58
	}
58
59
59
	static public ISTextExpert getExpert(String type, STextEnvironment environment) {
60
	static public ISTextExpert getExpert(String type, STextEnvironment environment) {
60
		ISTextExpert expert;
61
		ISTextExpert processor;
61
		synchronized (sharedExperts) {
62
		synchronized (sharedExperts) {
62
			Map experts = (Map) sharedExperts.get(type);
63
			Map processors = (Map) sharedExperts.get(type);
63
			if (experts == null) {
64
			if (processors == null) {
64
				experts = new HashMap(); // environment -> expert
65
				processors = new HashMap(); // environment -> processor
65
				sharedExperts.put(type, experts);
66
				sharedExperts.put(type, processors);
66
			}
67
			}
67
			expert = (ISTextExpert) experts.get(environment);
68
			processor = (ISTextExpert) processors.get(environment);
68
			if (expert == null) {
69
			if (processor == null) {
69
				STextTypeHandler handler = STextTypeHandlerFactory.getHandler(type);
70
				STextProcessor descriptor = STextProcessorFactory.getProcessor(type);
70
				if (handler == null)
71
				if (descriptor == null)
71
					return null;
72
					return null;
72
				expert = new STextImpl(handler, environment, null);
73
				processor = new STextExpertImpl(descriptor, environment);
73
				experts.put(type, expert);
74
				processors.put(type, processor);
74
			}
75
			}
75
		}
76
		}
76
		return expert;
77
		return processor;
77
	}
78
	}
78
79
79
	static public ISTextExpert getExpert(STextTypeHandler handler, STextEnvironment environment) {
80
	static public ISTextExpert getExpert(STextProcessor descriptor, STextEnvironment environment) {
80
		return new STextImpl(handler, environment, new int[1]);
81
		return new STextExpertImpl(descriptor, environment);
81
	}
82
	}
82
83
83
	static public ISTextExpertStateful getPrivateExpert(String type) {
84
	static public ISTextExpertStateful getPrivateExpert(String type) {
Lines 85-94 Link Here
85
	}
86
	}
86
87
87
	static public ISTextExpertStateful getPrivateExpert(String type, STextEnvironment environment) {
88
	static public ISTextExpertStateful getPrivateExpert(String type, STextEnvironment environment) {
88
		STextTypeHandler handler = STextTypeHandlerFactory.getHandler(type);
89
		STextProcessor descriptor = STextProcessorFactory.getProcessor(type);
89
		if (handler == null)
90
		if (descriptor == null)
90
			return null;
91
			return null;
91
		return new STextImpl(handler, environment, new int[1]);
92
		return new STextExpertMultipassImpl(descriptor, environment);
92
	}
93
	}
93
94
94
}
95
}
(-)src/org/eclipse/equinox/bidi/custom/STextCharTypes.java (-11 / +11 lines)
Lines 35-66 Link Here
35
35
36
	private static final int CHARTYPES_ADD = 2;
36
	private static final int CHARTYPES_ADD = 2;
37
37
38
	final protected STextTypeHandler handler;
38
	final protected STextProcessor processor;
39
	final protected STextEnvironment environment;
39
	final protected STextEnvironment environment;
40
	final protected String text;
40
	final protected String text;
41
41
42
	// 1 byte for each char in text
42
	// 1 byte for each char in text
43
	private byte[] types;
43
	private byte[] types;
44
44
45
	// structured text direction. -1 means not yet computed; -2 means within handler.getDirection
45
	// structured text direction. -1 means not yet computed; -2 means within processor.getDirection
46
	private int direction = -1;
46
	private int direction = -1;
47
47
48
	/**
48
	/**
49
	 *  Constructor
49
	 *  Constructor
50
	 *  
50
	 *  
51
	 *  @param  handler is the handler handling this occurrence of
51
	 *  @param  processor is the processor handling this occurrence of
52
	 *          structured text.
52
	 *          structured text.
53
	 *          
53
	 *          
54
	 *  @param  environment the current environment, which may affect the behavior of
54
	 *  @param  environment the current environment, which may affect the behavior of
55
	 *          the handler. This parameter may be specified as
55
	 *          the processor. This parameter may be specified as
56
	 *          <code>null</code>, in which case the
56
	 *          <code>null</code>, in which case the
57
	 *          {@link STextEnvironment#DEFAULT DEFAULT}
57
	 *          {@link STextEnvironment#DEFAULT DEFAULT}
58
	 *          environment should be assumed.
58
	 *          environment should be assumed.
59
	 *  
59
	 *  
60
	 *  @param text is the text whose characters are analyzed.
60
	 *  @param text is the text whose characters are analyzed.
61
	 */
61
	 */
62
	public STextCharTypes(STextTypeHandler handler, STextEnvironment environment, String text) {
62
	public STextCharTypes(STextProcessor processor, STextEnvironment environment, String text) {
63
		this.handler = handler;
63
		this.processor = processor;
64
		this.environment = environment;
64
		this.environment = environment;
65
		this.text = text;
65
		this.text = text;
66
		types = new byte[text.length()];
66
		types = new byte[text.length()];
Lines 68-74 Link Here
68
68
69
	public int getDirection() {
69
	public int getDirection() {
70
		if (direction < 0)
70
		if (direction < 0)
71
			direction = handler.getDirection(environment, text, this);
71
			direction = processor.getDirection(environment, text, this);
72
		return direction;
72
		return direction;
73
	}
73
	}
74
74
Lines 96-105 Link Here
96
		byte charType = Character.getDirectionality(text.charAt(index));
96
		byte charType = Character.getDirectionality(text.charAt(index));
97
		if (charType == B) {
97
		if (charType == B) {
98
			if (direction < 0) {
98
			if (direction < 0) {
99
				if (direction < -1) // called by handler.getDirection
99
				if (direction < -1) // called by processor.getDirection
100
					return charType; // avoid infinite recursion
100
					return charType; // avoid infinite recursion
101
				direction = -2; // signal we go within handler.getDirection
101
				direction = -2; // signal we go within processor.getDirection
102
				direction = handler.getDirection(environment, text, this);
102
				direction = processor.getDirection(environment, text, this);
103
			}
103
			}
104
			charType = (direction == STextEnvironment.ORIENT_RTL) ? R : L;
104
			charType = (direction == STextEnvironment.ORIENT_RTL) ? R : L;
105
		}
105
		}
Lines 125-131 Link Here
125
	 *  be displayed.
125
	 *  be displayed.
126
	 *  
126
	 *  
127
	 *  @param  envir is the current environment, which may affect the behavior of
127
	 *  @param  envir is the current environment, which may affect the behavior of
128
	 *          the handler. This parameter may be specified as
128
	 *          the processor. This parameter may be specified as
129
	 *          <code>null</code>, in which case the
129
	 *          <code>null</code>, in which case the
130
	 *          {@link STextEnvironment#DEFAULT DEFAULT}
130
	 *          {@link STextEnvironment#DEFAULT DEFAULT}
131
	 *          environment should be assumed.
131
	 *          environment should be assumed.
(-)src/org/eclipse/equinox/bidi/custom/STextOffsets.java (-1 / +1 lines)
Lines 67-73 Link Here
67
	/**
67
	/**
68
	 * Insert an offset value in the offset array so that the array 
68
	 * Insert an offset value in the offset array so that the array 
69
	 * stays in ascending order.
69
	 * stays in ascending order.
70
	 * @param  procData is a group of data accessible to handlers.
70
	 * @param  procData is a group of data accessible to processors.
71
	 * @param  offset is the value to insert.
71
	 * @param  offset is the value to insert.
72
	 */
72
	 */
73
	public void insertOffset(STextCharTypes charTypes, int offset) {
73
	public void insertOffset(STextCharTypes charTypes, int offset) {
(-)src/org/eclipse/equinox/bidi/custom/STextProcessor.java (+416 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.custom;
12
13
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
15
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
16
import org.eclipse.equinox.bidi.internal.STextImpl;
17
18
/**
19
 *  Generic processor to be used as superclass (base class)
20
 *  for specific structured text processors.
21
 *  <p>
22
 *  Here are some guidelines about how to write structured text
23
 *  processors.
24
 *  <ul>
25
 *    <li>Processor instances may be accessed simultaneously by
26
 *        several threads. They should have no instance variables.</li>
27
 *    <li>The common logic uses processor methods to query the
28
 *        characteristics of the specific processor:
29
 *        <ul>
30
 *          <li>the separators which separate the structured text into
31
 *              tokens. See {@link #getSeparators getSeparators}.</li>
32
 *          <li>the direction which governs the display of tokens
33
 *              one after the other. See {@link #getDirection getDirection}.</li>
34
 *          <li>the number of special cases which need to be handled by
35
 *              code specific to that processor.
36
 *              See {@link #getSpecialsCount getSpecialsCount}.</li>
37
 *        </ul></li>
38
 *    <li>Before starting deeper analysis of the submitted text, the common
39
 *        logic gives to the processor a chance to shorten the processus by
40
 *        invoking its {@link #skipProcessing skipProcessing} method.</li>
41
 *    <li>The common logic then analyzes the text to segment it into tokens
42
 *        according to the appearance of separators (as retrieved using
43
 *        {@link #getSeparators getSeparators}).</li>
44
 *    <li>If the processor indicated a positive number of special cases as
45
 *        return value from its {@link #getSpecialsCount getSpecialsCount}
46
 *        method, the common logic will repeatedly invoke the processor's
47
 *        {@link #indexOfSpecial indexOfSpecial} method to let it signal the
48
 *        presence of special strings which may further delimit the source text.</li>
49
 *    <li>When such a special case is signalled by the processor, the common
50
 *        logic will call the processor's {@link #processSpecial processSpecial}
51
 *        method to give it the opportunity to handle it as needed. Typical
52
 *        actions that the processor may perform are to add directional marks
53
 *        inconditionally (by calling {@link #insertMark insertMark} or
54
 *        conditionally (by calling {@link #processSeparator processSeparator}).</li>
55
 *  </ul>
56
 *
57
 * @author Matitiahu Allouche
58
 */
59
public class STextProcessor {
60
61
	final private String separators;
62
63
	/**
64
	 * Creates a new instance of the STextProcessor class.
65
	 */
66
	public STextProcessor() {
67
		separators = ""; //$NON-NLS-1$
68
	}
69
70
	/**
71
	 * Creates a new instance of the STextProcessor class.
72
	 * @param separators string consisting of characters that split the text into fragments
73
	 */
74
	public STextProcessor(String separators) {
75
		this.separators = separators;
76
	}
77
78
	/**
79
	 * Locate occurrences of special strings within a structured text
80
	 * and return their indexes one after the other in successive calls.
81
	 * <p>
82
	 * This method is called repeatedly if the number of special cases 
83
	 * returned by {@link #getSpecialsCount} is greater than zero.
84
	 * </p><p>
85
	 * A processor handling special cases must override this method.
86
	 * </p>
87
	 * @param  environment the current environment, which may affect the behavior of
88
	 *         the processor. This parameter may be specified as
89
	 *         <code>null</code>, in which case the
90
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
91
	 *         environment should be assumed.
92
	 *
93
	 * @param  text is the structured text string before
94
	 *         addition of any directional formatting characters.
95
	 *
96
	 * @param  charTypes is a parameter received by <code>indexOfSpecial</code>
97
	 *         uniquely to be used as argument for calls to methods which
98
	 *         need it.
99
	 *
100
	 * @param  offsets is a parameter received by <code>indexOfSpecial</code>
101
	 *         uniquely to be used as argument for calls to methods which
102
	 *         need it.
103
	 *
104
	 * @param  caseNumber number of the special case to locate.
105
	 *         This number varies from 1 to the number of special cases
106
	 *         returned by {@link #getSpecialsCount getSpecialsCount}
107
	 *         for this processor.
108
	 *         The meaning of this number is internal to the class
109
	 *         implementing <code>indexOfSpecial</code>.
110
	 *
111
	 * @param  fromIndex the index within <code>text</code> to start
112
	 *         the search from.
113
	 *
114
	 * @return the position where the start of the special case
115
	 *         corresponding to <code>caseNumber</code> was located.
116
	 *         The method must return the first occurrence of whatever
117
	 *         identifies the start of the special case starting from
118
	 *         <code>fromIndex</code>. The method does not have to check if
119
	 *         this occurrence appears within the scope of another special
120
	 *         case (e.g. a comment starting delimiter within the scope of
121
	 *         a literal or vice-versa).
122
	 *         <br>If no occurrence is found, the method must return -1.
123
	 *
124
	 * @throws IllegalStateException If not overridden, this method throws an
125
	 * <code>IllegalStateException</code>. This is appropriate behavior
126
	 * (and does not need to be overridden) for processors whose
127
	 * number of special cases is zero, which means that
128
	 * <code>indexOfSpecial</code> should never be called for them.
129
	 */
130
	public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
131
		// This method must be overridden by all subclasses with special cases.
132
		throw new IllegalStateException("A processor with specialsCount > 0 must have an indexOfSpecial() method."); //$NON-NLS-1$
133
	}
134
135
	/**
136
	 * This method handles special cases specific to this processor.
137
	 * It is called when a special case occurrence 
138
	 * is located by {@link #indexOfSpecial}.
139
	 * <p>
140
	 * If a special processing cannot be completed within a current call to
141
	 * <code>processSpecial</code> (for instance, a comment has been started
142
	 * in the current line but its end appears in a following line),
143
	 * <code>processSpecial</code> should specify a final state by
144
	 * putting its value in the first element of the <code>state</code>
145
	 * parameter.
146
	 * The meaning of this state is internal to the processor.
147
	 * On a later call, <code>processSpecial</code> will be called with that value 
148
	 * for parameter <code>caseNumber</code> and <code>-1</code> for parameter 
149
	 * <code>separLocation</code> and should perform whatever initializations are required
150
	 * depending on the state.
151
	 * </p><p>
152
	 * A processor handling special cases (with a number of
153
	 * special cases greater than zero) must override this method.
154
	 * </p>
155
	 * @param  environment the current environment, which may affect the behavior of
156
	 *         the processor. This parameter may be specified as
157
	 *         <code>null</code>, in which case the
158
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
159
	 *         environment should be assumed.
160
	 *
161
	 * @param  text is the structured text string before
162
	 *         addition of any directional formatting characters.
163
	 *
164
	 * @param  charTypes is a parameter received by <code>processSpecial</code>
165
	 *         uniquely to be used as argument for calls to methods which
166
	 *         need it.
167
	 *
168
	 * @param  offsets is a parameter received by <code>processSpecial</code>
169
	 *         uniquely to be used as argument for calls to methods which
170
	 *         need it.
171
	 *
172
	 * @param  state is an integer array with at least one element.
173
	 *         If the processor needs to signal the occurrence of a
174
	 *         special case which must be passed to the next call to
175
	 *         <code>leanToFullText</code> (for instance, a comment or a
176
	 *         literal started but not closed in the current
177
	 *         <code>text</code>), it must put a value in the first element
178
	 *         of the <code>state</code> parameter.
179
	 *         This number must be >= 1 and less or equal to the number of special
180
	 *         cases returned by {@link #getSpecialsCount getSpecialsCount}
181
	 *         by this processor.
182
	 *         This number is passed back to the caller
183
	 *         and should be specified as <code>state</code> argument
184
	 *         in the next call to <code>leanToFullText</code> together
185
	 *         with the continuation text.
186
	 *         The meaning of this number is internal to the processor.
187
	 *
188
	 * @param  caseNumber number of the special case to handle.
189
	 *
190
	 * @param  separLocation the position returned by
191
	 *         {@link #indexOfSpecial indexOfSpecial}. In calls to
192
	 *         {@link ISTextExpert#leanToFullText leanToFullText} and other
193
	 *         methods of {@link ISTextExpert} specifying a  non-null
194
	 *         <code>state</code> parameter, <code>processSpecial</code> is
195
	 *         called when initializing the processing with the value of
196
	 *         <code>caseNumber</code> equal to the value returned in the
197
	 *         first element of <code>state</code> and the value of
198
	 *         <code>separLocation</code> equal to <code>-1</code>.
199
	 *
200
	 * @return the position after the scope of the special case ends.
201
	 *         For instance, the position after the end of a comment,
202
	 *         the position after the end of a literal.
203
	 *         <br>A value greater or equal to the length of <code>text</code>
204
	 *         means that there is no further occurrence of this case in the
205
	 *         current structured text.
206
	 *
207
	 * @throws IllegalStateException If not overridden, this method throws an
208
	 * <code>IllegalStateException</code>. This is appropriate behavior
209
	 * (and does not need to be overridden) for processors whose
210
	 * number of special cases is zero, which means that
211
	 * <code>processSpecial</code> should never be called for them.
212
	 */
213
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
214
		// This method must be overridden by all subclasses with any special case.
215
		throw new IllegalStateException("A processor with specialsCount > 0 must have a processSpecial() method."); //$NON-NLS-1$
216
	}
217
218
	/**
219
	 * This method can be called from within {@link #indexOfSpecial} or
220
	 * {@link #processSpecial} in extensions of <code>STextProcessor</code>
221
	 * to specify that a mark character must be added before the character
222
	 * at the specified position of the <i>lean</i> text when generating the
223
	 * <i>full</i> text. The mark character will be LRM for structured text
224
	 * with a LTR base direction, and RLM for structured text with RTL
225
	 * base direction. The mark character is not added physically by this
226
	 * method, but its position is noted and will be used when generating
227
	 * the <i>full</i> text.
228
	 *
229
	 * @param  text is the structured text string received as
230
	 *         parameter to <code>indexOfSpecial</code> or
231
	 *         <code>processSpecial</code>.
232
	 *
233
	 * @param  charTypes is a parameter received by <code>indexOfSpecial</code>
234
	 *         or <code>processSpecial</code>, uniquely to be used as argument
235
	 *         for calls to <code>insertMark</code> and other methods used
236
	 *         by processors.
237
	 *
238
	 * @param  offsets is a parameter received by <code>indexOfSpecial</code>
239
	 *         or <code>processSpecial</code>, uniquely to be used as argument
240
	 *         for calls to <code>insertMark</code> and other methods used
241
	 *         by processors.
242
	 *
243
	 * @param  offset position of the character in the <i>lean</i> text.
244
	 *         It must be a non-negative number smaller than the length
245
	 *         of the <i>lean</i> text.
246
	 *         For the benefit of efficiency, it is better to insert
247
	 *         multiple marks in ascending order of the offsets.
248
	 */
249
	public static final void insertMark(String text, STextCharTypes charTypes, STextOffsets offsets, int offset) {
250
		offsets.insertOffset(charTypes, offset);
251
	}
252
253
	/**
254
	 * This method can be called from within {@link #indexOfSpecial} or
255
	 * {@link #processSpecial} in extensions of <code>STextProcessor</code> to add 
256
	 * a directional mark before a separator if needed for correct display, 
257
	 * depending on the base direction of the text and on the class of the
258
	 * characters in the <i>lean</i> text preceding and following the separator itself.
259
	 * <p>
260
	 * The logic implemented in this method considers the text before
261
	 * <code>separLocation</code> and the text following it. If, and only if,
262
	 * a directional mark is needed to insure that the two parts of text
263
	 * will be laid out according to the base direction, a mark will be
264
	 * added when generating the <i>full</i> text.
265
	 * </p>
266
	 * @param  text is the structured text string received as
267
	 *         parameter to <code>indexOfSpecial</code> or
268
	 *         <code>processSpecial</code>.
269
	 *
270
	 * @param  charTypes is a parameter received by <code>indexOfSpecial</code>
271
	 *         or <code>processSpecial</code>, uniquely to be used as argument
272
	 *         for calls to <code>processSeparator</code> and other methods used
273
	 *         by processors.
274
	 *
275
	 * @param  offsets is a parameter received by <code>indexOfSpecial</code>
276
	 *         or <code>processSpecial</code>, uniquely to be used as argument
277
	 *         for calls to <code>processSeparator</code> and other methods used
278
	 *         by processors.
279
	 *
280
	 * @param  separLocation offset of the separator in the <i>lean</i> text.
281
	 *         It must be a non-negative number smaller than the length
282
	 *         of the <i>lean</i> text.
283
	 */
284
	public static final void processSeparator(String text, STextCharTypes charTypes, STextOffsets offsets, int separLocation) {
285
		STextImpl.processSeparator(text, charTypes, offsets, separLocation);
286
	}
287
288
	/**
289
	 * Indicate the separators to use for the current processor.
290
	 * This method is invoked before starting the processing.
291
	 * <p>
292
	 * If no separators are specified, this method returns an empty string.
293
	 * </p>
294
	 * @param  environment the current environment, which may affect the behavior of
295
	 *         the processor. This parameter may be specified as
296
	 *         <code>null</code>, in which case the
297
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
298
	 *         environment should be assumed.
299
	 *
300
	 * @return a string grouping one-character separators which separate
301
	 *         the structured text into tokens.
302
	 */
303
	public String getSeparators(STextEnvironment environment) {
304
		return separators;
305
	}
306
307
	/**
308
	 * Indicate the base text direction appropriate for an instance of structured text.
309
	 * This method is invoked before starting the processing.
310
	 * <p>
311
	 * If not overridden, this method returns <code>DIR_LTR</code>.
312
	 * </p>
313
	 * @param  environment the current environment, which may affect the behavior of
314
	 *         the processor. This parameter may be specified as
315
	 *         <code>null</code>, in which case the
316
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
317
	 *         environment should be assumed.
318
	 *
319
	 * @param  text is the structured text string to process.
320
	 *
321
	 * @return the base direction of the structured text. This direction
322
	 *         may not be the same depending on the environment and on
323
	 *         whether the structured text contains Arabic or Hebrew
324
	 *         letters.<br>
325
	 *         The value returned is either
326
	 *         {@link STextDirection#DIR_LTR DIR_LTR} or {@link STextDirection#DIR_RTL DIR_RTL}.
327
	 */
328
	public int getDirection(STextEnvironment environment, String text) {
329
		return STextDirection.DIR_LTR;
330
	}
331
332
	/**
333
	 * Indicate the base text direction appropriate for an instance of structured text.
334
	 * This method is invoked before starting the processing.
335
	 * <p>
336
	 * If not overridden, this method returns <code>DIR_LTR</code>.
337
	 * </p>
338
	 * @param  environment the current environment, which may affect the behavior of
339
	 *         the processor. This parameter may be specified as
340
	 *         <code>null</code>, in which case the
341
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
342
	 *         environment should be assumed.
343
	 *
344
	 * @param  text is the structured text string to process.
345
	 *
346
	 * @param  charTypes is a parameter received uniquely to be used as argument
347
	 *         for calls to <code>getCharType</code> and other methods used
348
	 *         by processors.
349
	 *
350
	 * @return the base direction of the structured text. This direction
351
	 *         may not be the same depending on the environment and on
352
	 *         whether the structured text contains Arabic or Hebrew
353
	 *         letters.<br>
354
	 *         The value returned is either
355
	 *         {@link STextDirection#DIR_LTR DIR_LTR} or {@link STextDirection#DIR_RTL DIR_RTL}.
356
	 */
357
	public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
358
		return STextDirection.DIR_LTR;
359
	}
360
361
	/**
362
	 * Indicate the number of special cases handled by the current processor.
363
	 * This method is invoked before starting the processing.
364
	 * If the number returned is zero, {@link #indexOfSpecial} and
365
	 * {@link #processSpecial} will not be invoked.
366
	 * <p>
367
	 * If not overridden, this method returns <code>zero</code>.
368
	 * </p>
369
	 * @param  environment the current environment, which may affect the behavior of
370
	 *         the processor. This parameter may be specified as
371
	 *         <code>null</code>, in which case the
372
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
373
	 *         environment should be assumed.
374
	 *
375
	 * @return the number of special cases for the associated processor.
376
	 *         Special cases exist for some types of structured text
377
	 *         processors. They are implemented by overriding methods
378
	 *         {@link STextProcessor#indexOfSpecial} and {@link STextProcessor#processSpecial}.
379
	 *         Examples of special cases are comments, literals, or
380
	 *         anything which is not identified by a one-character separator.
381
	 *
382
	 */
383
	public int getSpecialsCount(STextEnvironment environment) {
384
		return 0;
385
	}
386
387
	/**
388
	 * Checks if there is a need for processing structured text.
389
	 * This method is invoked before starting the processing. If the
390
	 * processor returns <code>true</code>, no directional formatting
391
	 * characters are added to the <i>lean</i> text and the processing
392
	 * is shortened.
393
	 * <p>
394
	 * If not overridden, this method returns <code>false</code>.
395
	 * </p>
396
	 * @param  environment the current environment, which may affect the behavior of
397
	 *         the processor. This parameter may be specified as
398
	 *         <code>null</code>, in which case the
399
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
400
	 *         environment should be assumed.
401
	 *
402
	 * @param  text is the structured text string to process.
403
	 *
404
	 * @param  charTypes is a parameter received uniquely to be used as argument
405
	 *         for calls to <code>getCharType</code> and other methods used
406
	 *         by processors.
407
	 *
408
	 * @return a flag indicating if there is no need to process the structured
409
	 *         text to add directional formatting characters.
410
	 *
411
	 */
412
	public boolean skipProcessing(STextEnvironment environment, String text, STextCharTypes charTypes) {
413
		return false;
414
	}
415
416
}
(-)src/org/eclipse/equinox/bidi/custom/STextTypeHandler.java (-416 lines)
Lines 1-416 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.custom;
12
13
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
15
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
16
import org.eclipse.equinox.bidi.internal.STextImpl;
17
18
/**
19
 *  Generic handler to be used as superclass (base class)
20
 *  for specific structured text handlers.
21
 *  <p>
22
 *  Here are some guidelines about how to write structured text
23
 *  handlers.
24
 *  <ul>
25
 *    <li>Handler instances may be accessed simultaneously by
26
 *        several threads. They should have no instance variables.</li>
27
 *    <li>The common logic uses handler methods to query the
28
 *        characteristics of the specific handler:
29
 *        <ul>
30
 *          <li>the separators which separate the structured text into
31
 *              tokens. See {@link #getSeparators getSeparators}.</li>
32
 *          <li>the direction which governs the display of tokens
33
 *              one after the other. See {@link #getDirection getDirection}.</li>
34
 *          <li>the number of special cases which need to be handled by
35
 *              code specific to that handler.
36
 *              See {@link #getSpecialsCount getSpecialsCount}.</li>
37
 *        </ul></li>
38
 *    <li>Before starting deeper analysis of the submitted text, the common
39
 *        logic gives to the handler a chance to shorten the processus by
40
 *        invoking its {@link #skipProcessing skipProcessing} method.</li>
41
 *    <li>The common logic then analyzes the text to segment it into tokens
42
 *        according to the appearance of separators (as retrieved using
43
 *        {@link #getSeparators getSeparators}).</li>
44
 *    <li>If the handler indicated a positive number of special cases as
45
 *        return value from its {@link #getSpecialsCount getSpecialsCount}
46
 *        method, the common logic will repeatedly invoke the handler's
47
 *        {@link #indexOfSpecial indexOfSpecial} method to let it signal the
48
 *        presence of special strings which may further delimit the source text.</li>
49
 *    <li>When such a special case is signalled by the handler, the common
50
 *        logic will call the handler's {@link #processSpecial processSpecial}
51
 *        method to give it the opportunity to handle it as needed. Typical
52
 *        actions that the handler may perform are to add directional marks
53
 *        inconditionally (by calling {@link #insertMark insertMark} or
54
 *        conditionally (by calling {@link #processSeparator processSeparator}).</li>
55
 *  </ul>
56
 *
57
 * @author Matitiahu Allouche
58
 */
59
public class STextTypeHandler {
60
61
	final private String separators;
62
63
	/**
64
	 * Creates a new instance of the STextTypeHandler class.
65
	 */
66
	public STextTypeHandler() {
67
		separators = ""; //$NON-NLS-1$
68
	}
69
70
	/**
71
	 * Creates a new instance of the STextTypeHandler class.
72
	 * @param separators string consisting of characters that split the text into fragments
73
	 */
74
	public STextTypeHandler(String separators) {
75
		this.separators = separators;
76
	}
77
78
	/**
79
	 * Locate occurrences of special strings within a structured text
80
	 * and return their indexes one after the other in successive calls.
81
	 * <p>
82
	 * This method is called repeatedly if the number of special cases 
83
	 * returned by {@link #getSpecialsCount} is greater than zero.
84
	 * </p><p>
85
	 * A handler handling special cases must override this method.
86
	 * </p>
87
	 * @param  environment the current environment, which may affect the behavior of
88
	 *         the handler. This parameter may be specified as
89
	 *         <code>null</code>, in which case the
90
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
91
	 *         environment should be assumed.
92
	 *
93
	 * @param  text is the structured text string before
94
	 *         addition of any directional formatting characters.
95
	 *
96
	 * @param  charTypes is a parameter received by <code>indexOfSpecial</code>
97
	 *         uniquely to be used as argument for calls to methods which
98
	 *         need it.
99
	 *
100
	 * @param  offsets is a parameter received by <code>indexOfSpecial</code>
101
	 *         uniquely to be used as argument for calls to methods which
102
	 *         need it.
103
	 *
104
	 * @param  caseNumber number of the special case to locate.
105
	 *         This number varies from 1 to the number of special cases
106
	 *         returned by {@link #getSpecialsCount getSpecialsCount}
107
	 *         for this handler.
108
	 *         The meaning of this number is internal to the class
109
	 *         implementing <code>indexOfSpecial</code>.
110
	 *
111
	 * @param  fromIndex the index within <code>text</code> to start
112
	 *         the search from.
113
	 *
114
	 * @return the position where the start of the special case
115
	 *         corresponding to <code>caseNumber</code> was located.
116
	 *         The method must return the first occurrence of whatever
117
	 *         identifies the start of the special case starting from
118
	 *         <code>fromIndex</code>. The method does not have to check if
119
	 *         this occurrence appears within the scope of another special
120
	 *         case (e.g. a comment starting delimiter within the scope of
121
	 *         a literal or vice-versa).
122
	 *         <br>If no occurrence is found, the method must return -1.
123
	 *
124
	 * @throws IllegalStateException If not overridden, this method throws an
125
	 * <code>IllegalStateException</code>. This is appropriate behavior
126
	 * (and does not need to be overridden) for handlers whose
127
	 * number of special cases is zero, which means that
128
	 * <code>indexOfSpecial</code> should never be called for them.
129
	 */
130
	public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
131
		// This method must be overridden by all subclasses with special cases.
132
		throw new IllegalStateException("A handler with specialsCount > 0 must have an indexOfSpecial() method."); //$NON-NLS-1$
133
	}
134
135
	/**
136
	 * This method handles special cases specific to this handler.
137
	 * It is called when a special case occurrence 
138
	 * is located by {@link #indexOfSpecial}.
139
	 * <p>
140
	 * If a special processing cannot be completed within a current call to
141
	 * <code>processSpecial</code> (for instance, a comment has been started
142
	 * in the current line but its end appears in a following line),
143
	 * <code>processSpecial</code> should specify a final state by
144
	 * putting its value in the first element of the <code>state</code>
145
	 * parameter.
146
	 * The meaning of this state is internal to the handler.
147
	 * On a later call, <code>processSpecial</code> will be called with that value 
148
	 * for parameter <code>caseNumber</code> and <code>-1</code> for parameter 
149
	 * <code>separLocation</code> and should perform whatever initializations are required
150
	 * depending on the state.
151
	 * </p><p>
152
	 * A handler handling special cases (with a number of
153
	 * special cases greater than zero) must override this method.
154
	 * </p>
155
	 * @param  environment the current environment, which may affect the behavior of
156
	 *         the handler. This parameter may be specified as
157
	 *         <code>null</code>, in which case the
158
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
159
	 *         environment should be assumed.
160
	 *
161
	 * @param  text is the structured text string before
162
	 *         addition of any directional formatting characters.
163
	 *
164
	 * @param  charTypes is a parameter received by <code>processSpecial</code>
165
	 *         uniquely to be used as argument for calls to methods which
166
	 *         need it.
167
	 *
168
	 * @param  offsets is a parameter received by <code>processSpecial</code>
169
	 *         uniquely to be used as argument for calls to methods which
170
	 *         need it.
171
	 *
172
	 * @param  state is an integer array with at least one element.
173
	 *         If the handler needs to signal the occurrence of a
174
	 *         special case which must be passed to the next call to
175
	 *         <code>leanToFullText</code> (for instance, a comment or a
176
	 *         literal started but not closed in the current
177
	 *         <code>text</code>), it must put a value in the first element
178
	 *         of the <code>state</code> parameter.
179
	 *         This number must be >= 1 and less or equal to the number of special
180
	 *         cases returned by {@link #getSpecialsCount getSpecialsCount}
181
	 *         by this handler.
182
	 *         This number is passed back to the caller
183
	 *         and should be specified as <code>state</code> argument
184
	 *         in the next call to <code>leanToFullText</code> together
185
	 *         with the continuation text.
186
	 *         The meaning of this number is internal to the handler.
187
	 *
188
	 * @param  caseNumber number of the special case to handle.
189
	 *
190
	 * @param  separLocation the position returned by
191
	 *         {@link #indexOfSpecial indexOfSpecial}. In calls to
192
	 *         {@link ISTextExpert#leanToFullText leanToFullText} and other
193
	 *         methods of {@link ISTextExpert} specifying a  non-null
194
	 *         <code>state</code> parameter, <code>processSpecial</code> is
195
	 *         called when initializing the processing with the value of
196
	 *         <code>caseNumber</code> equal to the value returned in the
197
	 *         first element of <code>state</code> and the value of
198
	 *         <code>separLocation</code> equal to <code>-1</code>.
199
	 *
200
	 * @return the position after the scope of the special case ends.
201
	 *         For instance, the position after the end of a comment,
202
	 *         the position after the end of a literal.
203
	 *         <br>A value greater or equal to the length of <code>text</code>
204
	 *         means that there is no further occurrence of this case in the
205
	 *         current structured text.
206
	 *
207
	 * @throws IllegalStateException If not overridden, this method throws an
208
	 * <code>IllegalStateException</code>. This is appropriate behavior
209
	 * (and does not need to be overridden) for handlers whose
210
	 * number of special cases is zero, which means that
211
	 * <code>processSpecial</code> should never be called for them.
212
	 */
213
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
214
		// This method must be overridden by all subclasses with any special case.
215
		throw new IllegalStateException("A handler with specialsCount > 0 must have a processSpecial() method."); //$NON-NLS-1$
216
	}
217
218
	/**
219
	 * This method can be called from within {@link #indexOfSpecial} or
220
	 * {@link #processSpecial} in extensions of <code>STextTypeHandler</code>
221
	 * to specify that a mark character must be added before the character
222
	 * at the specified position of the <i>lean</i> text when generating the
223
	 * <i>full</i> text. The mark character will be LRM for structured text
224
	 * with a LTR base direction, and RLM for structured text with RTL
225
	 * base direction. The mark character is not added physically by this
226
	 * method, but its position is noted and will be used when generating
227
	 * the <i>full</i> text.
228
	 *
229
	 * @param  text is the structured text string received as
230
	 *         parameter to <code>indexOfSpecial</code> or
231
	 *         <code>processSpecial</code>.
232
	 *
233
	 * @param  charTypes is a parameter received by <code>indexOfSpecial</code>
234
	 *         or <code>processSpecial</code>, uniquely to be used as argument
235
	 *         for calls to <code>insertMark</code> and other methods used
236
	 *         by handlers.
237
	 *
238
	 * @param  offsets is a parameter received by <code>indexOfSpecial</code>
239
	 *         or <code>processSpecial</code>, uniquely to be used as argument
240
	 *         for calls to <code>insertMark</code> and other methods used
241
	 *         by handlers.
242
	 *
243
	 * @param  offset position of the character in the <i>lean</i> text.
244
	 *         It must be a non-negative number smaller than the length
245
	 *         of the <i>lean</i> text.
246
	 *         For the benefit of efficiency, it is better to insert
247
	 *         multiple marks in ascending order of the offsets.
248
	 */
249
	public static final void insertMark(String text, STextCharTypes charTypes, STextOffsets offsets, int offset) {
250
		offsets.insertOffset(charTypes, offset);
251
	}
252
253
	/**
254
	 * This method can be called from within {@link #indexOfSpecial} or
255
	 * {@link #processSpecial} in extensions of <code>STextTypeHandler</code> to add 
256
	 * a directional mark before a separator if needed for correct display, 
257
	 * depending on the base direction of the text and on the class of the
258
	 * characters in the <i>lean</i> text preceding and following the separator itself.
259
	 * <p>
260
	 * The logic implemented in this method considers the text before
261
	 * <code>separLocation</code> and the text following it. If, and only if,
262
	 * a directional mark is needed to insure that the two parts of text
263
	 * will be laid out according to the base direction, a mark will be
264
	 * added when generating the <i>full</i> text.
265
	 * </p>
266
	 * @param  text is the structured text string received as
267
	 *         parameter to <code>indexOfSpecial</code> or
268
	 *         <code>processSpecial</code>.
269
	 *
270
	 * @param  charTypes is a parameter received by <code>indexOfSpecial</code>
271
	 *         or <code>processSpecial</code>, uniquely to be used as argument
272
	 *         for calls to <code>processSeparator</code> and other methods used
273
	 *         by handlers.
274
	 *
275
	 * @param  offsets is a parameter received by <code>indexOfSpecial</code>
276
	 *         or <code>processSpecial</code>, uniquely to be used as argument
277
	 *         for calls to <code>processSeparator</code> and other methods used
278
	 *         by handlers.
279
	 *
280
	 * @param  separLocation offset of the separator in the <i>lean</i> text.
281
	 *         It must be a non-negative number smaller than the length
282
	 *         of the <i>lean</i> text.
283
	 */
284
	public static final void processSeparator(String text, STextCharTypes charTypes, STextOffsets offsets, int separLocation) {
285
		STextImpl.processSeparator(text, charTypes, offsets, separLocation);
286
	}
287
288
	/**
289
	 * Indicate the separators to use for the current handler.
290
	 * This method is invoked before starting the processing.
291
	 * <p>
292
	 * If no separators are specified, this method returns an empty string.
293
	 * </p>
294
	 * @param  environment the current environment, which may affect the behavior of
295
	 *         the handler. This parameter may be specified as
296
	 *         <code>null</code>, in which case the
297
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
298
	 *         environment should be assumed.
299
	 *
300
	 * @return a string grouping one-character separators which separate
301
	 *         the structured text into tokens.
302
	 */
303
	public String getSeparators(STextEnvironment environment) {
304
		return separators;
305
	}
306
307
	/**
308
	 * Indicate the base text direction appropriate for an instance of structured text.
309
	 * This method is invoked before starting the processing.
310
	 * <p>
311
	 * If not overridden, this method returns <code>DIR_LTR</code>.
312
	 * </p>
313
	 * @param  environment the current environment, which may affect the behavior of
314
	 *         the handler. This parameter may be specified as
315
	 *         <code>null</code>, in which case the
316
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
317
	 *         environment should be assumed.
318
	 *
319
	 * @param  text is the structured text string to process.
320
	 *
321
	 * @return the base direction of the structured text. This direction
322
	 *         may not be the same depending on the environment and on
323
	 *         whether the structured text contains Arabic or Hebrew
324
	 *         letters.<br>
325
	 *         The value returned is either
326
	 *         {@link STextDirection#DIR_LTR DIR_LTR} or {@link STextDirection#DIR_RTL DIR_RTL}.
327
	 */
328
	public int getDirection(STextEnvironment environment, String text) {
329
		return STextDirection.DIR_LTR;
330
	}
331
332
	/**
333
	 * Indicate the base text direction appropriate for an instance of structured text.
334
	 * This method is invoked before starting the processing.
335
	 * <p>
336
	 * If not overridden, this method returns <code>DIR_LTR</code>.
337
	 * </p>
338
	 * @param  environment the current environment, which may affect the behavior of
339
	 *         the handler. This parameter may be specified as
340
	 *         <code>null</code>, in which case the
341
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
342
	 *         environment should be assumed.
343
	 *
344
	 * @param  text is the structured text string to process.
345
	 *
346
	 * @param  charTypes is a parameter received uniquely to be used as argument
347
	 *         for calls to <code>getCharType</code> and other methods used
348
	 *         by handlers.
349
	 *
350
	 * @return the base direction of the structured text. This direction
351
	 *         may not be the same depending on the environment and on
352
	 *         whether the structured text contains Arabic or Hebrew
353
	 *         letters.<br>
354
	 *         The value returned is either
355
	 *         {@link STextDirection#DIR_LTR DIR_LTR} or {@link STextDirection#DIR_RTL DIR_RTL}.
356
	 */
357
	public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
358
		return STextDirection.DIR_LTR;
359
	}
360
361
	/**
362
	 * Indicate the number of special cases handled by the current handler.
363
	 * This method is invoked before starting the processing.
364
	 * If the number returned is zero, {@link #indexOfSpecial} and
365
	 * {@link #processSpecial} will not be invoked.
366
	 * <p>
367
	 * If not overridden, this method returns <code>zero</code>.
368
	 * </p>
369
	 * @param  environment the current environment, which may affect the behavior of
370
	 *         the handler. This parameter may be specified as
371
	 *         <code>null</code>, in which case the
372
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
373
	 *         environment should be assumed.
374
	 *
375
	 * @return the number of special cases for the associated handler.
376
	 *         Special cases exist for some types of structured text
377
	 *         handlers. They are implemented by overriding methods
378
	 *         {@link STextTypeHandler#indexOfSpecial} and {@link STextTypeHandler#processSpecial}.
379
	 *         Examples of special cases are comments, literals, or
380
	 *         anything which is not identified by a one-character separator.
381
	 *
382
	 */
383
	public int getSpecialsCount(STextEnvironment environment) {
384
		return 0;
385
	}
386
387
	/**
388
	 * Checks if there is a need for processing structured text.
389
	 * This method is invoked before starting the processing. If the
390
	 * handler returns <code>true</code>, no directional formatting
391
	 * characters are added to the <i>lean</i> text and the processing
392
	 * is shortened.
393
	 * <p>
394
	 * If not overridden, this method returns <code>false</code>.
395
	 * </p>
396
	 * @param  environment the current environment, which may affect the behavior of
397
	 *         the handler. This parameter may be specified as
398
	 *         <code>null</code>, in which case the
399
	 *         {@link STextEnvironment#DEFAULT DEFAULT}
400
	 *         environment should be assumed.
401
	 *
402
	 * @param  text is the structured text string to process.
403
	 *
404
	 * @param  charTypes is a parameter received uniquely to be used as argument
405
	 *         for calls to <code>getCharType</code> and other methods used
406
	 *         by handlers.
407
	 *
408
	 * @return a flag indicating if there is no need to process the structured
409
	 *         text to add directional formatting characters.
410
	 *
411
	 */
412
	public boolean skipProcessing(STextEnvironment environment, String text, STextCharTypes charTypes) {
413
		return false;
414
	}
415
416
}
(-)src/org/eclipse/equinox/bidi/internal/STextDelims.java (-3 / +4 lines)
Lines 11-20 Link Here
11
package org.eclipse.equinox.bidi.internal;
11
package org.eclipse.equinox.bidi.internal;
12
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
14
import org.eclipse.equinox.bidi.custom.*;
15
import org.eclipse.equinox.bidi.custom.*;
15
16
16
/**
17
/**
17
 *  A base handler for structured text composed of text segments separated 
18
 *  A base processor for structured text composed of text segments separated 
18
 *  by separators where the text segments may include delimited parts within 
19
 *  by separators where the text segments may include delimited parts within 
19
 *  which separators are treated like regular characters.
20
 *  which separators are treated like regular characters.
20
 *  <p>
21
 *  <p>
Lines 22-28 Link Here
22
 *  </p>
23
 *  </p>
23
 *  @author Matitiahu Allouche
24
 *  @author Matitiahu Allouche
24
 */
25
 */
25
public abstract class STextDelims extends STextTypeHandler {
26
public abstract class STextDelims extends STextProcessor {
26
27
27
	public STextDelims() {
28
	public STextDelims() {
28
		// placeholder
29
		// placeholder
Lines 59-65 Link Here
59
	 *          of <code>text</code> if no end delimiter is found.
60
	 *          of <code>text</code> if no end delimiter is found.
60
	 */
61
	 */
61
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
62
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
62
		STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
63
		STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
63
		int loc = separLocation + 1;
64
		int loc = separLocation + 1;
64
		char delim = getDelimiters().charAt((caseNumber * 2) - 1);
65
		char delim = getDelimiters().charAt((caseNumber * 2) - 1);
65
		loc = text.indexOf(delim, loc);
66
		loc = text.indexOf(delim, loc);
(-)src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java (-2 / +3 lines)
Lines 11-20 Link Here
11
package org.eclipse.equinox.bidi.internal;
11
package org.eclipse.equinox.bidi.internal;
12
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
14
import org.eclipse.equinox.bidi.custom.*;
15
import org.eclipse.equinox.bidi.custom.*;
15
16
16
/**
17
/**
17
 *  A base handler for structured text composed of text segments separated 
18
 *  A base processor for structured text composed of text segments separated 
18
 *  by separators where the text segments may include delimited parts within 
19
 *  by separators where the text segments may include delimited parts within 
19
 *  which separators are treated like regular characters and the delimiters 
20
 *  which separators are treated like regular characters and the delimiters 
20
 *  may be escaped.
21
 *  may be escaped.
Lines 50-56 Link Here
50
	 *  ignoring possibly escaped end delimiters.
51
	 *  ignoring possibly escaped end delimiters.
51
	 */
52
	 */
52
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
53
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
53
		STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
54
		STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
54
		int location = separLocation + 1;
55
		int location = separLocation + 1;
55
		char delim = getDelimiters().charAt((caseNumber * 2) - 1);
56
		char delim = getDelimiters().charAt((caseNumber * 2) - 1);
56
		while (true) {
57
		while (true) {
(-)src/org/eclipse/equinox/bidi/internal/STextExpertImpl.java (+58 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
15
import org.eclipse.equinox.bidi.custom.STextProcessor;
16
17
public class STextExpertImpl implements ISTextExpert {
18
19
	protected STextProcessor structuredTextDescriptor;
20
	protected STextEnvironment environment;
21
22
	// XXX potentially problematic - implementation might write into it?
23
	private final static int[] initialState = new int[] {0};
24
25
	public STextExpertImpl(STextProcessor structuredTextDescriptor, STextEnvironment environment) {
26
		this.structuredTextDescriptor = structuredTextDescriptor;
27
		this.environment = environment;
28
	}
29
30
	public String leanToFullText(String text) {
31
		return STextImpl.leanToFullText(structuredTextDescriptor, environment, text, initialState);
32
	}
33
34
	public int[] leanToFullMap(String text) {
35
		return STextImpl.leanToFullMap(structuredTextDescriptor, environment, text, initialState);
36
	}
37
38
	public int[] leanBidiCharOffsets(String text) {
39
		return STextImpl.leanBidiCharOffsets(structuredTextDescriptor, environment, text, initialState);
40
	}
41
42
	public String fullToLeanText(String text) {
43
		return STextImpl.fullToLeanText(structuredTextDescriptor, environment, text, initialState);
44
	}
45
46
	public int[] fullToLeanMap(String text) {
47
		return STextImpl.fullToLeanMap(structuredTextDescriptor, environment, text, initialState);
48
	}
49
50
	public int[] fullBidiCharOffsets(String text) {
51
		return STextImpl.fullBidiCharOffsets(structuredTextDescriptor, environment, text, initialState);
52
	}
53
54
	public int getCurDirection(String text) {
55
		return structuredTextDescriptor.getDirection(environment, text);
56
	}
57
58
}
(-)src/org/eclipse/equinox/bidi/internal/STextExpertMultipassImpl.java (+74 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal;
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.advanced.ISTextExpertStateful;
15
import org.eclipse.equinox.bidi.custom.STextProcessor;
16
17
public class STextExpertMultipassImpl extends STextExpertImpl implements ISTextExpertStateful {
18
19
	/**
20
	 *  Constant to use in the first element of the <code>state</code>
21
	 *  argument when calling most methods of this class
22
	 *  to indicate that there is no context of previous lines which
23
	 *  should be initialized before performing the operation.
24
	 */
25
	public static final int STATE_INITIAL = 0;
26
27
	private int[] state = new int[] {STATE_INITIAL};
28
29
	public STextExpertMultipassImpl(STextProcessor structuredTextDescriptor, STextEnvironment environment) {
30
		super(structuredTextDescriptor, environment);
31
		resetState();
32
	}
33
34
	public String leanToFullText(String text) {
35
		return STextImpl.leanToFullText(structuredTextDescriptor, environment, text, state);
36
	}
37
38
	public int[] leanToFullMap(String text) {
39
		return STextImpl.leanToFullMap(structuredTextDescriptor, environment, text, state);
40
	}
41
42
	public int[] leanBidiCharOffsets(String text) {
43
		return STextImpl.leanBidiCharOffsets(structuredTextDescriptor, environment, text, state);
44
	}
45
46
	public String fullToLeanText(String text) {
47
		return STextImpl.fullToLeanText(structuredTextDescriptor, environment, text, state);
48
	}
49
50
	public int[] fullToLeanMap(String text) {
51
		return STextImpl.fullToLeanMap(structuredTextDescriptor, environment, text, state);
52
	}
53
54
	public int[] fullBidiCharOffsets(String text) {
55
		return STextImpl.fullBidiCharOffsets(structuredTextDescriptor, environment, text, state);
56
	}
57
58
	public int getCurDirection(String text) {
59
		return structuredTextDescriptor.getDirection(environment, text);
60
	}
61
62
	public void resetState() {
63
		state[0] = STATE_INITIAL;
64
	}
65
66
	public void setState(int newState) {
67
		state[0] = newState;
68
	}
69
70
	public int getState() {
71
		return state[0];
72
	}
73
74
}
(-)src/org/eclipse/equinox/bidi/internal/STextImpl.java (-87 / +51 lines)
Lines 11-20 Link Here
11
package org.eclipse.equinox.bidi.internal;
11
package org.eclipse.equinox.bidi.internal;
12
12
13
import org.eclipse.equinox.bidi.STextDirection;
13
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.advanced.*;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
15
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
15
import org.eclipse.equinox.bidi.custom.*;
16
import org.eclipse.equinox.bidi.custom.*;
16
17
17
public class STextImpl implements ISTextExpertStateful {
18
public class STextImpl {
18
19
19
	static final String EMPTY_STRING = ""; //$NON-NLS-1$
20
	static final String EMPTY_STRING = ""; //$NON-NLS-1$
20
21
Lines 46-112 Link Here
46
	static final int FIXES_LENGTH = PREFIX_LENGTH + SUFFIX_LENGTH;
47
	static final int FIXES_LENGTH = PREFIX_LENGTH + SUFFIX_LENGTH;
47
	static final int[] EMPTY_INT_ARRAY = new int[0];
48
	static final int[] EMPTY_INT_ARRAY = new int[0];
48
	static final STextEnvironment IGNORE_ENVIRONMENT = new STextEnvironment(null, false, STextEnvironment.ORIENT_IGNORE);
49
	static final STextEnvironment IGNORE_ENVIRONMENT = new STextEnvironment(null, false, STextEnvironment.ORIENT_IGNORE);
49
	static final int STATE_INITIAL = 0;
50
50
51
	protected STextTypeHandler structuredTextHandler;
51
	/**
52
	protected STextEnvironment environment;
52
	 *  Prevent creation of a STextImpl instance
53
	protected int[] state;
53
	 */
54
54
	private STextImpl() {
55
	public STextImpl(STextTypeHandler structuredTextHandler, STextEnvironment environment, int[] state) {
55
		// nothing to do
56
		this.structuredTextHandler = structuredTextHandler;
57
		this.environment = environment;
58
		this.state = state;
59
	}
56
	}
60
57
61
	public String leanToFullText(String text) {
58
	static long computeNextLocation(STextProcessor processor, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] locations, int curPos) {
62
		return STextImpl.leanToFullText(structuredTextHandler, environment, text, state);
59
		String separators = processor.getSeparators(environment);
63
	}
64
65
	public int[] leanToFullMap(String text) {
66
		return STextImpl.leanToFullMap(structuredTextHandler, environment, text, state);
67
	}
68
69
	public int[] leanBidiCharOffsets(String text) {
70
		return STextImpl.leanBidiCharOffsets(structuredTextHandler, environment, text, state);
71
	}
72
73
	public String fullToLeanText(String text) {
74
		return STextImpl.fullToLeanText(structuredTextHandler, environment, text, state);
75
	}
76
77
	public int[] fullToLeanMap(String text) {
78
		return STextImpl.fullToLeanMap(structuredTextHandler, environment, text, state);
79
	}
80
81
	public int[] fullBidiCharOffsets(String text) {
82
		return STextImpl.fullBidiCharOffsets(structuredTextHandler, environment, text, state);
83
	}
84
85
	public int getCurDirection(String text) {
86
		return structuredTextHandler.getDirection(environment, text);
87
	}
88
89
	public void resetState() {
90
		state[0] = STATE_INITIAL;
91
	}
92
93
	public void setState(int newState) {
94
		state[0] = newState;
95
	}
96
97
	public static void setState(int[] state, int newState) {
98
		if (state != null)
99
			state[0] = newState;
100
	}
101
102
	public int getState() {
103
		return state[0];
104
	}
105
106
	static long computeNextLocation(STextTypeHandler handler, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] locations, int curPos) {
107
		String separators = handler.getSeparators(environment);
108
		int separCount = separators.length();
60
		int separCount = separators.length();
109
		int specialsCount = handler.getSpecialsCount(environment);
61
		int specialsCount = processor.getSpecialsCount(environment);
110
		int len = text.length();
62
		int len = text.length();
111
		int nextLocation = len;
63
		int nextLocation = len;
112
		int idxLocation = 0;
64
		int idxLocation = 0;
Lines 116-122 Link Here
116
			int location = locations[separCount + i];
68
			int location = locations[separCount + i];
117
			if (location < curPos) {
69
			if (location < curPos) {
118
				offsets.ensureRoom();
70
				offsets.ensureRoom();
119
				location = handler.indexOfSpecial(environment, text, charTypes, offsets, i + 1, curPos);
71
				location = processor.indexOfSpecial(environment, text, charTypes, offsets, i + 1, curPos);
120
				if (location < 0)
72
				if (location < 0)
121
					location = len;
73
					location = len;
122
				locations[separCount + i] = location;
74
				locations[separCount + i] = location;
Lines 243-254 Link Here
243
	 *  <p>
195
	 *  <p>
244
	 *  @see ISTextExpert#leanToFullText STextEngine.leanToFullText
196
	 *  @see ISTextExpert#leanToFullText STextEngine.leanToFullText
245
	 */
197
	 */
246
	public static String leanToFullText(STextTypeHandler handler, STextEnvironment environment, String text, int[] state) {
198
	public static String leanToFullText(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
247
		int len = text.length();
199
		int len = text.length();
248
		if (len == 0)
200
		if (len == 0)
249
			return text;
201
			return text;
250
		STextCharTypes charTypes = new STextCharTypes(handler, environment, text);
202
		STextCharTypes charTypes = new STextCharTypes(processor, environment, text);
251
		STextOffsets offsets = leanToFullCommon(handler, environment, text, state, charTypes);
203
		STextOffsets offsets = leanToFullCommon(processor, environment, text, state, charTypes);
252
		int prefixLength = offsets.getPrefixLength();
204
		int prefixLength = offsets.getPrefixLength();
253
		int count = offsets.getCount();
205
		int count = offsets.getCount();
254
		if (count == 0 && prefixLength == 0)
206
		if (count == 0 && prefixLength == 0)
Lines 290-301 Link Here
290
		return new String(fullChars);
242
		return new String(fullChars);
291
	}
243
	}
292
244
293
	public static int[] leanToFullMap(STextTypeHandler handler, STextEnvironment environment, String text, int[] state) {
245
	public static int[] leanToFullMap(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
294
		int len = text.length();
246
		int len = text.length();
295
		if (len == 0)
247
		if (len == 0)
296
			return EMPTY_INT_ARRAY;
248
			return EMPTY_INT_ARRAY;
297
		STextCharTypes charTypes = new STextCharTypes(handler, environment, text);
249
		STextCharTypes charTypes = new STextCharTypes(processor, environment, text);
298
		STextOffsets offsets = leanToFullCommon(handler, environment, text, state, charTypes);
250
		STextOffsets offsets = leanToFullCommon(processor, environment, text, state, charTypes);
299
		int prefixLength = offsets.getPrefixLength();
251
		int prefixLength = offsets.getPrefixLength();
300
		int[] map = new int[len];
252
		int[] map = new int[len];
301
		int count = offsets.getCount(); // number of used entries
253
		int count = offsets.getCount(); // number of used entries
Lines 310-351 Link Here
310
		return map;
262
		return map;
311
	}
263
	}
312
264
313
	public static int[] leanBidiCharOffsets(STextTypeHandler handler, STextEnvironment environment, String text, int[] state) {
265
	public static int[] leanBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
314
		int len = text.length();
266
		int len = text.length();
315
		if (len == 0)
267
		if (len == 0)
316
			return EMPTY_INT_ARRAY;
268
			return EMPTY_INT_ARRAY;
317
		STextCharTypes charTypes = new STextCharTypes(handler, environment, text);
269
		STextCharTypes charTypes = new STextCharTypes(processor, environment, text);
318
		STextOffsets offsets = leanToFullCommon(handler, environment, text, state, charTypes);
270
		STextOffsets offsets = leanToFullCommon(processor, environment, text, state, charTypes);
319
		return offsets.getArray();
271
		return offsets.getArray();
320
	}
272
	}
273
274
	/**
275
	 *  Constant to use in the first element of the <code>state</code>
276
	 *  argument when calling most methods of this class
277
	 *  to indicate that there is no context of previous lines which
278
	 *  should be initialized before performing the operation.
279
	 */
280
	public static final int STATE_INITIAL = 0; // TBD move
321
281
322
	static STextOffsets leanToFullCommon(STextTypeHandler handler, STextEnvironment environment, String text, int[] state, STextCharTypes charTypes) {
282
	static STextOffsets leanToFullCommon(STextProcessor processor, STextEnvironment environment, String text, int[] state, STextCharTypes charTypes) {
323
		if (environment == null)
283
		if (environment == null)
324
			environment = STextEnvironment.DEFAULT;
284
			environment = STextEnvironment.DEFAULT;
285
		if (state == null) {
286
			state = new int[1];
287
			state[0] = STATE_INITIAL;
288
		}
325
		int len = text.length();
289
		int len = text.length();
326
		int direction = handler.getDirection(environment, text, charTypes);
290
		int direction = processor.getDirection(environment, text, charTypes);
327
		STextOffsets offsets = new STextOffsets();
291
		STextOffsets offsets = new STextOffsets();
328
		if (!handler.skipProcessing(environment, text, charTypes)) {
292
		if (!processor.skipProcessing(environment, text, charTypes)) {
329
			// initialize locations
293
			// initialize locations
330
			int separCount = handler.getSeparators(environment).length();
294
			int separCount = processor.getSeparators(environment).length();
331
			int[] locations = new int[separCount + handler.getSpecialsCount(environment)];
295
			int[] locations = new int[separCount + processor.getSpecialsCount(environment)];
332
			for (int i = 0, k = locations.length; i < k; i++) {
296
			for (int i = 0, k = locations.length; i < k; i++) {
333
				locations[i] = -1;
297
				locations[i] = -1;
334
			}
298
			}
335
			// current position
299
			// current position
336
			int curPos = 0;
300
			int curPos = 0;
337
			if (state != null && state[0] > STATE_INITIAL) {
301
			if (state[0] > STATE_INITIAL) {
338
				offsets.ensureRoom();
302
				offsets.ensureRoom();
339
				int initState = state[0];
303
				int initState = state[0];
340
				state[0] = STATE_INITIAL;
304
				state[0] = STATE_INITIAL;
341
				curPos = handler.processSpecial(environment, text, charTypes, offsets, state, initState, -1);
305
				curPos = processor.processSpecial(environment, text, charTypes, offsets, state, initState, -1);
342
			}
306
			}
343
			while (true) {
307
			while (true) {
344
				// location of next token to handle
308
				// location of next token to handle
345
				int nextLocation;
309
				int nextLocation;
346
				// index of next token to handle (if < separCount, this is a separator; otherwise a special case
310
				// index of next token to handle (if < separCount, this is a separator; otherwise a special case
347
				int idxLocation;
311
				int idxLocation;
348
				long res = computeNextLocation(handler, environment, text, charTypes, offsets, locations, curPos);
312
				long res = computeNextLocation(processor, environment, text, charTypes, offsets, locations, curPos);
349
				nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */
313
				nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */
350
				if (nextLocation >= len)
314
				if (nextLocation >= len)
351
					break;
315
					break;
Lines 356-367 Link Here
356
					curPos = nextLocation + 1;
320
					curPos = nextLocation + 1;
357
				} else {
321
				} else {
358
					idxLocation -= (separCount - 1); // because caseNumber starts from 1
322
					idxLocation -= (separCount - 1); // because caseNumber starts from 1
359
					curPos = handler.processSpecial(environment, text, charTypes, offsets, state, idxLocation, nextLocation);
323
					curPos = processor.processSpecial(environment, text, charTypes, offsets, state, idxLocation, nextLocation);
360
				}
324
				}
361
				if (curPos >= len)
325
				if (curPos >= len)
362
					break;
326
					break;
363
			} // end while
327
			} // end while
364
		} // end if (!handler.skipProcessing())
328
		} // end if (!processor.skipProcessing())
365
		int prefixLength;
329
		int prefixLength;
366
		int orientation = environment.getOrientation();
330
		int orientation = environment.getOrientation();
367
		if (orientation == STextEnvironment.ORIENT_IGNORE)
331
		if (orientation == STextEnvironment.ORIENT_IGNORE)
Lines 379-390 Link Here
379
		return offsets;
343
		return offsets;
380
	}
344
	}
381
345
382
	public static String fullToLeanText(STextTypeHandler handler, STextEnvironment environment, String text, int[] state) {
346
	public static String fullToLeanText(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
383
		if (text.length() == 0)
347
		if (text.length() == 0)
384
			return text;
348
			return text;
385
		if (environment == null)
349
		if (environment == null)
386
			environment = STextEnvironment.DEFAULT;
350
			environment = STextEnvironment.DEFAULT;
387
		int dir = handler.getDirection(environment, text);
351
		int dir = processor.getDirection(environment, text);
388
		char curMark = MARKS[dir];
352
		char curMark = MARKS[dir];
389
		char curEmbed = EMBEDS[dir];
353
		char curEmbed = EMBEDS[dir];
390
		int i; // used as loop index
354
		int i; // used as loop index
Lines 422-428 Link Here
422
				chars[i - cnt] = c;
386
				chars[i - cnt] = c;
423
		}
387
		}
424
		String lean = new String(chars, 0, lenText - cnt);
388
		String lean = new String(chars, 0, lenText - cnt);
425
		String full = leanToFullText(handler, IGNORE_ENVIRONMENT, lean, state);
389
		String full = leanToFullText(processor, IGNORE_ENVIRONMENT, lean, state);
426
		if (full.equals(text))
390
		if (full.equals(text))
427
			return lean;
391
			return lean;
428
392
Lines 467-479 Link Here
467
		return lean;
431
		return lean;
468
	}
432
	}
469
433
470
	public static int[] fullToLeanMap(STextTypeHandler handler, STextEnvironment environment, String full, int[] state) {
434
	public static int[] fullToLeanMap(STextProcessor processor, STextEnvironment environment, String full, int[] state) {
471
		int lenFull = full.length();
435
		int lenFull = full.length();
472
		if (lenFull == 0)
436
		if (lenFull == 0)
473
			return EMPTY_INT_ARRAY;
437
			return EMPTY_INT_ARRAY;
474
		String lean = fullToLeanText(handler, environment, full, state);
438
		String lean = fullToLeanText(processor, environment, full, state);
475
		int lenLean = lean.length();
439
		int lenLean = lean.length();
476
		int dir = handler.getDirection(environment, lean);
440
		int dir = processor.getDirection(environment, lean);
477
		char curMark = MARKS[dir];
441
		char curMark = MARKS[dir];
478
		char curEmbed = EMBEDS[dir];
442
		char curEmbed = EMBEDS[dir];
479
		int[] map = new int[lenFull];
443
		int[] map = new int[lenFull];
Lines 498-508 Link Here
498
		return map;
462
		return map;
499
	}
463
	}
500
464
501
	public static int[] fullBidiCharOffsets(STextTypeHandler handler, STextEnvironment environment, String full, int[] state) {
465
	public static int[] fullBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String full, int[] state) {
502
		int lenFull = full.length();
466
		int lenFull = full.length();
503
		if (lenFull == 0)
467
		if (lenFull == 0)
504
			return EMPTY_INT_ARRAY;
468
			return EMPTY_INT_ARRAY;
505
		String lean = fullToLeanText(handler, environment, full, state);
469
		String lean = fullToLeanText(processor, environment, full, state);
506
		STextOffsets offsets = new STextOffsets();
470
		STextOffsets offsets = new STextOffsets();
507
		int lenLean = lean.length();
471
		int lenLean = lean.length();
508
		int idxLean, idxFull;
472
		int idxLean, idxFull;
(-)src/org/eclipse/equinox/bidi/internal/STextSingle.java (-7 / +8 lines)
Lines 11-35 Link Here
11
package org.eclipse.equinox.bidi.internal;
11
package org.eclipse.equinox.bidi.internal;
12
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
14
import org.eclipse.equinox.bidi.custom.*;
15
import org.eclipse.equinox.bidi.custom.*;
15
16
16
/**
17
/**
17
 *  A base handler for structured text composed of two parts separated by a separator.
18
 *  A base processor for structured text composed of two parts separated by a separator.
18
 *  The first occurrence of the separator delimits the end of the first part
19
 *  The first occurrence of the separator delimits the end of the first part
19
 *  and the start of the second part. Further occurrences of the separator,
20
 *  and the start of the second part. Further occurrences of the separator,
20
 *  if any, are treated like regular characters of the second text part.
21
 *  if any, are treated like regular characters of the second text part.
21
 *  The handler makes sure that the text be presented in the form
22
 *  The processor makes sure that the text be presented in the form
22
 *  (assuming that the equal sign is the separator):
23
 *  (assuming that the equal sign is the separator):
23
 *  <pre>
24
 *  <pre>
24
 *  part1=part2
25
 *  part1=part2
25
 *  </pre>
26
 *  </pre>
26
 *  The string returned by {@link STextTypeHandler#getSeparators getSeparators}
27
 *  The string returned by {@link STextProcessor#getSeparators getSeparators}
27
 *  for this handler should contain exactly one character.
28
 *  for this processor should contain exactly one character.
28
 *  Additional characters will be ignored.
29
 *  Additional characters will be ignored.
29
 *
30
 *
30
 *  @author Matitiahu Allouche
31
 *  @author Matitiahu Allouche
31
 */
32
 */
32
public class STextSingle extends STextTypeHandler {
33
public class STextSingle extends STextProcessor {
33
34
34
	public STextSingle(String separator) {
35
	public STextSingle(String separator) {
35
		super(separator);
36
		super(separator);
Lines 51-62 Link Here
51
	 *  @return the length of <code>text</code>.
52
	 *  @return the length of <code>text</code>.
52
	 */
53
	 */
53
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
54
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
54
		STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
55
		STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
55
		return text.length();
56
		return text.length();
56
	}
57
	}
57
58
58
	/**
59
	/**
59
	 *  This method returns 1 as number of special cases handled by this handler.
60
	 *  This method returns 1 as number of special cases handled by this processor.
60
	 *
61
	 *
61
	 *  @return 1.
62
	 *  @return 1.
62
	 */
63
	 */
(-)src/org/eclipse/equinox/bidi/internal/STextTypesCollector.java (-10 / +10 lines)
Lines 13-19 Link Here
13
import java.util.HashMap;
13
import java.util.HashMap;
14
import java.util.Map;
14
import java.util.Map;
15
import org.eclipse.core.runtime.*;
15
import org.eclipse.core.runtime.*;
16
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
16
import org.eclipse.equinox.bidi.custom.STextProcessor;
17
17
18
public class STextTypesCollector implements IRegistryEventListener {
18
public class STextTypesCollector implements IRegistryEventListener {
19
19
Lines 21-27 Link Here
21
21
22
	private static final String CE_NAME = "typeDescription"; //$NON-NLS-1$
22
	private static final String CE_NAME = "typeDescription"; //$NON-NLS-1$
23
	private static final String ATTR_TYPE = "type"; //$NON-NLS-1$
23
	private static final String ATTR_TYPE = "type"; //$NON-NLS-1$
24
	private static final String ATTR_HANDLER = "class"; //$NON-NLS-1$
24
	private static final String ATTR_PROCESSOR = "class"; //$NON-NLS-1$
25
25
26
	private Map types;
26
	private Map types;
27
	private Map factories;
27
	private Map factories;
Lines 46-57 Link Here
46
		return result;
46
		return result;
47
	}
47
	}
48
48
49
	public STextTypeHandler getHandler(String type) {
49
	public STextProcessor getProcessor(String type) {
50
		if (types == null)
50
		if (types == null)
51
			read();
51
			read();
52
		Object handler = types.get(type);
52
		Object processor = types.get(type);
53
		if (handler instanceof STextTypeHandler)
53
		if (processor instanceof STextProcessor)
54
			return (STextTypeHandler) handler;
54
			return (STextProcessor) processor;
55
		return null;
55
		return null;
56
	}
56
	}
57
57
Lines 76-89 Link Here
76
				if (CE_NAME != confElements[j].getName())
76
				if (CE_NAME != confElements[j].getName())
77
					STextActivator.logError("BiDi types: unexpected element name " + confElements[j].getName(), new IllegalArgumentException()); //$NON-NLS-1$
77
					STextActivator.logError("BiDi types: unexpected element name " + confElements[j].getName(), new IllegalArgumentException()); //$NON-NLS-1$
78
				String type = confElements[j].getAttribute(ATTR_TYPE);
78
				String type = confElements[j].getAttribute(ATTR_TYPE);
79
				Object handler;
79
				Object processor;
80
				try {
80
				try {
81
					handler = confElements[j].createExecutableExtension(ATTR_HANDLER);
81
					processor = confElements[j].createExecutableExtension(ATTR_PROCESSOR);
82
				} catch (CoreException e) {
82
				} catch (CoreException e) {
83
					STextActivator.logError("BiDi types: unable to create handler for " + type, e); //$NON-NLS-1$
83
					STextActivator.logError("BiDi types: unable to create processor for " + type, e); //$NON-NLS-1$
84
					continue;
84
					continue;
85
				}
85
				}
86
				types.put(type, handler);
86
				types.put(type, processor);
87
				factories.put(type, confElements[j]);
87
				factories.put(type, confElements[j]);
88
			}
88
			}
89
		}
89
		}
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextComma.java (-3 / +3 lines)
Lines 10-24 Link Here
10
 ******************************************************************************/
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
13
import org.eclipse.equinox.bidi.custom.STextProcessor;
14
14
15
/**
15
/**
16
 *  Handler adapted to processing comma-delimited lists, such as:
16
 *  Processor adapted to processing comma-delimited lists, such as:
17
 *  <pre>
17
 *  <pre>
18
 *    part1,part2,part3
18
 *    part1,part2,part3
19
 *  </pre>
19
 *  </pre>
20
 */
20
 */
21
public class STextComma extends STextTypeHandler {
21
public class STextComma extends STextProcessor {
22
	public STextComma() {
22
	public STextComma() {
23
		super(","); //$NON-NLS-1$
23
		super(","); //$NON-NLS-1$
24
	}
24
	}
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java (-2 / +2 lines)
Lines 16-22 Link Here
16
import org.eclipse.equinox.bidi.internal.STextDelimsEsc;
16
import org.eclipse.equinox.bidi.internal.STextDelimsEsc;
17
17
18
/**
18
/**
19
 *  Handler adapted to processing e-mail addresses.
19
 *  Processor adapted to processing e-mail addresses.
20
 */
20
 */
21
public class STextEmail extends STextDelimsEsc {
21
public class STextEmail extends STextDelimsEsc {
22
	static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
22
	static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
Lines 59-65 Link Here
59
	}
59
	}
60
60
61
	/**
61
	/**
62
	 *  @return 2 as number of special cases handled by this handler.
62
	 *  @return 2 as number of special cases handled by this processor.
63
	 */
63
	 */
64
	public int getSpecialsCount(STextEnvironment environment) {
64
	public int getSpecialsCount(STextEnvironment environment) {
65
		return 2;
65
		return 2;
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextFile.java (-3 / +3 lines)
Lines 10-21 Link Here
10
 ******************************************************************************/
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
13
import org.eclipse.equinox.bidi.custom.STextProcessor;
14
14
15
/**
15
/**
16
 *  Handler adapted to processing directory and file paths.
16
 *  Processor adapted to processing directory and file paths.
17
 */
17
 */
18
public class STextFile extends STextTypeHandler {
18
public class STextFile extends STextProcessor {
19
19
20
	public STextFile() {
20
	public STextFile() {
21
		super(":/\\."); //$NON-NLS-1$
21
		super(":/\\."); //$NON-NLS-1$
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java (-8 / +7 lines)
Lines 10-23 Link Here
10
 ******************************************************************************/
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
13
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
14
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
15
import org.eclipse.equinox.bidi.custom.*;
15
import org.eclipse.equinox.bidi.custom.*;
16
import org.eclipse.equinox.bidi.internal.STextActivator;
16
import org.eclipse.equinox.bidi.internal.STextActivator;
17
import org.eclipse.equinox.bidi.internal.STextImpl;
18
17
19
/**
18
/**
20
 *  <code>STextJava</code> is a handler for structured text
19
 *  <code>STextJava</code> is a processor for structured text
21
 *  composed of Java statements. Such a structured text may span
20
 *  composed of Java statements. Such a structured text may span
22
 *  multiple lines.
21
 *  multiple lines.
23
 *  <p>
22
 *  <p>
Lines 35-41 Link Here
35
 *
34
 *
36
 *  @author Matitiahu Allouche
35
 *  @author Matitiahu Allouche
37
 */
36
 */
38
public class STextJava extends STextTypeHandler {
37
public class STextJava extends STextProcessor {
39
	private static final byte WS = Character.DIRECTIONALITY_WHITESPACE;
38
	private static final byte WS = Character.DIRECTIONALITY_WHITESPACE;
40
	static final String lineSep = STextActivator.getInstance().getProperty("line.separator"); //$NON-NLS-1$
39
	static final String lineSep = STextActivator.getInstance().getProperty("line.separator"); //$NON-NLS-1$
41
40
Lines 44-50 Link Here
44
	}
43
	}
45
44
46
	/**
45
	/**
47
	 *  @return 4 as the number of special cases handled by this handler.
46
	 *  @return 4 as the number of special cases handled by this processor.
48
	 */
47
	 */
49
	public int getSpecialsCount(STextEnvironment environment) {
48
	public int getSpecialsCount(STextEnvironment environment) {
50
		return 4;
49
		return 4;
Lines 86-92 Link Here
86
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
85
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
87
		int location, counter, i;
86
		int location, counter, i;
88
87
89
		STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
88
		STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
90
		switch (caseNumber) {
89
		switch (caseNumber) {
91
			case 1 : /* space */
90
			case 1 : /* space */
92
				separLocation++;
91
				separLocation++;
Lines 115-126 Link Here
115
					location = separLocation + 2; // skip the opening slash-aster
114
					location = separLocation + 2; // skip the opening slash-aster
116
				location = text.indexOf("*/", location); //$NON-NLS-1$
115
				location = text.indexOf("*/", location); //$NON-NLS-1$
117
				if (location < 0) {
116
				if (location < 0) {
118
					STextImpl.setState(state, caseNumber);
117
					state[0] = caseNumber;
119
					return text.length();
118
					return text.length();
120
				}
119
				}
121
				// we need to call processSeparator since text may follow the
120
				// we need to call processSeparator since text may follow the
122
				//  end of comment immediately without even a space
121
				//  end of comment immediately without even a space
123
				STextTypeHandler.processSeparator(text, charTypes, offsets, location);
122
				STextProcessor.processSeparator(text, charTypes, offsets, location);
124
				return location + 2;
123
				return location + 2;
125
			case 4 : /* slash-slash comment */
124
			case 4 : /* slash-slash comment */
126
				location = text.indexOf(lineSep, separLocation + 2);
125
				location = text.indexOf(lineSep, separLocation + 2);
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java (-3 / +3 lines)
Lines 13-25 Link Here
13
import org.eclipse.equinox.bidi.STextDirection;
13
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
15
import org.eclipse.equinox.bidi.custom.STextCharTypes;
15
import org.eclipse.equinox.bidi.custom.STextCharTypes;
16
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
16
import org.eclipse.equinox.bidi.custom.STextProcessor;
17
17
18
/**
18
/**
19
 *  Handler adapted to processing arithmetic expressions with
19
 *  Processor adapted to processing arithmetic expressions with
20
 *  a possible right-to-left base direction.
20
 *  a possible right-to-left base direction.
21
 */
21
 */
22
public class STextMath extends STextTypeHandler {
22
public class STextMath extends STextProcessor {
23
	static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
23
	static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
24
	static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
24
	static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
25
	static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
25
	static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextProperty.java (-1 / +1 lines)
Lines 13-19 Link Here
13
import org.eclipse.equinox.bidi.internal.STextSingle;
13
import org.eclipse.equinox.bidi.internal.STextSingle;
14
14
15
/**
15
/**
16
 *  Handler adapted to processing property file statements.
16
 *  Processor adapted to processing property file statements.
17
 *  It expects the following string format:
17
 *  It expects the following string format:
18
 *  <pre>
18
 *  <pre>
19
 *    name=value
19
 *    name=value
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java (-12 / +11 lines)
Lines 11-23 Link Here
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.STextDirection;
13
import org.eclipse.equinox.bidi.STextDirection;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
15
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
15
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
16
import org.eclipse.equinox.bidi.custom.*;
16
import org.eclipse.equinox.bidi.custom.*;
17
import org.eclipse.equinox.bidi.internal.STextImpl;
18
17
19
/**
18
/**
20
 *  <code>STextRegex</code> is a handler for regular expressions.
19
 *  <code>STextRegex</code> is a processor for regular expressions.
21
 *  Such expressions may span multiple lines.
20
 *  Such expressions may span multiple lines.
22
 *  <p>
21
 *  <p>
23
 *  In applications like an editor where parts of the text might be modified
22
 *  In applications like an editor where parts of the text might be modified
Lines 34-40 Link Here
34
 *
33
 *
35
 *  @author Matitiahu Allouche
34
 *  @author Matitiahu Allouche
36
 */
35
 */
37
public class STextRegex extends STextTypeHandler {
36
public class STextRegex extends STextProcessor {
38
	static final String[] startStrings = {"", /*  0 *//* dummy *///$NON-NLS-1$
37
	static final String[] startStrings = {"", /*  0 *//* dummy *///$NON-NLS-1$
39
			"(?#", /*  1 *//* comment (?#...) *///$NON-NLS-1$
38
			"(?#", /*  1 *//* comment (?#...) *///$NON-NLS-1$
40
			"(?<", /*  2 *//* named group (?<name> *///$NON-NLS-1$
39
			"(?<", /*  2 *//* named group (?<name> *///$NON-NLS-1$
Lines 66-74 Link Here
66
	static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
65
	static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
67
66
68
	/**
67
	/**
69
	 *  This method retrieves the number of special cases handled by this handler.
68
	 *  This method retrieves the number of special cases handled by this processor.
70
	 *  
69
	 *  
71
	 *  @return the number of special cases for this handler.
70
	 *  @return the number of special cases for this processor.
72
	 */
71
	 */
73
	public int getSpecialsCount(STextEnvironment environment) {
72
	public int getSpecialsCount(STextEnvironment environment) {
74
		return maxSpecial;
73
		return maxSpecial;
Lines 155-167 Link Here
155
					// initial state from previous line
154
					// initial state from previous line
156
					location = 0;
155
					location = 0;
157
				} else {
156
				} else {
158
					STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
157
					STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
159
					// skip the opening "(?#"
158
					// skip the opening "(?#"
160
					location = separLocation + 3;
159
					location = separLocation + 3;
161
				}
160
				}
162
				location = text.indexOf(')', location);
161
				location = text.indexOf(')', location);
163
				if (location < 0) {
162
				if (location < 0) {
164
					STextImpl.setState(state, caseNumber);
163
					state[0] = caseNumber;
165
					return text.length();
164
					return text.length();
166
				}
165
				}
167
				return location + 1;
166
				return location + 1;
Lines 171-177 Link Here
171
			case 5 : /* conditional named back reference (?(<name>) */
170
			case 5 : /* conditional named back reference (?(<name>) */
172
			case 6 : /* conditional named back reference (?('name') */
171
			case 6 : /* conditional named back reference (?('name') */
173
			case 7 : /* named parentheses reference (?&name) */
172
			case 7 : /* named parentheses reference (?&name) */
174
				STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
173
				STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
175
				// no need for calling processSeparator() for the following cases
174
				// no need for calling processSeparator() for the following cases
176
				//   since the starting string contains a L char
175
				//   since the starting string contains a L char
177
			case 8 : /* named group (?P<name> */
176
			case 8 : /* named group (?P<name> */
Lines 195-214 Link Here
195
					// initial state from previous line
194
					// initial state from previous line
196
					location = 0;
195
					location = 0;
197
				} else {
196
				} else {
198
					STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
197
					STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
199
					// skip the opening "\Q"
198
					// skip the opening "\Q"
200
					location = separLocation + 2;
199
					location = separLocation + 2;
201
				}
200
				}
202
				location = text.indexOf("\\E", location); //$NON-NLS-1$
201
				location = text.indexOf("\\E", location); //$NON-NLS-1$
203
				if (location < 0) {
202
				if (location < 0) {
204
					STextImpl.setState(state, caseNumber);
203
					state[0] = caseNumber;
205
					return text.length();
204
					return text.length();
206
				}
205
				}
207
				// set the charType for the "E" to L (Left to Right character)
206
				// set the charType for the "E" to L (Left to Right character)
208
				charTypes.setBidiTypeAt(location + 1, L);
207
				charTypes.setBidiTypeAt(location + 1, L);
209
				return location + 2;
208
				return location + 2;
210
			case 18 : /* R, AL, AN, EN */
209
			case 18 : /* R, AL, AN, EN */
211
				STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
210
				STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
212
				return separLocation + 1;
211
				return separLocation + 1;
213
212
214
		}
213
		}
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java (-9 / +8 lines)
Lines 10-23 Link Here
10
 ******************************************************************************/
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
13
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
14
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
14
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
15
import org.eclipse.equinox.bidi.custom.*;
15
import org.eclipse.equinox.bidi.custom.*;
16
import org.eclipse.equinox.bidi.internal.STextActivator;
16
import org.eclipse.equinox.bidi.internal.STextActivator;
17
import org.eclipse.equinox.bidi.internal.STextImpl;
18
17
19
/**
18
/**
20
 *  <code>STextSql</code> is a handler for structured text
19
 *  <code>STextSql</code> is a processor for structured text
21
 *  composed of SQL statements. Such a structured text may span
20
 *  composed of SQL statements. Such a structured text may span
22
 *  multiple lines.
21
 *  multiple lines.
23
 *  <p>
22
 *  <p>
Lines 35-41 Link Here
35
 *
34
 *
36
 *  @author Matitiahu Allouche
35
 *  @author Matitiahu Allouche
37
 */
36
 */
38
public class STextSql extends STextTypeHandler {
37
public class STextSql extends STextProcessor {
39
	private static final byte WS = Character.DIRECTIONALITY_WHITESPACE;
38
	private static final byte WS = Character.DIRECTIONALITY_WHITESPACE;
40
	static final String lineSep = STextActivator.getInstance().getProperty("line.separator"); //$NON-NLS-1$
39
	static final String lineSep = STextActivator.getInstance().getProperty("line.separator"); //$NON-NLS-1$
41
40
Lines 44-50 Link Here
44
	}
43
	}
45
44
46
	/**
45
	/**
47
	 *  @return 5 as the number of special cases handled by this handler.
46
	 *  @return 5 as the number of special cases handled by this processor.
48
	 */
47
	 */
49
	public int getSpecialsCount(STextEnvironment environment) {
48
	public int getSpecialsCount(STextEnvironment environment) {
50
		return 5;
49
		return 5;
Lines 90-96 Link Here
90
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
89
	public int processSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] state, int caseNumber, int separLocation) {
91
		int location;
90
		int location;
92
91
93
		STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
92
		STextProcessor.processSeparator(text, charTypes, offsets, separLocation);
94
		switch (caseNumber) {
93
		switch (caseNumber) {
95
			case 1 : /* space */
94
			case 1 : /* space */
96
				separLocation++;
95
				separLocation++;
Lines 104-110 Link Here
104
				while (true) {
103
				while (true) {
105
					location = text.indexOf('\'', location);
104
					location = text.indexOf('\'', location);
106
					if (location < 0) {
105
					if (location < 0) {
107
						STextImpl.setState(state, caseNumber);
106
						state[0] = caseNumber;
108
						return text.length();
107
						return text.length();
109
					}
108
					}
110
					if ((location + 1) < text.length() && text.charAt(location + 1) == '\'') {
109
					if ((location + 1) < text.length() && text.charAt(location + 1) == '\'') {
Lines 133-144 Link Here
133
					location = separLocation + 2; // skip the opening slash-aster
132
					location = separLocation + 2; // skip the opening slash-aster
134
				location = text.indexOf("*/", location); //$NON-NLS-1$
133
				location = text.indexOf("*/", location); //$NON-NLS-1$
135
				if (location < 0) {
134
				if (location < 0) {
136
					STextImpl.setState(state, caseNumber);
135
					state[0] = caseNumber;
137
					return text.length();
136
					return text.length();
138
				}
137
				}
139
				// we need to call processSeparator since text may follow the
138
				// we need to call processSeparator since text may follow the
140
				//  end of comment immediately without even a space
139
				//  end of comment immediately without even a space
141
				STextTypeHandler.processSeparator(text, charTypes, offsets, location);
140
				STextProcessor.processSeparator(text, charTypes, offsets, location);
142
				return location + 2;
141
				return location + 2;
143
			case 5 : /* hyphen-hyphen comment */
142
			case 5 : /* hyphen-hyphen comment */
144
				location = text.indexOf(lineSep, separLocation + 2);
143
				location = text.indexOf(lineSep, separLocation + 2);
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextSystem.java (-1 / +1 lines)
Lines 13-19 Link Here
13
import org.eclipse.equinox.bidi.internal.STextSingle;
13
import org.eclipse.equinox.bidi.internal.STextSingle;
14
14
15
/**
15
/**
16
 *  Handler adapted to processing structured text with the following format:
16
 *  Processor adapted to processing structured text with the following format:
17
 *  <pre>
17
 *  <pre>
18
 *    system(user)
18
 *    system(user)
19
 *  </pre>
19
 *  </pre>
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextURL.java (-3 / +3 lines)
Lines 10-21 Link Here
10
 ******************************************************************************/
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
13
import org.eclipse.equinox.bidi.custom.STextProcessor;
14
14
15
/**
15
/**
16
 *  Handler adapted to processing URLs.
16
 *  Processor adapted to processing URLs.
17
 */
17
 */
18
public class STextURL extends STextTypeHandler {
18
public class STextURL extends STextProcessor {
19
	public STextURL() {
19
	public STextURL() {
20
		super(":?#/@.[]"); //$NON-NLS-1$
20
		super(":?#/@.[]"); //$NON-NLS-1$
21
	}
21
	}
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextUnderscore.java (-3 / +3 lines)
Lines 10-25 Link Here
10
 ******************************************************************************/
10
 ******************************************************************************/
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
13
import org.eclipse.equinox.bidi.custom.STextProcessor;
14
14
15
/**
15
/**
16
 *  Handler adapted to processing compound names.
16
 *  Processor adapted to processing compound names.
17
 *  This type covers names made of one or more parts, separated by underscores:
17
 *  This type covers names made of one or more parts, separated by underscores:
18
 *  <pre>
18
 *  <pre>
19
 *    part1_part2_part3
19
 *    part1_part2_part3
20
 *  </pre>
20
 *  </pre>
21
 */
21
 */
22
public class STextUnderscore extends STextTypeHandler {
22
public class STextUnderscore extends STextProcessor {
23
23
24
	public STextUnderscore() {
24
	public STextUnderscore() {
25
		super("_"); //$NON-NLS-1$
25
		super("_"); //$NON-NLS-1$
(-)src/org/eclipse/equinox/bidi/internal/consumable/STextXPath.java (-2 / +3 lines)
Lines 11-20 Link Here
11
package org.eclipse.equinox.bidi.internal.consumable;
11
package org.eclipse.equinox.bidi.internal.consumable;
12
12
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
13
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
14
14
import org.eclipse.equinox.bidi.internal.STextDelims;
15
import org.eclipse.equinox.bidi.internal.STextDelims;
15
16
16
/**
17
/**
17
 *  Handler adapted to processing XPath expressions.
18
 *  Processor adapted to processing XPath expressions.
18
 */
19
 */
19
public class STextXPath extends STextDelims {
20
public class STextXPath extends STextDelims {
20
21
Lines 23-29 Link Here
23
	}
24
	}
24
25
25
	/**
26
	/**
26
	 *  @return 2 as the number of special cases handled by this handler.
27
	 *  @return 2 as the number of special cases handled by this processor.
27
	 */
28
	 */
28
	public int getSpecialsCount(STextEnvironment environment) {
29
	public int getSpecialsCount(STextEnvironment environment) {
29
		return 2;
30
		return 2;

Return to bug 183164