1 /*******************************************************************************
2  * Copyright (c) 2000, 2018 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  *******************************************************************************/
14 package org.eclipse.ui.internal.ide.dialogs;
15 
16 import java.lang.reflect.InvocationTargetException;
17 
18 import org.eclipse.core.runtime.Platform;
19 import org.eclipse.jface.action.IAction;
20 import org.eclipse.ui.PlatformUI;
21 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
22 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
23 import org.osgi.framework.Bundle;
24 
25 /**
26  * Holds the information for an item appearing in the welcome editor
27  */
28 public class WelcomeItem {
29 	private String text;
30 
31 	private int[][] boldRanges;
32 
33 	private int[][] helpRanges;
34 
35 	private String[] helpIds;
36 
37 	private String[] helpHrefs;
38 
39 	private int[][] actionRanges;
40 
41 	private String[] actionPluginIds;
42 
43 	private String[] actionClasses;
44 
45 	/**
46 	 * Creates a new welcome item
47 	 */
WelcomeItem(String text, int[][] boldRanges, int[][] actionRanges, String[] actionPluginIds, String[] actionClasses, int[][] helpRanges, String[] helpIds, String[] helpHrefs)48 	public WelcomeItem(String text, int[][] boldRanges, int[][] actionRanges,
49 			String[] actionPluginIds, String[] actionClasses,
50 			int[][] helpRanges, String[] helpIds, String[] helpHrefs) {
51 
52 		this.text = text;
53 		this.boldRanges = boldRanges;
54 		this.actionRanges = actionRanges;
55 		this.actionPluginIds = actionPluginIds;
56 		this.actionClasses = actionClasses;
57 		this.helpRanges = helpRanges;
58 		this.helpIds = helpIds;
59 		this.helpHrefs = helpHrefs;
60 	}
61 
62 	/**
63 	 * Returns the action ranges (character locations)
64 	 */
getActionRanges()65 	public int[][] getActionRanges() {
66 		return actionRanges;
67 	}
68 
69 	/**
70 	 * Returns the bold ranges (character locations)
71 	 */
getBoldRanges()72 	public int[][] getBoldRanges() {
73 		return boldRanges;
74 	}
75 
76 	/**
77 	 * Returns the help ranges (character locations)
78 	 */
getHelpRanges()79 	public int[][] getHelpRanges() {
80 		return helpRanges;
81 	}
82 
83 	/**
84 	 * Returns the text to display
85 	 */
getText()86 	public String getText() {
87 		return text;
88 	}
89 
90 	/**
91 	 * Returns true is a link (action or help) is present at the given character location
92 	 */
isLinkAt(int offset)93 	public boolean isLinkAt(int offset) {
94 		// Check if there is a link at the offset
95 		for (int[] helpRange : helpRanges) {
96 			if (offset >= helpRange[0]
97 					&& offset < helpRange[0] + helpRange[1]) {
98 				return true;
99 			}
100 		}
101 
102 		// Check if there is an action link at the offset
103 		for (int[] actionRange : actionRanges) {
104 			if (offset >= actionRange[0]
105 					&& offset < actionRange[0] + actionRange[1]) {
106 				return true;
107 			}
108 		}
109 		return false;
110 	}
111 
112 	/**
113 	 * Logs a error to the workbench log
114 	 */
logActionLinkError(String actionPluginId, String actionClass)115 	public void logActionLinkError(String actionPluginId, String actionClass) {
116 		IDEWorkbenchPlugin
117 				.log(IDEWorkbenchMessages.WelcomeItem_unableToLoadClass + actionPluginId + " " + actionClass); //$NON-NLS-1$
118 	}
119 
120 	/**
121 	 * Open a help topic
122 	 */
openHelpTopic(String topic, String href)123 	private void openHelpTopic(String topic, String href) {
124 		if (href != null) {
125 			PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(href);
126 		} else {
127 			PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(topic);
128 		}
129 	}
130 
131 	/**
132 	 * Run an action
133 	 */
runAction(String pluginId, String className)134 	private void runAction(String pluginId, String className) {
135 		Bundle pluginBundle = Platform.getBundle(pluginId);
136 		if (pluginBundle == null) {
137 			logActionLinkError(pluginId, className);
138 			return;
139 		}
140 		Class<?> actionClass;
141 		IAction action;
142 		try {
143 			actionClass = pluginBundle.loadClass(className);
144 		} catch (ClassNotFoundException e) {
145 			logActionLinkError(pluginId, className);
146 			return;
147 		}
148 		try {
149 			action = (IAction) actionClass.getDeclaredConstructor().newInstance();
150 		} catch (InstantiationException | IllegalAccessException | ClassCastException | IllegalArgumentException
151 				| InvocationTargetException | NoSuchMethodException | SecurityException e) {
152 			logActionLinkError(pluginId, className);
153 			return;
154 		}
155 		action.run();
156 	}
157 
158 	/**
159 	 * Triggers the link at the given offset (if there is one)
160 	 */
triggerLinkAt(int offset)161 	public void triggerLinkAt(int offset) {
162 		// Check if there is a help link at the offset
163 		for (int i = 0; i < helpRanges.length; i++) {
164 			if (offset >= helpRanges[i][0]
165 					&& offset < helpRanges[i][0] + helpRanges[i][1]) {
166 				// trigger the link
167 				openHelpTopic(helpIds[i], helpHrefs[i]);
168 				return;
169 			}
170 		}
171 
172 		// Check if there is an action link at the offset
173 		for (int i = 0; i < actionRanges.length; i++) {
174 			if (offset >= actionRanges[i][0]
175 					&& offset < actionRanges[i][0] + actionRanges[i][1]) {
176 				// trigger the link
177 				runAction(actionPluginIds[i], actionClasses[i]);
178 				return;
179 			}
180 		}
181 	}
182 }
183