OW2 Consortium telosys

Rev

Blame | Last modification | View Log | RSS feed

package org.objectweb.telosys.screen.core;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Properties;

import org.objectweb.telosys.common.Telosys;
import org.objectweb.telosys.common.TelosysException;
import org.objectweb.telosys.common.TelosysObject;
import org.objectweb.telosys.common.TelosysProperties;
import org.objectweb.telosys.screen.env.ScreenSession;
import org.objectweb.telosys.util.ClassUtil;

/**
 * The standard "Screen Context Registry" <br>
 * This is the standard implementation of IScreenProvider and IScreenDataProvider <br>
 * 
 * Since ver 1.0.5 this registry is able to found a Screen definition dynamically <br>
 * by applying "Convention Over Configuration" principle ( see registerConvention methods )
 * 
 * @author Laurent GUERIN
 *  
 */
public class StandardScreenRegistry extends TelosysObject implements IScreenProvider, IScreenDataProvider
{

    private final HashMap    _hmRegistry  = new HashMap(40);

    private final LinkedList _conventions = new LinkedList(); // Convention-over-Configuration, since v 1.0.5

    //------------------------------------------------------------------------------------
    /**
     * Constructor 
     * 
     * @since 1.0.5
     */
    public StandardScreenRegistry()
    {
        super();
        info("StandardScreenRegistry created.");
        
        // The inialization cannot be done here 
        // because we're not sure the Telosys.properties have been loaded at this time 
        
    }
    
    //------------------------------------------------------------------------------------
    /* (non-Javadoc)
     * @see org.objectweb.telosys.screen.core.IScreenProvider#init()
     */
    public void init() // v 1.0.5
    {
        info("StandardScreenRegistry initialization...");
        //--- Init the conventions if defined in the "telosys.properties" file
        Properties prop = Telosys.getProperties();
        if ( prop != null )
        {
            String s = prop.getProperty( TelosysProperties.SCREEN_CONTEXT_CONVENTION ); // v 1.0.5
            if ( s != null )
            {
                registerParts(s, getParts(s));
            }
            
            for ( int i = 0 ; i < 100 ; i++ )
            {
                s = prop.getProperty( TelosysProperties.SCREEN_CONTEXT_CONVENTION + i ); // v 1.0.5
                if ( s != null )
                {
                    registerParts(s, getParts(s));
                }
            }
        }
        else
        {
            error("Cannot get Telosys properties !");
        }
    }
    
    //------------------------------------------------------------------------------------
    private String[] getParts(String s)
    {
        if (s != null)
        {
            String[] parts1 = s.split(",");
            int n = parts1.length ;
            if ( n > 0 )
            {
                String[] parts2 = new String[n];
                for ( int i = 0 ; i < n ; i++ )
                {
                    String part = parts1[i];
                    if ( part != null )
                    {
                        part = part.trim() ;
                    }
                    parts2[i] = part ;
                }
                return parts2 ;
            }
        }
        return null ;
    }
    
    //------------------------------------------------------------------------------------
    private void registerParts(String s, String[] parts)
    {
        if ( parts != null )
        {
            //--- Register the convention defined in the properties 
            if ( parts.length == 1 )
            {
                registerConvention( parts[0] );
            }
            else if ( parts.length == 4 )
            {
                registerConvention( parts[0], parts[1], parts[2], parts[3] );
            }
            else if ( parts.length == 5 )
            {
                registerConvention( parts[0], parts[1], parts[2], parts[3], parts[4] );
            }
            else if ( parts.length == 8 )
            {
                registerConvention( parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7] );
            }
            else
            {
                error("Invalid screen context convention : " + s );
            }
        }
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Registers a ScreenContext with all its components ( each class is defined explicitly )
     * @param screenName
     * @param screenDataClass
     * @param screenManagerClass
     * @param screenActionsClass
     * @param screenTriggersClass
     * @param screenProceduresClass
     */
    protected final void register(String screenName, Class screenDataClass, Class screenManagerClass, Class screenActionsClass, Class screenTriggersClass, Class screenProceduresClass)
    {
        trace("register '" + screenName + "' with 5 components");
        try
        {
            ScreenContextDefinition def = new ScreenContextDefinition(screenName, screenDataClass, screenManagerClass, screenActionsClass, screenTriggersClass, screenProceduresClass);
            //hmRegistry.put(screenName, def);
            registerScreenDefinition(screenName, def);
        } catch (TelosysException e)
        {
            error("Cannot register screen " + screenName);
            error(e.getMessage());
        }
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Registers a ScreenContext with the 4 main components ( each class is defined explicitly )
     * @param screenName
     * @param screenDataClass
     * @param screenManagerClass
     * @param screenTriggersClass
     * @param screenProceduresClass
     */
    protected final void register(String screenName, Class screenDataClass, Class screenManagerClass, Class screenTriggersClass, Class screenProceduresClass)
    {
        trace("register '" + screenName + "' with 4 components");
        try
        {
            ScreenContextDefinition def = new ScreenContextDefinition(screenName, screenDataClass, screenManagerClass, null, screenTriggersClass, screenProceduresClass);
            //hmRegistry.put(screenName, def);
            registerScreenDefinition(screenName, def);
        } catch (TelosysException e)
        {
            error("Cannot register screen " + screenName);
            error(e.getMessage());
        }
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Registers a ScreenContextDefinition  
     * @param screenName
     * @param def
     * @since 1.0.5
     */
    private final void registerScreenDefinition (String screenName, ScreenContextDefinition def)
    {
        _hmRegistry.put(screenName, def);
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Search a ScreenContextDefinition for the given screen name
     * @param sScreenName
     * @return
     * @throws TelosysException
     */
    private final ScreenContextDefinition lookup(String sScreenName) throws TelosysException
    {
        //--- 1) Search in the registry 
        ScreenContextDefinition screenDef = (ScreenContextDefinition) _hmRegistry.get(sScreenName);
        if (screenDef != null)
        {
            return screenDef;
        }
        else
        {
            //--- 2) Search "by convention" using the registered packages  ( since v 1.0.5 )
            screenDef = lookupByConvention(sScreenName);
            if (screenDef != null)
            {
                return screenDef;
            }
            else
            {
                throw new TelosysException("Screen context '" + sScreenName + "' not found (not in registy and not accessible by conventions) ");
            }
        }
    }

    //------------------------------------------------------------------------------------
    /* (non-Javadoc)
     * @see org.objectweb.telosys.screen.core.IScreenProvider#getScreen(org.objectweb.telosys.screen.env.ScreenSession, java.lang.String, int)
     */
    public ScreenContext getScreen( ScreenSession screenSession, String sScreenName, int iScreenId ) throws TelosysException
    {
        trace(" getScreen(" + sScreenName + ")");

        ScreenContextDefinition screenDef = lookup(sScreenName);
        if (screenDef != null)
        {
            return screenDef.createScreenContext(screenSession, iScreenId);
        }
        return null;
    }

    //------------------------------------------------------------------------------------
    /* (non-Javadoc)
     * @see org.objectweb.telosys.screen.core.IScreenDataProvider#getScreenData(java.lang.String)
     */
    public ScreenData getScreenData(String sScreenName) throws TelosysException
    {
        trace(" getScreenData(" + sScreenName + ")");

        ScreenContextDefinition screenDef = lookup(sScreenName);
        if (screenDef != null)
        {
            return screenDef.createScreenData();
        }
        return null;
    }

// Removed in v 1.0.4
//    public ScreenActions getScreenActions(String sScreenName) throws TelosysException
//    {
//        trace(" getScreenActions(" + sScreenName + ")");
//
//        ScreenContextDefinition screenDef = lookup(sScreenName);
//        if (screenDef != null)
//        {
//            return screenDef.createScreenActions();
//        }
//        return null;
//    }
    
    //------------------------------------------------------------------------------------
    // Unregistered screens loading ( packages management )  v 1.0.5
    // "Convention Over Configuration" principle
    //------------------------------------------------------------------------------------
    
    //------------------------------------------------------------------------------------
    /**
     * Register a convention based on a common class name pattern <br>
     * the java classes extensions are the default extensions ( "Data", "Mgr", etc ... ) <br>
     * all the ScreenContext classes are located in the same package ( ScreenData, ScreenManager, ScreenTrigger, etc )
     * 
     * @param sGenericClassNamePattern the class name pattern for all the classes ( ie "demo.screen.${SCREENNAME_LC}.${SCREENNAME}" )
     * @since 1.0.5
     */
    protected final void registerConvention( String sGenericClassNamePattern )
    {
        trace("registerConvention('" + sGenericClassNamePattern + "')");
        try
        {
            ScreenClassesConvention convention = new ScreenClassesConvention ( sGenericClassNamePattern );
            _conventions.add(convention);
        } catch (TelosysException e)
        {
            // Nothing to do : the convention is not registred
        }
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Register a convention based on a common class name pattern<br> 
     * with specific screen classes extensions <br>
     * all the ScreenContext classes are located in the same package ( ScreenData, ScreenManager, ScreenTrigger, etc )
     * 
     * @param sGenericClassNamePattern the class name pattern for all the classes ( ie "demo.screen.${SCREENNAME_LC}.${SCREENNAME}" )
     * @param screenDataExtension the ScreenData class suffix ( by default "Data" ) 
     * @param screenManagerExtension the ScreenManager class suffix ( by default "Mgr" ) 
     * @param screenTriggerExtension the ScreenTrigger class suffix ( by default "Trg" )
     * @param screenProcedureExtension the ScreenProcedure class suffix ( by default "Proc" )
     * @since 1.0.5
     */
    protected final void registerConvention( String sGenericClassNamePattern, 
            String screenDataExtension, String screenManagerExtension, 
            String screenTriggerExtension, String screenProcedureExtension )
    {
        trace("registerConvention('" + sGenericClassNamePattern 
                + "," + screenDataExtension + "," + screenManagerExtension 
                + "," + screenTriggerExtension + "," + screenProcedureExtension + "')");
        
        try
        {
            ScreenClassesConvention convention = new ScreenClassesConvention ( sGenericClassNamePattern, screenDataExtension, screenManagerExtension, screenTriggerExtension, screenProcedureExtension );
            _conventions.add( convention );
        } catch (TelosysException e)
        {
            // Nothing to do : the convention is not registred
        }
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Register a convention based on 4 specific class name patterns
     * 
     * @param screenDataClassName
     * @param screenManagerClassName
     * @param screenTriggerClassName
     * @param screenProcedureClassName
     * @since 1.0.5
     */
    protected final void registerConvention( String screenDataClassName, String screenManagerClassName, 
            String screenTriggerClassName, String screenProcedureClassName )
    {
        trace("registerConvention('" + screenDataClassName + "," + screenManagerClassName + "," + screenTriggerClassName 
                + "," + screenProcedureClassName + "')");
        
        ScreenClassesConvention convention = new ScreenClassesConvention ( screenDataClassName, 
                screenManagerClassName, screenTriggerClassName, screenProcedureClassName );
        _conventions.add(convention);
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Register a convention based on 4 specific package name patterns and 4 specific class name patterns
     * 
     * @param screenDataPackageName
     * @param screenDataClassName
     * @param screenManagerPackageName
     * @param screenManagerClassName
     * @param screenTriggerPackageName
     * @param screenTriggerClassName
     * @param screenProcedurePackageName
     * @param screenProcedureClassName
     * @since 1.0.5
     */
    protected final void registerConvention( 
            String screenDataPackageName, String screenDataClassName,
            String screenManagerPackageName, String screenManagerClassName,
            String screenTriggerPackageName, String screenTriggerClassName,
            String screenProcedurePackageName, String screenProcedureClassName )
    {
        trace("registerConvention('" 
                + screenDataPackageName + "," + screenDataClassName + "," 
                + screenManagerPackageName + "," + screenManagerClassName + "," 
                + screenTriggerPackageName + "," + screenTriggerClassName + "," 
                + screenProcedurePackageName + "," + screenProcedureClassName + "')" );
        
        try
        {
            ScreenClassesConvention convention = new ScreenClassesConvention ( 
                    screenDataPackageName, screenDataClassName,
                    screenManagerPackageName, screenManagerClassName,
                    screenTriggerPackageName, screenTriggerClassName,
                    screenProcedurePackageName, screenProcedureClassName );
            _conventions.add(convention);
        } catch (TelosysException e)
        {
            // Nothing to do : the convention is not registred
        }
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Search a screen definition applying conventions with the registred packages 
     * @param sScreenName
     * @return
     * @throws TelosysException
     * @since 1.0.5
     */
    private final ScreenContextDefinition lookupByConvention(String sScreenName) throws TelosysException
    {
        trace("lookupByConvention('" + sScreenName + "')");
        
        ScreenContextDefinition def = getDefinitionByConvention (sScreenName);
        if ( def != null )
        {
            //--- Register the service for future re-use
            // ServiceComponents sc = privateRegister(sServiceName, serviceClass, null, null );
            registerScreenDefinition(sScreenName, def);
            return def ;
        }
        return null ;
    }
    
    //------------------------------------------------------------------------------------
    /**
     * Try to find a ScreenContextDefinition by searching Java classes in the registered conventions
     *  
     * @param sScreenName
     * @return
     * @throws TelosysException
     * @since 1.0.5
     */
    private ScreenContextDefinition getDefinitionByConvention(String sScreenName) throws TelosysException
    {
        trace("getDefinitionByConvention('" + sScreenName + "')");
        Class screenClass = null ;
        int n = _conventions.size();
        for ( int i = 0 ; i < n ; i++ )
        {
            ScreenClassesConvention convention = (ScreenClassesConvention) _conventions.get(i) ;
            Class screenDataClass = ClassUtil.tryToLoadClass( convention.getScreenDataClassName(sScreenName) ) ;
            Class screenManagerClass = ClassUtil.tryToLoadClass( convention.getScreenManagerClassName(sScreenName) ) ;
            Class screenTriggerClass = ClassUtil.tryToLoadClass( convention.getScreenTriggerClassName(sScreenName) ) ;
            Class screenProcedureClass = ClassUtil.tryToLoadClass( convention.getScreenProcedureClassName(sScreenName) ) ;
            if ( screenDataClass != null || screenManagerClass != null || screenTriggerClass != null || screenProcedureClass != null )
            {
                //--- At least one class found => use this screen definition
                ScreenContextDefinition def = new ScreenContextDefinition(sScreenName, 
                        screenDataClass, screenManagerClass, 
                        null, screenTriggerClass, screenProcedureClass);
                return def ;
            }
        }
            return null ; // Not found !
    }
    
}

Generated by GNU enscript 1.6.4.