1 /*******************************************************************************
2  * Copyright (c) 2000, 2016 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  *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 487943
14  *******************************************************************************/
15 package org.eclipse.pde.internal.ui.wizards.extension;
16 
17 import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
18 
19 import java.io.*;
20 import java.net.URL;
21 import java.util.*;
22 import java.util.regex.Pattern;
23 import java.util.regex.PatternSyntaxException;
24 import org.eclipse.core.resources.IProject;
25 import org.eclipse.core.runtime.*;
26 import org.eclipse.jface.dialogs.Dialog;
27 import org.eclipse.jface.dialogs.IMessageProvider;
28 import org.eclipse.jface.dialogs.MessageDialog;
29 import org.eclipse.jface.internal.text.html.HTMLPrinter;
30 import org.eclipse.jface.preference.JFacePreferences;
31 import org.eclipse.jface.resource.*;
32 import org.eclipse.jface.viewers.*;
33 import org.eclipse.jface.wizard.IWizard;
34 import org.eclipse.jface.wizard.IWizardNode;
35 import org.eclipse.osgi.util.NLS;
36 import org.eclipse.pde.core.plugin.*;
37 import org.eclipse.pde.internal.core.PDECore;
38 import org.eclipse.pde.internal.core.ischema.ISchema;
39 import org.eclipse.pde.internal.core.ischema.ISchemaElement;
40 import org.eclipse.pde.internal.core.schema.*;
41 import org.eclipse.pde.internal.core.text.plugin.PluginExtensionNode;
42 import org.eclipse.pde.internal.core.text.plugin.PluginExtensionPointNode;
43 import org.eclipse.pde.internal.core.util.*;
44 import org.eclipse.pde.internal.ui.*;
45 import org.eclipse.pde.internal.ui.dialogs.PluginSelectionDialog;
46 import org.eclipse.pde.internal.ui.editor.contentassist.XMLInsertionComputer;
47 import org.eclipse.pde.internal.ui.elements.ElementLabelProvider;
48 import org.eclipse.pde.internal.ui.search.ShowDescriptionAction;
49 import org.eclipse.pde.internal.ui.util.SharedLabelProvider;
50 import org.eclipse.pde.internal.ui.util.TextUtil;
51 import org.eclipse.pde.internal.ui.wizards.*;
52 import org.eclipse.pde.internal.ui.wizards.templates.NewExtensionTemplateWizard;
53 import org.eclipse.pde.ui.IBasePluginWizard;
54 import org.eclipse.pde.ui.IExtensionWizard;
55 import org.eclipse.pde.ui.templates.ITemplateSection;
56 import org.eclipse.swt.SWT;
57 import org.eclipse.swt.SWTError;
58 import org.eclipse.swt.browser.Browser;
59 import org.eclipse.swt.custom.*;
60 import org.eclipse.swt.events.KeyEvent;
61 import org.eclipse.swt.events.KeyListener;
62 import org.eclipse.swt.graphics.Color;
63 import org.eclipse.swt.graphics.Image;
64 import org.eclipse.swt.layout.GridData;
65 import org.eclipse.swt.layout.GridLayout;
66 import org.eclipse.swt.widgets.*;
67 import org.eclipse.ui.PlatformUI;
68 
69 public class PointSelectionPage extends BaseWizardSelectionPage {
70 	private TableViewer fPointListViewer;
71 	private TableViewer fTemplateViewer;
72 
73 	private IPluginModelBase fModel;
74 	private Button fFilterCheck;
75 	private IPluginExtensionPoint fCurrentPoint;
76 	private HashSet<?> fAvailableImports;
77 	private IProject fProject;
78 	private Label fTemplateLabel;
79 	private ExtensionTreeSelectionPage fWizardsPage;
80 
81 	private IPluginExtension fNewExtension;
82 	private WizardCollectionElement fTemplateCollection;
83 	private WizardCollectionElement fWizardCollection;
84 	private NewExtensionWizard fWizard;
85 	private Text fFilterText;
86 	private WildcardFilter fWildCardFilter;
87 	private Text fPointDescription;
88 	private Link fDescLink;
89 	private Browser fPointDescBrowser;
90 
91 	class PointFilter extends ViewerFilter {
92 		@Override
select(Viewer viewer, Object parentElement, Object element)93 		public boolean select(Viewer viewer, Object parentElement, Object element) {
94 			if (!fFilterCheck.getSelection())
95 				return true;
96 
97 			IPluginExtensionPoint point = (IPluginExtensionPoint) element;
98 			if (point instanceof PluginExtensionPointNode)
99 				return true;
100 
101 			return fAvailableImports.contains(point.getPluginBase().getId());
102 		}
103 	}
104 
105 	class WildcardFilter extends ViewerFilter {
106 		private String wMatch = "*"; //$NON-NLS-1$
107 
setMatchText(String match)108 		protected void setMatchText(String match) {
109 			if (match.indexOf('*') != 0 & match.indexOf('?') != 0 & match.indexOf('.') != 0) {
110 				match = "*" + match; //$NON-NLS-1$
111 			}
112 			wMatch = match + "*"; //$NON-NLS-1$
113 		}
114 
115 		@Override
select(Viewer viewer, Object parentElement, Object element)116 		public boolean select(Viewer viewer, Object parentElement, Object element) {
117 			String text = ((PointLabelProvider) fPointListViewer.getLabelProvider()).getColumnText(element, 0);
118 			Pattern pattern = null;
119 			try {
120 				pattern = PatternConstructor.createPattern(wMatch, false);
121 			} catch (PatternSyntaxException e) {
122 				return false;
123 			}
124 			return pattern != null && pattern.matcher(text.subSequence(0, text.length())).matches();
125 		}
126 	}
127 
128 	class TemplateContentProvider implements IStructuredContentProvider {
129 		@Override
getElements(Object inputElement)130 		public Object[] getElements(Object inputElement) {
131 			if (inputElement instanceof IPluginExtensionPoint) {
132 				IPluginExtensionPoint point = (IPluginExtensionPoint) inputElement;
133 				String pointID = IdUtil.getFullId(point, fModel);
134 				ArrayList<Object> result = new ArrayList<>();
135 				if (fTemplateCollection.getWizards() != null) {
136 					Object[] wizards = fTemplateCollection.getWizards().getChildren();
137 					for (Object wizardObject : wizards) {
138 						String wizardContributorId = ((WizardElement) wizardObject).getContributingId();
139 						if (wizardContributorId == null || pointID == null)
140 							continue;
141 						if (wizardObject instanceof WizardElement && wizardContributorId.equals(pointID))
142 							result.add(wizardObject);
143 					}
144 					return result.toArray();
145 				}
146 			}
147 			return new Object[0];
148 		}
149 	}
150 
151 	class PointContentProvider implements IStructuredContentProvider {
152 		@Override
getElements(Object parent)153 		public Object[] getElements(Object parent) {
154 			ArrayList<IPluginExtensionPoint> extPoints = new ArrayList<>();
155 			IPluginModelBase[] plugins = PluginRegistry.getActiveModels();
156 			for (IPluginModelBase plugin : plugins) {
157 				IPluginExtensionPoint[] points = plugin.getPluginBase().getExtensionPoints();
158 				String id = plugin.getPluginBase().getId();
159 				if (id.equals(fModel.getPluginBase().getId()))
160 					continue;
161 				Collections.addAll(extPoints, points);
162 			}
163 
164 			IPluginExtensionPoint[] points = fModel.getPluginBase().getExtensionPoints();
165 			Collections.addAll(extPoints, points);
166 
167 			return extPoints.toArray();
168 		}
169 	}
170 
171 	class PointLabelProvider extends LabelProvider implements ITableLabelProvider {
172 		@Override
getText(Object obj)173 		public String getText(Object obj) {
174 			return getColumnText(obj, 0);
175 		}
176 
177 		@Override
getColumnText(Object obj, int index)178 		public String getColumnText(Object obj, int index) {
179 			IPluginExtensionPoint extPoint = (IPluginExtensionPoint) obj;
180 			PDELabelProvider provider = PDEPlugin.getDefault().getLabelProvider();
181 			if (provider.isFullNameModeEnabled())
182 				return provider.getText(extPoint);
183 
184 			return IdUtil.getFullId(extPoint, fModel);
185 		}
186 
187 		@Override
getImage(Object obj)188 		public Image getImage(Object obj) {
189 			return getColumnImage(obj, 0);
190 		}
191 
192 		@Override
getColumnImage(Object obj, int index)193 		public Image getColumnImage(Object obj, int index) {
194 			IPluginExtensionPoint exp = (IPluginExtensionPoint) obj;
195 
196 			if (((TemplateContentProvider) fTemplateViewer.getContentProvider()).getElements(exp).length > 0) {
197 				return PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_NEWEXP_WIZ_TOOL, 0);
198 			}
199 
200 			// If the schema is deprecated add a warning flag
201 			int flags = 0;
202 			SchemaRegistry reg = PDECore.getDefault().getSchemaRegistry();
203 			ISchema schema = reg.getSchema(exp.getFullId());
204 			if (schema != null && schema.isDeperecated()) {
205 				PDEPlugin.getDefault().getLabelProvider();
206 				flags = SharedLabelProvider.F_WARNING;
207 			}
208 
209 			return PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_EXT_POINT_OBJ, flags);
210 		}
211 	}
212 
PointSelectionPage(IProject project, IPluginModelBase model, WizardCollectionElement element, WizardCollectionElement templates, NewExtensionWizard wizard)213 	public PointSelectionPage(IProject project, IPluginModelBase model, WizardCollectionElement element, WizardCollectionElement templates, NewExtensionWizard wizard) {
214 		super("pointSelectionPage", PDEUIMessages.NewExtensionWizard_PointSelectionPage_title); //$NON-NLS-1$
215 		this.fModel = model;
216 		this.fWizardCollection = element;
217 		this.fTemplateCollection = templates;
218 		this.fWizard = wizard;
219 		this.fProject = project;
220 		fWildCardFilter = new WildcardFilter();
221 		fAvailableImports = PluginSelectionDialog.getExistingImports(model, true);
222 		setTitle(PDEUIMessages.NewExtensionWizard_PointSelectionPage_title);
223 		setDescription(PDEUIMessages.NewExtensionWizard_PointSelectionPage_desc);
224 	}
225 
226 	@Override
createControl(Composite parent)227 	public void createControl(Composite parent) {
228 		// tab folder
229 		final CTabFolder tabFolder = new CTabFolder(parent, SWT.FLAT);
230 		CTabItem firstTab = new CTabItem(tabFolder, SWT.NULL);
231 		firstTab.setText(PDEUIMessages.PointSelectionPage_tab1);
232 		CTabItem secondTab = new CTabItem(tabFolder, SWT.NULL);
233 		secondTab.setText(PDEUIMessages.PointSelectionPage_tab2);
234 		secondTab.setControl(createWizardsPage(tabFolder));
235 		tabFolder.addSelectionListener(widgetSelectedAdapter(e -> updateTabSelection(tabFolder.getSelectionIndex())));
236 		// top level group
237 		Composite outerContainer = new Composite(tabFolder, SWT.NONE);
238 		firstTab.setControl(outerContainer);
239 		GridLayout layout = new GridLayout();
240 		outerContainer.setLayout(layout);
241 		GridData gd = new GridData(GridData.FILL_BOTH);
242 		outerContainer.setLayoutData(gd);
243 
244 		Composite pointContainer = new Composite(outerContainer, SWT.NONE);
245 		layout = new GridLayout();
246 		layout.marginHeight = layout.marginWidth = 0;
247 		pointContainer.setLayout(layout);
248 		gd = new GridData(GridData.FILL_BOTH);
249 		pointContainer.setLayoutData(gd);
250 
251 		Composite labelContainer = new Composite(pointContainer, SWT.NONE);
252 		layout = new GridLayout(2, false);
253 		layout.marginHeight = layout.marginWidth = 0;
254 		labelContainer.setLayout(layout);
255 		labelContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
256 
257 		Label filterLabel = new Label(labelContainer, SWT.NONE);
258 		filterLabel.setText(PDEUIMessages.NewExtensionWizard_PointSelectionPage_availExtPoints_label);
259 		gd = new GridData();
260 		gd.verticalAlignment = GridData.CENTER;
261 		filterLabel.setLayoutData(gd);
262 		fFilterText = new Text(labelContainer, SWT.BORDER);
263 		fFilterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
264 		fFilterText.addModifyListener(e -> {
265 			fWildCardFilter.setMatchText(fFilterText.getText());
266 			refreshPointListViewer();
267 		});
268 		fFilterText.addKeyListener(new KeyListener() {
269 			@Override
270 			public void keyPressed(KeyEvent e) {
271 				if (e.keyCode == SWT.ARROW_DOWN)
272 					fPointListViewer.getControl().setFocus();
273 			}
274 
275 			@Override
276 			public void keyReleased(KeyEvent e) {
277 			}
278 		});
279 
280 		fFilterCheck = new Button(outerContainer, SWT.CHECK);
281 		fFilterCheck.setText(PDEUIMessages.NewExtensionWizard_PointSelectionPage_filterCheck);
282 		gd = new GridData(GridData.FILL_HORIZONTAL);
283 		fFilterCheck.setLayoutData(gd);
284 		fFilterCheck.setSelection(true);
285 		fFilterCheck.addSelectionListener(widgetSelectedAdapter(e -> refreshPointListViewer()));
286 
287 		fPointListViewer = new TableViewer(pointContainer, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
288 		fPointListViewer.setContentProvider(new PointContentProvider());
289 		fPointListViewer.setLabelProvider(new PointLabelProvider());
290 		fPointListViewer.addSelectionChangedListener(this);
291 		fPointListViewer.addDoubleClickListener(event -> {
292 			if (canFinish()) {
293 				fWizard.performFinish();
294 				fWizard.getShell().close();
295 				fWizard.dispose();
296 				fWizard.setContainer(null);
297 			}
298 		});
299 		fPointListViewer.addFilter(fWildCardFilter);
300 		fPointListViewer.setComparator(ListUtil.NAME_COMPARATOR);
301 		gd = new GridData(GridData.FILL_BOTH);
302 		gd.heightHint = 150;
303 		fPointListViewer.getTable().setLayoutData(gd);
304 
305 		Composite templateComposite = new Composite(outerContainer, SWT.NONE);
306 		layout = new GridLayout();
307 		layout.marginHeight = 4;
308 		layout.marginWidth = 0;
309 		templateComposite.setLayout(layout);
310 		gd = new GridData(GridData.FILL_HORIZONTAL);
311 		templateComposite.setLayoutData(gd);
312 
313 		fDescLink = new Link(templateComposite, SWT.NONE);
314 		fDescLink.setText(NLS.bind(PDEUIMessages.PointSelectionPage_extPointDesc, "")); //$NON-NLS-1$
315 		fDescLink.addSelectionListener(widgetSelectedAdapter(e -> {
316 			if (fCurrentPoint != null)
317 				new ShowDescriptionAction(fCurrentPoint, true).run();
318 		}));
319 		fDescLink.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
320 
321 		Control c = null;
322 		Composite comp = new Composite(templateComposite, SWT.BORDER);
323 		layout = new GridLayout();
324 		layout.marginHeight = layout.marginWidth = 0;
325 		comp.setLayout(layout);
326 		comp.setLayoutData(new GridData(GridData.FILL_BOTH));
327 		try {
328 			c = fPointDescBrowser = new Browser(comp, SWT.NONE);
329 		} catch (SWTError e) {
330 		}
331 		if (c == null)
332 			c = fPointDescription = new Text(comp, SWT.WRAP | SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY);
333 
334 		setPointDescriptionText(PDEUIMessages.NewExtensionWizard_PointSelectionPage_extPointDescription);
335 		gd = new GridData(GridData.FILL_HORIZONTAL);
336 		gd.heightHint = 80;
337 		c.setLayoutData(gd);
338 
339 		fTemplateLabel = new Label(templateComposite, SWT.NONE | SWT.WRAP);
340 		fTemplateLabel.setText(PDEUIMessages.NewExtensionWizard_PointSelectionPage_contributedTemplates_title);
341 		gd = new GridData(GridData.FILL_HORIZONTAL);
342 		fTemplateLabel.setLayoutData(gd);
343 
344 		SashForm templateSashForm = new SashForm(templateComposite, SWT.HORIZONTAL);
345 		templateSashForm.setLayout(new GridLayout());
346 		gd = new GridData(GridData.FILL_BOTH);
347 		gd.heightHint = 80;
348 		templateSashForm.setLayoutData(gd);
349 
350 		Composite wizardComposite = new Composite(templateSashForm, SWT.NONE);
351 		layout = new GridLayout();
352 		layout.marginHeight = 0;
353 		layout.marginWidth = 0;
354 		wizardComposite.setLayout(layout);
355 		gd = new GridData(GridData.FILL_BOTH | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
356 		wizardComposite.setLayoutData(gd);
357 		fTemplateViewer = new TableViewer(wizardComposite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
358 		fTemplateViewer.setContentProvider(new TemplateContentProvider());
359 		fTemplateViewer.setLabelProvider(ElementLabelProvider.INSTANCE);
360 		fTemplateViewer.setComparator(ListUtil.NAME_COMPARATOR);
361 		fTemplateViewer.addSelectionChangedListener(this);
362 		gd = new GridData(GridData.FILL_BOTH);
363 
364 		fTemplateViewer.getTable().setLayoutData(gd);
365 		TableItem[] selection = fPointListViewer.getTable().getSelection();
366 		if (selection != null && selection.length > 0)
367 			fTemplateViewer.setInput(selection[0]);
368 		fTemplateViewer.addDoubleClickListener(event -> {
369 			if (canFlipToNextPage()) {
370 				advanceToNextPage();
371 			}
372 		});
373 
374 		Composite descriptionComposite = new Composite(templateSashForm, SWT.NONE);
375 		layout = new GridLayout();
376 		layout.marginHeight = 0;
377 		layout.marginWidth = 0;
378 		descriptionComposite.setLayout(layout);
379 		gd = new GridData(GridData.FILL_BOTH | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
380 		descriptionComposite.setLayoutData(gd);
381 		createDescriptionIn(descriptionComposite);
382 
383 		initialize();
384 		setControl(tabFolder);
385 		Dialog.applyDialogFont(outerContainer);
386 		PlatformUI.getWorkbench().getHelpSystem().setHelp(outerContainer.getParent(), IHelpContextIds.ADD_EXTENSIONS_SCHEMA_BASED);
387 	}
388 
refreshPointListViewer()389 	private void refreshPointListViewer() {
390 		Control control = fPointListViewer.getControl();
391 		try {
392 			control.setRedraw(false);
393 			fPointListViewer.refresh();
394 		} finally {
395 			control.setRedraw(true);
396 		}
397 	}
398 
createWizardsPage(Composite parent)399 	private Control createWizardsPage(Composite parent) {
400 		fWizardsPage = new ExtensionTreeSelectionPage(fWizardCollection, null, PDEUIMessages.PointSelectionPage_categories);
401 		fWizardsPage.createControl(parent);
402 		fWizardsPage.setWizard(fWizard);
403 		fWizardsPage.getSelectionProvider().addSelectionChangedListener(this);
404 		fWizardsPage.init(fProject, fModel.getPluginBase());
405 		return fWizardsPage.getControl();
406 	}
407 
advanceToNextPage()408 	public void advanceToNextPage() {
409 		getContainer().showPage(getNextPage());
410 	}
411 
412 	@Override
canFlipToNextPage()413 	public boolean canFlipToNextPage() {
414 		return getNextPage() != null;
415 	}
416 
canFinish()417 	public boolean canFinish() {
418 		if (fTemplateViewer != null) {
419 			IStructuredSelection selection = fTemplateViewer.getStructuredSelection();
420 			if (!selection.isEmpty())
421 				return false;
422 		}
423 		if (fPointListViewer != null) {
424 			IStructuredSelection selection = fPointListViewer.getStructuredSelection();
425 			if (selection.isEmpty() == false)
426 				return true;
427 		}
428 		return false;
429 	}
430 
431 	@Override
dispose()432 	public void dispose() {
433 		fWizardsPage.dispose();
434 		super.dispose();
435 	}
436 
finish()437 	public boolean finish() {
438 		String point = IdUtil.getFullId(fCurrentPoint, fModel);
439 
440 		try {
441 			IPluginExtension extension = fModel.getFactory().createExtension();
442 			// Set the point attribute
443 			// The point value overrides an auto-generated value
444 			extension.setPoint(point);
445 			fModel.getPluginBase().add(extension);
446 
447 			// Recursively auto-insert required child elements and attributes
448 			// respecting multiplicity
449 			ISchemaElement schemaElement = null;
450 			// Get the extension's schema
451 			Object object = extension.getSchema();
452 			if ((object != null) && (object instanceof Schema)) {
453 				Schema schema = (Schema) object;
454 				if (extension instanceof PluginExtensionNode) {
455 					// Get the extension's XML element name
456 					String elementName = ((PluginExtensionNode) extension).getXMLTagName();
457 					// Find the extension's corresponding schema element
458 					schemaElement = schema.findElement(elementName);
459 				}
460 				// If there is an associated schema, do the auto-insert
461 				if (schemaElement != null) {
462 					XMLInsertionComputer.computeInsertion(schemaElement, extension);
463 				}
464 			}
465 
466 			String pluginID = fCurrentPoint.getPluginBase().getId();
467 			if (!(fCurrentPoint instanceof PluginExtensionPointNode) && !fAvailableImports.contains(pluginID) && !(fCurrentPoint.getPluginBase() instanceof IFragment)) {
468 				if (MessageDialog.openQuestion(getShell(), PDEUIMessages.NewExtensionWizard_PointSelectionPage_dependencyTitle, NLS.bind(PDEUIMessages.NewExtensionWizard_PointSelectionPage_dependencyMessage, new String[] {pluginID, fCurrentPoint.getId()}))) {
469 					IPluginImport importNode = fModel.getPluginFactory().createImport();
470 					importNode.setId(pluginID);
471 					fModel.getPluginBase().add(importNode);
472 				}
473 			}
474 		} catch (CoreException e) {
475 			PDEPlugin.logException(e);
476 		}
477 		return true;
478 	}
479 
getNewExtension()480 	public IPluginExtension getNewExtension() {
481 		return fNewExtension;
482 	}
483 
initialize()484 	protected void initialize() {
485 		fPointListViewer.addFilter(new PointFilter());
486 		fPointListViewer.setInput(PDECore.getDefault().getModelManager());
487 		fPointListViewer.getTable().setFocus();
488 	}
489 
490 	@Override
selectionChanged(SelectionChangedEvent event)491 	public void selectionChanged(SelectionChangedEvent event) {
492 		ISelection selection = event.getSelection();
493 		if (selection instanceof IStructuredSelection) {
494 			IStructuredSelection ssel = (IStructuredSelection) selection;
495 			if (!ssel.isEmpty()) {
496 				Object element = ssel.getFirstElement();
497 				if (element instanceof WizardElement)
498 					handleTemplateSelection((WizardElement) element);
499 				else if (element instanceof IPluginExtensionPoint)
500 					handlePointSelection((IPluginExtensionPoint) element);
501 			} else {
502 				setDescription(""); //$NON-NLS-1$
503 				setDescriptionText(""); //$NON-NLS-1$
504 				fTemplateLabel.setText(PDEUIMessages.NewExtensionWizard_PointSelectionPage_contributedTemplates_title);
505 				setPointDescriptionText(PDEUIMessages.PointSelectionPage_noDescAvailable);
506 				fDescLink.setText(NLS.bind(PDEUIMessages.PointSelectionPage_extPointDesc, "")); //$NON-NLS-1$
507 				setSelectedNode(null);
508 				setPageComplete(false);
509 			}
510 			getContainer().updateButtons();
511 		}
512 	}
513 
handleTemplateSelection(WizardElement element)514 	private void handleTemplateSelection(WizardElement element) {
515 		setSelectedNode(createWizardNode(element));
516 		setDescriptionText(element.getDescription());
517 		setDescription(NLS.bind(PDEUIMessages.NewExtensionWizard_PointSelectionPage_templateDescription, element.getLabel()));
518 		setPageComplete(false);
519 	}
520 
handlePointSelection(IPluginExtensionPoint element)521 	private void handlePointSelection(IPluginExtensionPoint element) {
522 		fCurrentPoint = element;
523 		fTemplateViewer.setInput(fCurrentPoint);
524 		fTemplateViewer.setSelection(StructuredSelection.EMPTY);
525 		String fullPointID = IdUtil.getFullId(fCurrentPoint, fModel);
526 
527 		String description = XMLComponentRegistry.Instance().getDescription(fullPointID, XMLComponentRegistry.F_SCHEMA_COMPONENT);
528 		String name = XMLComponentRegistry.Instance().getName(fullPointID, XMLComponentRegistry.F_SCHEMA_COMPONENT);
529 		URL url = null;
530 		if ((description == null) || (name == null)) {
531 			url = SchemaRegistry.getSchemaURL(fCurrentPoint, fModel);
532 		}
533 		if (url != null) {
534 			SchemaAnnotationHandler handler = new SchemaAnnotationHandler();
535 			SchemaUtil.parseURL(url, handler);
536 			description = handler.getDescription();
537 			name = handler.getName();
538 		}
539 		if (description == null) {
540 			setPointDescriptionText(PDEUIMessages.PointSelectionPage_noDescAvailable);
541 		} else {
542 			setPointDescriptionText(description);
543 		}
544 		if (name == null) {
545 			name = fullPointID;
546 		}
547 		// Check if the extension point is deprecated and display a warning
548 		SchemaRegistry reg = PDECore.getDefault().getSchemaRegistry();
549 		ISchema schema = reg.getSchema(fCurrentPoint.getFullId());
550 		if (schema != null && schema.isDeperecated()) {
551 			setMessage(NLS.bind(PDEUIMessages.NewExtensionWizard_PointSelectionPage_pluginDescription_deprecated, name), IMessageProvider.WARNING);
552 		} else {
553 			setMessage(null);
554 			setDescription(NLS.bind(PDEUIMessages.NewExtensionWizard_PointSelectionPage_pluginDescription, name));
555 		}
556 		setDescriptionText(""); //$NON-NLS-1$
557 		fTemplateLabel.setText(NLS.bind(PDEUIMessages.NewExtensionWizard_PointSelectionPage_contributedTemplates_label, name.toLowerCase(Locale.ENGLISH)));
558 		fDescLink.setText(NLS.bind(PDEUIMessages.PointSelectionPage_extPointDesc, name));
559 		setSelectedNode(null);
560 		setPageComplete(true);
561 
562 		XMLComponentRegistry.Instance().putDescription(fullPointID, description, XMLComponentRegistry.F_SCHEMA_COMPONENT);
563 		XMLComponentRegistry.Instance().putName(fullPointID, name, XMLComponentRegistry.F_SCHEMA_COMPONENT);
564 	}
565 
updateTabSelection(int index)566 	private void updateTabSelection(int index) {
567 		if (index == 0) {
568 			// extension point page
569 			IStructuredSelection selection = fTemplateViewer.getStructuredSelection();
570 			if (selection.isEmpty() == false)
571 				selectionChanged(new SelectionChangedEvent(fTemplateViewer, selection));
572 			else
573 				selectionChanged(
574 						new SelectionChangedEvent(fPointListViewer, fPointListViewer.getStructuredSelection()));
575 			fFilterText.setFocus();
576 		} else {
577 			// wizard page
578 			ISelectionProvider provider = fWizardsPage.getSelectionProvider();
579 			selectionChanged(new SelectionChangedEvent(provider, provider.getSelection()));
580 		}
581 	}
582 
583 	@Override
createWizardNode(WizardElement element)584 	protected IWizardNode createWizardNode(WizardElement element) {
585 		return new WizardNode(this, element) {
586 			@Override
587 			public IBasePluginWizard createWizard() throws CoreException {
588 				IExtensionWizard wizard = createWizard(wizardElement);
589 				if (wizard == null)
590 					throw new CoreException(new Status(IStatus.ERROR, wizardElement.getConfigurationElement().getNamespaceIdentifier(), PDEUIMessages.PointSelectionPage_cannotFindTemplate));
591 				wizard.init(fProject, fModel);
592 				return wizard;
593 			}
594 
595 			protected IExtensionWizard createWizard(WizardElement element) throws CoreException {
596 				if (element.isTemplate()) {
597 					IConfigurationElement template = element.getTemplateElement();
598 					if (template == null)
599 						return null;
600 					ITemplateSection section = (ITemplateSection) template.createExecutableExtension("class"); //$NON-NLS-1$
601 					return new NewExtensionTemplateWizard(section);
602 				}
603 				return (IExtensionWizard) element.createExecutableExtension();
604 			}
605 		};
606 	}
607 
608 	public void checkModel() {
609 		IWizardNode node = getSelectedNode();
610 		if (node == null)
611 			return;
612 		IWizard wizard = node.getWizard();
613 		if (wizard instanceof NewExtensionTemplateWizard) {
614 			if (((NewExtensionTemplateWizard) wizard).updatedDependencies()) {
615 				if (MessageDialog.openQuestion(getShell(), PDEUIMessages.PointSelectionPage_newDepFound, PDEUIMessages.PointSelectionPage_newDepMessage)) {
616 					fWizard.getEditor().doSave(new NullProgressMonitor());
617 				}
618 			}
619 		}
620 	}
621 
622 	@Override
623 	public void setVisible(boolean visible) {
624 		if (visible)
625 			fFilterText.setFocus();
626 		super.setVisible(visible);
627 	}
628 
629 	private void setPointDescriptionText(String text) {
630 		if (fPointDescBrowser != null) {
631 			StringBuilder desc = new StringBuilder();
632 
633 			ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
634 			Color fgcolor = colorRegistry.get(JFacePreferences.INFORMATION_FOREGROUND_COLOR);
635 			if (fgcolor == null) {
636 				fgcolor = JFaceColors.getInformationViewerForegroundColor(Display.getDefault());
637 			}
638 			Color bgcolor = colorRegistry.get(JFacePreferences.INFORMATION_BACKGROUND_COLOR);
639 			if (bgcolor == null) {
640 				bgcolor = JFaceColors.getInformationViewerForegroundColor(Display.getDefault());
641 			}
642 
643 			StringBuilder stylesheet = new StringBuilder();
644 			String line;
645 			try (BufferedReader br = new BufferedReader(new InputStreamReader(TextUtil.getJavaDocStyleSheerURL().openStream()))) {
646 				while ((line = br.readLine()) != null) {
647 					stylesheet.append('\n');
648 					stylesheet.append(line);
649 				}
650 			} catch (IOException e) {
651 				// continue, and attempt to render without stylesheet
652 				stylesheet.setLength(0);
653 			}
654 
655 			HTMLPrinter.insertPageProlog(desc, 0, fgcolor.getRGB(), bgcolor.getRGB(),
656 					stylesheet.length() > 0 ? stylesheet.substring(1) : ""); //$NON-NLS-1$
657 			desc.append(text);
658 			HTMLPrinter.addPageEpilog(desc);
659 			fPointDescBrowser.setText(desc.toString());
660 		} else
661 			fPointDescription.setText(PDEHTMLHelper.stripTags(text));
662 	}
663 }
664