blob: fda50cfca179306366eb0300422534884ca825af [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.common.events;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
/**
* Create EventDriver implementations.
*/
public class EventDriverFactory
{
private static final Logger LOG = Log.getLogger(EventDriverFactory.class);
private final WebSocketPolicy policy;
private final List<EventDriverImpl> implementations;
public EventDriverFactory(WebSocketPolicy policy)
{
this.policy = policy;
this.implementations = new ArrayList<>();
addImplementation(new JettyListenerImpl());
addImplementation(new JettyAnnotatedImpl());
}
public void addImplementation(EventDriverImpl impl)
{
if (implementations.contains(impl))
{
LOG.warn("Ignoring attempt to add duplicate EventDriverImpl: " + impl);
return;
}
implementations.add(impl);
}
public void clearImplementations()
{
this.implementations.clear();
}
protected String getClassName(Object websocket)
{
return websocket.getClass().getName();
}
public List<EventDriverImpl> getImplementations()
{
return implementations;
}
public boolean removeImplementation(EventDriverImpl impl)
{
return this.implementations.remove(impl);
}
@Override
public String toString()
{
StringBuilder msg = new StringBuilder();
msg.append(this.getClass().getSimpleName());
msg.append("[implementations=[");
boolean delim = false;
for (EventDriverImpl impl : implementations)
{
if (delim)
{
msg.append(',');
}
msg.append(impl.toString());
delim = true;
}
msg.append("]");
return msg.toString();
}
/**
* Wrap the given WebSocket object instance in a suitable EventDriver
*
* @param websocket
* the websocket instance to wrap. Must either implement {@link WebSocketListener} or be annotated with {@link WebSocket &#064WebSocket}
* @return appropriate EventDriver for this websocket instance.
*/
public EventDriver wrap(Object websocket)
{
if (websocket == null)
{
throw new InvalidWebSocketException("null websocket object");
}
for (EventDriverImpl impl : implementations)
{
if (impl.supports(websocket))
{
try
{
return impl.create(websocket,policy.clonePolicy());
}
catch (Throwable e)
{
throw new InvalidWebSocketException("Unable to create websocket",e);
}
}
}
// Create a clear error message for the developer
StringBuilder err = new StringBuilder();
err.append(getClassName(websocket));
err.append(" is not a valid WebSocket object.");
err.append(" Object must obey one of the following rules: ");
int len = implementations.size();
for (int i = 0; i < len; i++)
{
EventDriverImpl impl = implementations.get(i);
if (i > 0)
{
err.append(" or ");
}
err.append("\n(").append(i + 1).append(") ");
err.append(impl.describeRule());
}
throw new InvalidWebSocketException(err.toString());
}
}