| /******************************************************************************* |
| * Copyright (c) 2004, 2011 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.impl.model; |
| |
| import java.util.List; |
| import java.util.Vector; |
| |
| import org.eclipse.ui.internal.intro.impl.model.url.IntroURLParser; |
| |
| /* |
| * Intro History Model. |
| */ |
| public class History { |
| // History of Intro Pages and real URL visited by Intro Browser. All |
| // elements are all of type HistoryObject. |
| private Vector<HistoryObject> history = new Vector<>(); |
| private int navigationLocation = 0; |
| |
| |
| // Model class for history objects. A history object may be a url or an |
| // Intro page. A url is a regular URL navigated to from a fully qualified |
| // link. An intro page may be an IFrame page. IFrame pages are not created |
| // for every Help topic navigated in an embedded IFrame. Instead the same |
| // IFrame is stored in history as a different object with the IFrameURL set. |
| // This way the model actually creates one page for every embedded Help |
| // Topic target but the navigation history updates the IFrame accordingly. |
| class HistoryObject { |
| AbstractIntroPage page; |
| String iframeUrl; |
| String url; |
| |
| HistoryObject(Object location) { |
| if (location instanceof String) |
| this.url = (String) location; |
| |
| if (location instanceof AbstractIntroPage) { |
| this.page = (AbstractIntroPage) location; |
| // will be set to null if the page is not an IFrame page. |
| this.iframeUrl = this.page.getIFrameURL(); |
| } |
| } |
| |
| /** |
| * returns the history page. If iframe page, updated to correct url. |
| * |
| * @return |
| */ |
| AbstractIntroPage getPage() { |
| if (page.isIFramePage()) |
| // when page was stored, the IFrame url was also stored. Make |
| // sure to return the same state. The page is the same, only the |
| // IFrame url changes. |
| page.setIFrameURL(getIFrameUrl()); |
| return page; |
| } |
| |
| String getPageId() { |
| return page.getId(); |
| } |
| |
| String getIFrameUrl() { |
| return iframeUrl; |
| } |
| |
| String getUrl() { |
| return url; |
| } |
| |
| boolean isURL() { |
| return (url != null) ? true : false; |
| } |
| |
| boolean isIntroPage() { |
| return (page != null) ? true : false; |
| } |
| |
| boolean isIFramePage() { |
| return (iframeUrl != null) ? true : false; |
| } |
| |
| } |
| |
| |
| /** |
| * Updates the UI navigation history with either a real URL, or a page ID. |
| * |
| * @param pageId |
| */ |
| public void updateHistory(String location) { |
| // quick exit. |
| if (!history.isEmpty() && isSameLocation(location)) |
| // resetting the same location is useless. |
| return; |
| doUpdateHistory(location); |
| } |
| |
| /** |
| * Updates the UI navigation history with either a real URL, or a page ID. |
| * |
| * @param page |
| */ |
| public void updateHistory(AbstractIntroPage page) { |
| // quick exit. |
| if (!history.isEmpty() && isSameLocation(page)) |
| // resetting the same location is useless. |
| return; |
| doUpdateHistory(page); |
| } |
| |
| private void doUpdateHistory(Object location) { |
| // we got here due to an intro URL listener or an SWT Form hyperlink |
| // listener. location may be a url or an IntroPage. |
| if (navigationLocation == getHistoryEndPosition()) |
| // we are at the end of the vector, just push. |
| pushToHistory(location); |
| else |
| // we already navigated. add item at current location, and clear |
| // rest of history. (Same as browser behavior.) |
| trimHistory(location); |
| } |
| |
| |
| private boolean isSameLocation(Object location) { |
| HistoryObject currentLocation = getCurrentLocation(); |
| if (location instanceof String && currentLocation.isURL()) |
| return currentLocation.getUrl().equals(location); |
| |
| if (location instanceof AbstractIntroPage |
| && currentLocation.isIntroPage()) { |
| |
| AbstractIntroPage locationPage = (AbstractIntroPage) location; |
| // be carefull here with calling getPage on historyOvject. |
| if (!currentLocation.getPageId().equals(locationPage.getId())) |
| return false; |
| |
| // both pages have same ids, they are either both regular pages or |
| // both are Iframe pages. check if they have the same IFrame urls |
| if (currentLocation.isIFramePage() && locationPage.isIFramePage()) |
| return currentLocation.getIFrameUrl().equals( |
| locationPage.getIFrameURL()); |
| |
| // both pages are not IFrame pages, and they have same id. |
| return true; |
| } |
| |
| return false; |
| } |
| |
| |
| |
| |
| private void pushToHistory(Object location) { |
| history.add(new HistoryObject(location)); |
| // point the nav location to the end of the vector. |
| navigationLocation = getHistoryEndPosition(); |
| } |
| |
| public void removeLastHistory() { |
| history.remove(getHistoryEndPosition()); |
| // point the nav location to the end of the vector. |
| navigationLocation = getHistoryEndPosition(); |
| } |
| |
| private void trimHistory(Object location) { |
| List<HistoryObject> newHistory = history.subList(0, navigationLocation + 1); |
| history = new Vector<>(newHistory); |
| history.add(new HistoryObject(location)); |
| // point the nav location to the end of the vector. |
| navigationLocation = getHistoryEndPosition(); |
| } |
| |
| /** |
| * Return the position of the last element in the navigation history. If |
| * vector is empty, return 0. |
| * |
| * @param vector |
| * @return |
| */ |
| private int getHistoryEndPosition() { |
| if (history.isEmpty()) |
| return 0; |
| return history.size() - 1; |
| } |
| |
| public void navigateHistoryBackward() { |
| if (badNavigationLocation(navigationLocation - 1)) |
| // do nothing. We are at the begining. |
| return; |
| --navigationLocation; |
| } |
| |
| /** |
| * Navigate forward in the history. |
| * |
| * @return |
| */ |
| public void navigateHistoryForward() { |
| if (badNavigationLocation(navigationLocation + 1)) |
| // do nothing. We are at the begining. |
| return; |
| ++navigationLocation; |
| } |
| |
| |
| private boolean badNavigationLocation(int navigationLocation) { |
| if (navigationLocation < 0 || navigationLocation >= history.size()) |
| // bad nav location. |
| return true; |
| return false; |
| } |
| |
| |
| /** |
| * Returns true if the current location in the navigation history represents |
| * a URL. False if the location is an Intro Page id. |
| * |
| * @return Returns the locationIsURL. |
| */ |
| private HistoryObject getCurrentLocation() { |
| return (HistoryObject) history.elementAt(navigationLocation); |
| } |
| |
| public boolean canNavigateForward() { |
| return navigationLocation != getHistoryEndPosition() ? true : false; |
| } |
| |
| public boolean canNavigateBackward() { |
| return navigationLocation == 0 ? false : true; |
| } |
| |
| public boolean currentLocationIsUrl() { |
| if (history.size() == 0) { |
| return false; |
| } |
| return getCurrentLocation().isURL(); |
| } |
| |
| public String getCurrentLocationAsUrl() { |
| return getCurrentLocation().getUrl(); |
| } |
| |
| public AbstractIntroPage getCurrentLocationAsPage() { |
| return getCurrentLocation().getPage(); |
| } |
| |
| public static boolean isURL(String aString) { |
| IntroURLParser parser = new IntroURLParser(aString); |
| if (parser.hasProtocol()) |
| return true; |
| return false; |
| } |
| |
| |
| public void clear() { |
| history.clear(); |
| navigationLocation = 0; |
| } |
| |
| |
| |
| |
| } |