Skip to main content
summaryrefslogtreecommitdiffstats
blob: b38985b3bcbccaf7f3c0e3838426cb6a683118a4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Sebastian Davids <sdavids@gmx.de> - fix for Bug 182466
 *     Dave Carver - modification to isAdvanced(), see Bug 238533
 *******************************************************************************/
package org.eclipse.help.internal.webapp.data;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.core.runtime.Platform;
import org.eclipse.help.internal.HelpPlugin;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpBasePlugin;
import org.eclipse.help.internal.util.ProductPreferences;

public class UrlUtil {

	// for Safari build 125.1 finds version 125
	static final Pattern safariPattern = Pattern.compile(
			"Safari/(\\d+)(?:\\.|\\s|$)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$

	// Default locale to use for serving requests to help
	private static String defaultLocale;
	// Locales that infocenter can serve in addition to the default locale.
	// null indicates that infocenter can serve every possible client locale.
	private static Collection<String> locales;

	private static final int INFOCENTER_DIRECTION_BY_LOCALE = 1;
	private static final int INFOCENTER_DIRECTION_LTR = 2;
	private static final int INFOCENTER_DIRECTION_RTL = 3;
	private static int infocenterDirection = INFOCENTER_DIRECTION_BY_LOCALE;

	/**
	 * Encodes string for embedding in JavaScript source
	 */
	public static String JavaScriptEncode(String str) {
		if (str == null) return null;
		char[] wordChars = new char[str.length()];
		str.getChars(0, str.length(), wordChars, 0);
		StringBuffer jsEncoded = new StringBuffer();
		for (char unicode : wordChars) {
			// to enhance readability, do not encode A-Z,a-z
			if (('A' <= unicode && unicode <= 'Z')
					|| ('a' <= unicode && unicode <= 'z')) {
				jsEncoded.append(unicode);
				continue;
			}
			// encode the character
			String charInHex = Integer.toString(unicode, 16).toUpperCase();
			switch (charInHex.length()) {
				case 1 :
					jsEncoded.append("\\u000").append(charInHex); //$NON-NLS-1$
					break;
				case 2 :
					jsEncoded.append("\\u00").append(charInHex); //$NON-NLS-1$
					break;
				case 3 :
					jsEncoded.append("\\u0").append(charInHex); //$NON-NLS-1$
					break;
				default :
					jsEncoded.append("\\u").append(charInHex); //$NON-NLS-1$
					break;
			}
		}
		return jsEncoded.toString();
	}

	/**
	 * Encodes string for embedding in html source.
	 */
	public static String htmlEncode(String str) {
		if (str == null) {
			return null;
		}

		StringBuffer result = new StringBuffer();
		for (int i = 0 ; i < str.length(); i++) {
			appendEncodedChar(result, str.charAt(i));
		}
		return result.toString();
	}

	private static void appendEncodedChar(StringBuffer result, char ch) {
		if (needsEncoding(ch)) {
			int chInt = ch;
			result.append("&#" + chInt + ';'); //$NON-NLS-1$
			return;
		}
		result.append(ch);
	}

	private static boolean needsEncoding(char ch) {
		if (ch > 255) {
			return false;
		}
		if (Character.isLetterOrDigit(ch)) {
			return false;
		}
		if ( ch == ' ' || ch == '_' || ch  == '%' || ch == '+') {
			return false;
		}
		return true;
	}

	public static boolean isLocalRequest(HttpServletRequest request) {
		String reqIP = request.getRemoteAddr();
		if ("127.0.0.1".equals(reqIP)) { //$NON-NLS-1$
			return true;
		}

		try {
			String hostname = InetAddress.getLocalHost().getHostName();
			InetAddress[] addr = InetAddress.getAllByName(hostname);
			for (InetAddress element : addr) {
				// test all addresses retrieved from the local machine
				if (element.getHostAddress().equals(reqIP))
					return true;
			}
		} catch (IOException ioe) {
		}
		return false;
	}

	/**
	 * Returns a URL that can be loaded from a browser. This method is used for
	 * all url's except those from the webapp plugin.
	 *
	 * @param url
	 * @return String
	 */
	public static String getHelpURL(String url) {
		return getHelpURL(url, 1);
	}


	/**
	 * Returns a URL that can be used as
	 *
	 * @param url either a complete url including protocol or a help page
	 * path of form /plugin/path
	 * @param depth the number of directory segments beneath /help of the containing pages url
	 * @return a path that can be used as the href value of an anchor
	 */
	public static String getHelpURL(String url, int depth) {
		if (url == null || url.length() == 0)
			url = "about:blank"; //$NON-NLS-1$
		else if (url.startsWith("http:/") || url.startsWith("https:/")); //$NON-NLS-1$ //$NON-NLS-2$
		else if (url.startsWith("file:/") || url.startsWith("jar:file:/")) //$NON-NLS-1$ //$NON-NLS-2$
			url = getHelpUrlPrefix(depth) +'/' + url;
		else
			url =  getHelpUrlPrefix(depth) + url;
		return url;
	}

	private static String getHelpUrlPrefix(int depth) {
		String prefix;
		prefix = ""; //$NON-NLS-1$
		for (int d = 0; d < depth; d++) {
			prefix += "../"; //$NON-NLS-1$
		};
		prefix += "topic"; //$NON-NLS-1$
		return prefix;
	}

	/**
	 * Tests to see if the path specified in a topic parameter can be opened in
	 * the content frame. See Bug 233466 for an explanation of why in general we do
	 * do not want to open external sites in the content frame.
	 *
	 * If the preference org.eclipse.help.base/restrictTopicParameter is false any
	 * path is permitted. Any href which was just opened from the help display is
	 * also permitted, this is required for cheat sheets and intro. Otherwise the
	 * path is permitted only if it does not contain a protocol.
	 * @param path the path passed as a ?topic parameter. May not be null.
	 * @return true if the conditions above are met.
	 */
	public static boolean isValidTopicParamOrWasOpenedFromHelpDisplay(String path) {
		// Topics opened via the help display ( including cheat sheets and intro )
		// are are always valid
		if (wasOpenedFromHelpDisplay(path)) {
			return true;
		}

		if (new WebappPreferences().isRestrictTopicParameter()) {
		    if (path.indexOf("://") >= 0) {  //$NON-NLS-1$
			    return false;
		    }
		}
		return true;
	}

	public static boolean wasOpenedFromHelpDisplay(String path) {
		if (path.equals(BaseHelpSystem.getHelpDisplay().getHrefOpenedFromHelpDisplay())) {
			return true;
		}
		return path.equals(getHelpURL(BaseHelpSystem.getHelpDisplay().getHrefOpenedFromHelpDisplay()));
	}

	/**
	 * Returns a path to the given topic in the form of child indexes. For
	 * example, if the path points to the 3rd subtopic under the 2nd topic of
	 * the 4th toc, it will return { 3, 1, 2 }.
	 *
	 * @param path the path portion of the url without the initial "/help", e.g. "/topic/my.plugin/foo.html"
	 * @param locale
	 * @return path to the topic using zero-based indexes
	 * If the path is empty or has invalid syntax null is returned
	 */
	public static int[] getTopicPath(String path, String locale) {
		if (path.startsWith("/nav/")) { //$NON-NLS-1$
			path = path.substring(5);
			return splitPath(path);
		}
		else {
			// grab the part after /help/*topic/
			String href = path.substring(path.indexOf('/', 1));
			return HelpPlugin.getTocManager().getTopicPath(href, locale);
		}
	}

	/*
	 * Similar to getTopicPath except that the path has no prefix
	 */
	public static int[] splitPath(String path) {
		try {
			StringTokenizer tok = new StringTokenizer(path, "_"); //$NON-NLS-1$
			int[] array = new int[tok.countTokens()];
			if (array.length == 0) {
				return null;
			}
			for (int i=0;i<array.length;++i) {
				array[i] = Integer.parseInt(tok.nextToken());
			}
			return array;
		} catch (RuntimeException e) {
			return null;
		}
	}

	public static boolean isBot(HttpServletRequest request) {
        String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
        if (agent==null)
		    return false;
        agent=agent.toLowerCase(Locale.ENGLISH);
		// sample substring Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
		return agent.indexOf("bot") >= 0 || agent.indexOf("crawl") >= 0//$NON-NLS-1$ //$NON-NLS-2$
                || request.getParameter("bot") != null;//$NON-NLS-1$
    }

	public static boolean isGecko(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return isGecko(agent);
	}

	public static boolean isGecko(String agent) {
		if (agent==null)
		    return false;
		agent=agent.toLowerCase(Locale.ENGLISH);
		// sample substring Gecko/20020508
		if (agent.indexOf("like gecko") >= 0) { //$NON-NLS-1$
			return false;
		}
		return agent.indexOf("gecko") >= 0; //$NON-NLS-1$
	}

	public static boolean isIE(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return isIE(agent);
	}

	public static boolean isIE(String agent) {
		if (agent==null)
		    return false;
		agent=agent.toLowerCase(Locale.ENGLISH);

		// When accessing with Bobby identified Bobby return 5.5 to allow
		// testing advanced UI as bobby cannot identifiy as IE >=5.5
		if (agent.startsWith("bobby/")) { //$NON-NLS-1$
			return true;
		}
		//

		return (agent.indexOf("msie") >= 0); //$NON-NLS-1$
	}

	public static String getIEVersion(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return getIEVersion(agent);
	}

	public static String getIEVersion(String agent) {
		if (agent==null)
		    return "0"; //$NON-NLS-1$

		agent=agent.toLowerCase(Locale.ENGLISH);
		// When accessing with Bobby identified Bobby return 5.5 to allow
		// testing advanced UI as bobby cannot identifiy as IE >=5.5
		if (agent.startsWith("bobby/")) { //$NON-NLS-1$
			return "5.5"; //$NON-NLS-1$
		}
		//

		int start = agent.indexOf("msie ") + "msie ".length(); //$NON-NLS-1$ //$NON-NLS-2$
		if (start < "msie ".length() || start >= agent.length()) //$NON-NLS-1$
			return "0"; //$NON-NLS-1$
		int end = agent.indexOf(";", start); //$NON-NLS-1$
		if (end <= start)
			return "0"; //$NON-NLS-1$
		return agent.substring(start, end);
	}

	public static boolean isKonqueror(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return isKonqueror(agent);
	}

	public static boolean isKonqueror(String agent) {
		if (agent==null)
		    return false;
		agent=agent.toLowerCase(Locale.ENGLISH);
		return agent.indexOf("konqueror") >= 0; //$NON-NLS-1$
	}

	/**
	 * Test to see if this is a "mozilla" browser, i.e.
	 * just about anything other than Internet Explorer
	 * @param request a request from the browser
	 * @return true if the browser is Netcape, Firefox, Safari or Konqueror
	 */
	public static boolean isMozilla(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return isMozilla(agent);
	}

	public static boolean isMozilla(String agent) {
		if (agent==null)
		    return false;
		agent=agent.toLowerCase(Locale.ENGLISH);
		return agent.indexOf("mozilla/5") >= 0; //$NON-NLS-1$
	}

	public static String getMozillaVersion(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return getMozillaVersion(agent);
	}

	public static String getMozillaVersion(String agent) {
		if (agent==null)
		    return "0"; //$NON-NLS-1$
		agent=agent.toLowerCase(Locale.ENGLISH);
		if (agent.indexOf("mozilla/5") < 0) //$NON-NLS-1$
			return "0"; //$NON-NLS-1$
		int start = agent.indexOf("rv:") + "rv:".length(); //$NON-NLS-1$ //$NON-NLS-2$
		if (start < "rv:".length() || start >= agent.length()) //$NON-NLS-1$
			return "0"; //$NON-NLS-1$
		int end = agent.indexOf(")", start); //$NON-NLS-1$
		if (end <= start)
			return "0"; //$NON-NLS-1$
		return agent.substring(start, end);
	}

	public static boolean isOpera(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return isOpera(agent);
	}

	public static boolean isOpera(String agent) {
		if (agent==null)
		    return false;
		agent=agent.toLowerCase(Locale.ENGLISH);
		return agent.indexOf("opera") >= 0; //$NON-NLS-1$
	}

	public static String getOperaVersion(String agent) {
		if (agent==null)
		    return "0"; //$NON-NLS-1$
		agent=agent.toLowerCase(Locale.ENGLISH);
		final String OperaPrefix = "opera/"; //$NON-NLS-1$
		int start = agent.indexOf(OperaPrefix) + OperaPrefix.length();
		if (start < OperaPrefix.length() || start >= agent.length())
			return "0"; //$NON-NLS-1$
		int end = agent.indexOf(" (", start); //$NON-NLS-1$
		if (end <= start)
			return "0"; //$NON-NLS-1$
		return agent.substring(start, end);
	}

	public static boolean isSafari(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return isSafari(agent);
	}

	public static boolean isSafari(String agent) {
		if (agent==null)
		    return false;
		agent=agent.toLowerCase(Locale.ENGLISH);
		return agent.indexOf("safari/") >= 0; //$NON-NLS-1$
	}

	public static String getSafariVersion(HttpServletRequest request) {
		String agent = request.getHeader("User-Agent"); //$NON-NLS-1$
		return getSafariVersion(agent);
	}

	public static String getSafariVersion(String agent) {
		String version = "0"; //$NON-NLS-1$
		if (agent==null)
		    return version;
		agent=agent.toLowerCase(Locale.ENGLISH);
		Matcher m = safariPattern.matcher(agent);
		boolean matched = m.find();
		if (matched) {
			version = m.group(1);
			while (version.length() < 3) {
				version = "0" + version; //$NON-NLS-1$
			}
		}
		return version;
	}
	/**
	 *
	 * @param request
	 * @param response
	 *            HttpServletResponse or null (locale will not be persisted in
	 *            session cookie)
	 * @return
	 */
	public static Locale getLocaleObj(HttpServletRequest request,
			HttpServletResponse response) {
		String localeStr = getLocale(request, response);
		return getLocale(localeStr);
	}

	/**
	 * Returns the locale object from the provided string.
	 * @param localeStr the encoded locale string
	 * @return the Locale object
	 *
	 * @since 3.1
	 */
	public static Locale getLocale(String localeStr) {
		if (localeStr.length() >= 5) {
			return new Locale(localeStr.substring(0, 2), localeStr.substring(3,
					5));
		} else if (localeStr.length() >= 2) {
			return new Locale(localeStr.substring(0, 2), ""); //$NON-NLS-1$
		} else {
			return Locale.getDefault();
		}
	}
	/**
	 *
	 * @param request
	 * @param response
	 *            HttpServletResponse or null (locale will not be persisted in
	 *            session cookie)
	 * @return
	 */
	public static String getLocale(HttpServletRequest request,
			HttpServletResponse response) {
		if (defaultLocale == null) {
			initializeNL();
		}
		if ((BaseHelpSystem.getMode() != BaseHelpSystem.MODE_INFOCENTER)
				|| request == null) {
			return defaultLocale;
		}

		// use locale passed in a request in current user session
		String forcedLocale = getForcedLocale(request, response);
		if (forcedLocale != null) {
			if (locales == null) {
				// infocenter set up to serve any locale
				return forcedLocale;
			}
			// match forced locale with one of infocenter locales
			if (locales.contains(forcedLocale)) {
				return forcedLocale;
			}
			// match language of forced locale with one of infocenter locales
			if (forcedLocale.length() > 2) {
				String ll = forcedLocale.substring(0, 2);
				if (locales.contains(ll)) {
					return ll;
				}
			}
		}

		// use one of the browser locales
		if (locales == null) {
			// infocenter set up to serve any locale
			return request.getLocale().toString();
		}
		// match client browser locales with one of infocenter locales
		for (Enumeration<Locale> e = request.getLocales(); e.hasMoreElements();) {
			String locale = e.nextElement().toString();
			if (locale.length() >= 5) {
				String ll_CC = locale.substring(0, 5);
				if (locales.contains(ll_CC)) {
					// client locale available
					return ll_CC;
				}
			}
			if (locale.length() >= 2) {
				String ll = locale.substring(0, 2);
				if (locales.contains(ll)) {
					// client language available
					return ll;
				}
			}
		}
		// no match
		return defaultLocale;
	}

	/*
	 * Replace any characters other than alphanumeric or hyphen in a locale string with "_"
	 * See Bug 223361
	 */
	public static String cleanLocale(String parameter) {
		if (parameter == null) {
			return null;
		}
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < parameter.length(); i++) {
			char nextChar = parameter.charAt(i);
			if (Character.isLetterOrDigit(nextChar) || nextChar == '-') {
				result.append(nextChar);
			} else {
				result.append('_');
			}
		}
		return result.toString();
	}

