Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *  Licensed to the Apache Software Foundation (ASF) under one or more
   *  contributor license agreements.  See the NOTICE file distributed with
   *  this work for additional information regarding copyright ownership.
   *  The ASF licenses this file to You under the Apache License, Version 2.0
   *  (the "License"); you may not use this file except in compliance with
   *  the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
 package org.apache.tomcat.websocket.server;
 
 import static org.jboss.web.WebsocketsMessages.MESSAGES;
 
 import java.util.Map;
 import java.util.Set;
 
 
Provides a per class loader (i.e. per web application) instance of a ServerContainer. Web application wide defaults may be configured by setting the following servlet context initialisation parameters to the desired values.
 
 public class WsServerContainer extends WsWebSocketContainer
         implements ServerContainer {
 
     private static final CloseReason AUTHENTICATED_HTTP_SESSION_CLOSED =
 
     private final WsWriteTimeout wsWriteTimeout = new WsWriteTimeout();
 
     private final ServletContext servletContext;
     private final Map<String,ServerEndpointConfigconfigExactMatchMap =
             new ConcurrentHashMap<StringServerEndpointConfig>();
     private volatile boolean enforceNoAddAfterHandshake =
     private volatile boolean addAllowed = true;
             new ConcurrentHashMap<StringSet<WsSession>>();
     private final ExecutorService executorService;
     private final ThreadGroup threadGroup;
     private volatile boolean endpointsRegistered = false;
     private final ClassIntrospecter classIntrospecter;
 
 
    WsServerContainer(ServletContext servletContext) {
        this. = servletContext;
        ClassIntrospecter classIntrospecter = (ClassIntrospecterservletContext.getAttribute(ClassIntrospecter.class.getName());
        servletContext.removeAttribute(ClassIntrospecter.class.getName()); //remove the attribute as it is only needed for bootstrap
        if(classIntrospecter == null) {
            classIntrospecter = null;
        }
        this. = classIntrospecter;
        //this is a horrible horrible hack.
        ThreadBindingListener threadBindingListener = (ThreadBindingListener)servletContext.getAttribute(ThreadBindingListener.class.getName());
        servletContext.removeAttribute(ThreadBindingListener.class.getName());
        if(threadBindingListener != null) {
            this. = threadBindingListener;
        } else {
        }
        // Configure servlet context wide defaults
        String value = servletContext.getInitParameter(
        if (value != null) {
            setDefaultMaxBinaryMessageBufferSize(Integer.parseInt(value));
        }
        value = servletContext.getInitParameter(
        if (value != null) {
            setDefaultMaxTextMessageBufferSize(Integer.parseInt(value));
        }
        value = servletContext.getInitParameter(
        if (value != null) {
            setEnforceNoAddAfterHandshake(Boolean.parseBoolean(value));
        }
        // Executor config
        int executorCoreSize = 0;
        long executorKeepAliveTimeSeconds = 60;
        value = servletContext.getInitParameter(
                .);
        if (value != null) {
            executorCoreSize = Integer.parseInt(value);
        }
        value = servletContext.getInitParameter(
        if (value != null) {
            executorKeepAliveTimeSeconds = Long.parseLong(value);
        }
        FilterRegistration.Dynamic fr = servletContext.addFilter(
                "Tomcat WebSocket (JSR356) Filter"new WsFilter());
        fr.setAsyncSupported(true);
        EnumSet<DispatcherTypetypes = EnumSet.of(.,
                .);
        fr.addMappingForUrlPatterns(typestrue"/*");
        // Use a per web application executor for any threads the the WebSocket
        // server code needs to create. Group all of the threads under a single
        // ThreadGroup.
        StringBuffer threadGroupName = new StringBuffer("WebSocketServer-");
        if ("".equals(servletContext.getContextPath())) {
            threadGroupName.append("ROOT");
        } else {
            threadGroupName.append(servletContext.getContextPath());
        }
         = new ThreadGroup(threadGroupName.toString());
        WsThreadFactory wsThreadFactory = new WsThreadFactory();
         = new ThreadPoolExecutor(executorCoreSize,
                .executorKeepAliveTimeSeconds.,
                new SynchronousQueue<Runnable>(), wsThreadFactory);
    }


    
Published the provided endpoint implementation at the specified path with the specified configuration. WsServerContainer(javax.servlet.ServletContext) must be called before calling this method.

Parameters:
sec The configuration to use when creating endpoint instances
Throws:
javax.websocket.DeploymentException
    @Override
    public void addEndpoint(ServerEndpointConfig sec)
            throws DeploymentException {
        if ( && !) {
            throw new DeploymentException(.addNotAllowed());
        }
        if ( == null) {
            throw new DeploymentException(.missingServletContext());
        }
        String path = sec.getPath();
        UriTemplate uriTemplate = new UriTemplate(path);
        if (uriTemplate.hasParameters()) {
            Integer key = Integer.valueOf(uriTemplate.getSegmentCount());
            SortedSet<TemplatePathMatchtemplateMatches =
                    .get(key);
            if (templateMatches == null) {
                // Ensure that if concurrent threads execute this block they
                // both end up using the same TreeSet instance
                templateMatches = new TreeSet<TemplatePathMatch>(
                        TemplatePathMatchComparator.getInstance());
                .putIfAbsent(keytemplateMatches);
                templateMatches = .get(key);
            }
            if (!templateMatches.add(new TemplatePathMatch(securiTemplate))) {
                // Duplicate uriTemplate;
                throw new DeploymentException(.duplicatePaths(path));
            }
        } else {
            // Exact match
            ServerEndpointConfig old = .put(pathsec);
            if (old != null) {
                // Duplicate path mappings
                throw new DeploymentException(.duplicatePaths(path));
            }
        }
         = true;
    }


    
Provides the equivalent of addEndpoint(javax.websocket.server.ServerEndpointConfig) for publishing plain old java objects (POJOs) that have been annotated as WebSocket endpoints.

Parameters:
pojo The annotated POJO
    @Override
    public void addEndpoint(Class<?> pojothrows DeploymentException {
        ServerEndpoint annotation = pojo.getAnnotation(ServerEndpoint.class);
        if (annotation == null) {
            throw new DeploymentException(.cannotDeployPojo(pojo.getName()));
        }
        String path = annotation.value();
        // Validate encoders
        validateEncoders(annotation.encoders());
        // Method mapping
        PojoMethodMapping methodMapping = new PojoMethodMapping(pojo,
                annotation.decoders(), path);
        // ServerEndpointConfig
        ServerEndpointConfig sec;
        Class<? extends ConfiguratorconfiguratorClazz =
                annotation.configurator();
        Configurator configurator = null;
        if (!configuratorClazz.equals(Configurator.class)) {
            try {
                configurator = annotation.configurator().newInstance();
            } catch (InstantiationException e) {
                throw new DeploymentException(.configuratorFailed(annotation.configurator().getName(),
                        pojo.getClass().getName()), e);
            } catch (IllegalAccessException e) {
                throw new DeploymentException(.configuratorFailed(annotation.configurator().getName(),
                        pojo.getClass().getName()), e);
            }
        } else if( != null) {
            try {
                configurator = new ServerInstanceFactoryConfigurator(.createInstanceFactory(pojo));
            } catch (NoSuchMethodException e) {
                        pojo.getClass().getName()), e);
            }
        }
        sec = ServerEndpointConfig.Builder.create(pojopath).
                decoders(Arrays.asList(annotation.decoders())).
                encoders(Arrays.asList(annotation.encoders())).
                subprotocols(Arrays.asList(annotation.subprotocols())).
                configurator(configurator).
                build();
        sec.getUserProperties().put(
                .,
                methodMapping);
        addEndpoint(sec);
    }
    @Override
    public void destroy() {
        shutdownExecutor();
        super.destroy();
        // If the executor hasn't fully shutdown it won't be possible to
        // destroy this thread group as there will still be threads running.
        // Mark the thread group as daemon one, so that it destroys itself
        // when thread count reaches zero.
        // Synchronization on threadGroup is needed, as there is a race between
        // destroy() call from termination of the last thread in thread group
        // marked as daemon versus the explicit destroy() call.
        int threadCount = .activeCount();
        boolean success = false;
        try {
            while (true) {
                int oldThreadCount = threadCount;
                synchronized () {
                    if (threadCount > 0) {
                        Thread.yield();
                        threadCount = .activeCount();
                    }
                    if (threadCount > 0 && threadCount != oldThreadCount) {
                        // Value not stabilized. Retry.
                        continue;
                    }
                    if (threadCount > 0) {
                        .setDaemon(true);
                    } else {
                        .destroy();
                        success = true;
                    }
                    break;
                }
            }
        } catch (IllegalThreadStateException exception) {
            // Fall-through
        }
        if (!success) {
            ..threadGroupNotDestryed(.getName(), Integer.valueOf(threadCount));
        }
    }
    boolean areEndpointsRegistered() {
        return ;
    }
    public void doUpgrade(HttpServletRequest request,
            HttpServletResponse responseServerEndpointConfig sec,
            Map<String,StringpathParams)
            throws ServletExceptionIOException {
        UpgradeUtil.doUpgrade(thisrequestresponsesecpathParams);
    }
    public WsMappingResult findMapping(String path) {
        // Prevent registering additional endpoints once the first attempt has
        // been made to use one
        if () {
             = false;
        }
        // Check an exact match. Simple case as there are no templates.
        ServerEndpointConfig sec = .get(path);
        if (sec != null) {
            return new WsMappingResult(sec,
                    Collections.<StringStringemptyMap());
        }
        // No exact match. Need to look for template matches.
        UriTemplate pathUriTemplate = null;
        try {
            pathUriTemplate = new UriTemplate(path);
        } catch (DeploymentException e) {
            // Path is not valid so can't be matched to a WebSocketEndpoint
            return null;
        }
        // Number of segments has to match
        Integer key = Integer.valueOf(pathUriTemplate.getSegmentCount());
        SortedSet<TemplatePathMatchtemplateMatches =
                .get(key);
        if (templateMatches == null) {
            // No templates with an equal number of segments so there will be
            // no matches
            return null;
        }
        // List is in alphabetical order of normalised templates.
        // Correct match is the first one that matches.
        Map<String,StringpathParams = null;
        for (TemplatePathMatch templateMatch : templateMatches) {
            pathParams = templateMatch.getUriTemplate().match(pathUriTemplate);
            if (pathParams != null) {
                sec = templateMatch.getConfig();
                break;
            }
        }
        if (sec == null) {
            // No match
            return null;
        }
        if (!PojoEndpointServer.class.isAssignableFrom(sec.getEndpointClass())) {
            // Need to make path params available to POJO
            sec.getUserProperties().put(
                    .,
                    pathParams);
        }
        return new WsMappingResult(secpathParams);
    }
    public boolean isEnforceNoAddAfterHandshake() {
        return ;
    }
    public void setEnforceNoAddAfterHandshake(
            boolean enforceNoAddAfterHandshake) {
        this. = enforceNoAddAfterHandshake;
    }
    protected WsWriteTimeout getTimeout() {
        return ;
    }


    
Overridden to make it visible to other classes in this package.
    @Override
    protected void registerSession(Endpoint endpointWsSession wsSession) {
        super.registerSession(endpointwsSession);
        if (wsSession.isOpen() &&
                wsSession.getUserPrincipal() != null &&
                wsSession.getHttpSessionId() != null) {
            registerAuthenticatedSession(wsSession,
                    wsSession.getHttpSessionId());
        }
    }


    
Overridden to make it visible to other classes in this package.
    @Override
    protected void unregisterSession(Endpoint endpointWsSession wsSession) {
        if (wsSession.getUserPrincipal() != null &&
                wsSession.getHttpSessionId() != null) {
            unregisterAuthenticatedSession(wsSession,
                    wsSession.getHttpSessionId());
        }
        super.unregisterSession(endpointwsSession);
    }
    private void registerAuthenticatedSession(WsSession wsSession,
            String httpSessionId) {
        Set<WsSessionwsSessions = .get(httpSessionId);
        if (wsSessions == null) {
            wsSessions = Collections.newSetFromMap(
                     new ConcurrentHashMap<WsSession,Boolean>());
             .putIfAbsent(httpSessionIdwsSessions);
             wsSessions = .get(httpSessionId);
        }
        wsSessions.add(wsSession);
    }
    private void unregisterAuthenticatedSession(WsSession wsSession,
            String httpSessionId) {
        Set<WsSessionwsSessions = .get(httpSessionId);
        // wsSessions will be null if the HTTP session has ended
        if (wsSessions != null) {
            wsSessions.remove(wsSession);
        }
    }
    public void closeAuthenticatedSession(String httpSessionId) {
        Set<WsSessionwsSessions = .remove(httpSessionId);
        if (wsSessions != null && !wsSessions.isEmpty()) {
            for (WsSession wsSession : wsSessions) {
                try {
                    wsSession.close();
                } catch (IOException e) {
                    // Any IOExceptions during close will have been caught and the
                    // onError method called.
                }
            }
        }
    }
        return ;
    }
    @Override
        return ;
    }
    public ClassLoader getClassLoader() {
        return .getClassLoader();
    }
    private void shutdownExecutor() {
        if ( == null) {
            return;
        }
        .shutdown();
        try {
            .awaitTermination(10, .);
        } catch (InterruptedException e) {
            // Ignore the interruption and carry on
        }
    }
    private static void validateEncoders(Class<? extends Encoder>[] encoders)
            throws DeploymentException {
        for (Class<? extends Encoderencoder : encoders) {
            // Need to instantiate decoder to ensure it is valid and that
            // deployment can be failed if it is not
            @SuppressWarnings("unused")
            Encoder instance;
            try {
                encoder.newInstance();
            } catch(InstantiationException e) {
                throw new DeploymentException(.cannotInstatiateEncoder(encoder.getName()), e);
            } catch (IllegalAccessException e) {
                throw new DeploymentException(.cannotInstatiateEncoder(encoder.getName()), e);
            }
        }
    }
    private static class TemplatePathMatch {
        private final ServerEndpointConfig config;
        private final UriTemplate uriTemplate;
        public TemplatePathMatch(ServerEndpointConfig config,
                UriTemplate uriTemplate) {
            this. = config;
            this. = uriTemplate;
        }
        public ServerEndpointConfig getConfig() {
            return ;
        }
        public UriTemplate getUriTemplate() {
            return ;
        }
    }


    
This Comparator implementation is thread-safe so only create a single instance.
    private static class TemplatePathMatchComparator
            implements Comparator<TemplatePathMatch> {
        private static final TemplatePathMatchComparator INSTANCE =
                new TemplatePathMatchComparator();
        public static TemplatePathMatchComparator getInstance() {
            return ;
        }
        private TemplatePathMatchComparator() {
            // Hide default constructor
        }
        @Override
        public int compare(TemplatePathMatch tpm1TemplatePathMatch tpm2) {
            return tpm1.getUriTemplate().getNormalizedPath().compareTo(
                    tpm2.getUriTemplate().getNormalizedPath());
        }
    }
    private static class WsThreadFactory implements ThreadFactory {
        private final ThreadGroup tg;
        private final AtomicLong count = new AtomicLong(0);
        private WsThreadFactory(ThreadGroup tg) {
            this. = tg;
        }
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setName(.getName() + "-" + .incrementAndGet());
            return t;
        }
    }
    private static final class ServerInstanceFactoryConfigurator extends ServerEndpointConfig.Configurator {
        private final InstanceFactory factory;
        private ServerInstanceFactoryConfigurator(final InstanceFactory factory) {
            this. = factory;
        }
        @Override
        public <T> T getEndpointInstance(final Class<T> endpointClassthrows InstantiationException {
            return (T) .createInstance();
        }
    }
New to GrepCode? Check out our FAQ X