OW2 Consortium telosys

Rev

Blame | Last modification | View Log | RSS feed

package org.objectweb.telosys.uil.screenmap;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.objectweb.telosys.common.Telosys;
import org.objectweb.telosys.common.TelosysException;
import org.objectweb.telosys.common.TelosysServlet;
import org.objectweb.telosys.rpl.ScreenRequestParameters;
import org.objectweb.telosys.screen.core.ScreenContext;
import org.objectweb.telosys.screen.env.ScreenContextManager;
import org.objectweb.telosys.uil.RequestEnv;
import org.objectweb.telosys.uil.TelosysUIL;
import org.objectweb.telosys.util.StrUtil;
import org.objectweb.telosys.util.web.WebUtil;


/**
 * The servlet dedicated to the screenmap requests management <br>
 * This servlet is invoked when the client side requests for a screenmap  <br>
 * Example : /context/screenmap/S001-html/1:use <br>
 * 
 * @author Laurent GUERIN
 *  
 */
public class ScreenMapServlet extends TelosysServlet // HttpServlet
{
    
    //---------------------------------------------------------------------------
    // INNER CLASS for ScreenMap request parsing
    //---------------------------------------------------------------------------
        private static class ScreenMapRequest 
        {
            String sScreenMapName = null ;
            String sScreenMapType = null ;
            String sContextId     = null ;
            int    iContextId     = 0 ;
            String sContextName   = null ;
            String sContextAction = null ;          
        }
        
    //---------------------------------------------------------------------------
    
    private final static String SEPARATOR = "- - - - - - - - - - - - - - - - - - - - - - - - - - - -" ;
    
    private final static String      SCREEN_NAME        = "name";

    private final static String      SCREEN_TYPE        = "type";

    private final static String      SCREEN_ID          = "id";

    private final static String      SCREEN_ACTION      = "action";

//    private final static String      ACTION_OPEN        = "open";
//
//    private final static String      ACTION_USE         = "use";
//
//    private final static String      ACTION_NONE        = "none";

    private static ScreenDefinitions _screenDefinitions = null;

    //private static boolean           _bAutoOpenContext  = false;
    private static String            _sDefaultAction    = null ;