	/**
	 * Obtains locale passed as lang parameter with a request during user
	 * session
	 *
	 * @param request
	 * @param response
	 *            response or null; if null, locale will not be persisted (in
	 *            session cookie)
	 * @return ll_CC or ll or null
	 */
	private static String getForcedLocale(HttpServletRequest request,
			HttpServletResponse response) {
		// get locale passed in this request
		String forcedLocale = cleanLocale(request.getParameter("lang")); //$NON-NLS-1$
		if (forcedLocale != null) {
			// save locale (in session cookie) for later use in a user session
			if (response != null) {
				Cookie cookieTest = new Cookie("lang", forcedLocale); //$NON-NLS-1$
				response.addCookie(cookieTest);
			}
		} else {
			// check if locale was passed earlier in this session
			Cookie[] cookies = request.getCookies();
			if (cookies != null) {
        			for (Cookie cookie : cookies) {
        				if ("lang".equals(cookie.getName())) { //$NON-NLS-1$
        					forcedLocale = cookie.getValue();
        					break;
        				}
        			}
			}
		}

		// format forced locale
		if (forcedLocale != null) {
			if (forcedLocale.length() >= 5) {
				forcedLocale = forcedLocale.substring(0, 2) + "_" //$NON-NLS-1$
						+ forcedLocale.substring(3, 5);
			} else if (forcedLocale.length() >= 2) {
				forcedLocale = forcedLocale.substring(0, 2);
			}
		}
		return forcedLocale;
	}

