1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.jsr356;
20
21 import java.util.Map;
22 import java.util.Objects;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import javax.websocket.Encoder;
26 import javax.websocket.EndpointConfig;
27
28 import org.eclipse.jetty.util.log.Log;
29 import org.eclipse.jetty.util.log.Logger;
30 import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
31 import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope;
32 import org.eclipse.jetty.websocket.jsr356.metadata.EncoderMetadata;
33 import org.eclipse.jetty.websocket.jsr356.metadata.EncoderMetadataSet;
34
35
36
37
38 public class EncoderFactory implements Configurable
39 {
40 public static class Wrapper implements Configurable
41 {
42 private final Encoder encoder;
43 private final EncoderMetadata metadata;
44
45 private Wrapper(Encoder encoder, EncoderMetadata metadata)
46 {
47 this.encoder = encoder;
48 this.metadata = metadata;
49 }
50
51 public Encoder getEncoder()
52 {
53 return encoder;
54 }
55
56 public EncoderMetadata getMetadata()
57 {
58 return metadata;
59 }
60
61 @Override
62 public void init(EndpointConfig config)
63 {
64 this.encoder.init(config);
65 }
66 }
67
68 private static final Logger LOG = Log.getLogger(EncoderFactory.class);
69
70 private final EncoderMetadataSet metadatas;
71 private final WebSocketContainerScope containerScope;
72 private EncoderFactory parentFactory;
73 private Map<Class<?>, Wrapper> activeWrappers;
74
75 public EncoderFactory(WebSocketContainerScope containerScope, EncoderMetadataSet metadatas)
76 {
77 this(containerScope,metadatas,null);
78 }
79
80 public EncoderFactory(WebSocketSessionScope sessionScope, EncoderMetadataSet metadatas, EncoderFactory parentFactory)
81 {
82 this(sessionScope.getContainerScope(),metadatas,parentFactory);
83 }
84
85 protected EncoderFactory(WebSocketContainerScope containerScope, EncoderMetadataSet metadatas, EncoderFactory parentFactory)
86 {
87 Objects.requireNonNull(containerScope,"Container Scope cannot be null");
88 this.containerScope = containerScope;
89 this.metadatas = metadatas;
90 this.activeWrappers = new ConcurrentHashMap<>();
91 this.parentFactory = parentFactory;
92 }
93
94 public Encoder getEncoderFor(Class<?> type)
95 {
96 Wrapper wrapper = getWrapperFor(type);
97 if (wrapper == null)
98 {
99 return null;
100 }
101 return wrapper.encoder;
102 }
103
104 public EncoderMetadata getMetadataFor(Class<?> type)
105 {
106 if (LOG.isDebugEnabled())
107 {
108 LOG.debug("getMetadataFor({})",type);
109 }
110 EncoderMetadata metadata = metadatas.getMetadataByType(type);
111
112 if (metadata != null)
113 {
114 return metadata;
115 }
116
117 if (parentFactory != null)
118 {
119 return parentFactory.getMetadataFor(type);
120 }
121
122 return null;
123 }
124
125 public Wrapper getWrapperFor(Class<?> type)
126 {
127 synchronized (activeWrappers)
128 {
129 Wrapper wrapper = activeWrappers.get(type);
130
131
132 if ((wrapper == null) && (parentFactory != null))
133 {
134 wrapper = parentFactory.getWrapperFor(type);
135 }
136
137 if (wrapper == null)
138 {
139
140 EncoderMetadata metadata = metadatas.getMetadataByType(type);
141 if (metadata == null)
142 {
143 return null;
144 }
145 wrapper = newWrapper(metadata);
146
147 activeWrappers.put(type,wrapper);
148 }
149
150 return wrapper;
151 }
152 }
153
154 @Override
155 public void init(EndpointConfig config)
156 {
157 if (LOG.isDebugEnabled())
158 {
159 LOG.debug("init({})",config);
160 }
161
162
163 for (EncoderMetadata metadata : metadatas)
164 {
165 Wrapper wrapper = newWrapper(metadata);
166 activeWrappers.put(metadata.getObjectType(),wrapper);
167 }
168
169
170 for (Wrapper wrapper : activeWrappers.values())
171 {
172 wrapper.encoder.init(config);
173 }
174 }
175
176 private Wrapper newWrapper(EncoderMetadata metadata)
177 {
178 Class<? extends Encoder> encoderClass = metadata.getCoderClass();
179 try
180 {
181 Encoder encoder = containerScope.getObjectFactory().createInstance(encoderClass);
182 return new Wrapper(encoder,metadata);
183 }
184 catch (InstantiationException | IllegalAccessException e)
185 {
186 throw new IllegalStateException("Unable to instantiate Encoder: " + encoderClass.getName());
187 }
188 }
189 }