    //---------------------------------------------------------------------------
    private void traceRootDir( String sType, ScreenDefRootDir rootDir ) throws ServletException
    {
        trace( sType + " Root Dir : ");

        trace(". Template : " + rootDir.getTemplateRootDir());
        trace(". Body     : " + rootDir.getBodyRootDir());
        trace(". Page     : " + rootDir.getPageRootDir());
        trace(". Script   : " + rootDir.getScriptRootDir());
        trace(". CSS      : " + rootDir.getCssRootDir());
        trace(". Images   : " + rootDir.getImagesRootDir());        
    }
    //---------------------------------------------------------------------------
    /* (non-Javadoc)
     * @see javax.servlet.GenericServlet#init()
     */
    public final void init() throws ServletException
    {
        info(SEPARATOR);
        info("ScreenMap servlet init ...");

        info(" - Retrieve ScreenMap definitions ...");
        _screenDefinitions = TelosysUIL.getScreenDefinitions();
        //--- If UIL is not yet initialized
        if (_screenDefinitions == null)
        {
            trace("init UIL ...");            
            TelosysUIL.init( getServletContext() );
            trace("get ScreenMap definitions...");
            _screenDefinitions = TelosysUIL.getScreenDefinitions();
            if (_screenDefinitions == null)
            {
                error("Cannot get the screen definitions !");
                return;
            }
        }

        info("  " + _screenDefinitions.getScreenDefCount() + " screen definitions loaded ");
        info("  Telosys application root dir = " + Telosys.getWebAppRootDir());

        ScreenDefConfig config = _screenDefinitions.getConfig();
        if (config != null)
        {
            //_bAutoOpenContext = config.getAutoOpenContext();
            String s = config.getDefaultAction() ;
            if ( s != null )
            {
                _sDefaultAction = s.trim().toLowerCase() ;                
            }
            info("Config : ");
            info(". Telosys JAR file          : " + config.getTelosysJarFile());
            info(". Framework javascript file : " + config.getFrameworkJavascriptFile());
            info(". Framework CSS directory   : " + config.getFrameworkCSSDir());
            info(". Screen Map URL            : " + config.getScreenMapUrl());
            info(". AJAX request URL          : " + config.getAjaxRequestUrl());
            info(". Default action            : " + _sDefaultAction);
        }
        else
        {
            error("Cannot get config from screen definitions !");
        }

        ScreenDefRootDir rootDir = _screenDefinitions.getHtmlRootDir();
        if (rootDir != null)
        {
            traceRootDir("HTML", rootDir);
            /***
            trace("HTML Root Dir : ");
            trace(". Template : " + rootDir.getTemplateRootDir());
            trace(". Body     : " + rootDir.getBodyRootDir());
            trace(". Page     : " + rootDir.getPageRootDir());
            trace(". Script   : " + rootDir.getScriptRootDir());
            trace(". CSS      : " + rootDir.getCssRootDir());
            trace(". Images   : " + rootDir.getImagesRootDir());
            ***/
        }
        else
        {
            error("Cannot get 'HTML root dir' from screen definitions !");
        }
        
        rootDir = _screenDefinitions.getXulRootDir();
        if (rootDir != null)
        {
            traceRootDir("XUL", rootDir);
        }
        else
        {
            error("Cannot get 'XUL root dir' from screen definitions !");
        }

//        //--- Extract the file "telosys.js" from "telosys.jar"
// NOW DONE IN "TelosysUIL"
//        if (config != null)
//        {
//            String sJarFile = config.getTelosysJarFile();
//            info("Extracting framework files from JAR (" + sJarFile + ") ...");
//            info("  Config framework CSS dir      = '" + config.getFrameworkCSSDir() + "' ");
//            info("  File system framework CSS dir = '" + config.getFrameworkCSSDirPath() + "' ");
//            
//            //--- Extract the Javascript framework file 
//            extract(sJarFile, "js/telosys.js", config.getFrameworkJavascriptFilePath() );
//            
//            //--- Extract all the CSS files ( all the "css" directory in the JAR file )
//            try
//            {
//                JarUtil.extractFiles(sJarFile, "css", config.getFrameworkCSSDirPath(), JarUtil.REMOVE_PARENT_DIR );
//            } catch (TelosysException e)
//            {
//                error("Cannot extract 'css' framework files from '" + sJarFile + "' !");
//                e.printStackTrace();
//            }
//            //--- Extract the file "telosys.css"
//            extract(sJarFile, "css/telosys.css", config.getFrameworkCSSFilePath(TelosysUIL.TELOSYS_CSS_FILE) ); 
//        }
//        else
//        {
//            error("Config is null => Cannot extract framework files from JAR !");
//        }
        info("End of ScreenMap servlet init.");
        info(SEPARATOR);
    }

    //---------------------------------------------------------------------------
//    private void extract(String sJarFile, String sJarEntry, String sDestFile) 
//    {
//        info(" . Extracting file '" + sJarEntry + "' to '" + sDestFile + "' ...");
//        try
//        {
//            JarUtil.extract(sJarFile, sJarEntry, sDestFile);
//        } catch (TelosysException e)
//        {
//            error("Cannot set '" + sDestFile + "' from '" + sJarFile + "' !");
//            e.printStackTrace();
//        }
//    }

    //---------------------------------------------------------------------------
    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        trace("========================================");
        trace("doGet()");
        process(request, response);
    }

    //---------------------------------------------------------------------------
    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        trace("========================================");
        trace("doPost()");
        process(request, response);
    }

    //---------------------------------------------------------------------------
    /* (non-Javadoc)
     * @see javax.servlet.Servlet#destroy()
     */
    public void destroy()
    {
        trace("destroy()");
    }

    //---------------------------------------------------------------------------
    /**
     * Returns true if the request URI is conform to the new syntax <br>
     * . New syntax : "/context/screenmap/Xxxx" or "/context/screenmap/Xxxx/xxx"  <br>
     * . Old syntax : "/context/screenmap?name=Xxxx" <br>
     * @param request
     * @return
     */
    private boolean isNewFashionRequest(HttpServletRequest request ) 
    {
                String sPathInfo = request.getPathInfo() ;
                if ( sPathInfo != null ) // there's somethig after "/context/screenmap" 
                {
                    if ( sPathInfo.length() > 0 ) 
                    {
                    //--- New URI syntax ( /context/screenmap/Xxxx or /context/screenmap/Xxxx/xxx ) 
                            return true ; // New fashion
                    }
                }
            return false ; // Old fashion
    }
    //---------------------------------------------------------------------------
    private void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        trace("process()... URL = " + request.getRequestURL() );
        
        //--- Avoid Browser caching 
        WebUtil.noCache(response);
        
        if (_screenDefinitions == null)
        {
            String sMsg = "Screens definitions are not initialized ! ";
            error(sMsg);
            response_error(request, response, sMsg);
            return;
        }        
        
                ScreenMap screenMap = null;
                
