summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Drossel2008-08-05 12:21:11 (EDT)
committerCarsten Drossel2008-08-05 12:21:11 (EDT)
commit02104215d9560895ff62a86144086b0d595fb6a5 (patch)
treef69362119a89e9db3509a4d901aa693cd0adc266
parent9cea29e1145a31777ebff14b7cc75352617d594c (diff)
downloadorg.eclipse.riena-02104215d9560895ff62a86144086b0d595fb6a5.zip
org.eclipse.riena-02104215d9560895ff62a86144086b0d595fb6a5.tar.gz
org.eclipse.riena-02104215d9560895ff62a86144086b0d595fb6a5.tar.bz2
applying patch for bugzilla entry 243173 - add navigation history and related stuff
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IApplicationModel.java4
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistory.java32
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryEvent.java22
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListener.java31
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListernable.java35
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationNode.java7
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationProcessor.java9
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IPresentationProviderService.java5
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/ApplicationModel.java35
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationHistoryEvent.java46
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNode.java35
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNodeId.java10
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationProcessor.java231
-rw-r--r--org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/PresentationProviderService.java7
14 files changed, 477 insertions, 32 deletions
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IApplicationModel.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IApplicationModel.java
index 83e0181..467b4d7 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IApplicationModel.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IApplicationModel.java
@@ -17,6 +17,6 @@ import org.eclipse.riena.navigation.listener.INavigationNodeListenerable;
* Describes the riena mode of an application consisting of sub applications
*/
public interface IApplicationModel extends INavigationNode<ISubApplicationNode>,
- INavigationNodeListenerable<IApplicationModel, ISubApplicationNode, IApplicationModelListener> {
-
+ INavigationNodeListenerable<IApplicationModel, ISubApplicationNode, IApplicationModelListener>,
+ INavigationHistoryListernable {
}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistory.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistory.java
new file mode 100644
index 0000000..a8dc036
--- /dev/null
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistory.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2007 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.riena.navigation;
+
+/**
+ * Gives access to the navigation history.
+ */
+public interface INavigationHistory {
+
+ /**
+ * Navigates one step back in the navigation history
+ *
+ * @see org.eclipse.riena.navigation.INavigationNode#navigateHistoryBack()
+ */
+ public void historyBack();
+
+ /**
+ * Navigates one step forward in the navigation history
+ *
+ * @see org.eclipse.riena.navigation.INavigationNode#navigateHistoryBack()
+ */
+ public void historyForward();
+
+}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryEvent.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryEvent.java
new file mode 100644
index 0000000..a43311b
--- /dev/null
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryEvent.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.riena.navigation;
+
+import java.util.List;
+
+/**
+ * This event is fired, when the navigation history is changed.
+ */
+public interface INavigationHistoryEvent {
+ int getHistorySize();
+
+ List<INavigationNode<?>> getHistoryNodes();
+}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListener.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListener.java
new file mode 100644
index 0000000..bf60ec9
--- /dev/null
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListener.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.riena.navigation;
+
+/**
+ * Defines the API for a NavigationHistoryListener. Every time when the
+ * navigation history changes, the matching listener method is called.
+ */
+public interface INavigationHistoryListener {
+ /**
+ * This method is called, when the backward history is changed.
+ *
+ * @param event
+ */
+ void backHistoryChanged(INavigationHistoryEvent event);
+
+ /**
+ * This method is called, when the forward history is changed.
+ *
+ * @param event
+ */
+ void forwardHistoryChanged(INavigationHistoryEvent event);
+}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListernable.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListernable.java
new file mode 100644
index 0000000..b92fa5a
--- /dev/null
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationHistoryListernable.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.riena.navigation;
+
+/**
+ * Describes the ability of registering a NavigationHistoryListener.
+ */
+public interface INavigationHistoryListernable {
+
+ void addNavigationHistoryListener(INavigationHistoryListener pListener);
+
+ void removeNavigationHistoryListener(INavigationHistoryListener pListener);
+
+ /**
+ * Answer the current size of the next navigation history
+ *
+ * @return the amount of navigation nodes on the navigation stack
+ */
+ public int getHistoryBackSize();
+
+ /**
+ * Answer the current size of the forward navigation history
+ *
+ * @return the amount of navigation nodes on the navigation stack
+ */
+ public int getHistoryForwardSize();
+}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationNode.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationNode.java
index e66b8f0..82cb421 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationNode.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationNode.java
@@ -23,7 +23,8 @@ import org.eclipse.riena.navigation.common.ITypecastingAdaptable;
* The children ability and parent ability is not included because it is
* different for different model nodes
*/
-public interface INavigationNode<C extends INavigationNode<?>> extends ITypecastingAdaptable, IMarkable {
+public interface INavigationNode<C extends INavigationNode<?>> extends ITypecastingAdaptable, IMarkable,
+ INavigationHistory {
/**
* The states of the navigation node.
@@ -422,4 +423,8 @@ public interface INavigationNode<C extends INavigationNode<?>> extends ITypecast
*/
void navigate(INavigationNodeId targetId, Object argument, INavigationArgumentListener argumentListener);
+ /**
+ * Navigates back to the caller of a navigation.
+ */
+ void navigateBack();
}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationProcessor.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationProcessor.java
index 559fdbc..6b8329f 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationProcessor.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/INavigationProcessor.java
@@ -17,7 +17,7 @@ package org.eclipse.riena.navigation;
* be active at the same time -> the default navigation processor allows only
* one node of each type
*/
-public interface INavigationProcessor {
+public interface INavigationProcessor extends INavigationHistory, INavigationHistoryListernable {
void activate(INavigationNode<?> toActivate);
@@ -28,4 +28,11 @@ public interface INavigationProcessor {
void navigate(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
INavigationArgumentListener argumentListener);
+ /**
+ * Navigates to the caller (the source node) of the given targetNode.
+ *
+ * @param targetNode
+ * The node where we have navigate to and return from
+ */
+ void navigateBack(INavigationNode<?> targetNode);
}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IPresentationProviderService.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IPresentationProviderService.java
index 0d824b2..25701c1 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IPresentationProviderService.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/IPresentationProviderService.java
@@ -23,14 +23,15 @@ import org.eclipse.riena.ui.ridgets.viewcontroller.IViewController;
public interface IPresentationProviderService {
/**
- * Returns a navigationNode identified by the given navigationNodeId
+ * Returns a navigationNode identified by the given navigationNodeId. The
+ * node is lazy created if it not yet exists.
*
* @param sourceNode
* @param targetId
* @return
*/
- INavigationNode<?> createNode(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
+ INavigationNode<?> provideNode(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
INavigationArgumentListener argumentListener);
/**
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/ApplicationModel.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/ApplicationModel.java
index af82b13..2ddf30e 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/ApplicationModel.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/ApplicationModel.java
@@ -11,6 +11,7 @@
package org.eclipse.riena.navigation.model;
import org.eclipse.riena.navigation.IApplicationModel;
+import org.eclipse.riena.navigation.INavigationHistoryListener;
import org.eclipse.riena.navigation.ISubApplicationNode;
import org.eclipse.riena.navigation.listener.IApplicationModelListener;
@@ -53,8 +54,42 @@ public class ApplicationModel extends NavigationNode<IApplicationModel, ISubAppl
initializeNavigationProcessor();
}
+ /**
+ *
+ */
protected void initializeNavigationProcessor() {
setNavigationProcessor(new NavigationProcessor());
}
+ /**
+ * @see org.eclipse.riena.navigation.INavigationHistoryListernable#
+ * addNavigationHistoryListener
+ * (org.eclipse.riena.navigation.INavigationHistoryListener)
+ */
+ public void addNavigationHistoryListener(INavigationHistoryListener listener) {
+ getNavigationProcessor().addNavigationHistoryListener(listener);
+ }
+
+ /**
+ * @see org.eclipse.riena.navigation.INavigationHistoryListernable#
+ * removeNavigationHistoryListener
+ * (org.eclipse.riena.navigation.INavigationHistoryListener)
+ */
+ public void removeNavigationHistoryListener(INavigationHistoryListener listener) {
+ getNavigationProcessor().removeNavigationHistoryListener(listener);
+ }
+
+ /**
+ * @see org.eclipse.riena.navigation.INavigationHistoryListernable#getHistoryBackSize()
+ */
+ public int getHistoryBackSize() {
+ return getNavigationProcessor().getHistoryBackSize();
+ }
+
+ /**
+ * @see org.eclipse.riena.navigation.INavigationHistoryListernable#getHistoryForwardSize()
+ */
+ public int getHistoryForwardSize() {
+ return getNavigationProcessor().getHistoryForwardSize();
+ }
}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationHistoryEvent.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationHistoryEvent.java
new file mode 100644
index 0000000..9f41c9a
--- /dev/null
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationHistoryEvent.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.riena.navigation.model;
+
+import java.util.List;
+
+import org.eclipse.riena.navigation.INavigationHistoryEvent;
+import org.eclipse.riena.navigation.INavigationNode;
+
+/**
+ * This event is fired in case of a change in the navigation history. The event
+ * is fired independently for the backward and forward history.
+ */
+public class NavigationHistoryEvent implements INavigationHistoryEvent {
+
+ List<INavigationNode<?>> historyNodes = null;
+
+ public NavigationHistoryEvent(List<INavigationNode<?>> list) {
+ historyNodes = list;
+ }
+
+ /**
+ * @see
+ * org.eclipse.riena.navigation.INavigationHistoryEvent#getHistoryNodes()
+ */
+ public List<INavigationNode<?>> getHistoryNodes() {
+ return historyNodes;
+ }
+
+ /**
+ * @see
+ * org.eclipse.riena.navigation.INavigationHistoryEvent#getHistorySize()
+ */
+ public int getHistorySize() {
+ return historyNodes.size();
+ }
+
+}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNode.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNode.java
index fda6954..9ce8e87 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNode.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNode.java
@@ -318,15 +318,17 @@ public abstract class NavigationNode<S extends INavigationNode<C>, C extends INa
}
- /* (non-Javadoc)
- * @see org.eclipse.riena.navigation.INavigationNode#addSimpleListener(org.eclipse.riena.navigation.model.ISimpleNavigationNodeListener)
+ /**
+ * @see org.eclipse.riena.navigation.INavigationNode#addSimpleListener(org.eclipse
+ * .riena.navigation.model.ISimpleNavigationNodeListener)
*/
public void addSimpleListener(ISimpleNavigationNodeListener simpleListener) {
simpleListeners.add(simpleListener);
}
- /* (non-Javadoc)
- * @see org.eclipse.riena.navigation.INavigationNode#removeSimpleListener(org.eclipse.riena.navigation.model.ISimpleNavigationNodeListener)
+ /**
+ * @see org.eclipse.riena.navigation.INavigationNode#removeSimpleListener(org
+ * .eclipse.riena.navigation.model.ISimpleNavigationNodeListener)
*/
public void removeSimpleListener(ISimpleNavigationNodeListener simpleListener) {
simpleListeners.remove(simpleListener);
@@ -891,6 +893,30 @@ public abstract class NavigationNode<S extends INavigationNode<C>, C extends INa
}
/**
+ * Navigates to the caller (the source node) of the given targetNode.
+ *
+ * @param targetNode
+ * The node where we have navigate to and return from
+ */
+ public void navigateBack() {
+ getNavigationProcessor().navigateBack(this);
+ }
+
+ /**
+ * @see org.eclipse.riena.navigation.INavigationHistory#historyBack()
+ */
+ public void historyBack() {
+ getNavigationProcessor().historyBack();
+ }
+
+ /**
+ * @see org.eclipse.riena.navigation.INavigationHistory#historyPrev()
+ */
+ public void historyForward() {
+ getNavigationProcessor().historyForward();
+ }
+
+ /**
* @see org.eclipse.riena.navigation.INavigationNode#getPresentationId()
*/
public INavigationNodeId getPresentationId() {
@@ -901,5 +927,4 @@ public abstract class NavigationNode<S extends INavigationNode<C>, C extends INa
// TODO set via constructor, remove setter
this.presentationId = presentationId;
}
-
}
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNodeId.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNodeId.java
index 24a815d..aa4980d 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNodeId.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationNodeId.java
@@ -19,6 +19,7 @@ public class NavigationNodeId implements INavigationNodeId {
private String instanceId;
private String typeId;
+ int hash = 0;
public NavigationNodeId(String typeId, String instanceId) {
this.typeId = typeId;
@@ -72,10 +73,13 @@ public class NavigationNodeId implements INavigationNodeId {
*/
@Override
public int hashCode() {
- if (typeId != null) {
- return typeId.hashCode();
+ if (hash == 0) {
+ if (typeId != null)
+ hash += typeId.hashCode();
+ if (instanceId != null)
+ hash += instanceId.hashCode();
}
- return 0;
+ return hash;
}
private boolean equals(String string1, String string2) {
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationProcessor.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationProcessor.java
index f16b599..0221a3a 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationProcessor.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/NavigationProcessor.java
@@ -6,19 +6,27 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * compeople AG - initial API and implementation
+ * compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.navigation.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.EmptyStackException;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.Vector;
import org.eclipse.riena.navigation.IModuleNode;
import org.eclipse.riena.navigation.INavigationArgumentListener;
import org.eclipse.riena.navigation.INavigationContext;
+import org.eclipse.riena.navigation.INavigationHistory;
+import org.eclipse.riena.navigation.INavigationHistoryEvent;
+import org.eclipse.riena.navigation.INavigationHistoryListener;
import org.eclipse.riena.navigation.INavigationNode;
import org.eclipse.riena.navigation.INavigationNodeId;
import org.eclipse.riena.navigation.INavigationProcessor;
@@ -28,7 +36,14 @@ import org.eclipse.riena.navigation.ISubModuleNode;
/**
* Default implementation for the navigation processor
*/
-public class NavigationProcessor implements INavigationProcessor {
+public class NavigationProcessor implements INavigationProcessor, INavigationHistory {
+ // private static Logger LOGGER =
+ // Activator.getDefault().getLogger(NavigationProcessor.class.getName());
+ private static int MAX_STACKSIZE = 20;
+ private Stack<INavigationNode<?>> histBack = new Stack<INavigationNode<?>>();
+ private Stack<INavigationNode<?>> histForward = new Stack<INavigationNode<?>>();
+ private Map<INavigationNode<?>, INavigationNode<?>> navigationMap = new HashMap<INavigationNode<?>, INavigationNode<?>>();
+ private List<INavigationHistoryListener> navigationListener = new Vector<INavigationHistoryListener>();
/**
* @see org.eclipse.riena.navigation.INavigationProcessor#activate(org.eclipse.riena.navigation.INavigationNode)
@@ -40,26 +55,53 @@ public class NavigationProcessor implements INavigationProcessor {
// if toActivate is module, module group or sub application
// the same sub module will be activated on activation of
// the toActivate, in any case there is nothing to do
+ buildHistory(toActivate);
} else {
// 1.find the chain to activate
// 2.find the chain to deactivate
// 3.check the deactivation chain
// 4.check the activation chain
// 5. do the deactivation chain
- // 6. do the activation chain
+ // 6. hande node on the histBack
+ // 7. do the activation chain
List<INavigationNode<?>> toActivateList = getNodesToActivateOnActivation(toActivate);
List<INavigationNode<?>> toDeactivateList = getNodesToDeactivateOnActivation(toActivate);
INavigationContext navigationContext = new NavigationContext(toActivateList, toDeactivateList);
if (allowsDeactivate(navigationContext)) {
if (allowsActivate(navigationContext)) {
deactivate(navigationContext);
+ buildHistory(toActivate);
activate(navigationContext);
}
}
-
}
}
+ }
+ /**
+ * Remembers the node to push onto the navigation history stack. A maximum
+ * of MAX_STACKSIZE elements are stored. Older elements are removed from the
+ * stack.
+ *
+ * @param toActivate
+ */
+ private void buildHistory(INavigationNode<?> toActivate) {
+ // filter out unnavigatable nodes
+ if (!(toActivate instanceof ISubModuleNode) || toActivate.isDisposed())
+ return;
+ if (histBack.isEmpty() || !histBack.peek().equals(toActivate)) {
+ histBack.push(toActivate);
+ // limit the stack size and remove older elements
+ if (histBack.size() > MAX_STACKSIZE)
+ histBack.remove(histBack.firstElement());
+ fireBackHistoryChangedEvent();
+ }
+ // is forewarding history top stack element equals node toActivate,
+ // remove it!
+ if (!histForward.isEmpty() && histForward.peek().equals(toActivate)) {
+ histForward.pop();// remove newest node
+ fireForewardHistoryChangedEvent();
+ }
}
/**
@@ -98,10 +140,34 @@ public class NavigationProcessor implements INavigationProcessor {
}
}
}
+ cleanupHistory(nodeToDispose);
}
-
}
+ }
+ /**
+ * Cleanup the History stacks and removes all occurences of the node.
+ *
+ * @param toDispose
+ */
+ private void cleanupHistory(INavigationNode<?> toDispose) {
+ boolean bhc = false;
+ while (histBack.contains(toDispose)) {
+ histBack.remove(toDispose);
+ bhc = true;
+ }
+ if (bhc)
+ fireBackHistoryChangedEvent();
+ boolean fhc = false;
+ while (histForward.contains(toDispose)) {
+ histForward.remove(toDispose);
+ fhc = true;
+ }
+ if (fhc)
+ fireForewardHistoryChangedEvent();
+ if (navigationMap.containsKey(toDispose)) {
+ navigationMap.remove(toDispose);
+ }
}
/**
@@ -109,7 +175,7 @@ public class NavigationProcessor implements INavigationProcessor {
* org.eclipse.riena.navigation.INavigationNodeId)
*/
public void create(INavigationNode<?> sourceNode, INavigationNodeId targetId) {
- createTarget(sourceNode, targetId, null, null);
+ provideNode(sourceNode, targetId, null, null);
}
/**
@@ -119,24 +185,21 @@ public class NavigationProcessor implements INavigationProcessor {
*/
public void navigate(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
INavigationArgumentListener argumentListener) {
-
- INavigationNode<?> targetNode = createTarget(sourceNode, targetId, argument, argumentListener);
-
+ INavigationNode<?> targetNode = provideNode(sourceNode, targetId, argument, argumentListener);
+ navigationMap.put(targetNode, sourceNode);
targetNode.activate();
}
- private INavigationNode<?> createTarget(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
+ private INavigationNode<?> provideNode(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
INavigationArgumentListener argumentListener) {
- INavigationNode<?> targetNode = getPresentationDefinitionService().createNode(sourceNode, targetId, argument,
+ INavigationNode<?> targetNode = getPresentationDefinitionService().provideNode(sourceNode, targetId, argument,
argumentListener);
return targetNode;
}
protected IPresentationProviderService getPresentationDefinitionService() {
-
// TODO: handling if no service found ???
return PresentationProviderServiceAccessor.current().getPresentationProviderService();
-
}
/**
@@ -424,6 +487,8 @@ public class NavigationProcessor implements INavigationProcessor {
}
for (INavigationNode<?> nextToDispose : context.getToDeactivate()) {
nextToDispose.onAfterDispose(context);
+ // clean up history stacks
+ cleanupHistory(nextToDispose);
}
}
@@ -627,4 +692,142 @@ public class NavigationProcessor implements INavigationProcessor {
return listReverse;
}
-}
+
+ /**
+ * Navigates one step back in the navigation history
+ *
+ * @see org.eclipse.riena.navigation.INavigationNode#navigateHistoryBack()
+ */
+ public void historyBack() {
+ try {
+ if (getHistoryBackSize() == 0)
+ return;
+ INavigationNode<?> current = histBack.pop();// skip self
+ fireBackHistoryChangedEvent();
+ histForward.push(current);
+ if (histForward.size() > MAX_STACKSIZE)
+ histForward.remove(histForward.firstElement());
+ fireForewardHistoryChangedEvent();
+ INavigationNode<?> node = histBack.peek();// activate parent
+ if (node != null) {
+ activate(node);
+ }
+ } catch (EmptyStackException ex) {
+ // should we throw exception here?
+ }
+ }
+
+ /**
+ * Fires a INavigationHistoryEvent when the backward history changes.
+ */
+ private void fireBackHistoryChangedEvent() {
+ // if (LOGGER.isLoggable(LogService.LOG_DEBUG))
+ // LOGGER.log(LogService.LOG_DEBUG, "BACK " + histBack.size() + "," + histBack);//$NON-NLS-1$ //$NON-NLS-2$
+ if (navigationListener.size() == 0)
+ return;
+ INavigationHistoryEvent event = new NavigationHistoryEvent(histBack.subList(0, histBack.size() - 1));
+ for (INavigationHistoryListener listener : navigationListener) {
+ listener.backHistoryChanged(event);
+ }
+ }
+
+ /**
+ * Navigates one step forward in the navigation history
+ *
+ * @see org.eclipse.riena.navigation.INavigationNode#navigateHistoryBack()
+ */
+ public void historyForward() {
+ try {
+ INavigationNode<?> current = histForward.pop();
+ fireForewardHistoryChangedEvent();
+ if (current != null) {
+ histBack.push(current);
+ activate(current);
+ fireBackHistoryChangedEvent();
+ }
+ } catch (EmptyStackException ex) {
+ // TODO should we throw exception here?
+ }
+ }
+
+ /**
+ * Fires a INavigationHistoryEvent when the forward history changes.
+ */
+ private void fireForewardHistoryChangedEvent() {
+ // if (LOGGER.isLoggable(LogService.LOG_DEBUG))
+ // LOGGER.log(LogService.LOG_DEBUG, "FORW " //$NON-NLS-1$
+ // + histForward.size() + "," + histForward); //$NON-NLS-1$
+ if (navigationListener.size() == 0)
+ return;
+ INavigationHistoryEvent event = new NavigationHistoryEvent(histBack.subList(0, histForward.size()));
+ for (INavigationHistoryListener listener : navigationListener) {
+ listener.backHistoryChanged(event);
+ }
+ }
+
+ /**
+ * Answer the current size of the next navigation history
+ *
+ * @see org.eclipse.riena.navigation.INavigationNode#getHistorySize()
+ * @return the amount of navigation nodes on the navigation stack
+ */
+ public int getHistoryBackSize() {
+ return histBack.size() - 1;
+ }
+
+ /**
+ * Answer the current size of the previous navigation history
+ *
+ * @see org.eclipse.riena.navigation.INavigationNode#getHistorySize()
+ * @return the amount of navigation nodes on the navigation stack
+ */
+ public int getHistoryForwardSize() {
+ return histForward.size();
+ }
+
+ /**
+ * Navigates to the caller (the source node) of the given targetNode. If
+ * there is no previous caller, no navigation is performed. If the
+ * targetNode itself has no caller in the navigationMap, the tree hierarchy
+ * is searched up to the tree root.
+ *
+ * @param targetNode
+ * The node where we have navigate to and return from
+ */
+ public void navigateBack(INavigationNode<?> targetNode) {
+ INavigationNode<?> sourceNode = null;
+ INavigationNode<?> lookupNode = targetNode;
+ while (sourceNode == null) {
+ sourceNode = navigationMap.get(lookupNode);
+ if (sourceNode == null) {
+ lookupNode = lookupNode.getParent();
+ if (lookupNode == null)
+ return;
+ }
+ }
+ navigate(targetNode, sourceNode.getPresentationId(), null, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.riena.navigation.INavigationHistoryListernable#
+ * addNavigationHistoryListener
+ * (org.eclipse.riena.navigation.INavigationHistoryListener)
+ */
+ public synchronized void addNavigationHistoryListener(INavigationHistoryListener listener) {
+ if (!navigationListener.contains(listener))
+ navigationListener.add(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.riena.navigation.INavigationHistoryListernable#
+ * removeNavigationHistoryListener
+ * (org.eclipse.riena.navigation.INavigationHistoryListener)
+ */
+ public synchronized void removeNavigationHistoryListener(INavigationHistoryListener listener) {
+ navigationListener.remove(listener);
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/PresentationProviderService.java b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/PresentationProviderService.java
index 3f3a6fc..61933a0 100644
--- a/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/PresentationProviderService.java
+++ b/org.eclipse.riena.navigation/src/org/eclipse/riena/navigation/model/PresentationProviderService.java
@@ -69,7 +69,7 @@ public class PresentationProviderService implements IPresentationProviderService
* org.eclipse.riena.navigation.INavigationArgumentListener)
*/
@SuppressWarnings("unchecked")
- public INavigationNode<?> createNode(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
+ public INavigationNode<?> provideNode(INavigationNode<?> sourceNode, INavigationNodeId targetId, Object argument,
INavigationArgumentListener argumentListener) {
INavigationNode<?> targetNode = findNode(getRootNode(sourceNode), targetId);
if (targetNode == null) {
@@ -80,7 +80,7 @@ public class PresentationProviderService implements IPresentationProviderService
INavigationNodeBuilder builder = presentationDefinition.createNodeBuilder();
prepareNavigationNodeBuilder(targetId, builder);
targetNode = builder.buildNode(targetId);
- INavigationNode parentNode = createNode(sourceNode, new NavigationNodeId(presentationDefinition
+ INavigationNode parentNode = provideNode(sourceNode, new NavigationNodeId(presentationDefinition
.getParentPresentationId()), null, null);
parentNode.addChild(targetNode);
} else {
@@ -196,8 +196,7 @@ public class PresentationProviderService implements IPresentationProviderService
if (presentationDefinition != null) {
return presentationDefinition.getViewId();
} else {
- throw new ApplicationModelFailure("No presentation definition found for node '" + nodeId.getTypeId()
- + "'.");
+ throw new ApplicationModelFailure("No presentation definition found for node '" + nodeId.getTypeId() + "'.");
}
}