1 /*******************************************************************************
2  * Copyright (c) 2007, 2015 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 
15 package org.eclipse.ui.internal.splash;
16 
17 import java.util.HashMap;
18 import java.util.Map;
19 import org.eclipse.core.runtime.IConfigurationElement;
20 import org.eclipse.core.runtime.IExtension;
21 import org.eclipse.core.runtime.IExtensionPoint;
22 import org.eclipse.core.runtime.IProduct;
23 import org.eclipse.core.runtime.Platform;
24 import org.eclipse.core.runtime.SafeRunner;
25 import org.eclipse.jface.util.SafeRunnable;
26 import org.eclipse.ui.PlatformUI;
27 import org.eclipse.ui.internal.WorkbenchPlugin;
28 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
29 import org.eclipse.ui.splash.AbstractSplashHandler;
30 
31 /**
32  * Simple non-caching access to the splashHandler extension point.
33  *
34  * @since 3.3
35  */
36 public final class SplashHandlerFactory {
37 
38 	/**
39 	 * Find the splash handler for the given product or <code>null</code> if it
40 	 * cannot be found.
41 	 *
42 	 * @param product the product
43 	 * @return the splash or <code>null</code>
44 	 */
findSplashHandlerFor(IProduct product)45 	public static AbstractSplashHandler findSplashHandlerFor(IProduct product) {
46 		if (product == null)
47 			return null;
48 
49 		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID,
50 				IWorkbenchRegistryConstants.PL_SPLASH_HANDLERS);
51 
52 		if (point == null)
53 			return null;
54 
55 		IExtension[] extensions = point.getExtensions();
56 		Map idToSplash = new HashMap(); // String->ConfigurationElement
57 		String[] targetId = new String[1];
58 		for (IExtension extension : extensions) {
59 			IConfigurationElement[] children = extension.getConfigurationElements();
60 			for (IConfigurationElement element : children) {
61 				AbstractSplashHandler handler = processElement(element, idToSplash, targetId, product);
62 				if (handler != null)
63 					return handler;
64 
65 			}
66 		}
67 		return null;
68 	}
69 
70 	/**
71 	 * Process a given element.
72 	 *
73 	 * @param configurationElement the element to process
74 	 * @param idToSplash           the map of current splash elements
75 	 * @param targetId             the target id if known
76 	 * @param product              the product to search for
77 	 * @return a splash matching the target id from this element or
78 	 *         <code>null</code>
79 	 */
processElement(IConfigurationElement configurationElement, Map idToSplash, String[] targetId, IProduct product)80 	private static AbstractSplashHandler processElement(IConfigurationElement configurationElement, Map idToSplash,
81 			String[] targetId, IProduct product) {
82 		String type = configurationElement.getName();
83 		if (IWorkbenchRegistryConstants.TAG_SPLASH_HANDLER.equals(type)) {
84 			String id = configurationElement.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
85 			if (id == null)
86 				return null;
87 
88 			// we know the target and this element is it
89 			if (targetId[0] != null && id.equals(targetId[0])) {
90 				return create(configurationElement);
91 			}
92 			// store for later examination
93 			idToSplash.put(id, configurationElement);
94 
95 		} else if (IWorkbenchRegistryConstants.TAG_SPLASH_HANDLER_PRODUCT_BINDING.equals(type)) {
96 			String productId = configurationElement.getAttribute(IWorkbenchRegistryConstants.ATT_PRODUCTID);
97 			if (product.getId().equals(productId) && targetId[0] == null) { // we
98 				// found the target ID
99 				targetId[0] = configurationElement.getAttribute(IWorkbenchRegistryConstants.ATT_SPLASH_ID);
100 				// check all currently located splashes
101 				IConfigurationElement splashElement = (IConfigurationElement) idToSplash.get(targetId[0]);
102 				if (splashElement != null)
103 					return create(splashElement);
104 			}
105 		}
106 
107 		return null;
108 	}
109 
110 	/**
111 	 * Create the splash implementation.
112 	 *
113 	 * @param splashElement the element to create from
114 	 * @return the element or <code>null</code> if it couldn't be created
115 	 */
create(final IConfigurationElement splashElement)116 	private static AbstractSplashHandler create(final IConfigurationElement splashElement) {
117 		final AbstractSplashHandler[] handler = new AbstractSplashHandler[1];
118 		SafeRunner.run(new SafeRunnable() {
119 
120 			@Override
121 			public void run() throws Exception {
122 				handler[0] = (AbstractSplashHandler) WorkbenchPlugin.createExtension(splashElement,
123 						IWorkbenchRegistryConstants.ATT_CLASS);
124 			}
125 
126 			@Override
127 			public void handleException(Throwable e) {
128 				WorkbenchPlugin.log("Problem creating splash implementation", e); //$NON-NLS-1$
129 			}
130 		});
131 
132 		return handler[0];
133 	}
134 }
135