	/**
	 * If locales for infocenter specified in prefernces or as command line
	 * parameters, this methods stores these locales in locales local variable
	 * for later access.
	 */
	private static synchronized void initializeNL() {
		if (defaultLocale != null) {
			// already initialized
			return;
		}
		initializeLocales();
		if ((BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER)) {
			initializeIcDirection();
		}

	}
	/**
	 *
	 */
	private static void initializeLocales() {
		// initialize default locale
		defaultLocale = Platform.getNL();
		if (defaultLocale == null) {
			defaultLocale = Locale.getDefault().toString();
		}
		if (BaseHelpSystem.getMode() != BaseHelpSystem.MODE_INFOCENTER) {
			return;
		}

		// locale strings as passed in command line or in preferences
		final List<String> infocenterLocales= new ArrayList<>();

		// first check if locales passed as command line arguments
		String[] args = Platform.getCommandLineArgs();
		boolean localeOption = false;
		for (String arg : args) {
			if ("-locales".equalsIgnoreCase(arg)) { //$NON-NLS-1$
				localeOption = true;
				continue;
			} else if (arg.startsWith("-")) { //$NON-NLS-1$
				localeOption = false;
				continue;
			}
			if (localeOption) {
				infocenterLocales.add(arg);
			}
		}
		// if no locales from command line, get them from preferences
		if (infocenterLocales.isEmpty()) {
			String preferredLocales = Platform.getPreferencesService().getString
			    (HelpBasePlugin.PLUGIN_ID, ("locales"), "", null); //$NON-NLS-1$ //$NON-NLS-2$
			StringTokenizer tokenizer = new StringTokenizer(preferredLocales,
					" ,\t"); //$NON-NLS-1$
			while (tokenizer.hasMoreTokens()) {
				infocenterLocales.add(tokenizer.nextToken());
			}
		}

		// format locales and collect in a set for lookup
		if (!infocenterLocales.isEmpty()) {
			locales = new HashSet<>(10, 0.4f);
			for (String locale : infocenterLocales) {
				if (locale.length() >= 5) {
					locales.add(locale.substring(0, 2).toLowerCase(Locale.ENGLISH) + "_" //$NON-NLS-1$
							+ locale.substring(3, 5).toUpperCase(Locale.ENGLISH));

				} else if (locale.length() >= 2) {
					locales.add(locale.substring(0, 2).toLowerCase(Locale.ENGLISH));
				}
			}
		}
	}

