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.Decoder;
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.DecoderMetadata;
33 import org.eclipse.jetty.websocket.jsr356.metadata.DecoderMetadataSet;
34
35
36
37
38
39
40
41
42
43
44
45 public class DecoderFactory implements Configurable
46 {
47 public static class Wrapper implements Configurable
48 {
49 private final Decoder decoder;
50 private final DecoderMetadata metadata;
51
52 private Wrapper(Decoder decoder, DecoderMetadata metadata)
53 {
54 this.decoder = decoder;
55 this.metadata = metadata;
56 }
57
58 public Decoder getDecoder()
59 {
60 return decoder;
61 }
62
63 public DecoderMetadata getMetadata()
64 {
65 return metadata;
66 }
67
68 @Override
69 public void init(EndpointConfig config)
70 {
71 this.decoder.init(config);
72 }
73 }
74
75 private static final Logger LOG = Log.getLogger(DecoderFactory.class);
76
77 private final DecoderMetadataSet metadatas;
78 private final WebSocketContainerScope containerScope;
79 private DecoderFactory parentFactory;
80 private Map<Class<?>, Wrapper> activeWrappers;
81
82 public DecoderFactory(WebSocketContainerScope containerScope, DecoderMetadataSet metadatas)
83 {
84 this(containerScope,metadatas,null);
85 }
86
87 public DecoderFactory(WebSocketSessionScope sessionScope, DecoderMetadataSet metadatas, DecoderFactory parentFactory)
88 {
89 this(sessionScope.getContainerScope(),metadatas,parentFactory);
90 }
91
92 protected DecoderFactory(WebSocketContainerScope containerScope, DecoderMetadataSet metadatas, DecoderFactory parentFactory)
93 {
94 Objects.requireNonNull(containerScope,"Container Scope cannot be null");
95 this.containerScope = containerScope;
96 this.metadatas = metadatas;
97 this.activeWrappers = new ConcurrentHashMap<>();
98 this.parentFactory = parentFactory;
99 }
100
101 public Decoder getDecoderFor(Class<?> type)
102 {
103 Wrapper wrapper = getWrapperFor(type);
104 if (wrapper == null)
105 {
106 return null;
107 }
108 return wrapper.decoder;
109 }
110
111 public DecoderMetadata getMetadataFor(Class<?> type)
112 {
113 if (LOG.isDebugEnabled())
114 {
115 LOG.debug("getMetadataFor({})",type);
116 }
117
118 DecoderMetadata metadata = metadatas.getMetadataByType(type);
119
120 if (metadata != null)
121 {
122 return metadata;
123 }
124
125 if (parentFactory != null)
126 {
127 return parentFactory.getMetadataFor(type);
128 }
129
130 return null;
131 }
132
133 public Wrapper getWrapperFor(Class<?> type)
134 {
135 synchronized (activeWrappers)
136 {
137 Wrapper wrapper = activeWrappers.get(type);
138
139
140 if ((wrapper == null) && (parentFactory != null))
141 {
142 wrapper = parentFactory.getWrapperFor(type);
143 }
144
145 if (wrapper == null)
146 {
147
148 DecoderMetadata metadata = metadatas.getMetadataByType(type);
149 if (metadata == null)
150 {
151 return null;
152 }
153 wrapper = newWrapper(metadata);
154
155 activeWrappers.put(type,wrapper);
156 }
157
158 return wrapper;
159 }
160 }
161
162 @Override
163 public void init(EndpointConfig config)
164 {
165 if (LOG.isDebugEnabled())
166 {
167 LOG.debug("init({})",config);
168 }
169
170 for (DecoderMetadata metadata : metadatas)
171 {
172 Wrapper wrapper = newWrapper(metadata);
173 activeWrappers.put(metadata.getObjectType(),wrapper);
174 }
175
176
177 for (Wrapper wrapper : activeWrappers.values())
178 {
179 wrapper.decoder.init(config);
180 }
181 }
182
183 public Wrapper newWrapper(DecoderMetadata metadata)
184 {
185 Class<? extends Decoder> decoderClass = metadata.getCoderClass();
186 try
187 {
188 Decoder decoder = containerScope.getObjectFactory().createInstance(decoderClass);
189 return new Wrapper(decoder,metadata);
190 }
191 catch (InstantiationException | IllegalAccessException e)
192 {
193 throw new IllegalStateException("Unable to instantiate Decoder: " + decoderClass.getName());
194 }
195 }
196 }