1 /*******************************************************************************
2  * Copyright (c) 2006, 2020 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 560168
14  *******************************************************************************/
15 package org.eclipse.help.internal.base.remote;
16 
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.net.URL;
20 
21 import org.eclipse.core.runtime.Platform;
22 import org.eclipse.help.AbstractTocProvider;
23 import org.eclipse.help.ITocContribution;
24 import org.eclipse.help.internal.base.util.ProxyUtil;
25 
26 /*
27  * Provides the TOC data that is located on the remote infocenter, if the system
28  * is configured for remote help. If not, returns no contributions.
29  */
30 public class RemoteTocProvider extends AbstractTocProvider {
31 
32 	private static final String PATH_TOC = "/toc"; //$NON-NLS-1$
33 	private static final String PROTOCOL = "http"; //$NON-NLS-1$
34 	private static final String PARAM_LANG = "lang"; //$NON-NLS-1$
35 	private static final String PROTOCOL_HTTPS = "https"; //$NON-NLS-1$
36 
37 	/*
38 	 * Constructs a new remote toc provider, which listens for remote
39 	 * help preference changes.
40 	 */
RemoteTocProvider()41 	public RemoteTocProvider() {
42 		RemoteHelp.addPreferenceChangeListener(event -> contentChanged());
43 	}
44 
45 	@Override
getTocContributions(String locale)46 	public ITocContribution[] getTocContributions(String locale) {
47 
48 		if (RemoteHelp.isEnabled()) {
49 
50 			InputStream in = null;
51 
52 			/*
53 			 * Loop through remote all the InfoCenters and get their TOCs.
54 			 * Combine the TOCs into an array of ITocContribution[]
55 			 */
56 
57 			PreferenceFileHandler prefHandler = new PreferenceFileHandler();
58 			// myHandler.getHost
59 			RemoteTocParser parser = new RemoteTocParser();
60 
61 			String host[] = prefHandler.getHostEntries();
62 			String port[] = prefHandler.getPortEntries();
63 			String path[] = prefHandler.getPathEntries();
64 			String protocol[] = prefHandler.getProtocolEntries();
65 			String isEnabled[] = prefHandler.isEnabled();
66 
67 			ITocContribution[] currentContributions = new ITocContribution[0];
68 			ITocContribution[] temp = new ITocContribution[0];
69 			ITocContribution[] totalContributions = new ITocContribution[0];
70 
71 			int numICs = host.length;
72 			if (numICs == 0) // No remote InfoCenters in preferences.ini
73 				return new ITocContribution[0];
74 
75 			URL url = null;
76 			String urlStr = ""; //$NON-NLS-1$
77 			for (int i = numICs-1; i >= 0; i--) {
78 				if (isEnabled[i].equalsIgnoreCase("true")) { //$NON-NLS-1$
79 					try {
80 
81 						if(protocol[i].equalsIgnoreCase(PROTOCOL))
82 						{
83 							url = new URL(protocol[i], host[i], Integer.valueOf(port[i]) .intValue(),
84 									path[i] + PATH_TOC + '?' + PARAM_LANG + '=' + locale);
85 
86 							in = ProxyUtil.getStream(url);
87 							urlStr = PROTOCOL + "://"+host[i] + ":" + port[i] + path[i]; //$NON-NLS-1$ //$NON-NLS-2$
88 						}
89 						else
90 						{
91 							in = HttpsUtility.getHttpsInputStream(protocol[i],host[i],port[i],path[i],locale);
92 							urlStr = PROTOCOL_HTTPS + "://"+host[i] + ":" + port[i] + path[i]; //$NON-NLS-1$ //$NON-NLS-2$
93 						}
94 
95 						if (in != null) {
96 							// pass URL to parser
97 							currentContributions = parser.parse(in, urlStr);
98 							/*
99 							 * Save previous contributed tocs to a temp variable
100 							 */
101 							temp = new ITocContribution[totalContributions.length];
102 							System.arraycopy(totalContributions, 0, temp, 0,
103 									totalContributions.length);
104 
105 							/*
106 							 * Combine current contributed tocs and previous
107 							 * contributed
108 							 */
109 
110 							totalContributions = new ITocContribution[temp.length
111 									+ currentContributions.length];
112 							System.arraycopy(temp, 0, totalContributions, 0,
113 									temp.length);
114 
115 							System.arraycopy(currentContributions, 0,
116 									totalContributions, temp.length,
117 									currentContributions.length);
118 						}
119 					} catch (Throwable t) {
120 						String msg = "Internal error while reading TOC contents from remote server"; //$NON-NLS-1$
121 						Platform.getLog(getClass()).error(msg, t);
122 						RemoteHelp.setError(t);
123 					} finally {
124 						if (in != null) {
125 							try {
126 								in.close();
127 								in = null;
128 							} catch (IOException e) {
129 								// nothing more we can do
130 							}
131 						}
132 					}
133 				}
134 			}
135 
136 			return totalContributions;
137 
138 		}
139 		return new ITocContribution[0];
140 	}
141 
142 	@Override
getPriority()143 	public int getPriority() {
144 
145 		int helpOption=PreferenceFileHandler.getEmbeddedHelpOption();
146 
147 		if(helpOption ==PreferenceFileHandler.LOCAL_HELP_ONLY || helpOption==PreferenceFileHandler.LOCAL_HELP_PRIORITY)
148 			return TOC_FILE_PRIORITY+1;
149 		else return DEFAULT_PRIORITY-1;
150 	}
151 }
152