| /******************************************************************************* |
| * Copyright (c) 2006, 2009 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.Collections; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.core.runtime.FileLocator; |
| 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.help.internal.util.ProductPreferences; |
| import org.eclipse.help.internal.util.SequenceResolver; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.ui.internal.intro.impl.model.ExtensionMap; |
| import org.eclipse.ui.internal.intro.impl.model.IntroTheme; |
| import org.eclipse.ui.internal.intro.universal.contentdetect.ContentDetector; |
| import org.eclipse.ui.internal.intro.universal.util.ImageUtil; |
| import org.eclipse.ui.internal.intro.universal.util.PreferenceArbiter; |
| 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 IntroData primaryIntroData; |
| private IntroData[] secondaryIntroData; |
| private SequenceResolver<IntroElement> sequenceResolver; |
| |
| public UniversalIntroConfigurer() { |
| loadData(); |
| } |
| |
| @Override |
| public String getVariable(String variableName) { |
| if (variableName.equals(HIGH_CONTRAST)) { |
| boolean highContrast = ImageUtil.isHighContrast(); |
| if (highContrast) |
| return variableName; |
| else |
| return ""; //$NON-NLS-1$ |
| } |
| 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; |
| } |
| // if intro description for the page is not defined |
| // return a blank string to prevent the variable |
| // from showing up in the page |
| if (variableName.startsWith(VAR_INTRO_DESCRIPTION_PREFIX)) |
| return ""; //$NON-NLS-1$ |
| // nothing - try preferences |
| // try to prefix with a product id first |
| String key = product.getId() + "_" + variableName; //$NON-NLS-1$ |
| value = Platform.getPreferencesService().getString(UniversalIntroPlugin.PLUGIN_ID, key, "", null); //$NON-NLS-1$ |
| if (value.length() == 0) { |
| // try direct variable name |
| key = variableName; |
| value = Platform.getPreferencesService().getString(UniversalIntroPlugin.PLUGIN_ID, key, "", null); //$NON-NLS-1$ |
| } |
| 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) |
| */ |
| @Override |
| public String getMixinStyle(String pageId, String extensionId) { |
| // if active product has a preference, use it |
| if (primaryIntroData != null) { |
| int importance = getImportance(primaryIntroData, pageId, extensionId); |
| if (importance >= 0) { |
| return ExtensionData.IMPORTANCE_STYLE_TABLE[importance]; |
| } |
| } |
| // else, find the most referenced importance style from other products |
| int[] importanceRefs = new int[ExtensionData.IMPORTANCE_TABLE.length]; |
| for (int i=0;i<secondaryIntroData.length;++i) { |
| IntroData data = secondaryIntroData[i]; |
| int importance = getImportance(data, pageId, extensionId); |
| if (importance >= 0) { |
| ++importanceRefs[importance]; |
| } |
| } |
| int maxIndex = 0; |
| for (int i=1;i<importanceRefs.length;++i) { |
| if (importanceRefs[i] > importanceRefs[maxIndex]) { |
| maxIndex = i; |
| } |
| } |
| if (importanceRefs[maxIndex] > 0) { |
| return ExtensionData.IMPORTANCE_STYLE_TABLE[maxIndex]; |
| } |
| // nobody has a preference |
| return null; |
| } |
| |
| /* |
| * Returns the given extension's importance as specified by the |
| * given intro data. |
| */ |
| private int getImportance(IntroData data, String pageId, String extensionId) { |
| String pluginId = ExtensionMap.getInstance().getPluginId(extensionId); |
| if (ContentDetector.isNew(pluginId)) { |
| updateStartPage(pageId); |
| return ExtensionData.NEW; |
| } |
| PageData pdata = data.getPage(pageId); |
| if (pdata != null) { |
| ExtensionData ed = pdata.findExtension(extensionId, false); |
| if (ed != null) { |
| return ed.getImportance(); |
| } |
| } |
| // none specified |
| return -1; |
| } |
| |
| /* |
| * Modify the start page if this is a root page and it's position |
| * in the root page list is earlier than the current start page |
| */ |
| private void updateStartPage(String pageId) { |
| String currentStartPage = ExtensionMap.getInstance().getStartPage(); |
| 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(); |
| if (id.equals(pageId)) { |
| ExtensionMap.getInstance().setStartPage(pageId); |
| return; |
| } |
| if (id.equals(currentStartPage)) { |
| // The current start page has higher priority than the new page |
| return; |
| } |
| } |
| } |
| } |
| |
| private String resolveVariable(Bundle bundle, String value) { |
| if (value == null) { |
| return null; |
| } |
| if (value.startsWith("intro:")) { //$NON-NLS-1$ |
| bundle = UniversalIntroPlugin.getDefault().getBundle(); |
| return resolveFile(bundle, value.substring(6)); |
| } else if (value.startsWith("product:")) { //$NON-NLS-1$ |
| return resolveFile(bundle, value.substring(8)); |
| } |
| return value; |
| } |
| |
| private String resolveFile(Bundle bundle, String path) { |
| String prefixedPath = getThemePrefixedPath(path); |
| try { |
| URL url = null; |
| if (prefixedPath != null) { |
| url = bundle.getEntry(prefixedPath); |
| } |
| if (url == null) { |
| 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 path; |
| } |
| |
| /** |
| * Prefix the file component of the given path with the theme's id. For |
| * example, with theme <code>org.eclipse.ui.intro.universal.solstice</code>: |
| * <ul> |
| * <li>foo → org.eclipse.ui.intro.universal.solstice/foo |
| * </ul> |
| * |
| * @param path |
| * the path |
| * @return same path with a prefixed theme directory component |
| */ |
| private String getThemePrefixedPath(String path) { |
| String prefix = themeProperties != null ? themeProperties.get(IntroTheme.ATT_ID) : null; |
| prefix = prefix == null ? "" : prefix.trim(); //$NON-NLS-1$ |
| if (prefix.length() == 0) { |
| return null; |
| } |
| return prefix + Path.SEPARATOR + path; |
| } |
| |
| 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; |
| } |
| |
| @Override |
| public IntroElement[] getGroupChildren(String pageId, String groupId) { |
| // root-like pages have more details on the page and action links |
| boolean rootLike = pageId.equals(ID_ROOT) || isStartPage(pageId) || pageId.equals(ID_STANDBY); |
| if (rootLike && groupId.equals(DIV_PAGE_LINKS)) |
| return getRootPageLinks(false); |
| if (rootLike && groupId.equals(DIV_ACTION_LINKS)) |
| return getRootPageActionLinks(false); |
| // 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]; |
| } |
| |
| @Override |
| public IntroElement[] getLaunchBarShortcuts() { |
| ArrayList<IntroElement> 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 links.toArray(new IntroElement[links.size()]); |
| } |
| |
| private IntroElement[] getRootPageLinks(boolean standby) { |
| ArrayList<IntroElement> 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 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<IntroElement> links = new ArrayList<>(); |
| String ids = getVariable(VAR_INTRO_ROOT_PAGES); |
| /* |
| * In high contrast mode the workbench link must be generated in the nav links |
| * otherwise it will not show |
| */ |
| if (ImageUtil.isHighContrast()) { |
| ids = ids + ',' + IUniversalIntroConstants.ID_WORKBENCH; |
| } |
| 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 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$ |
| if (id.equals(ID_WORKBENCH)) |
| return createNavLink( |
| Messages.SharedIntroConfigurer_workbench_name, |
| "http://org.eclipse.ui.intro/switchToLaunchBar", //$NON-NLS-1$ |
| 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$ |
| boolean highContrast = ImageUtil.isHighContrast(); |
| if (highContrast) { |
| String key = HIGH_CONTRAST_PREFIX+id; |
| String value = getVariable(key); |
| if (value!=null) |
| img.setAttribute("src", value); //$NON-NLS-1$ |
| } |
| img.setAttribute("alt", imgAlt); //$NON-NLS-1$ |
| img.setAttribute("title", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| 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$ |
| boolean highContrast = ImageUtil.isHighContrast(); |
| if (highContrast) { |
| IntroElement img = new IntroElement("img"); //$NON-NLS-1$ |
| img.setAttribute("style-id", "content-img"); //$NON-NLS-1$ //$NON-NLS-2$ |
| String key = HIGH_CONTRAST_NAV_PREFIX+id; |
| String value = getVariable(key); |
| if (value!=null) |
| img.setAttribute("src", value); //$NON-NLS-1$ |
| img.setAttribute("alt", label); //$NON-NLS-1$ |
| element.addChild(img); |
| styleId += " "+HIGH_CONTRAST; //$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() { |
| // load the active product's intro data first |
| IProduct product = Platform.getProduct(); |
| if (product != null) { |
| String dataFile = getVariable(VAR_INTRO_DATA); |
| if (dataFile != null) { |
| primaryIntroData = new IntroData(product.getId(), dataFile, true); |
| } |
| } |
| // load all other installed (but not running) products' intro data |
| List<IntroData> result = new ArrayList<>(); |
| Properties[] prefs = ProductPreferences.getProductPreferences(false); |
| for (int i=0;i<prefs.length;++i) { |
| String key = UniversalIntroPlugin.PLUGIN_ID + '/' + VAR_INTRO_DATA; |
| String dataFile = prefs[i].getProperty(key); |
| if (dataFile != null) { |
| String pluginId = ProductPreferences.getPluginId(prefs[i]); |
| Bundle bundle = Platform.getBundle(pluginId); |
| if (bundle != null) { |
| String pid = ProductPreferences.getProductId(prefs[i]); |
| dataFile = resolveVariable(bundle, dataFile); |
| result.add(new IntroData(pid, dataFile, false)); |
| } |
| } |
| } |
| secondaryIntroData = result.toArray(new IntroData[result.size()]); |
| } |
| |
| private IntroElement[] getContent(String pageId, String groupId) { |
| List<IntroElement> result = new ArrayList<>(); |
| if (!ContentDetector.getNewContributors().isEmpty()) { |
| // Add a new content fallback anchor |
| IntroElement fallback = new IntroElement("anchor"); //$NON-NLS-1$ |
| fallback.setAttribute("id", NEW_CONTENT_ANCHOR); //$NON-NLS-1$ |
| result.add(fallback); |
| } |
| List<IntroElement> anchors = getAnchors(pageId, groupId); |
| if (anchors != null) { |
| result.addAll(anchors); |
| } |
| // Add the fallback anchor |
| IntroElement fallback = new IntroElement("anchor"); //$NON-NLS-1$ |
| fallback.setAttribute("id", DEFAULT_ANCHOR); //$NON-NLS-1$ |
| result.add(fallback); |
| return result.toArray(new IntroElement[result.size()]); |
| } |
| |
| private List<IntroElement> getAnchors(String pageId, String groupId) { |
| List<IntroElement> primaryAnchors = null; |
| if (primaryIntroData != null) { |
| primaryAnchors = getAnchors(primaryIntroData, pageId, groupId); |
| } |
| if (primaryAnchors == null) { |
| primaryAnchors = Collections.emptyList(); |
| } |
| List<List<IntroElement>> secondaryAnchorsList = new ArrayList<>(); |
| for (int i=0;i<secondaryIntroData.length;++i) { |
| IntroData idata = secondaryIntroData[i]; |
| List<IntroElement> anchors = getAnchors(idata, pageId, groupId); |
| if (anchors != null) { |
| secondaryAnchorsList.add(anchors); |
| } |
| } |
| |
| List<IntroElement>[] secondaryAnchors = secondaryAnchorsList.toArray(new List[secondaryAnchorsList.size()]); |
| if (sequenceResolver == null) { |
| sequenceResolver = new SequenceResolver<>(); |
| } |
| return sequenceResolver.getSequence(primaryAnchors, secondaryAnchors); |
| } |
| |
| private List<IntroElement> getAnchors(IntroData data, String pageId, String groupId) { |
| PageData pdata = data.getPage(pageId); |
| if (pdata != null) { |
| List<IntroElement> anchors = new ArrayList<>(); |
| pdata.addAnchors(anchors, groupId); |
| return anchors; |
| } |
| return null; |
| } |
| |
| @Override |
| 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 it's "@extension_id" then target that extension instead |
| if (s2.startsWith("@") && s2.length() > 1) { //$NON-NLS-1$ |
| extensionId = s2.substring(1); |
| } |
| if (!s2.equals("@")) { //$NON-NLS-1$ |
| extensionRelativePath = true; |
| } |
| if (!isHidden(extensionId, pageId)) { |
| String resolvedPath = resolveExtensionPath(extensionId, pageId); |
| if (resolvedPath != null) { |
| 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; |
| } |
| return pageId + DEFAULT_CONTENT_PATH; |
| } |
| return null; |
| } |
| |
| private String resolveExtensionPath(String extensionId, String pageId) { |
| // does the active product have a preference? |
| if (primaryIntroData != null) { |
| PageData pdata = primaryIntroData.getPage(pageId); |
| if (pdata != null) { |
| String path = pdata.resolvePath(extensionId); |
| if (path != null) { |
| return path; |
| } |
| } |
| } |
| // if not, do the others have preferences? |
| PreferenceArbiter arbiter = new PreferenceArbiter(); |
| for (int i=0;i<secondaryIntroData.length;++i) { |
| IntroData idata = secondaryIntroData[i]; |
| PageData pdata = idata.getPage(pageId); |
| if (pdata != null) { |
| arbiter.consider(pdata.resolvePath(extensionId)); |
| } |
| } |
| String path = (String)arbiter.getWinner(); |
| if (path != null) { |
| return path; |
| } |
| // there was no clear winner; fall back to the default |
| return resolveDefaultPath(pageId, extensionId); |
| } |
| |
| private String resolveDefaultPath(String pageId, String extensionId) { |
| String pluginId = ExtensionMap.getInstance().getPluginId(extensionId); |
| if (ContentDetector.isNew(pluginId)) { |
| return pageId + IUniversalIntroConstants.NEW_CONTENT_PATH; |
| } |
| // does the active product have a preference? |
| if (primaryIntroData != null) { |
| PageData pdata = primaryIntroData.getPage(pageId); |
| if (pdata != null) { |
| String path = pdata.resolveDefaultPath(); |
| if (path != null) { |
| return path; |
| } |
| } |
| } |
| // if not, do the others have preferences? |
| PreferenceArbiter arbiter = new PreferenceArbiter(); |
| for (int i=0;i<secondaryIntroData.length;++i) { |
| IntroData idata = secondaryIntroData[i]; |
| PageData pdata = idata.getPage(pageId); |
| if (pdata != null) { |
| arbiter.consider(pdata.resolveDefaultPath()); |
| } |
| } |
| return (String)arbiter.getWinner(); |
| } |
| |
| private boolean isHidden(String extensionId, String pageId) { |
| if (primaryIntroData != null) { |
| PageData pdata = primaryIntroData.getPage(pageId); |
| if (pdata != null) { |
| return pdata.isHidden(extensionId); |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public void init(IIntroSite site, Map<String, String> themeProperties) { |
| super.init(site, themeProperties); |
| Action customizeAction = new CustomizeAction(site); |
| 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); |
| } |
| } |