diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/entrypoints/URLHandler.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/entrypoints/URLHandler.java
index efdd45e5e..9a556ac6c 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/entrypoints/URLHandler.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/entrypoints/URLHandler.java
@@ -16,6 +16,10 @@ import org.apache.commons.logging.LogFactory;
import org.navalplanner.web.common.converters.Converter;
import org.navalplanner.web.common.converters.IConverterFactory;
import org.zkoss.zk.ui.Execution;
+import org.zkoss.zk.ui.Page;
+import org.zkoss.zk.ui.event.BookmarkEvent;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
/**
*
@@ -23,6 +27,9 @@ import org.zkoss.zk.ui.Execution;
*/
public class URLHandler {
+ private static final String FLAG_ATTRIBUTE = URLHandler.class.getName()
+ + "_";
+
private static final Log LOG = LogFactory.getLog(URLHandler.class);
private static class EntryPointMetadata {
@@ -66,6 +73,9 @@ public class URLHandler {
}
public void doTransition(String methodName, Object... values) {
+ if (isFlagedInThisRequest())
+ return;
+ flagAlreadyExecutedInThisRequest();
if (!metadata.containsKey(methodName)) {
LOG.error("Method " + methodName
+ "doesn't represent a state(It doesn't have a "
@@ -83,15 +93,55 @@ public class URLHandler {
stringRepresentations[i] = converterFor
.asStringUngeneric(values[i]);
}
- StringBuilder linkValue = new StringBuilder(page);
- for (int i = 0; i < parameterNames.length; i++) {
- linkValue.append(";").append(parameterNames[i]);
- if (stringRepresentations[i] != null)
- linkValue.append("=").append(stringRepresentations[i]);
- }
+ String fragment = getFragment(parameterNames, stringRepresentations);
+ String requestPath = executorRetriever.getCurrent().getDesktop()
+ .getRequestPath();
+ if (requestPath.contains(page)) {
+ doBookmark(fragment);
+ } else
+ sendRedirect(fragment);
+ }
+
+ private boolean isFlagedInThisRequest() {
+ return getRequest().getAttribute(FLAG_ATTRIBUTE) == this;
+ }
+
+ private void flagAlreadyExecutedInThisRequest() {
+ getRequest().setAttribute(FLAG_ATTRIBUTE, this);
+ }
+
+ private void doBookmark(String fragment) {
+ executorRetriever.getCurrent().getDesktop().setBookmark(
+ stripHash(fragment));
+ }
+
+ private String stripHash(String fragment) {
+ if (fragment.startsWith("#"))
+ return fragment.substring(1);
+ return fragment;
+ }
+
+ private void sendRedirect(String fragment) {
+ StringBuilder linkValue = new StringBuilder(page).append(fragment);
executorRetriever.getCurrent().sendRedirect(linkValue.toString());
}
+ private String getFragment(String[] parameterNames,
+ String[] stringRepresentations) {
+ StringBuilder result = new StringBuilder();
+ if (parameterNames.length > 0)
+ result.append("#");
+ for (int i = 0; i < parameterNames.length; i++) {
+ result.append(parameterNames[i]);
+ if (stringRepresentations[i] != null)
+ result.append("=").append(stringRepresentations[i]);
+ if (i < parameterNames.length - 1) {
+ result.append(";");
+ }
+ }
+ return result.toString();
+ }
+
private static void callMethod(Object target, Method superclassMethod,
Object[] params) {
try {
@@ -105,9 +155,24 @@ public class URLHandler {
}
public void applyIfMatches(S controller) {
+ String uri = getRequest().getRequestURI();
+ applyIfMatches(controller, uri);
+ }
+
+ private HttpServletRequest getRequest() {
Execution current = executorRetriever.getCurrent();
- Map matrixParams = MatrixParameters
- .extract((HttpServletRequest) current.getNativeRequest());
+ HttpServletRequest request = (HttpServletRequest) current
+ .getNativeRequest();
+ return request;
+ }
+
+ public void applyIfMatches(S controller, String fragment) {
+ if (isFlagedInThisRequest()) {
+ return;
+ }
+ flagAlreadyExecutedInThisRequest();
+ String string = insertSemicolonIfNeeded(fragment);
+ Map matrixParams = MatrixParameters.extract(string);
Set matrixParamsNames = matrixParams.keySet();
for (Entry entry : metadata.entrySet()) {
EntryPointMetadata entryPointMetadata = entry.getValue();
@@ -124,6 +189,24 @@ public class URLHandler {
}
}
+ public void registerListener(final S controller, Page page) {
+ page.addEventListener("onBookmarkChange", new EventListener() {
+
+ @Override
+ public void onEvent(Event event) throws Exception {
+ BookmarkEvent bookmarkEvent = (BookmarkEvent) event;
+ String bookmark = bookmarkEvent.getBookmark();
+ applyIfMatches(controller, bookmark);
+ }
+ });
+ }
+
+ private String insertSemicolonIfNeeded(String uri) {
+ if (!uri.startsWith(";"))
+ return ";" + uri;
+ return uri;
+ }
+
private Object[] retrieveArguments(Map matrixParams,
EntryPoint linkToStateAnnotation, Class>[] parameterTypes) {
Object[] result = new Object[parameterTypes.length];
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/IWorkerCRUDControllerEntryPoints.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/IWorkerCRUDControllerEntryPoints.java
index 60cd7581d..79991f707 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/IWorkerCRUDControllerEntryPoints.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/IWorkerCRUDControllerEntryPoints.java
@@ -20,4 +20,7 @@ public interface IWorkerCRUDControllerEntryPoints {
@EntryPoint("create")
public abstract void goToCreateForm();
+ @EntryPoint("list")
+ void goToList();
+
}
\ No newline at end of file
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerCRUDController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerCRUDController.java
index 8edfb4091..cbc4e1e67 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerCRUDController.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerCRUDController.java
@@ -57,6 +57,8 @@ public class WorkerCRUDController extends GenericForwardComposer implements
private WorkRelationshipsController editWorkRelationship;
+ private IWorkerCRUDControllerEntryPoints workerCRUD;
+
public WorkerCRUDController() {
}
@@ -64,7 +66,8 @@ public class WorkerCRUDController extends GenericForwardComposer implements
Window editWindow, Window workRelationshipsWindow,
Window addWorkRelationshipWindow,
Window editWorkRelationshipWindow, IWorkerModel workerModel,
- IMessagesForUser messages) {
+ IMessagesForUser messages,
+ IWorkerCRUDControllerEntryPoints workerCRUD) {
this.createWindow = createWindow;
this.listWindow = listWindow;
this.editWindow = editWindow;
@@ -73,6 +76,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
this.editWorkRelationshipWindow = editWorkRelationshipWindow;
this.workerModel = workerModel;
this.messages = messages;
+ this.workerCRUD = workerCRUD;
}
public Worker getWorker() {
@@ -92,7 +96,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
public void save() {
try {
workerModel.save();
- getVisibility().showOnly(listWindow);
+ goToList();
Util.reloadBindings(listWindow);
messages.showMessage(Level.INFO, "traballador gardado");
} catch (ValidationException e) {
@@ -103,10 +107,16 @@ public class WorkerCRUDController extends GenericForwardComposer implements
}
public void cancel() {
+ goToList();
+ }
+
+ public void goToList() {
+ getBookmarker().goToList();
getVisibility().showOnly(listWindow);
}
public void goToEditForm(Worker worker) {
+ getBookmarker().goToEditForm(worker);
workerModel.prepareEditFor(worker);
getVisibility().showOnly(editWindow);
Util.reloadBindings(editWindow);
@@ -133,6 +143,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
}
public void goToCreateForm() {
+ getBookmarker().goToCreateForm();
workerModel.prepareForCreate();
getVisibility().showOnly(createWindow);
Util.reloadBindings(createWindow);
@@ -151,7 +162,6 @@ public class WorkerCRUDController extends GenericForwardComposer implements
localizationsForCreationController = createLocalizationsController(
comp, "createWindow");
comp.setVariable("controller", this, true);
- getVisibility().showOnly(listWindow);
if (messagesContainer == null)
throw new RuntimeException("messagesContainer is needed");
messages = new MessagesForUser(messagesContainer);
@@ -164,9 +174,12 @@ public class WorkerCRUDController extends GenericForwardComposer implements
this.workerModel, this, messages),
editWorkRelationshipWindow);
- URLHandler handler = URLHandlerRegistry
+ final URLHandler handler = URLHandlerRegistry
.getRedirectorFor(IWorkerCRUDControllerEntryPoints.class);
- handler.applyIfMatches(this);
+ handler.registerListener(this, page);
+ getVisibility().showOnly(listWindow);
+ handler.registerListener(this, page);
+ getVisibility().showOnly(listWindow);
}
private void setupWorkRelationshipController(
@@ -200,4 +213,8 @@ public class WorkerCRUDController extends GenericForwardComposer implements
return this.addWorkRelationship;
}
+ private IWorkerCRUDControllerEntryPoints getBookmarker() {
+ return workerCRUD;
+ }
+
}
diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerCRUDControllerTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerCRUDControllerTest.java
index c21dff6fe..ffc550881 100644
--- a/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerCRUDControllerTest.java
+++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/resources/WorkerCRUDControllerTest.java
@@ -17,6 +17,7 @@ import org.junit.Test;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.web.common.IMessagesForUser;
import org.navalplanner.web.common.Level;
+import org.navalplanner.web.resources.worker.IWorkerCRUDControllerEntryPoints;
import org.navalplanner.web.resources.worker.IWorkerModel;
import org.navalplanner.web.resources.worker.WorkerCRUDController;
import org.zkoss.zul.api.Window;
@@ -33,6 +34,7 @@ public class WorkerCRUDControllerTest {
private Window workRelationshipsWindow;
private Window addWorkRelationshipWindow;
private Window editWorkRelationshipWindow;
+
private WorkerCRUDController createControllerForModel(
IWorkerModel workerModel) {
return createControllerForModel(workerModel, null);
@@ -44,17 +46,16 @@ public class WorkerCRUDControllerTest {
listWindow = createNiceMock(Window.class);
editWindow = createNiceMock(Window.class);
workRelationshipsWindow = createNiceMock(Window.class);
- addWorkRelationshipWindow = createNiceMock(Window.class);
- editWorkRelationshipWindow = createNiceMock(Window.class);
-
+ addWorkRelationshipWindow = createNiceMock(Window.class);
+ editWorkRelationshipWindow = createNiceMock(Window.class);
WorkerCRUDController workerCRUDController = new WorkerCRUDController(
createWindow, listWindow, editWindow, workRelationshipsWindow,
- addWorkRelationshipWindow, editWorkRelationshipWindow ,workerModel, messages);
+ addWorkRelationshipWindow, editWorkRelationshipWindow,
+ workerModel, messages, createNiceMock(IWorkerCRUDControllerEntryPoints.class));
return workerCRUDController;
}
-
@Test
public void testSave() throws Exception {
IWorkerModel workerModel = createMock(IWorkerModel.class);
@@ -81,6 +82,7 @@ public class WorkerCRUDControllerTest {
// verify
verify(workerModel, messagesForUser);
}
+
@Test
public void testGoToSaveAndThenCancel() {
IWorkerModel workerModel = createMock(IWorkerModel.class);
@@ -95,7 +97,8 @@ public class WorkerCRUDControllerTest {
expect(workRelationshipsWindow.setVisible(true)).andReturn(false);
expect(addWorkRelationshipWindow.setVisible(true)).andReturn(false);
replay(createWindow, listWindow, editWindow, workRelationshipsWindow,
- addWorkRelationshipWindow, editWorkRelationshipWindow, workerModel);
+ addWorkRelationshipWindow, editWorkRelationshipWindow,
+ workerModel);
// actions
workerCRUDController.goToCreateForm();
workerCRUDController.cancel();