Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  */
 
 package com.sun.enterprise.web.portunif;
 
 import java.util.Map;
This Pipeline goal is to try to determine the TCP protocol used (http, soap, https, etc.). First, all ProtocolFinder are executed trying to determine which protocol is used. Once the protocol is found, the associated ProtocolHandler. You can add ProtocolHandler and ProtocolFinder by doing (from a SelectorThread) SelectorThread st = SelectorThread.getSelector(port); PortUnificationPipeline php = (PortUnificationPipeline)st.getReadPipeline(); php.addProtocolFinder(..); php.addProtocolHandler(...);

Author(s):
Jeanfrancois Arcand
 
 public class PortUnificationPipeline extends SSLPipeline{  
     private final static int MAX_RETRY = Integer.getInteger("com.sun.enterprise.web.portunif.PortUnificationPipeline.maxRetry", 2);
 
     public final static String PROTOCOL_FINDERS = 
             "com.sun.enterprise.web.connector.grizzly.protocolFinders";
     
     public final static String PROTOCOL_HANDLERS = 
             "com.sun.enterprise.web.connector.grizzly.protocolHandlers";

    
List of available ProtocolHandler.
            = new ConcurrentHashMap<String,ProtocolHandler>();

    
    
List of available ProtocolFinder.
            = new ConcurrentQueue<ProtocolFinder>("PortUnificationPipeline.protocolFinders");
    
    
    
List of available ProtocolFinder.
            Collections.synchronizedMap(
                new WeakHashMap<SelectionKey,ProtocolHandler>());
    
    
    
The SSLContext used for handshaking.
    private SSLContext sslContext;
    
    
    
Is the protocol of this listener configured
    private boolean isSet = false;
    
    
    
Is the protocol used secure.
    private boolean isRequestedTransportSecure = false;
    
    
    
A cached list of PUTask.
    private Queue<PUTaskpuTasks =
        new ConcurrentQueue<PUTask>("PortUnificationPipeline.puTasks");
    
    
    
Logger
    private static Logger logger = SelectorThread.getLogger();
    
    // ----------------------------------------------------------------------//
    
    
    public PortUnificationPipeline(){
        super();
        loadFinders();
        loadHandlers();
    }
    
    
    
Seek for the TCP protocol used. First all ProtocolFinder will be invoked. If the protocol is found, the associated ProtocolHandler will be executed. The execution of this method will occurs on the same thread and the main Selector (SelectorThread).

Parameters:
task An implementation of ReadTask
    @Override
    public void addTask(Task task) {    
        // Performance optimization used when a single protocol
        // is supported by this Pipeline.
        ProtocolHandler protocolHandler = null;
        boolean cachedHandler =  != null 
                && (protocolHandler = 
                        .get(task.getSelectionKey())) != null;
        SelectorThread selectorThread = task.getSelectorThread();
        KeepAlivePipeline kap = selectorThread == null ? null : 
                                        selectorThread.getKeepAlivePipeline();
        if (.isEmpty() 
                || kap == null
                || .isEmpty()
                || task.getType() != . 
                || (kap.isKeepAlive(task.getSelectionKey()) && !cachedHandler)){
            super.addTask(task);
            return;
        } 
        task.getSelectionKey().attach(null);
        
        if (!) {
             = 
                (task.getSelectorThread() instanceof SecureSelector
                    ? truefalse;
             = true;
            if (){
                 = ((SSLSelectorThread)task.getSelectorThread())
                                .getSSLContext();
            }
            
            if (! ||  == null) {
                if (  == null ){
                    Enumeration<SelectorThreadselectors 
                        = SelectorThread.getSelectors();                          
                    SelectorThread sel;
                    while (selectors.hasMoreElements()){
                        sel = selectors.nextElement();
                        if (sel instanceof SSLSelectorThread){
                             = 
                                    ((SSLSelectorThread)sel).getSSLContext();
                            if ( != null)
                                break;
                        }
                    }
                }
            }
            
            if ( == null){
                try{
                    SSLImplementation sslHelper = SSLImplementation.getInstance();
                    ServerSocketFactory serverSF = 
                            sslHelper.getServerSocketFactory();
                    serverSF.setAttribute("keystoreType","JKS");
                    serverSF.setAttribute("keystore",
                            System.getProperty("javax.net.ssl.keyStore"));
                    serverSF.setAttribute("truststoreType","JKS");
                    serverSF.setAttribute("truststore",
                            System.getProperty("javax.net.ssl.trustStore"));                    
                    serverSF.init();
                     = serverSF.getSSLContext();                    
                } catch(Throwable ex){
                    .log(.,
                               "SSL not supported.",ex);                    
                }
            }
        }      
        super.addTask(getPUTask((DefaultReadTask)task,protocolHandler));
    }
    
    
    private PUTask getPUTask(DefaultReadTask readTask,
            ProtocolHandler protocolHandler){
        PUTask task = .poll();
        if (task == null){
            task = new PUTask();
        }
        task.readTask = readTask;
        task.protocolHandler = protocolHandler;
        task.setSelectionKey(readTask.getSelectionKey());
        task.setSelectorThread(readTask.getSelectorThread());
        return task;
    }
    
    
    
Invoked when the SelectorThread is about to expire a SelectionKey.

Returns:
true if the SelectorThread should expire the SelectionKey, false if not.
    @Override
    public boolean expireKey(SelectionKey key){
        ProtocolHandler ph = .get(key);
        if (ph != null){           
            try{
                
Workaround issue 3615 This code is an ugly workaround as we cannot change the current API to handle this scenario. Since we can't predict what the user attach to the SelectionKey a ClassCastException is required.
                Long maxKeepAliveRequestsToken = (Longkey.attachment();
                if (maxKeepAliveRequestsToken == -1
                        && ph.getClass().getName().equals("com.sun.xml.ws.transport.tcp.grizzly.WSTCPProtocolHandler")){
                    return false;
                } 
            } catch (ClassCastException ex){
                if (.isLoggable(.)){
                    .log(.,"expireKey",ex);
                }
            }
            return ph.expireKey(key);
        } else {
            return true;
        }
    }       
    
    
PortUnification Grizzly Task implementation.
    private class PUTask extends TaskBase{
        
        final static int PU_TASK = 4;
        
        DefaultReadTask readTask;
        
        ProtocolInfo protocolInfo = new ProtocolInfo();
        
        private int maxTry = ;
        
        private ProtocolHandler protocolHandler = null;
        
        public void doTask(){
            // prevent multiple task.terminate that enqueues
            // same take to readTasks in SelectorThread
            boolean isTaskTerminated = false;
            
            if ( != null) {
                . = ;
            }
        
            SelectionKey key = .getSelectionKey();
            SSLEngine sslEngine = null;
            if (  ) {
                sslEngine = ((SSLReadTask)).getSSLEngine();
            }
            . = sslEngine;
            . = key;
            . = ;
            if (){
                SSLReadTask sslReadTask = (SSLReadTask);
                sslReadTask.allocateBuffers();
                . = sslReadTask.getInputBB();
                . = sslReadTask.getOutputBB();
            }
            . = .getByteBuffer();
                        
            boolean notFound = true;
            int readTry = 0;
            try{
                if ( == null){           
                    while (notFound && readTry++ < ){
                        String protocol = null;            
                        Iterator<ProtocolFinderiterator = .iterator();
                        while (iterator.hasNext()) {
                            try{
                                iterator.next().find();                                                           
                            } catch (IOException ex){
                                . = -1;
                                return;                    
                            } finally {
                                if (. == -1){
                                    isTaskTerminated = true;
                                    .terminate(false);
                                    return;
                                }                                                                
                            }
                            protocol = .;                     
                            if (protocol != null){
                                break;
                            }
                        }         
                        // Get the associated ProtocolHandler. If the current 
                        // SelectorThread can server the request, avoid redirection
                        if (protocol != null) {
                            notFound = false;
                            boolean isHttp = ..startsWith("http");
                             = .get(
                                    protocol.toLowerCase());
                            // Since Grizzly is listening by default for http, don't redirect
                            // if http is used and this pipeline can serve it.
                            boolean redirect = ( 
                                    == . && isHttp);               
                            // Tell the ReadTask we already have read bytes.
                            .setBytesAvailable(true);           
                            .setByteBuffer(.);
                            if ( != null && !redirect){
                                .handle();
                                if (!isHttp){
                                    if ( == null){
                                        new ConcurrentHashMap
                                                <SelectionKey,ProtocolHandler>();
                                    }
                                    .put(key,);
                                }
                                if (.){
                                    .registerKey();
                                }
                                isTaskTerminated = true;
                                .terminate(.);                            
                            } else { 
                                if (  ) {
                                    ((SSLReadTask)).setHandshake(false);
                                }
                                .doTask();
                                if (.getSelectionKey() != key) {
                                   isTaskTerminated = true;
                                }
                            } 
                        } else {
                            // If the protocol wasn't found, it might be because 
                            // lack of missing bytes. Thus we must register the key for 
                            // extra bytes. The trick here is to re-use the ReadTask
                            // ByteBufferInpuStream.
                            final boolean isSslBuffer = !.;
                            ByteBuffer tmpBB;
                            
                            if (isSslBuffer) {
                                tmpBB = .;
                            } else {
                                tmpBB = .;
                            }
                            if (!tmpBB.hasRemaining()) {
                                tmpBB.clear();
                            }
                            
                            int byteAvailables = tmpBB.position();
                            ByteBufferInputStream.readBlocking(
                                    (SocketChannelkey.channel(), tmpBB, 1000);
                            
                            if ((tmpBB.position() - byteAvailables) <= 0){
                                isTaskTerminated = true;
                                cancel(,tmpBB);    
                                return;
                            }
                            
//                            protocolInfo.byteBuffer = tmpBB;
                        }
                    } 
                } else {
                    .handle();
                    .registerKey();
                    isTaskTerminated = true;
                    .terminate(true);
                }
            } catch (Throwable ex){
                notFound = false;
                if (.isLoggable(.)){
                    .log(.,"PortUnification exception",ex);
                }   
                if (!isTaskTerminated) {
                    isTaskTerminated = true;
                    cancel(.);
                }
                
                cancel(,.);         
            } finally {                                
                if (readTry >=  && !isTaskTerminated){
                    cancel(,.);
                } 
                 = null;
                 = null;
                .recycle();
                .offer(this);                
            }
        }
        
        
        @Override
        public int getType(){
            return ;
        }
        private void cancel(Task task,ByteBuffer bb){
            // Prevent calling multiple terminate.
            if ( == null || task == null
                    || task.getSelectionKey() != ) {
                return;
            }
            if (.isLoggable(.
                    || task.getSelectorThread().isEnableNioLogging() ){                
                .log(.,"Invalid request from: " +
                           task.getSelectionKey().channel() 
                           + " " + bb.remaining());
            }
            .terminate(false);
        }
        
        
        
When the Task is completed, make sure it is removed from the cached list.
        @Override
        public void taskEvent(TaskEvent event) {
        }
    }

    
    
Load ProtocolHandler defined as a System property (-Dcom.sun.enterprise.web.connector.grizzly.protocolHandlers=... , ...)
    private void loadHandlers(){      
        if ( System.getProperty() != null){
            StringTokenizer st = new StringTokenizer(
                    System.getProperty(),",");
            
            while (st.hasMoreTokens()){
                ProtocolHandler protocolHandler = (ProtocolHandler)
                    loadInstance(st.nextToken());
                if ( protocolHandler != null) {
                    String[] protocols = protocolHandler.getProtocols();
                    for(String protocolprotocols) {
                        if (protocol != null) {
                            .put(protocol.toLowerCase(), protocolHandler);
                        }
                    }
                }
            } 
        }   
    }
    
    
    
Load ProtocolFinder defined as a System property (-Dcom.sun.enterprise.web.connector.grizzly.protocolFinders=... , ...)
    
    private void loadFinders(){      
        if ( System.getProperty() != null){
            StringTokenizer st = new StringTokenizer(
                    System.getProperty(),",");
            
            while (st.hasMoreTokens()){
                ProtocolFinder protocolFinder = (ProtocolFinder)
                    loadInstance(st.nextToken());
                .offer(protocolFinder);
            } 
        }   
    }
    

    
Util to load classes using reflection.
    private Object loadInstance(String property){        
        Class className = null;                               
        try{                              
            className = Class.forName(property,true,
                    Thread.currentThread().getContextClassLoader());
            return className.newInstance();
        } catch (Throwable t) {
            // Log me 
        }   
        return null;
    }  
    
    
    
Add an instance of ProtocolFinder
    public void addProtocolFinder(ProtocolFinder protocolFinder){
        .offer(protocolFinder);
    }
    
    
    
Add an instance of ProtocolHandler
    public void addProtocolHandler(ProtocolHandler protocolHandler){
        String[] protocols = protocolHandler.getProtocols();
        for(String protocolprotocols){
            .put(protocol,protocolHandler);  
        }
    }   
    
    
    
Remove a ProtocolFinder
    public void removeProtocolFinder(ProtocolFinder protocolFinder){
        .remove(protocolFinder);
    }
    
    
    
Remove a ProtocolHandler
    public void removeProtocolHandler(ProtocolHandler protocolHandler){
        String[] protocols = protocolHandler.getProtocols();
        for(String protocolprotocols){
            .remove(protocol);  
        }
    } 
New to GrepCode? Check out our FAQ X