/*
* WBI Indicator Explorer
*
* Copyright 2015 Sebastian Nogara <snogaraleal@gmail.com>
*
* This file is part of WBI.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package client.managers.history;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import client.managers.Manager;
/**
* {@link Manager} that keeps track of the current {@link HistoryState}.
*/
public class HistoryManager implements Manager, ValueChangeHandler<String> {
/**
* Interface for {@link HistoryManager} listeners.
*/
public static interface Listener {
/**
* Handle connection to {@link HistoryManager}.
*
* @param historyManager Manager connected to.
*/
void onAdd(HistoryManager historyManager);
/**
* Handle disconnection from {@link HistoryManager}.
*/
void onRemove();
/**
* Handle change of {@link HistoryState}.
*
* @param state Current state.
*/
void onChange(HistoryState state);
}
/**
* Base class for {@code HistoryManager.Listener} implementers.
*/
public static abstract class BaseHistory implements Listener {
protected HistoryManager historyManager;
@Override
public void onAdd(HistoryManager historyManager) {
assert this.historyManager == null;
this.historyManager = historyManager;
}
@Override
public void onRemove() {
assert this.historyManager != null;
this.historyManager = null;
}
/**
* Get the {@code HistoryManager} this listener is currently
* listening to.
*
* @return Current {@code HistoryManager}.
*/
public HistoryManager getCurrentHistoryManager() {
return historyManager;
}
}
/**
* {@code Listener} objects listening to changes in this manager.
*/
private List<Listener> listeners = new ArrayList<Listener>();
/**
* Current history state.
*/
private HistoryState currentState;
/**
* Initialize {@code HistoryManager}.
*/
private HistoryManager() {
History.addValueChangeHandler(this);
currentState = HistoryState.fromHistoryToken(History.getToken());
}
/**
* Change the current {@link HistoryState}.
*
* @param state New history state.
*/
public void setState(HistoryState state) {
currentState = state;
History.newItem(state.getHistoryToken(), false);
}
/**
* Get the current {@link HistoryState}.
*
* @return Current history state.
*/
public HistoryState getCurrentState() {
return currentState;
}
/**
* Attach {@code Listener}.
*
* @param listener Listener to attach.
*/
public void addListener(Listener listener) {
listeners.add(listener);
listener.onAdd(this);
listener.onChange(currentState);
}
/**
* Detach {@code Listener}.
*
* @param listener Listener to detach.
*/
public void removeListener(Listener listener) {
listeners.remove(listener);
listener.onRemove();
}
/**
* Handle browser history state changes.
*/
@Override
public void onValueChange(ValueChangeEvent<String> event) {
HistoryState state = HistoryState.fromHistoryToken(event.getValue());
if (state != null && !state.isEmpty()) {
// Update the current {@code HistoryState}
currentState.replace(state);
// Re-generate the current history token
History.replaceItem(currentState.getHistoryToken(), false);
// Call listeners
for (Listener listener : listeners) {
listener.onChange(currentState);
}
}
}
/*
* Singleton
*/
private static HistoryManager manager;
public static HistoryManager get() {
if (manager == null) {
manager = new HistoryManager();
}
return manager;
}
}