//              String sURI = request.getRequestURI(); // "/context/screenmap/aaa/bbb/ccc"
//              if ( StrUtil.countChar( sURI, '/' ) > 2 ) // at least 3 '/' in the "new fashion URI"
//              {
//            //--- New URI ( /context/screenmap/Xxxx or /context/screenmap/Xxxx/xxx ) => New fashion request
//                  screenMap = processNewFashion(request, response);
//              }
//              else
//              {
//            //--- Old fashion request ( /context/screenmap?name=Xxxx )
//                  screenMap = processOldFashion(request, response);
//              }

                if ( isNewFashionRequest(request) ) 
                {
            //--- New URI ( /context/screenmap/Xxxx or /context/screenmap/Xxxx/xxx ) => New fashion request
                    screenMap = processNewFashion(request, response);
                }
                else
                {
            //--- Old fashion request ( /context/screenmap?name=Xxxx )
                    screenMap = processOldFashion(request, response);
                }
                
        if ( screenMap != null )
        {            
                //--- Set the Screen Map object as request attribute
                request.setAttribute(ScreenMapConst.SCREEN_MAP, screenMap);
                trace("Screen map set as request attribute");
        
                //--- Retrieve the main target URL of the screen map
                String sScreenMapUrl = screenMap.getTargetPath();
                if (sScreenMapUrl == null)
                {
                    String sMsg = "No URL for the screen : " + screenMap.getName() + " ( type = " + screenMap.getType() + " )";
                    error(sMsg);
                    response_error(request, response, sMsg);
                    return;
                }
                
                //--- Forward to the Screen Map Target URL (usualy the screenmap template)
                trace("Forward to " + sScreenMapUrl);
                boolean bForwardOk = forward(sScreenMapUrl, request, response);
                if (!bForwardOk)
                {
                    String sMsg = "Cannot forward to " + sScreenMapUrl;
                    error(sMsg);
                    response_error(request, response, sMsg);
                    return;
                }
                else
                {
                    // Forward OK => notify the navigation 
                    navigation(request, screenMap );
                }
        }
    }
    //---------------------------------------------------------------------------
    /**
     * Hook method designed to be overridden in a subclasse
     * @param screenMap
     * @param request
     */
    protected void navigation(HttpServletRequest request, ScreenMap screenMap )
    {
        trace("navigation() : " + request.getRequestURI() +")");
    }
    //---------------------------------------------------------------------------
    /**
     * Try to retrieve the requested ScreenMap and prepare the associated ScreenContext if any
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    private ScreenMap processNewFashion(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        trace("processNewFashion()...");
//        String sURI = request.getRequestURI(); // "/context/aaaa/bbb/ccc"
//        String sContextPath = request.getContextPath() ; // "/context"
//        String s = sURI.substring(sContextPath.length()); // "/aaaa/bbb/ccc"
        
        // ScreenMapRequest smr = parseURI(request);
        ScreenMapRequest smr = null ;        
        try
        {
            smr = parseURI(request);
        } catch (TelosysException e1) // v 1.0.4
        {
            String sMsg = "Cannot parse URI : " + e1.getMessage() ;
                error(sMsg);
                response_error(request, response, sMsg, e1);
                return null ;
        }
        
        if ( smr != null )
        {
            //--- Get a Screen Map instance from the Screen Definitions
            trace("call getScreenMap(" + smr.sScreenMapName + "," + smr.sScreenMapType 
                    + "," + smr.iContextId 
                    + "," + smr.sContextName 
                    + "," + smr.sContextAction 
                    + ")...");
            
            ServletContext servletContext = getServletContext() ;
            //ScreenMap screenMap = _screenDefinitions.getScreenMap(smr.sScreenMapName, smr.sScreenMapType, smr.iContextId, smr.sContextName );
            ScreenMap screenMap = _screenDefinitions.getScreenMap( servletContext, // v 1.0.5 ( + servletContext )
                    smr.sScreenMapName, smr.sScreenMapType, 
                    smr.iContextId, smr.sContextName, smr.sContextAction ); // v 1.0.5 ( + sContextAction )
            // NB : 
            //  at this step, the ContextId can be "-1" (dynamic) or "0,1,2,...,N" in the ScreenMap instance
            //  but not "undefined"

            if (screenMap != null)
            {
                ScreenContext screenContext = null ;
                //--- Try to prepare the ScreenContext 
                try
                {
                    ScreenRequestParameters params = getRequestParameters(request, response );
                    //screenContext = prepareScreenContext(request, response, smr.sContextName, smr.iContextId, smr.sContextAction, params );
                    screenContext = prepareScreenContext(request, response, screenMap, params ); // v 1.0.5
                    // NB : the ScreenContext can be null
                    
                    //--- Apply the Screen Context informations on the ScreenMap 
                    //--- The ContextId of the ScreenMap is affected HERE if the ScreenContext is not null 
                    screenMap.setAssociatedScreenContext(screenContext); 
                    
                } catch (TelosysException e)
                {
//                    String sMsg = "Cannot prepare screen context ( name='" + smr.sContextName 
//                      + "', id=" + smr.iContextId + ", action='" + smr.sContextAction + "' ) " ;
                    String sMsg = "Cannot prepare screen context ( name='" + screenMap.getScreenContextName() 
                                + "', id=" + screenMap.getScreenContextId() 
                                + ", action='" + screenMap.getScreenContextAction() + "' ) " ;
                    error(sMsg);
                    response_error(request, response, sMsg, e);
                    return null ;
                }

                //--- EXPOSE THE SCREEN CONTEXT for TAGLIB and EXPOSE DATA ELEMENTS for standard JSP E.L. 
                //--- Create a request environment and and expose it at "request level" 
                //RequestEnv.setEnv(request, screenContext); // v 0.9.9
                RequestEnv.setEnv(request, screenContext, RequestEnv.EXPOSE_DATA); // v 1.0.1
                
//                //--- Expose the ScreenContext if any 
//                if ( screenContext != null )
//                {
//                    ScreenData screenData = screenContext.getCurrentData() ;
//                    if ( screenData != null )
//                    {
//                        screenData.exposeData(request); // since v 1.0.1 : Done in "RequestEnv.setENV"
//                    }
//                }
                
                return screenMap ;
            }
            else
            {
                String sMsg = "Cannot get the screen map : getScreenMap(" + smr.sScreenMapName + "," + smr.sScreenMapType + "," + smr.iContextId + ")";
                error(sMsg);
                response_error(request, response, sMsg);
                return null ;
            }
            
        }
        else
        {
            String sMsg = "Invalid URI : '" + request.getRequestURI() + "'" ;
            error(sMsg);
            response_error(request, response, sMsg );
            return null ;
        }
    }
    //---------------------------------------------------------------------------
    private ScreenRequestParameters getRequestParameters(HttpServletRequest request, HttpServletResponse response )
    {
//        ScreenRequestParameters params = new ScreenRequestParameters();
//        Map map = request.getParameterMap();
//        if ( map != null )
//        {
//            if ( map.size() > 0 )
//            {
//              Set set = map.entrySet();
//              Iterator iter = set.iterator() ;
//              for ( int i = 0 ; iter.hasNext() ; i++ )
//              {
//                  Map.Entry entry = (Map.Entry) iter.next();
//                  String   sKey  = (String)   entry.getKey() ;
//                  String[] array = (String[]) entry.getValue() ;
//                  String   sVal  = array.length > 0 ? array[0] : "" ;
//                  
//                  params.setParameter( sKey, sVal );
//              }
//            }
//        }
//        return params ;
        
        return new ScreenRequestParameters( request.getParameterMap() ); // v 1.0.2
    }

    /**
     * Prepare a ScreenContext if necessary, depending on the given ScreenAction 
     * @param request
     * @param response
     * @param screenMap
     * @param params
     * @return
     * @throws ServletException
     * @throws IOException
     * @throws TelosysException
     * @since 1.0.5
     */
    private ScreenContext prepareScreenContext(HttpServletRequest request, HttpServletResponse response, 
            ScreenMap screenMap, ScreenRequestParameters params ) throws ServletException, IOException, TelosysException
    {
        trace("prepareScreenContext(ScreenMap, ScreenRequestParameters)" );            
        return prepareScreenContext(
                request, 
                response, 
                screenMap.getScreenContextName(),
                screenMap.getScreenContextId(),
                screenMap.getScreenContextAction(),
                params );
    }
    
    //---------------------------------------------------------------------------
    /**
     * Prepare a ScreenContext if necessary, depending on the given ScreenAction 
     * @param request
     * @param response
     * @param sContextName
     * @param iScreenContextId
     * @param sScreenAction the ScreenContext action : "open", "use" or "none"
     * @param params
     * 
     * @return the prepared ScreenContext or null (if action is "none" and if there's no current ScreenContext) 
     * 
     * @throws ServletException
     * @throws IOException
     * @throws TelosysException
     */
    private ScreenContext prepareScreenContext(HttpServletRequest request, HttpServletResponse response, 
            String sContextName, int iScreenContextId, String sScreenAction,
            ScreenRequestParameters params ) throws ServletException, IOException, TelosysException
    {
        trace("prepareScreenContext("+ sContextName +","+ iScreenContextId + ",'" + sScreenAction + "')" );            
        //ScreenContext screenContext = null;
        if (sScreenAction != null)
        {
            //Map requestParams = request.getParameterMap();
            if (sScreenAction.equals(TelosysUIL.ACTION_OPEN))
            {
                trace("Open (create) a new screen context (action=" + sScreenAction + ")");
                return ScreenContextManager.openScreenContext(request, sContextName, iScreenContextId, params);
//                screenContext = ScreenContextManager.openScreenContext(request, sContextName, iScreenContextId, params);
                // The Screen Manager is notified by the ScreenContextManager ( "create" event )
//                //--- Notify the Screen Manager
//                eventCreate (screenContext, requestParams );
            }
            else if (sScreenAction.equals(TelosysUIL.ACTION_USE))
            {
                trace("Reuse or create screen contex (action=" + sScreenAction + ")");
                return ScreenContextManager.useScreenContext(request, sContextName, iScreenContextId, params);
//                screenContext = ScreenContextManager.useScreenContext(request, sContextName, iScreenContextId, params);
                // The Screen Manager is notified by the ScreenContextManager ( "reuse" or "create" event )
                //--- Notify the Screen Manager
//                if ( screenContext.hasBeenReused() )
//                {
//                    eventReuse(screenContext, requestParams);
//                }
//                else
//                {
//                    eventCreate (screenContext, requestParams );
//                }
            }
            else if (sScreenAction.equals(TelosysUIL.ACTION_NONE))
            {
                trace("No action on the screen contex (action=" + sScreenAction + ")");
            }
            else
            {
                //--- ERROR !
                throw new TelosysException("Invalid action '" + sScreenAction + "'");
            }
        }
        else
        {
            trace("No action in request and no default action => No context preparation.");            
        }
        
        //--- If there's a current screen context return it ( for data exposition )
        //return null ; // v 0.9.9
        return ScreenContextManager.findScreenContext(request, iScreenContextId, sContextName); // v 0.9.9
    }

    //---------------------------------------------------------------------------
    private ScreenMap processOldFashion(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        trace("processOldFashion()...");

        //--- Get the Screen Name ( request parameter : mandatory )
        String sScreenName = request.getParameter(SCREEN_NAME);
        if (sScreenName == null)
        {
            String sMsg = "No screen name parameter !";
            error(sMsg);
            response_error(request, response, sMsg);
            return null ;
        }
        trace(". Screen name = " + sScreenName);

        //--- Get the Screen Type from request parameter ( optional )
        String sScreenType = request.getParameter(SCREEN_TYPE);
        if (sScreenType == null)
        {
            //sScreenType = ScreenMapConst.HTML_SCREEN_TYPE;
            sScreenType = TelosysUIL.getDefaultScreenType() ;
        }
        trace(". Screen type = " + sScreenType);

        //--- Get the Screen Context ID from request parameter ( optional )
        //int iScreenContextId = 0; // ZERO = Default Screen Context Id
        int iScreenContextId = TelosysUIL.getDefaultScreenId() ; 
        String sScreenContextId = request.getParameter(SCREEN_ID);
        if (sScreenContextId != null)
        {
            try
            {
                iScreenContextId = Integer.parseInt(sScreenContextId);
            } catch (NumberFormatException e)
            {
                String sMsg = "Invalid Screen Context Id : '" + sScreenContextId + "'";
                error(sMsg);
                response_error(request, response, sMsg);
                return null ;
            }
        }
        trace(". Screen context id = " + sScreenContextId + "(" + iScreenContextId + ")");

        //--- Get the Screen Action ( request parameter : optional )
        String sScreenAction = request.getParameter(SCREEN_ACTION);
        if (sScreenAction != null)
        {
            sScreenAction = sScreenAction.toLowerCase();
        }
        trace(". Screen action = " + sScreenAction);

        ServletContext servletContext = getServletContext() ;
        
        //--- Get a Screen Map instance from the Screen Definitions
        trace("getScreenMap(" + sScreenName + "," + sScreenType + "," + iScreenContextId + ")...");
        //ScreenMap screenMap = _screenDefinitions.getScreenMap(sScreenName, sScreenType, iScreenContextId);
        //ScreenMap screenMap = _screenDefinitions.getScreenMap(sScreenName, sScreenType, iScreenContextId, null ); // v 0.9.9
        ScreenMap screenMap = _screenDefinitions.getScreenMap( servletContext,  // v 1.0.5 ( + servletContext )
                sScreenName, sScreenType, 
                iScreenContextId, null, null ); // v 1.0.5 ( + sContextAction )
        if (screenMap == null)
        {
            String sMsg = "Cannot get the screen map : getScreenMap(" + sScreenName + "," + sScreenType + "," + iScreenContextId + ")";
            error(sMsg);
            response_error(request, response, sMsg);
            return null ;
        }
        trace("ScreenMap found : URL = " + screenMap.getTargetPath() + " Body URL = " + screenMap.getScreenBodyPath());
        //trace("SCREEN : " + screenMap.describe());

//        //--- Retrieve the main target URL of the screen map
//        String sScreenMapUrl = screenMap.getTargetURL();
//        if (sScreenMapUrl == null)
//        {
//            String sMsg = "No URL for the screen : " + sScreenName + " ( type = " + sScreenType + " )";
//            error(sMsg);
//            response_error(request, response, sMsg);
//            return null ;
//        }

        //--- Open or Use a ScreenContext ? ( action="open|use" or "default_action" )
        ScreenContext screenContext = null;
        if (sScreenAction == null)
        {
            if ( _sDefaultAction != null )
            {
                sScreenAction = _sDefaultAction ;                
                trace("No specific action => use default action ( " + _sDefaultAction + " )");
            }
        }
        
        if (sScreenAction != null)
        {
            try
            {
                if (sScreenAction.equals(TelosysUIL.ACTION_OPEN))
                {
                    trace("Open a new screen context (action=" + sScreenAction + ")");
                    screenContext = ScreenContextManager.openScreenContext(request, sScreenName, iScreenContextId);
                }
                else if (sScreenAction.equals(TelosysUIL.ACTION_USE))
                {
                    trace("Reuse or open screen contex (action=" + sScreenAction + ")");
                    screenContext = ScreenContextManager.useScreenContext(request, sScreenName, iScreenContextId);
                }
                else if (sScreenAction.equals(TelosysUIL.ACTION_NONE))
                {
                    trace("No action on the screen contex (action=" + sScreenAction + ")");
                }
                else
                {
                    String sMsg = "Invalid action '" + sScreenAction + "'";
                    error(sMsg);
                    response_error(request, response, sMsg);
                    return null ;
                }
            } catch (TelosysException e)
            {
                String sMsg = "Cannot " + sScreenAction + " Screen Context [" + iScreenContextId + "-" + sScreenName + "] - Exception :" + e.getMessage();
                error(sMsg);
                response_error(request, response, sMsg);
                return null ;
            }
        }
        else
        {
            trace("No action in request and no default action.");            
        }

        if (screenContext != null)
        {
            trace("Screen context ready ( screen name = '" + screenContext.getScreenName() + "' )");
        }
        else
        {
            trace("No screen context.");
        }

        /***********************************************************************************************************************************************************************************************
         * if ( sScreenContextId != null || _bAutoOpen ) { trace("Screen context required"); try { screenContext = ScreenContextManager.useScreenContext(request, sScreenName, iScreenContextId); }
         * catch (TelosysException e) { String sMsg = "Cannot use Screen Context [" + iScreenContextId + "-" + sScreenName + "] - Exception :" + e.getMessage(); error(sMsg); response_error(response,
         * sMsg); return; } trace("OK : Screen context ready. ClassName = " + screenContext.getScreenClassName()); //--- Set the screen context for future use by the Tags 
         * screenMap.setScreenContext(screenContext); } else { trace("No screen context required"); }
         **********************************************************************************************************************************************************************************************/

        return screenMap ;
        
//        //--- Set the Screen Map object as request attribute
//        request.setAttribute(ScreenMapConst.SCREEN_MAP, screenMap);
//        trace("Screen map set as request attribute");
//
//        //--- Forward to the Screen Map Target URL
//        trace("Forward to " + sScreenMapUrl);
//        boolean bForwardOk = forward(sScreenMapUrl, request, response);
//        if (!bForwardOk)
//        {
//            String sMsg = "Cannot forward to " + sScreenMapUrl;
//            error(sMsg);
//            response_error(request, response, sMsg);
//            return;
//        }
    }

    //---------------------------------------------------------------------------
    private boolean forward(final String sUrl, final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
    {
        trace("forward(" + sUrl + ")...");
        RequestDispatcher rd = request.getRequestDispatcher(sUrl);
        if (rd != null)
        {
            rd.forward(request, response);
            return true;
        }
        return false;
    }

    //---------------------------------------------------------------------------
    private void response_error(HttpServletRequest request, HttpServletResponse response, String sMsg) throws ServletException, IOException
    {
        response_error( request, response, sMsg, null );
    }
    //---------------------------------------------------------------------------
    private void response_error(HttpServletRequest request, HttpServletResponse response, String sMsg, Throwable t) throws ServletException, IOException
    {
        trace("response_error()...");
        try
        {
            response.setContentType("text/html");
            // Servlet output stream
            PrintWriter out = response.getWriter();
            if (out == null)
            {
                error("Output stream is null ");
                return;
            }
            out.println("<html>");
            out.println("<body>");
            out.println("<h1> SCREEN MAP ERROR : </h1>");
            out.println("<h2>URL = " + request.getRequestURL() + "</h2>");
            out.println("<br>");
            out.println("<h2> " + sMsg + "</h2>");
            out.println("<br>");
            if ( t != null )
            {
                out.println("<h2> Exception : </h2>");
                out.println("<h3> Class : "+t.getClass().getName() +"</h3>");                
                out.println("<h3> Message : "+t.getMessage()+"</h3>");
                
                //--- Print the cause if any
                printCause(out, t);
            }
            out.println("</body>");
            out.println("</html>");
            out.close();
        } catch (Exception e)
        {
            error("Exception : " + e.getMessage());
        }
    }
    
    private void printCause(PrintWriter out, Throwable t) //throws ServletException, IOException
    {
        if ( out != null && t != null )
        {
            Throwable cause = t.getCause() ;
            if ( cause != null )
            {
                out.println("<h2> Exception cause : </h2>");
                out.println("<h3> Class : " +cause.getClass().getName() +"</h3>");                
                out.println("<h3> Message : "+cause.getMessage()+"</h3>");     
                if ( cause.getCause() != null )
                {
                    printCause(out, cause );
                }
            }
        }
    }
    
    //--------------------------------------------------------------------------------
    /**
     * Parse the given URI <br>
     * URI syntaxe <br>
     *  /context/screenmap/ScreenName[-type][/ContextId[-ContextName]][:action]<br>
     * URI examples : <br>
     *  /context/screenmap/S001 <br>
     *  /context/screenmap/S001:open <br>
     *  /context/screenmap/S001-html <br>
     *  /context/screenmap/S001/1 <br>
     *  /context/screenmap/S001-html/1:use <br>
     *  /context/screenmap/S001-html/1-SHARED:use <br>
     * @param request
     * @return
     * @throws TelosysException
     */
    private ScreenMapRequest parseURI( HttpServletRequest request ) throws TelosysException
        {
                trace("parseURI( '" + request.getRequestURI() + "', out )" );
                
                ScreenMapRequest r = new ScreenMapRequest();

                //--- Init with default values
//              r.iContextId     = TelosysUIL.getDefaultScreenId();
//              r.sContextAction = _sDefaultAction ;
//        r.sScreenMapType = TelosysUIL.getDefaultScreenType() ;
                r.iContextId     = ScreenMapConst.UNDEFINED_CONTEXT_ID ; // v 1.0.5 
                r.sContextAction = null ; // v 1.0.5 
        r.sScreenMapType = null ; // v 1.0.5 

                String sURI = request.getRequestURI() ;
                
                //-------------------------------------------------------------------------
                //----- Patch for ROOT web app ( ver 1.0.3 ) : add a dummy context path 
                String sContextPath = request.getContextPath() ; 
                if ( sContextPath == null )
                {
                    sURI = "/ROOT" + sURI ;
                }
                else if ( sContextPath.length() == 0 ) // never happend
                {
                    sURI = "/ROOT" + sURI ;
                }
                //-------------------------------------------------------------------------
                
                if ( sURI.startsWith("/") ) // Yes ( always starts with '/' )
                {
                    sURI = sURI.substring(1);
                }
                
                //--- Extract action if any 
                int i = sURI.indexOf(':') ;
                if ( i > 0 )
                {
            String s = sURI.substring(i+1);
            r.sContextAction = s.trim().toLowerCase() ;
            sURI = sURI.substring(0, i);
                }
                
                //--- Split with '/' separator ( /context/screenmap/ScreenName[-type] 
        String [] parts = StrUtil.split(sURI, '/');
                
        if ( parts.length < 3 ) // Invalid request URI
        {
                return null ;
        }
        else
        {            
            if ( parts.length > 2 )
            {
                String s = parts[2];  // "ScreenName" or "ScreenName-html" or "ScreenName-xul"
                String [] p = StrUtil.split(s, '-');
                if ( p.length > 1 )
                {
                    r.sScreenMapName = p[0] ;
                    r.sScreenMapType = p[1].toLowerCase();
                }
                else
                {
                    r.sScreenMapName = s ;
                    //r.sScreenMapType = TelosysUIL.getDefaultScreenType() ;
                    r.sScreenMapType = null ;
                }
            }
            if ( parts.length > 3 )
            {                
                String s = parts[3]; // "1", "1-CtxName" ...
                if ( s != null )
                {                    
                        String [] p = StrUtil.split(s, '-');
                        if ( p.length > 1 )
                        {
                            r.sContextId = p[0] ;   // can be "0..N", "!", or an invalid ID (not yet checked)
                            r.sContextName = p[1] ;
                        }
                        else
                        {
                            // Only one part => what is it ? ( context ID or context name )
                            if ( s.trim().length() > 0 )
                            {
                                    char c = s.charAt(0);
                                if ( c == '!' ) // v 1.0.4
                                {
                                    // It's the special character for "next available ID"
                                    r.sContextId = s ;
                                }
                                    else if ( c >= '0' && c <= '9' )
                                    {
                                        // It's a number => Context Id
                                            int id = StrUtil.getInt(s, -1);
                                            if ( id >= 0 )
                                            {
                                                    r.sContextId = s ;
                                            }
                                            else // It's not a '!' and not a number => Context Name
                                            {
                                                r.sContextName = s ;
                                            }
                                    }
                                    else
                                    {
                                        // It's not a number => Context Name
                                        r.sContextName = s ;
                                    }
                            }
                            //r.sContextName = r.sScreenMapName ;
                        }
                }
            }
            
// v 1.0.5 : the contextName can be null 
//            if ( r.sContextName == null )
//            {
//                // By default use the ScreenMap name as ScreenContext name
//                r.sContextName = r.sScreenMapName ;
//            }
            
            if ( r.sContextId != null )
            {
                if ( "!".equals( r.sContextId.trim() ) )  // v 1.0.4
                {
                    //r.iContextId = -1 ; // Next available Context ID
                    r.iContextId = ScreenMapConst.DYNAMIC_CONTEXT_ID ; // Next available Context ID
                }
                else
                {
                    // r.iContextId = StrUtil.getInt(r.sContextId, r.iContextId); 
                    // v 1.0.4
                    int id = StrUtil.getInt(r.sContextId, -9);
                    if ( id == -9 )
                    {
                        throw new TelosysException("Invalid context id '" + r.sContextId + "' (int expected)");
                    }
                    r.iContextId = id ;
                }
            }
            
                return r ;
        }
        }
    
}

Generated by GNU enscript 1.6.4.