/*******************************************************************************
* Copyright (c) 2002, 2016 Innoopract Informationssysteme GmbH 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:
* Innoopract Informationssysteme GmbH - initial API and implementation
* Frank Appel - replaced singletons and static fields (Bug 337787)
* EclipseSource - ongoing implementation
******************************************************************************/
package org.eclipse.rap.rwt.internal.service;
import static org.eclipse.rap.rwt.internal.protocol.ClientMessageConst.CONNECTION_ID;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.rap.rwt.internal.RWTProperties;
import org.eclipse.rap.rwt.internal.util.ParamCheck;
import org.eclipse.rap.rwt.service.ServiceHandler;
import org.eclipse.rap.rwt.service.ServiceManager;
import org.eclipse.rap.rwt.service.UISession;
public class ServiceManagerImpl implements ServiceManager {
public static final String REQUEST_PARAM = "servicehandler";
private final ServiceHandler defaultHandler;
private final ServiceHandlerRegistry customHandlers;
public ServiceManagerImpl( ServiceHandler defaultServieHandler ) {
defaultHandler = defaultServieHandler;
customHandlers = new ServiceHandlerRegistry();
}
public ServiceHandler getServiceHandler( String customId ) {
return customHandlers.get( customId );
}
@Override
public void registerServiceHandler( String id, ServiceHandler handler ) {
ParamCheck.notNullOrEmpty( id, "id" );
ParamCheck.notNull( handler, "handler" );
if( !customHandlers.put( id, handler ) ) {
String message = "A service handler is already registered with this id: " + id;
throw new IllegalArgumentException( message );
}
}
@Override
public void unregisterServiceHandler( String id ) {
ParamCheck.notNullOrEmpty( id, "id" );
customHandlers.remove( id );
}
@Override
public String getServiceHandlerUrl( String id ) {
ParamCheck.notNull( id, "id" );
HttpServletRequest request = ContextProvider.getRequest();
StringBuilder url = new StringBuilder();
String baseUrl = RWTProperties.getServiceHandlerBaseUrl();
if( baseUrl != null ) {
url.append( baseUrl );
}
url.append( request.getRequestURI() )
.append( '?' )
.append( REQUEST_PARAM )
.append( '=' )
.append( encodeParameter( id ) );
String connectionId = getConnectionId();
if( connectionId != null ) {
url.append( '&' )
.append( CONNECTION_ID )
.append( '=' )
.append( connectionId );
}
return ContextProvider.getResponse().encodeURL( url.toString() );
}
public void clear() {
customHandlers.clear();
}
public ServiceHandler getHandler() {
ServiceHandler result;
String customId = getCustomHandlerId();
if( customId != null && customId.length() > 0 ) {
result = getCustomHandlerChecked( customId );
} else {
result = defaultHandler;
}
return result;
}
private ServiceHandler getCustomHandlerChecked( String customId ) {
ServiceHandler customHandler = customHandlers.get( customId );
if( customHandler == null ) {
throw new IllegalArgumentException( "No service handler registered with id " + customId );
}
return customHandler;
}
private static String getCustomHandlerId() {
return ContextProvider.getRequest().getParameter( REQUEST_PARAM );
}
private static String getConnectionId() {
UISession uiSession = ContextProvider.getUISession();
return uiSession == null ? null : ( ( UISessionImpl )uiSession ).getConnectionId();
}
private static String encodeParameter( String id ) {
try {
// TODO [rst] Encode parameters according to URI spec (RFC 2396). URLEncoder is meant for form
// encoding which is not the same, but better than nothing for the moment.
// See http://stackoverflow.com/questions/444112/how-do-i-encode-uri-parameter-values
return URLEncoder.encode( id, "UTF-8" ).replace( "+", "%20" );
} catch( UnsupportedEncodingException exception ) {
throw new RuntimeException( exception );
}
}
}