Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 243ac604ab57c82650efef474ce7f53f63ab8377 (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
/*******************************************************************************
 * Copyright (c) 2000, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 560168
 *******************************************************************************/
package org.eclipse.help.internal.base;

import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.Platform;
import org.eclipse.help.HelpSystem;
import org.eclipse.help.ILiveHelpAction;
import org.eclipse.help.browser.IBrowser;
import org.eclipse.help.internal.HelpPlugin;
import org.eclipse.help.internal.base.util.IErrorUtil;
import org.eclipse.help.internal.browser.BrowserManager;
import org.eclipse.help.internal.search.LocalSearchManager;
import org.eclipse.help.internal.search.SearchManager;
import org.eclipse.help.internal.server.WebappManager;
import org.eclipse.help.internal.workingset.WorkingSetManager;
import org.osgi.framework.Bundle;

/**
 * Base Help System.
 */
public final class BaseHelpSystem {

	private static final BaseHelpSystem instance = new BaseHelpSystem();

	public static final String BOOKMARKS = "bookmarks"; //$NON-NLS-1$
	public static final String WORKING_SETS = "workingSets"; //$NON-NLS-1$
	public static final String WORKING_SET = "workingSet"; //$NON-NLS-1$

	public static final int MODE_WORKBENCH = 0;
	public static final int MODE_INFOCENTER = 1;
	public static final int MODE_STANDALONE = 2;

	private int mode = MODE_WORKBENCH;

	private SearchManager searchManager;
	private WorkingSetManager workingSetManager;
	private BookmarkManager bookmarkManager;

	private boolean webappStarted = false;
	private boolean webappRunning = false;
	private IErrorUtil defaultErrorMessenger;
	private IBrowser browser;
	private IBrowser internalBrowser;
	private HelpDisplay helpDisplay = null;
	private String liveHelpToken = null;

	private BaseHelpSystem() {
		super();
	}

	public static BaseHelpSystem getInstance() {
		return instance;
	}

	/*
	 * Returns the singleton search manager, which is the main interface to the
	 * help system's search capability.
	 */
	public static SearchManager getSearchManager() {
		if (getInstance().searchManager == null) {
			synchronized (BaseHelpSystem.class) {
				if (getInstance().searchManager == null) {
					getInstance().searchManager = new SearchManager();
				}
			}
		}
		return getInstance().searchManager;
	}

	/*
	 * Returns the local search manager which deals only with the local content
	 * and is called by the global search manager.
	 */
	public static LocalSearchManager getLocalSearchManager() {
		return getSearchManager().getLocalSearchManager();
	}

	public static synchronized WorkingSetManager getWorkingSetManager() {
		if (getInstance().workingSetManager == null) {
			getInstance().workingSetManager = new WorkingSetManager();
		}
		return getInstance().workingSetManager;
	}

	public static synchronized BookmarkManager getBookmarkManager() {
		if (getInstance().bookmarkManager == null) {
			getInstance().bookmarkManager = new BookmarkManager();
		}
		return getInstance().bookmarkManager;
	}

	/*
	 * Allows Help UI to plug-in a soft adapter that delegates all the work to
	 * the workbench browser support.
	 */
	public synchronized void setBrowserInstance(IBrowser browser) {
		this.browser = browser;
	}

	public static synchronized IBrowser getHelpBrowser(boolean forceExternal) {
		if (!forceExternal && !BrowserManager.getInstance().isAlwaysUseExternal()) {
			if (getInstance().internalBrowser == null) {
				getInstance().internalBrowser = BrowserManager.getInstance().createBrowser(false);
			}
			return getInstance().internalBrowser;
		}
		if (getInstance().browser == null) {
			getInstance().browser = BrowserManager.getInstance().createBrowser(true);
		}
		return getInstance().browser;
	}

	public static synchronized HelpDisplay getHelpDisplay() {
		if (getInstance().helpDisplay == null)
			getInstance().helpDisplay = new HelpDisplay();
		return getInstance().helpDisplay;
	}

	/*
	 * Shuts down the BaseHelpSystem.
	 */
	public static void shutdown() throws CoreException {
		if (getInstance().bookmarkManager != null) {
			getInstance().bookmarkManager.close();
			getInstance().bookmarkManager = null;
		}
		if (getInstance().searchManager != null) {
			getInstance().searchManager.close();
			getInstance().searchManager = null;
		}
		if (getInstance().webappStarted) {
			// stop the web app
			WebappManager.stop("help"); //$NON-NLS-1$
		}
	}

	/**
	 * Called by Platform after loading the plugin
	 */
	public static void startup() {
		try {
			setDefaultErrorUtil(new IErrorUtil() {
				@Override
				public void displayError(String msg) {
					System.out.println(msg);
				}
				@Override
				public void displayError(String msg, Thread uiThread) {
					System.out.println(msg);
				}
			});
		}
		catch (Exception e) {
			Platform.getLog(BaseHelpSystem.class).error("Error launching help.", e); //$NON-NLS-1$
		}

		/*
		 * Assigns the provider responsible for providing help
		 * document content.
		 */
		HelpPlugin.getDefault().setHelpProvider(new HelpProvider());
	}

	public static boolean ensureWebappRunning() {
		if (!getInstance().webappStarted) {
			getInstance().webappStarted = true;
			try {
				// start the help web app
				WebappManager.start("help"); //$NON-NLS-1$
			} catch (Exception e) {
				Platform.getLog(BaseHelpSystem.class).error(HelpBaseResources.HelpWebappNotStarted, e);
				return false;
			}
			getInstance().webappRunning = true;
		}
		return getInstance().webappRunning;
	}

	public static URL resolve(String href, boolean documentOnly) {
		String url = null;
		if (href == null || href.contains("://") //$NON-NLS-1$
					|| isFileProtocol(href))
			url = href;
		else {
			BaseHelpSystem.ensureWebappRunning();
			String base = getBase(documentOnly);
			if (href.startsWith("/")) //$NON-NLS-1$
				url = base + href;
			else
				url = base + "/" + href; //$NON-NLS-1$
		}
		try {
			return new URL(url);
		} catch (MalformedURLException e) {
			return null;
		}
	}

	public static URL resolve(String href, String servlet) {
		String url = null;
		if (href == null || href.contains("://") //$NON-NLS-1$
			|| isFileProtocol(href)) {
			url = href;
		}
		else {
			BaseHelpSystem.ensureWebappRunning();
			String base = getBase(servlet);
			if (href.startsWith("/")) { //$NON-NLS-1$
				url = base + href;
			}
			else {
				url = base + "/" + href; //$NON-NLS-1$
			}
		}
		try {
			return new URL(url);
		}
		catch (MalformedURLException e) {
			return null;
		}
	}

	private static boolean isFileProtocol(String href) {
		// Test for file: or /file:
		int index = href.indexOf("file:"); //$NON-NLS-1$
		return ( index == 0 ||  (index == 1 && href.charAt(0) == '/' ));
	}

	public static String unresolve(URL url) {
		return unresolve(url.toString());
	}

	public static String unresolve(String href) {
		String[] baseVariants = { getBase("/help/topic"), //$NON-NLS-1$
				getBase("/help/nftopic"),  //$NON-NLS-1$
				getBase("/help/ntopic"),  //$NON-NLS-1$
				getBase("/help/rtopic") }; //$NON-NLS-1$
		for (String baseVariant : baseVariants) {
			if (href.startsWith(baseVariant)) {
				return href.substring(baseVariant.length());
			}
		}
		return href;
	}

	private static String getBase(boolean documentOnly) {
		String servlet = documentOnly ? "/help/nftopic" : "/help/topic";//$NON-NLS-1$ //$NON-NLS-2$
		return getBase(servlet);
	}

	private static String getBase(String servlet) {
		return "http://" //$NON-NLS-1$
				+ WebappManager.getHost() + ":" //$NON-NLS-1$
				+ WebappManager.getPort() + servlet;
	}

	/*
	 * Returns the mode of operation.
	 */
	public static int getMode() {
		return getInstance().mode;
	}

	/*
	 * Sets the mode of operation.
	 */
	public static void setMode(int mode) {
		getInstance().mode = mode;
		HelpSystem.setShared(mode == MODE_INFOCENTER);
	}

	/*
	 * Sets the error messenger
	 */
	public static void setDefaultErrorUtil(IErrorUtil em) {
		getInstance().defaultErrorMessenger = em;
	}

	/*
	 * Returns the default error messenger. When no UI is present, all errors
	 * are sent to System.out.
	 */
	public static IErrorUtil getDefaultErrorUtil() {
		return getInstance().defaultErrorMessenger;
	}

	/**
	 * Obtains name of the Eclipse product
	 *
	 * @return String
	 */
	public static String getProductName() {
		IProduct product = Platform.getProduct();
		if (product == null) {
			return ""; //$NON-NLS-1$
		}
		String name = product.getName();
		return name == null ? "" : name; //$NON-NLS-1$
	}

	public static void runLiveHelp(String pluginID, String className, String arg) {
		Bundle bundle = Platform.getBundle(pluginID);
		if (bundle == null) {
			return;
		}

		try {
			Class<?> c = bundle.loadClass(className);
			Object o = c.getDeclaredConstructor().newInstance();
			//Runnable runnable = null;
			if (o instanceof ILiveHelpAction) {
				ILiveHelpAction helpExt = (ILiveHelpAction) o;
				if (arg != null)
					helpExt.setInitializationString(arg);
				Thread runnableLiveHelp = new Thread(helpExt);
				runnableLiveHelp.setDaemon(true);
				runnableLiveHelp.start();
			}
		} catch (ThreadDeath td) {
			throw td;
		} catch (Exception e) {
		}
	}

	/**
	 * Called when index.jsp is opened, check to see if we index.jsp is running outside out server in which
	 * case set the mode to infocenter
	 */
	public static void checkMode() {
		if (!getInstance().webappStarted) {
			setMode(MODE_INFOCENTER);
		}
	}

	/**
	 * Check supplied token against stored token. Clears the stored token if
	 * successful.
	 *
	 * @param helpSessionToken
	 * @return true if match successful
	 */
	public boolean matchOnceLiveHelpToken(String helpSessionToken) {
		/*
		 * @FIXME - should we use a constant time comparison, and store/compare a
		 * cryptographic hash?
		 */
		if (liveHelpToken != null && liveHelpToken.equals(helpSessionToken)) {
			// Enforce one-time use.
			liveHelpToken = null;
			return true;
		} else {
			return false;
		}
	}

	public void setLiveHelpToken(String helpSessionToken) {
		liveHelpToken = helpSessionToken;
	}

}

Back to the top