/*******************************************************************************
* Copyright (c) 2009, 2015 EclipseSource 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:
* EclipseSource - initial API and implementation
* Ralf Zahn (ARS) - browser history support (Bug 283291)
******************************************************************************/
package org.eclipse.rap.rwt.internal.client;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.eclipse.rap.json.JsonObject;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.client.service.BrowserNavigation;
import org.eclipse.rap.rwt.client.service.BrowserNavigationEvent;
import org.eclipse.rap.rwt.client.service.BrowserNavigationListener;
import org.eclipse.rap.rwt.internal.remote.ConnectionImpl;
import org.eclipse.rap.rwt.internal.util.ParamCheck;
import org.eclipse.rap.rwt.remote.AbstractOperationHandler;
import org.eclipse.rap.rwt.remote.RemoteObject;
import org.eclipse.swt.SWT;
public final class BrowserNavigationImpl implements BrowserNavigation {
private final static String TYPE = "rwt.client.BrowserNavigation";
private final static String PROP_NAVIGATION_LISTENER = "Navigation";
private final static String METHOD_ADD_TO_HISTORY = "addToHistory";
private final static String PROP_STATE = "state";
private final static String PROP_TITLE = "title";
private static final Object EVENT_HISTORY_NAVIGATED = "Navigation";
private static final String EVENT_HISTORY_NAVIGATED_STATE = "state";
private final Collection<BrowserNavigationListener> listeners;
private final RemoteObject remoteObject;
public BrowserNavigationImpl() {
ConnectionImpl connection = ( ConnectionImpl )RWT.getUISession().getConnection();
remoteObject = connection.createServiceObject( TYPE );
remoteObject.setHandler( new NavigationOperationHandler() );
listeners = new LinkedHashSet<>();
}
@Override
public void pushState( String state, String title ) {
ParamCheck.notNullOrEmpty( state, "state" );
JsonObject properties = new JsonObject().add( PROP_STATE, state ).add( PROP_TITLE, title );
remoteObject.call( METHOD_ADD_TO_HISTORY, properties );
}
@Override
public void addBrowserNavigationListener( BrowserNavigationListener listener ) {
if( listener == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
listeners.add( listener );
if( listeners.size() == 1 ) {
remoteObject.listen( PROP_NAVIGATION_LISTENER, true );
}
}
@Override
public void removeBrowserNavigationListener( BrowserNavigationListener listener ) {
if( listener == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
listeners.remove( listener );
if( listeners.isEmpty() ) {
remoteObject.listen( PROP_NAVIGATION_LISTENER, false );
}
}
void notifyListeners( BrowserNavigationEvent event ) {
BrowserNavigationListener[] listeners = getListeners();
for( BrowserNavigationListener listener : listeners ) {
listener.navigated( event );
}
}
private BrowserNavigationListener[] getListeners() {
return listeners.toArray( new BrowserNavigationListener[ listeners.size() ] );
}
////////////////
// Inner classes
private final class NavigationOperationHandler extends AbstractOperationHandler {
@Override
public void handleNotify( String event, JsonObject properties ) {
if( EVENT_HISTORY_NAVIGATED.equals( event ) ) {
String state = properties.get( EVENT_HISTORY_NAVIGATED_STATE ).asString();
notifyListeners( new BrowserNavigationEvent( this, state ) );
}
}
}
}