	private static void initializeIcDirection() {
		// from property
		String orientation = System.getProperty("eclipse.orientation"); //$NON-NLS-1$
		if ("rtl".equals(orientation)) { //$NON-NLS-1$
			infocenterDirection = INFOCENTER_DIRECTION_RTL;
			return;
		} else if ("ltr".equals(orientation)) { //$NON-NLS-1$
			infocenterDirection = INFOCENTER_DIRECTION_LTR;
			return;
		}
		// from command line
		String[] args = Platform.getCommandLineArgs();
		for (int i = 0; i < args.length; i++) {
			if ("-dir".equalsIgnoreCase(args[i])) { //$NON-NLS-1$
				if ((i + 1) < args.length
						&& "rtl".equalsIgnoreCase(args[i + 1])) { //$NON-NLS-1$
					infocenterDirection = INFOCENTER_DIRECTION_RTL;
					return;
				}
				infocenterDirection = INFOCENTER_DIRECTION_LTR;
				return;
			}
		}
		// by client locale
	}

	public static boolean isRTL(HttpServletRequest request,
			HttpServletResponse response) {
		if (BaseHelpSystem.getMode() != BaseHelpSystem.MODE_INFOCENTER) {
			return ProductPreferences.isRTL();
		}
		{
			if (infocenterDirection == INFOCENTER_DIRECTION_RTL) {
				return true;
			} else if (infocenterDirection == INFOCENTER_DIRECTION_LTR) {
				return false;
			}
			String locale = getLocale(request, response);
			if (locale.startsWith("ar") || locale.startsWith("fa") //$NON-NLS-1$ //$NON-NLS-2$
					|| locale.startsWith("he") || locale.startsWith("iw") //$NON-NLS-1$ //$NON-NLS-2$
					| locale.startsWith("ur")) { //$NON-NLS-1$
				return true;
			}
			return false;
		}
	}

