ItEr11S12ArquitecturaClientesItEr09S11: EntryPoints mechanism now used to keep track of browser history, AKA back button support.
This commit is contained in:
parent
5dea68fa30
commit
9633509dbb
4 changed files with 125 additions and 19 deletions
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* <br />
|
||||
|
|
@ -23,6 +27,9 @@ import org.zkoss.zk.ui.Execution;
|
|||
*/
|
||||
public class URLHandler<T> {
|
||||
|
||||
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<T> {
|
|||
}
|
||||
|
||||
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<T> {
|
|||
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<T> {
|
|||
}
|
||||
|
||||
public <S extends T> void applyIfMatches(S controller) {
|
||||
String uri = getRequest().getRequestURI();
|
||||
applyIfMatches(controller, uri);
|
||||
}
|
||||
|
||||
private HttpServletRequest getRequest() {
|
||||
Execution current = executorRetriever.getCurrent();
|
||||
Map<String, String> matrixParams = MatrixParameters
|
||||
.extract((HttpServletRequest) current.getNativeRequest());
|
||||
HttpServletRequest request = (HttpServletRequest) current
|
||||
.getNativeRequest();
|
||||
return request;
|
||||
}
|
||||
|
||||
public <S extends T> void applyIfMatches(S controller, String fragment) {
|
||||
if (isFlagedInThisRequest()) {
|
||||
return;
|
||||
}
|
||||
flagAlreadyExecutedInThisRequest();
|
||||
String string = insertSemicolonIfNeeded(fragment);
|
||||
Map<String, String> matrixParams = MatrixParameters.extract(string);
|
||||
Set<String> matrixParamsNames = matrixParams.keySet();
|
||||
for (Entry<String, EntryPointMetadata> entry : metadata.entrySet()) {
|
||||
EntryPointMetadata entryPointMetadata = entry.getValue();
|
||||
|
|
@ -124,6 +189,24 @@ public class URLHandler<T> {
|
|||
}
|
||||
}
|
||||
|
||||
public <S extends T> 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<String, String> matrixParams,
|
||||
EntryPoint linkToStateAnnotation, Class<?>[] parameterTypes) {
|
||||
Object[] result = new Object[parameterTypes.length];
|
||||
|
|
|
|||
|
|
@ -20,4 +20,7 @@ public interface IWorkerCRUDControllerEntryPoints {
|
|||
@EntryPoint("create")
|
||||
public abstract void goToCreateForm();
|
||||
|
||||
@EntryPoint("list")
|
||||
void goToList();
|
||||
|
||||
}
|
||||
|
|
@ -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<IWorkerCRUDControllerEntryPoints> handler = URLHandlerRegistry
|
||||
final URLHandler<IWorkerCRUDControllerEntryPoints> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue