blob: ecf503b23883863b1b2c51de6af9863fb9c0a1a4 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}