	/*
	 * Get the version from a string of the form mm.nn
	 */
	private static int getMajorVersion(String version) {
		int result = 0;
		for (int i = 0; i < version.length(); i++) {
			char next = version.charAt(i);
			if (next >= '0' && next <= '9') {
				result = result * 10 + next - '0';
			} else {
				break;
			}
		}
		return result;
	}

	public static boolean isAdvanced(String agent) {
	        if (agent == null) return false;
		if (isIE(agent) && "5.5".compareTo(getIEVersion(agent)) <= 0) return true; //$NON-NLS-1$
		if (isMozilla(agent) && isGecko(agent)) return true;
		if (isSafari(agent) && "120".compareTo(getSafariVersion(agent)) <= 0) return true; //$NON-NLS-1$
		if (isOpera(agent) && getMajorVersion(getOperaVersion(agent)) >= 9) return true;
		if (isMozilla(agent) && !isKonqueror(agent)) return true;
		return false;
	}

	// Return true if the URI is of the form /<context>/nav/*
	public static boolean isNavPath(String uri) {
		int slash1 = uri.indexOf('/');
		int slash2 = uri.indexOf('/', 1);
		return (slash1 == 0 && slash2 >= 0 && uri.substring(slash2).startsWith("/nav")); //$NON-NLS-1$
	}

	// Create a relative path based on the current URL
	public static String getRelativePath(HttpServletRequest req, String filePath) {
		StringBuffer result = new StringBuffer(""); //$NON-NLS-1$
		String reqPath = req.getPathInfo();
		if (reqPath != null) {
			for (int i; 0 <= (i = reqPath.indexOf('/', 1));) {
				if (result.length() == 0 && filePath.startsWith(reqPath.substring(0, i + 1))) {
					filePath = filePath.substring(i);
				} else {
					result.append("../"); //$NON-NLS-1$
				}
				reqPath = reqPath.substring(i);
			}
		}
		return result.toString() + filePath.substring(1);
	}
}

Back to the top