/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.client.mvp; import java.util.logging.Logger; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.History; import com.google.web.bindery.event.shared.EventBus; import com.google.web.bindery.event.shared.HandlerRegistration; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; @Dependent public class PlaceHistoryHandler { private static final Logger log = Logger.getLogger(PlaceHistoryHandler.class.getName()); private final Historian historian; @Inject private PlaceRequestHistoryMapper mapper; private PlaceManager placeManager; private PlaceRequest defaultPlaceRequest = PlaceRequest.NOWHERE; /** * Create a new PlaceHistoryHandler. */ public PlaceHistoryHandler() { this.historian = GWT.create(DefaultHistorian.class); } /** * Handle the current history token. Typically called at application start, * to ensure bookmark launches work. */ public void handleCurrentHistory() { handleHistoryToken(historian.getToken()); } /** * Initialize this place history handler. * @return a registration object to de-register the handler */ public HandlerRegistration register(final PlaceManager placeManager, final EventBus eventBus, final PlaceRequest defaultPlaceRequest) { this.placeManager = placeManager; this.defaultPlaceRequest = defaultPlaceRequest; /* * final HandlerRegistration placeReg = * eventBus.addHandler(PlaceChangeEvent.TYPE, new * PlaceChangeEvent.Handler() { public void * onPlaceChange(PlaceChangeEvent event) { Place newPlace = * event.getNewPlace(); * historian.newItem(tokenForPlace(newPlaceRequest), false); } }); */ final HandlerRegistration historyReg = historian.addValueChangeHandler(new ValueChangeHandler<String>() { @Override public void onValueChange(ValueChangeEvent<String> event) { String token = event.getValue(); handleHistoryToken(token); } }); return new HandlerRegistration() { @Override public void removeHandler() { PlaceHistoryHandler.this.defaultPlaceRequest = DefaultPlaceRequest.NOWHERE; PlaceHistoryHandler.this.placeManager = null; //placeReg.removeHandler(); historyReg.removeHandler(); } }; } public void onPlaceChange(final PlaceRequest placeRequest) { if (placeRequest.isUpdateLocationBarAllowed()) { historian.newItem(tokenForPlace(placeRequest), false); } } /** * Visible for testing. */ Logger log() { return log; } private void handleHistoryToken(String token) { PlaceRequest newPlaceRequest = null; if ("".equals(token)) { newPlaceRequest = defaultPlaceRequest; } if (newPlaceRequest == null) { newPlaceRequest = mapper.getPlaceRequest(token); } if (newPlaceRequest == null) { log().warning("Unrecognized history token: " + token); newPlaceRequest = defaultPlaceRequest; } placeManager.goTo(newPlaceRequest); } private String tokenForPlace(final PlaceRequest newPlaceRequest) { if (defaultPlaceRequest.equals(newPlaceRequest)) { return ""; } return newPlaceRequest.getFullIdentifier(); } /** * Optional delegate in charge of History related events. Provides nice * isolation for unit testing, and allows pre- or post-processing of tokens. * Methods correspond to the like named methods on {@link History}. */ public interface Historian { /** * Adds a {@link com.google.gwt.event.logical.shared.ValueChangeEvent} * handler to be informed of changes to the browser's history stack. * @param valueChangeHandler the handler * @return the registration used to remove this value change handler */ com.google.gwt.event.shared.HandlerRegistration addValueChangeHandler(final ValueChangeHandler<String> valueChangeHandler); /** * @return the current history token. */ String getToken(); /** * Adds a new browser history entry. Calling this method will cause * {@link ValueChangeHandler#onValueChange(com.google.gwt.event.logical.shared.ValueChangeEvent)} * to be called as well. */ void newItem(final String token, final boolean issueEvent); } /** * Default implementation of {@link Historian}, based on {@link History}. */ public static class DefaultHistorian implements Historian { @Override public com.google.gwt.event.shared.HandlerRegistration addValueChangeHandler(final ValueChangeHandler<String> valueChangeHandler) { return History.addValueChangeHandler(valueChangeHandler); } @Override public String getToken() { return History.getToken(); } @Override public void newItem(String token, boolean issueEvent) { History.newItem(token, issueEvent); } } }