src-html.com.pusher.client.util.Factory.html Maven / Gradle / Ivy
Source code
001package com.pusher.client.util;
002
003import java.net.Proxy;
004import java.net.URI;
005import java.net.URISyntaxException;
006import java.util.concurrent.ExecutorService;
007import java.util.concurrent.Executors;
008import java.util.concurrent.ScheduledExecutorService;
009import java.util.concurrent.ThreadFactory;
010
011import javax.net.ssl.SSLException;
012
013import org.java_websocket.client.WebSocketClient;
014
015import com.pusher.client.Authorizer;
016import com.pusher.client.PusherOptions;
017import com.pusher.client.channel.impl.ChannelImpl;
018import com.pusher.client.channel.impl.ChannelManager;
019import com.pusher.client.channel.impl.PresenceChannelImpl;
020import com.pusher.client.channel.impl.PrivateChannelImpl;
021import com.pusher.client.connection.impl.InternalConnection;
022import com.pusher.client.connection.websocket.WebSocketClientWrapper;
023import com.pusher.client.connection.websocket.WebSocketConnection;
024import com.pusher.client.connection.websocket.WebSocketListener;
025
026/**
027 * This is a lightweight way of doing dependency injection and enabling classes
028 * to be unit tested in isolation. No class in this library instantiates another
029 * class directly, otherwise they would be tightly coupled. Instead, they all
030 * call the factory methods in this class when they want to create instances of
031 * another class.
032 *
033 * An instance of Factory is provided on construction to each class which may
034 * require it, the initial factory is instantiated in the Pusher constructor,
035 * the only constructor which a library consumer should need to call directly.
036 *
037 * Conventions:
038 *
039 * - any method that starts with "new", such as
040 * {@link #newPublicChannel(String)} creates a new instance of that class every
041 * time it is called.
042 *
043 */
044public class Factory {
045
046 private InternalConnection connection;
047 private ChannelManager channelManager;
048 private ExecutorService eventQueue;
049 private ScheduledExecutorService timers;
050 private static final Object eventLock = new Object();
051
052 public synchronized InternalConnection getConnection(final String apiKey, final PusherOptions options) {
053 if (connection == null) {
054 try {
055 connection = new WebSocketConnection(options.buildUrl(apiKey), options.getActivityTimeout(),
056 options.getPongTimeout(), options.getProxy(), this);
057 }
058 catch (final URISyntaxException e) {
059 throw new IllegalArgumentException("Failed to initialise connection", e);
060 }
061 }
062 return connection;
063 }
064
065 public WebSocketClientWrapper newWebSocketClientWrapper(final URI uri, final Proxy proxy, final WebSocketListener webSocketListener) throws SSLException {
066 return new WebSocketClientWrapper(uri, proxy, webSocketListener);
067 }
068
069 public synchronized ScheduledExecutorService getTimers() {
070 if (timers == null) {
071 timers = Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory("timers"));
072 }
073 return timers;
074 }
075
076 public ChannelImpl newPublicChannel(final String channelName) {
077 return new ChannelImpl(channelName, this);
078 }
079
080 public PrivateChannelImpl newPrivateChannel(final InternalConnection connection, final String channelName,
081 final Authorizer authorizer) {
082 return new PrivateChannelImpl(connection, channelName, authorizer, this);
083 }
084
085 public PresenceChannelImpl newPresenceChannel(final InternalConnection connection, final String channelName,
086 final Authorizer authorizer) {
087 return new PresenceChannelImpl(connection, channelName, authorizer, this);
088 }
089
090 public synchronized ChannelManager getChannelManager() {
091 if (channelManager == null) {
092 channelManager = new ChannelManager(this);
093 }
094 return channelManager;
095 }
096
097 public synchronized void queueOnEventThread(final Runnable r) {
098 if (eventQueue == null) {
099 eventQueue = Executors.newSingleThreadExecutor(new DaemonThreadFactory("eventQueue"));
100 }
101 eventQueue.execute(new Runnable() {
102 @Override
103 public void run() {
104 synchronized (eventLock) {
105 r.run();
106 }
107 }
108 });
109 }
110
111 public synchronized void shutdownThreads() {
112 if (eventQueue != null) {
113 eventQueue.shutdown();
114 eventQueue = null;
115 }
116 if (timers != null) {
117 timers.shutdown();
118 timers = null;
119 }
120 }
121
122 private static class DaemonThreadFactory implements ThreadFactory {
123 private final String name;
124
125 public DaemonThreadFactory(final String name) {
126 this.name = name;
127 }
128
129 @Override
130 public Thread newThread(final Runnable r) {
131 final Thread t = new Thread(r);
132 t.setDaemon(true);
133 t.setName("pusher-java-client " + name);
134 return t;
135 }
136 }
137}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy