| /*************************************************************************************************** |
| * Copyright (c) 2006 IBM Corporation and others. All rights reserved. This program and the |
| * accompanying materials are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: IBM Corporation - initial API and implementation |
| **************************************************************************************************/ |
| |
| package org.eclipse.ui.internal.intro.universal; |
| |
| import java.io.IOException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.core.runtime.FileLocator; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProduct; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Preferences; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.ui.internal.intro.universal.util.ImageUtil; |
| import org.eclipse.ui.intro.IIntroSite; |
| import org.eclipse.ui.intro.config.IntroConfigurer; |
| import org.eclipse.ui.intro.config.IntroElement; |
| import org.osgi.framework.Bundle; |
| |
| /** |
| * This class provides for dynamic configuration of the shared intro |
| * implementation based on the data file associated with the product. |
| * |
| * @since 3.2 |
| */ |
| |
| public class UniversalIntroConfigurer extends IntroConfigurer implements |
| IUniversalIntroConstants { |
| private ArrayList introData = new ArrayList(); |
| |
| public UniversalIntroConfigurer() { |
| loadData(); |
| } |
| |
| public String getVariable(String variableName) { |
| IProduct product = Platform.getProduct(); |
| if (product != null) { |
| // try product property first |
| String value = getProductProperty(product, variableName); |
| if (value != null) { |
| value = resolveVariable(product.getDefiningBundle(), value); |
| return value; |
| } |
| // nothing - try preferences |
| Preferences prefs = UniversalIntroPlugin.getDefault() |
| .getPluginPreferences(); |
| // try to prefix with a preduct id first |
| String key = product.getId() + "_" + variableName; //$NON-NLS-1$ |
| value = prefs.getString(key); |
| if (value.length() == 0) { |
| // try direct variable name |
| key = variableName; |
| value = prefs.getString(key); |
| } |
| if (value.length() > 0) |
| value = resolveVariable(product.getDefiningBundle(), value); |
| else { |
| // pass it to the theme |
| value = getThemeProperty(variableName); |
| } |
| return value; |
| } |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.intro.config.IntroConfigurer#getMixinStyle(java.lang.String) |
| */ |
| public String getMixinStyle(String pageId, String extensionId) { |
| if (introData.size() > 0) { |
| // TODO getting the active product one only |
| // Eventually we should consult the data from all the products |
| IntroData idata = (IntroData) introData.get(0); |
| PageData pdata = idata.getPage(pageId); |
| if (pdata != null) { |
| ExtensionData ed = pdata.findExtension(extensionId, false); |
| if (ed!=null) { |
| int importance = ed.getImportance(); |
| if (importance != ExtensionData.HIDDEN) |
| return ExtensionData.IMPORTANCE_STYLE_TABLE[importance]; |
| } |
| } |
| } |
| return null; |
| } |
| |
| private String resolveVariable(Bundle bundle, String value) { |
| if (value != null) { |
| String path = null; |
| if (value.startsWith("intro:")) { //$NON-NLS-1$ |
| bundle = UniversalIntroPlugin.getDefault().getBundle(); |
| path = value.substring(6); |
| } else if (value.startsWith("product:")) { //$NON-NLS-1$ |
| path = value.substring(8); |
| } else |
| return value; |
| try { |
| URL url = bundle.getEntry(path); |
| if (url != null) { |
| URL localURL = FileLocator.toFileURL(url); |
| return localURL.toString(); |
| } |
| } catch (IOException e) { |
| // just use the value as-is |
| return value; |
| } |
| } |
| return null; |
| } |
| |
| private String getProductProperty(IProduct product, String variableName) { |
| String value = product.getProperty(variableName); |
| if (value == null) { |
| // return default values |
| if (variableName.equals(VAR_INTRO_BACKGROUND_IMAGE)) |
| return "css/graphics/root/welcomebckgrd.jpg"; //$NON-NLS-1$ |
| } |
| return value; |
| } |
| |
| public IntroElement[] getGroupChildren(String pageId, String groupId) { |
| if (pageId.equals(ID_ROOT)) { |
| if (groupId.equals(DIV_PAGE_LINKS)) |
| return getRootPageLinks(false); |
| if (groupId.equals(DIV_ACTION_LINKS)) |
| return getRootPageActionLinks(false); |
| } else if (pageId.equals(ID_STANDBY)) { |
| if (groupId.equals(DIV_PAGE_LINKS)) |
| return getRootPageLinks(true); |
| if (groupId.equals(DIV_ACTION_LINKS)) |
| return getRootPageActionLinks(true); |
| } else { |
| // other pages |
| if (groupId.equals(DIV_PAGE_LINKS)) |
| return getNavLinks(pageId); |
| if (groupId.equals(DIV_LAYOUT_TOP_LEFT) |
| || groupId.equals(DIV_LAYOUT_TOP_RIGHT) |
| || groupId.equals(DIV_LAYOUT_BOTTOM_LEFT) |
| || groupId.equals(DIV_LAYOUT_BOTTOM_RIGHT)) |
| return getContent(pageId, groupId); |
| } |
| return new IntroElement[0]; |
| } |
| |
| public IntroElement[] getLaunchBarShortcuts() { |
| ArrayList links = new ArrayList(); |
| String ids = getVariable(VAR_INTRO_ROOT_PAGES); |
| if (ids != null) { |
| StringTokenizer stok = new StringTokenizer(ids, ","); //$NON-NLS-1$ |
| while (stok.hasMoreTokens()) { |
| String id = stok.nextToken().trim(); |
| IntroElement page = createLaunchBarShortcut(id); |
| if (page != null) |
| links.add(page); |
| } |
| } |
| return (IntroElement[]) links.toArray(new IntroElement[links.size()]); |
| } |
| |
| private IntroElement[] getRootPageLinks(boolean standby) { |
| ArrayList links = new ArrayList(); |
| String ids = getVariable(VAR_INTRO_ROOT_PAGES); |
| if (ids != null) { |
| StringTokenizer stok = new StringTokenizer(ids, ","); //$NON-NLS-1$ |
| while (stok.hasMoreTokens()) { |
| String id = stok.nextToken().trim(); |
| IntroElement page = createRootPageLink(id, standby); |
| if (page != null) |
| links.add(page); |
| } |
| } |
| // add workbench link if so configured by the theme |
| String wb = getVariable(VAR_WORKBENCH_AS_ROOT_LINK); |
| if (wb!=null && wb.equalsIgnoreCase("true")) { //$NON-NLS-1$ |
| IntroElement page = createRootPageLink(ID_WORKBENCH, standby); |
| if (page !=null) |
| links.add(page); |
| } |
| return (IntroElement[]) links.toArray(new IntroElement[links.size()]); |
| } |
| |
| private IntroElement[] getRootPageActionLinks(boolean standby) { |
| String wb = getVariable(VAR_WORKBENCH_AS_ROOT_LINK); |
| // only create the workbench link if |
| // not already configured as a root link |
| if (wb==null || !wb.equalsIgnoreCase("true")) { //$NON-NLS-1$ |
| IntroElement page = createRootPageLink(ID_WORKBENCH, standby); |
| if (page !=null) |
| return new IntroElement[] { page }; |
| } |
| return new IntroElement [0]; |
| } |
| |
| private IntroElement[] getNavLinks(String pageId) { |
| ArrayList links = new ArrayList(); |
| String ids = getVariable(VAR_INTRO_ROOT_PAGES); |
| if (ids != null) { |
| StringTokenizer stok = new StringTokenizer(ids, ","); //$NON-NLS-1$ |
| int [] counter = new int [1]; |
| while (stok.hasMoreTokens()) { |
| String id = stok.nextToken().trim(); |
| IntroElement page = createNavLink(id, pageId, counter); |
| if (page != null) |
| links.add(page); |
| } |
| } |
| return (IntroElement[]) links.toArray(new IntroElement[links.size()]); |
| } |
| |
| private IntroElement createRootPageLink(String id, boolean standby) { |
| |
| if (id.equals(ID_OVERVIEW)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_overview_name, |
| createPageURL(id, standby), |
| id, |
| "overview_img", "$theme$/graphics/root/overview.gif", Messages.SharedIntroConfigurer_overview_alt, //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.SharedIntroConfigurer_overview_tooltip, "left"); //$NON-NLS-1$ |
| if (id.equals(ID_FIRSTSTEPS)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_firststeps_name, |
| createPageURL(id, standby), |
| id, |
| "firststeps_img", "$theme$/graphics/root/firststeps.gif", Messages.SharedIntroConfigurer_firststeps_alt, //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.SharedIntroConfigurer_firststeps_tooltip, "left"); //$NON-NLS-1$ |
| if (id.equals(ID_TUTORIALS)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_tutorials_name, |
| createPageURL(id, standby), |
| id, |
| "tutorials_img", "$theme$/graphics/root/tutorials.gif", Messages.SharedIntroConfigurer_tutorials_alt, //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.SharedIntroConfigurer_tutorials_tooltip, "left"); //$NON-NLS-1$ |
| if (id.equals(ID_SAMPLES)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_samples_name, |
| createPageURL(id, standby), |
| id, |
| "samples_img", "$theme$/graphics/root/samples.gif", Messages.SharedIntroConfigurer_samples_alt, Messages.SharedIntroConfigurer_samples_tooltip, "right"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| if (id.equals(ID_WHATSNEW)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_whatsnew_name, |
| createPageURL(id, standby), |
| id, |
| "whatsnew_img", "$theme$/graphics/root/whatsnew.gif", Messages.SharedIntroConfigurer_whatsnew_alt, //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.SharedIntroConfigurer_whatsnew_tooltip, "right"); //$NON-NLS-1$ |
| if (id.equals(ID_MIGRATE)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_migrate_name, |
| createPageURL(id, standby), |
| id, |
| "migrate_img", "$theme$/graphics/root/migrate.gif", Messages.SharedIntroConfigurer_migrate_alt, Messages.SharedIntroConfigurer_migrate_tooltip, "right"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| if (id.equals(ID_WEBRESOURCES)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_webresources_name, |
| createPageURL(id, standby), |
| id, |
| "webresources_img", "css/graphics/root/webresources.gif", //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.SharedIntroConfigurer_webresources_alt, |
| Messages.SharedIntroConfigurer_webresources_tooltip, |
| "right"); //$NON-NLS-1$ |
| if (id.equals(ID_WORKBENCH)) |
| return createRootLink( |
| Messages.SharedIntroConfigurer_workbench_name, |
| "http://org.eclipse.ui.intro/switchToLaunchBar", //$NON-NLS-1$ |
| id, |
| "workbench_img", "css/graphics/root/workbench.gif", //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.SharedIntroConfigurer_workbench_alt, |
| Messages.SharedIntroConfigurer_workbench_tooltip, |
| "right"); //$NON-NLS-1$ |
| return null; |
| } |
| |
| private IntroElement createNavLink(String id, String pageId, int [] counter) { |
| if (id.equals(ID_OVERVIEW)) |
| return createNavLink(Messages.SharedIntroConfigurer_overview_nav, |
| createPageURL(id, false), id, "left nav_link"+(++counter[0])); //$NON-NLS-1$ |
| if (id.equals(ID_FIRSTSTEPS)) |
| return createNavLink(Messages.SharedIntroConfigurer_firststeps_nav, |
| createPageURL(id, false), id, "left nav_link"+(++counter[0])); //$NON-NLS-1$ |
| if (id.equals(ID_TUTORIALS)) |
| return createNavLink(Messages.SharedIntroConfigurer_tutorials_nav, |
| createPageURL(id, false), id, "left nav_link"+(++counter[0])); //$NON-NLS-1$ |
| if (id.equals(ID_SAMPLES)) |
| return createNavLink(Messages.SharedIntroConfigurer_samples_nav, |
| createPageURL(id, false), id, "right nav_link"+(++counter[0])); //$NON-NLS-1$ |
| if (id.equals(ID_WHATSNEW)) |
| return createNavLink(Messages.SharedIntroConfigurer_whatsnew_nav, |
| createPageURL(id, false), id, "right nav_link"+(++counter[0])); //$NON-NLS-1$ |
| if (id.equals(ID_MIGRATE)) |
| return createNavLink(Messages.SharedIntroConfigurer_migrate_nav, |
| createPageURL(id, false), id, "right nav_link"+(++counter[0])); //$NON-NLS-1$ |
| if (id.equals(ID_WEBRESOURCES)) |
| return createNavLink( |
| Messages.SharedIntroConfigurer_webresources_nav, |
| createPageURL(id, false), id, "right nav_link"+(++counter[0])); //$NON-NLS-1$ |
| return null; |
| } |
| |
| private String createPageURL(String id, boolean standby) { |
| String url = "http://org.eclipse.ui.intro/showPage?id=" + id; //$NON-NLS-1$ |
| if (standby) |
| url += "&standby=false"; //$NON-NLS-1$ |
| return url; |
| } |
| |
| private IntroElement createLaunchBarShortcut(String id) { |
| if (id.equals(ID_OVERVIEW)) |
| return createShortcutLink( |
| getThemeProperty(LAUNCHBAR_OVERVIEW_ICON), Messages.SharedIntroConfigurer_overview_nav, |
| id); |
| if (id.equals(ID_FIRSTSTEPS)) |
| return createShortcutLink( |
| getThemeProperty(LAUNCHBAR_FIRSTSTEPS_ICON), Messages.SharedIntroConfigurer_firststeps_nav, |
| id); |
| if (id.equals(ID_TUTORIALS)) |
| return createShortcutLink( |
| getThemeProperty(LAUNCHBAR_TUTORIALS_ICON), Messages.SharedIntroConfigurer_tutorials_nav, |
| id); |
| if (id.equals(ID_SAMPLES)) |
| return createShortcutLink( |
| getThemeProperty(LAUNCHBAR_SAMPLES_ICON), Messages.SharedIntroConfigurer_samples_nav, |
| id); |
| if (id.equals(ID_WHATSNEW)) |
| return createShortcutLink( |
| getThemeProperty(LAUNCHBAR_WHATSNEW_ICON), Messages.SharedIntroConfigurer_whatsnew_nav, |
| id); |
| if (id.equals(ID_MIGRATE)) |
| return createShortcutLink( |
| getThemeProperty(LAUNCHBAR_MIGRATE_ICON), Messages.SharedIntroConfigurer_migrate_nav, |
| id); |
| if (id.equals(ID_WEBRESOURCES)) |
| return createShortcutLink( |
| getThemeProperty(LAUNCHBAR_WEBRESOURCES_ICON), Messages.SharedIntroConfigurer_webresources_nav, |
| id); |
| return null; |
| } |
| |
| private IntroElement createRootLink(String name, String url, String id, |
| String imgId, String imgSrc, String imgAlt, String imgText, |
| String styleId) { |
| IntroElement element = new IntroElement("link"); //$NON-NLS-1$ |
| element.setAttribute("label", name); //$NON-NLS-1$ |
| element.setAttribute("url", url); //$NON-NLS-1$ |
| element.setAttribute("id", id); //$NON-NLS-1$ |
| element.setAttribute("style-id", styleId);//$NON-NLS-1$ |
| IntroElement img = new IntroElement("img"); //$NON-NLS-1$ |
| img.setAttribute("id", imgId); //$NON-NLS-1$ |
| img.setAttribute("style-id", "content-img"); //$NON-NLS-1$ //$NON-NLS-2$ |
| // img.setAttribute("src", imgSrc); //$NON-NLS-1$ |
| img.setAttribute("alt", imgAlt); //$NON-NLS-1$ |
| IntroElement text = new IntroElement("text"); //$NON-NLS-1$ |
| text.setValue(imgText); |
| element.addChild(img); |
| element.addChild(text); |
| return element; |
| } |
| |
| private IntroElement createNavLink(String label, String url, String id, |
| String styleId) { |
| IntroElement element = new IntroElement("link"); //$NON-NLS-1$ |
| element.setAttribute("label", label); //$NON-NLS-1$ |
| element.setAttribute("url", url); //$NON-NLS-1$ |
| element.setAttribute("id", id); //$NON-NLS-1$ |
| element.setAttribute("style-id", styleId); //$NON-NLS-1$ |
| return element; |
| } |
| |
| private IntroElement createShortcutLink(String icon, String tooltip, |
| String id) { |
| IntroElement element = new IntroElement("shortcut"); //$NON-NLS-1$ |
| element.setAttribute("icon", icon); //$NON-NLS-1$ |
| element.setAttribute("tooltip", tooltip); //$NON-NLS-1$ |
| element.setAttribute("url", createPageURL(id, false)); //$NON-NLS-1$ |
| return element; |
| } |
| |
| private void loadData() { |
| // add intro data for this product first |
| String dataFile = getVariable(VAR_INTRO_DATA); |
| String pid = Platform.getProduct().getId(); |
| if (dataFile != null) |
| introData.add(new IntroData(pid, dataFile, true)); |
| IConfigurationElement[] products = Platform.getExtensionRegistry() |
| .getConfigurationElementsFor( |
| "org.eclipse.core.runtime.products"); //$NON-NLS-1$ |
| for (int i = 0; i < products.length; i++) { |
| IConfigurationElement product = products[i]; |
| IExtension extension = product.getDeclaringExtension(); |
| String uid = extension.getUniqueIdentifier(); |
| // skip this product |
| if (pid.equals(uid)) |
| continue; |
| addIntroDataFor(uid, product); |
| } |
| } |
| |
| private void addIntroDataFor(String pid, IConfigurationElement product) { |
| IConfigurationElement[] children = product.getChildren("property"); //$NON-NLS-1$ |
| for (int i = 0; i < children.length; i++) { |
| IConfigurationElement child = children[i]; |
| String name = child.getAttribute("name"); //$NON-NLS-1$ |
| if (name != null && name.equals(VAR_INTRO_DATA)) { |
| String value = child.getAttribute("value"); //$NON-NLS-1$ |
| String bid = child.getDeclaringExtension() |
| .getNamespaceIdentifier(); |
| Bundle bundle = Platform.getBundle(bid); |
| if (bundle != null) { |
| String dataFile = resolveVariable(bundle, value); |
| introData.add(new IntroData(pid, dataFile, false)); |
| } |
| } |
| } |
| } |
| |
| private IntroElement[] getContent(String pageId, String groupId) { |
| ArrayList result = new ArrayList(); |
| if (introData.size() > 0) { |
| // TODO getting the active product one only |
| // Eventually we should consult the data from all the products |
| IntroData idata = (IntroData) introData.get(0); |
| PageData pdata = idata.getPage(pageId); |
| if (pdata != null) { |
| pdata.addAnchors(result, groupId); |
| } |
| } |
| // Add the fallback anchor |
| IntroElement fallback = new IntroElement("anchor"); //$NON-NLS-1$ |
| fallback.setAttribute("id", DEFAULT_ANCHOR); //$NON-NLS-1$ |
| result.add(fallback); |
| return (IntroElement[]) result.toArray(new IntroElement[result.size()]); |
| } |
| |
| public String resolvePath(String extensionId, String path) { |
| boolean extensionRelativePath = false; |
| IPath ipath = new Path(path); |
| String pageId = ipath.segment(0); |
| String s2 = ipath.segment(1); |
| if (!s2.equals("@")) //$NON-NLS-1$ |
| extensionRelativePath = true; |
| if (introData.size() > 0) { |
| // TODO getting the active product one only |
| // Eventually we should consult the data from all the products |
| IntroData idata = (IntroData) introData.get(0); |
| PageData pdata = idata.getPage(pageId); |
| if (pdata != null) { |
| String resolvedPath = pdata.resolvePath(extensionId); |
| if (extensionRelativePath) { |
| // not done - use the resolved extension path |
| // to complete the source path |
| IPath p2 = new Path(resolvedPath); |
| IPath p1 = ipath.removeFirstSegments(2); |
| // remove the last anchor and append the |
| // relative path from the extension |
| resolvedPath = p2.removeLastSegments(1).append(p1) |
| .toString(); |
| } |
| return resolvedPath; |
| } |
| } else { |
| // use fallback anchor |
| return pageId + DEFAULT_CONTENT_PATH; |
| } |
| return null; |
| } |
| |
| public void init(IIntroSite site, Map themeProperties) { |
| super.init(site, themeProperties); |
| IConfigurationElement element = CustomizeAction.getPageElement(); |
| if (element == null) |
| return; |
| Action customizeAction = new CustomizeAction(site, element); |
| customizeAction.setText(Messages.SharedIntroConfigurer_customize_label); |
| customizeAction |
| .setToolTipText(Messages.SharedIntroConfigurer_customize_text); |
| customizeAction.setImageDescriptor(ImageUtil |
| .createImageDescriptor("full/elcl16/configure.gif")); //$NON-NLS-1$ |
| site.getActionBars().getToolBarManager().appendToGroup(TB_ADDITIONS, |
| customizeAction); |
| } |
| } |