All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.almende.eve.transport.ws.WebsocketTransportBuilder Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
/*
 * Copyright: Almende B.V. (2014), Rotterdam, The Netherlands
 * License: The Apache Software License, Version 2.0
 */
package com.almende.eve.transport.ws;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.websocket.server.ServerEndpointConfig;

import com.almende.eve.capabilities.AbstractCapabilityBuilder;
import com.almende.eve.capabilities.Capability;
import com.almende.eve.capabilities.handler.Handler;
import com.almende.eve.transport.Receiver;
import com.almende.eve.transport.Transport;
import com.almende.eve.transport.TransportService;
import com.almende.eve.transport.http.ServletLauncher;
import com.almende.util.ClassUtil;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * The Class WebsocketService.
 */
public class WebsocketTransportBuilder extends
		AbstractCapabilityBuilder {
	private static final Logger		LOG			= Logger.getLogger(WebsocketService.class
														.getName());
	private static WebsocketService	singleton	= null;
	
	@Override
	public WebsocketTransport build() {
		if (singleton == null) {
			singleton = new WebsocketService();
		}
		return singleton.get(getParams(), getHandle());
	}
	
	/**
	 * Gets the transport.
	 * 
	 * @param address
	 *            the address
	 * @return the ws client transport
	 */
	public static WebsocketTransport get(final URI address) {
		if (singleton != null) {
			return singleton.getTransport(address);
		}
		return null;
	}
	
	class WebsocketService implements TransportService {
		private final Map	transports	= new HashMap();
		
		/**
		 * Gets the.
		 * 
		 * @param 
		 *            the generic type
		 * @param 
		 *            the value type
		 * @param params
		 *            the params
		 * @param handle
		 *            the handle
		 * @return the websocket transport
		 */
		public  WebsocketTransport get(
				final ObjectNode params, final Handler handle) {
			final Handler newHandle = Transport.TYPEUTIL
					.inject(handle);
			final WebsocketTransportConfig config = new WebsocketTransportConfig(
					params);
			if (config.isServer()) {
				return getServer(config, newHandle);
			} else {
				return getClient(config, newHandle);
			}
		}

		private WebsocketTransport getServer(final WebsocketTransportConfig config, final Handler handle){
			WebsocketTransport result = null;
			final String address = config.getAddress();
			
			if (address != null) {
				try {
					final URI serverUri = new URI(address);
					if (transports.containsKey(serverUri)) {
						result = transports.get(serverUri);
						result.getHandle().update(handle);
					} else {
						result = new WsServerTransport(serverUri,
								handle, this, config);
						transports.put(serverUri, result);
						String servletLauncher = config
								.getServletLauncher();
						if (servletLauncher != null) {
							if (servletLauncher.equals("JettyLauncher")) {
								servletLauncher = "com.almende.eve.transport.http.embed.JettyLauncher";
							}
							try {
								final Class launcherClass = Class
										.forName(servletLauncher);
								if (!ClassUtil.hasInterface(launcherClass,
										ServletLauncher.class)) {
									throw new IllegalArgumentException(
											"ServletLauncher class "
													+ launcherClass
															.getName()
													+ " must implement "
													+ ServletLauncher.class
															.getName());
								}
								final ServletLauncher launcher = (ServletLauncher) launcherClass
										.newInstance();
								
								final ServerEndpointConfig sec = ServerEndpointConfig.Builder
										.create(WebsocketEndpoint.class,
												serverUri.getPath())
										.build();
								sec.getUserProperties().put("address",
										serverUri);
								
								launcher.add(sec, config);
								
							} catch (final Exception e1) {
								LOG.log(Level.WARNING,
										"Failed to load servlet in servletlauncher!",
										e1);
							}
						}
					}
				} catch (final URISyntaxException e) {
					LOG.log(Level.WARNING, "Couldn't parse address:"
							+ address, e);
				}
			} else {
				LOG.warning("Parameter 'address' is required.");
			}
			return result;
		}
		
		private WebsocketTransport getClient(final WebsocketTransportConfig config, final Handler handle){
			WebsocketTransport result = null;
			final String id = config.getId();
			if (id != null) {
				try {
					final URI key = new URI("wsclient:" + id);
					LOG.log(Level.WARNING, "Looking up:" + key);
					if (transports.containsKey(key)) {
						result = transports.get(key);
						if (!(new WebsocketTransportConfig(
								result.getParams())).getServerUrl().equals(
								config.getServerUrl())) {
							((WsClientTransport) result)
									.updateConfig(config);
						}
						result.getHandle().update(handle);
					} else {
						result = new WsClientTransport(key, handle,
								this, config);
						transports.put(key, result);
					}
				} catch (final URISyntaxException e) {
					LOG.log(Level.WARNING,
							"Couldn't parse Client Url: wsclient:" + id, e);
				} catch (IOException e) {
					LOG.log(Level.WARNING,
							"Couldn't reconnect with new config.", e);
				}
			} else {
				LOG.warning("Parameter 'id' is required.");
			}
			return result;
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.almende.eve.transport.TransportService#delete(com.almende.eve.
		 * transport
		 * .Transport)
		 */
		@Override
		public void delete(final Transport instance) {
			transports.remove(instance.getAddress());
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.almende.eve.transport.TransportService#getLocal(java.net.URI)
		 */
		@Override
		public Transport getLocal(final URI address) {
			return null;
		}
		
		/**
		 * Gets the transport.
		 * 
		 * @param address
		 *            the address
		 * @return the transport
		 */
		public WebsocketTransport getTransport(final URI address) {
			return transports.get(address);
		}
		
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy