/** * Provide an instance of {@link javax.websocket.Encoder} or {@link javax.websocket.Decoder} * descendant which is coupled to {@link Session}. The first time the method is called the * provider creates an instance, calls {@link * javax.websocket.Encoder#init(javax.websocket.EndpointConfig)} or {@link * javax.websocket.Decoder#init(javax.websocket.EndpointConfig)} and caches it. Next time the * method is called the cached instance is returned. * * @param c {@link Class} whose instance will be provided. * @param collector error collector. * @param endpointConfig configuration corresponding to current context. Used for {@link * javax.websocket.Encoder#init(javax.websocket.EndpointConfig)} and {@link * javax.websocket.Decoder#init(javax.websocket.EndpointConfig)} * @param <T> type of the provided instance. * @return instance */ public <T> Object getCoderInstance( Class<T> c, Session session, EndpointConfig endpointConfig, ErrorCollector collector) { Object loaded = null; final Map<Class<?>, Object> classObjectMap = sessionToObject.get(session); try { if (classObjectMap != null) { synchronized (classObjectMap) { if (classObjectMap.containsKey(c)) { loaded = classObjectMap.get(c); } else { loaded = getInstance(c); if (loaded != null) { if (loaded instanceof Encoder) { ((Encoder) loaded).init(endpointConfig); } else if (loaded instanceof Decoder) { ((Decoder) loaded).init(endpointConfig); } sessionToObject.get(session).put(c, loaded); } } } } else { loaded = getInstance(c); if (loaded != null) { if (loaded instanceof Encoder) { ((Encoder) loaded).init(endpointConfig); } else if (loaded instanceof Decoder) { ((Decoder) loaded).init(endpointConfig); } final HashMap<Class<?>, Object> hashMap = new HashMap<Class<?>, Object>(); hashMap.put(c, loaded); sessionToObject.put(session, hashMap); } } } catch (InstantiationException e) { collector.addException( new DeploymentException( LocalizationMessages.COMPONENT_PROVIDER_THREW_EXCEPTION(c.getName()), e)); } return loaded; }
/** * Remove {@link Session} from cache. * * @param session to be removed. */ public void removeSession(Session session) { final Map<Class<?>, Object> classObjectMap = sessionToObject.get(session); if (classObjectMap != null) { synchronized (classObjectMap) { for (Object o : classObjectMap.values()) { if (o instanceof Encoder) { ((Encoder) o).destroy(); } else if (o instanceof Decoder) { ((Decoder) o).destroy(); } for (ComponentProvider componentProvider : providers) { if (componentProvider.destroy(o)) { break; } } } } } sessionToObject.remove(session); }