Attached is changes to fix issue with portlet skin use. /services/portaltoolkit/JetspeedPortalToolkitService.java

The software change fulfills the Jetspeed requirements to
>>>>- first check the current portlet(set), if no skin then
>>>> - fallback to its parent, if no skin then
>>>> - fallback to global setting

I could not access Bugzilla to get the bug number, but it would be really great if this fix could be checked into the 1.4b3 build.
Thanks,
Glen

I ran the following tests.

1) no skin ref in PSML
RESULT: uses default skin

2) skin set a top level, no skin setting for children portlets
RESULT: children portlets use the top level skin setting

3) skin set at top level, and skin set in child portlet
RESULT: uses skin assigned for child portlet

4) no skin at top level, and skin set in child portlet
RESULT: uses skin assigned for child portlet, and all other portlets use default

---- Begin change description -----
protected PortletConfig getPortletConfig( Portlets portlets )
{

PortletConfig pc = new BasePortletConfig();

pc.setName( portlets.getName() );
pc.setInitParameters( getParameters( portlets ) );

if (portlets.getSkin()!=null)
{
pc.setPortletSkin( getSkin( portlets.getSkin() ) );
}
- else
- {
- pc.setPortletSkin( getSkin( this.defaultSkin ) );
- }

--- End change description -----



David Sean Taylor wrote:

-----Original Message-----
From: Glen Carl [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, November 27, 2002 11:08 AM
To: Jetspeed Developers List
Subject: Re: default skin change in JetspeedPortalkitServices.java




The skin algorithm described below is what I think the community would prefer. Is there a Bugzilla entry for this change?

No. Mark sets a great example for us, logging everything in Bugzilla.
Silly me, I still track my tasks in a Mead Cambridge Action Planner Pad (extra smooth paper) where this one currently is :)
I'll add it to Bugzilla now


David, regarding your comment on individual changes to the core code. I agree, it is best to consider what is best for a community. I do understand the difficulties of keeping an open source project focused, and you guys are doing a fantastic job with Jetspeed. My intent was to express my joy in being able to keep my client happy with Jetspeed.


Thanks Glen. I think I misunderstood your last email, my apologies.
Im glad to hear that you client is happy with Jetspeed!


Glen

Luta, Raphael (VUN) wrote:

De : David Sean Taylor [mailto:[EMAIL PROTECTED]]


The change was what I perceived to be a bugfix.
I have no other reason for making this change.
Perhaps there should be a fallback algorithm:
- first check the current portlet(set), if no skin then
- fallback to its parent, if no skin then
- fallback to global setting


+1. It's the algorithm that was supposed to be implemented initially. :)

--
Raphal Luta - [EMAIL PROTECTED]
Jakarta Jetspeed - Enterprise Portal in Java
http://jakarta.apache.org/jetspeed/
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *     "Apache Jetspeed" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache" or
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.jetspeed.services.portaltoolkit;

//jetspeed stuff
import org.apache.jetspeed.portal.*;
import org.apache.jetspeed.om.profile.*;
import org.apache.jetspeed.services.Profiler;
import org.apache.jetspeed.services.PortalToolkit;

import org.apache.jetspeed.services.Registry;
import org.apache.jetspeed.services.PortletFactory;
import org.apache.jetspeed.om.registry.PortletEntry;
import org.apache.jetspeed.om.registry.PortletControlEntry;
import org.apache.jetspeed.om.registry.PortletControllerEntry;
import org.apache.jetspeed.om.registry.SkinEntry;
import org.apache.jetspeed.util.MetaData;
import org.apache.jetspeed.util.JetspeedException;

import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.TurbineBaseService;
import org.apache.turbine.services.InitializationException;
import org.apache.turbine.services.resources.ResourceService;
import org.apache.turbine.util.Log;

import java.util.Iterator;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import javax.servlet.ServletConfig;

/**
 * Simple implementation of the PortalFactoryService.
 *
 * @author <a href="mailto:[EMAIL PROTECTED]";>Rapha�l Luta</a>
 * @author <a href="mailto:[EMAIL PROTECTED]";>David Sean Taylor</a>
 *
 * @version $Id: JetspeedPortalToolkitService.java,v 1.3 2002/12/13 22:07:01 gcarl Exp 
$
 */
public class JetspeedPortalToolkitService extends TurbineBaseService
    implements PortalToolkitService
{

    /** The default control to use when none is specified */
    private String defaultControl = null;

    /** The default controller to use when none is specified */
    private String defaultController = null;

    /** The default skin to use when none is specified */
    private String defaultSkin = null;

    /**
     * This is the early initialization method called by the
     * Turbine <code>Service</code> framework
     */
    public void init( ServletConfig conf ) throws InitializationException
    {

        ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
                                                     
.getResources(PortalToolkitService.SERVICE_NAME);

        this.defaultControl = serviceConf.getString("default.control");
        this.defaultController = serviceConf.getString("default.controller");
        this.defaultSkin = serviceConf.getString("default.skin");
        setInit(true);

    }

    /**
     * Instanciates a PortletControl based on a Registry entry, if available
     * or directly from a classname.
     *
     * @param name a PortletControl name available in the registry or a classname
     * @return the created PortletControl
     */
    public PortletControl getControl( String name )
    {
        PortletControl pc = null;
        PortletControlEntry entry = null;

        if (name != null)
        {
            entry = (PortletControlEntry)Registry.getEntry(Registry.PORTLET_CONTROL, 
name);
        }

        Map params = null;

        try
        {
            if (entry == null)
            {
                if (name!=null)
                {
                    pc = (PortletControl)Class.forName(name).newInstance();
                    params = new Hashtable();
                }
            }
            else
            {
                pc = 
(PortletControl)Class.forName(entry.getClassname()).newInstance();
                params = entry.getParameterMap();
            }
        }
        catch (Exception e)
        {
            Log.error("Unable to instanciate control "+name+", using default", e);
        }

        if (    (pc == null)
             && (defaultControl != null)
             && (!defaultControl.equals(name)) )
        {
            return getControl( defaultControl );
        }

        PortletControlConfig pcConf = new BasePortletControlConfig();
        pcConf.setName( name );
        pcConf.setInitParameters(params);
        pc.setConfig(pcConf);

        return pc;
    }

    /**
     * Instanciates a PortletControl based on a PSML Control object
     *
     * @param control the PSML control object
     * @return the created PortletControl
     */
    public PortletControl getControl( Control control )
    {
        PortletControl pc = null;

        if (control!=null)
        {
            pc = getControl(control.getName());
            pc.getConfig().getInitParameters().putAll(getParameters(control));
        }
        else
        {
            if (defaultControl!=null)
            {
                pc = getControl(this.defaultControl);
            }
        }

        return pc;
    }


    protected PortletControl getControl( Control control, PortletEntry entry )
    {
        PortletControl pc = null;

        if (control != null)
        {
            pc = getControl(control.getName());
            pc.getConfig().getInitParameters().putAll(getParameters(control));
        }
        else
        {
            org.apache.jetspeed.om.registry.Parameter dftPortletCtrl =
                entry.getParameter("_control");

            if (dftPortletCtrl != null)
            {
                pc = getControl(dftPortletCtrl.getValue());
            }
            else if (defaultControl != null)
            {
                pc = getControl(this.defaultControl);
            }
        }

        return pc;
    }


    /**
     * Instanciates a PortletController based on a Registry entry, if available
     * or directly from a classname.
     *
     * @param name a PortletController name available in the registry or a classname
     * @return the created PortletController
     */
    public PortletController getController( String name )
    {
        PortletController pc = null;
        PortletControllerEntry entry = null;


        if (name != null)
        {
            entry = (PortletControllerEntry)Registry
                                            .getEntry(Registry.PORTLET_CONTROLLER, 
name);
        }

        Map params = null;

        try
        {
            if (entry == null)
            {
                if (name!=null)
                {
                    pc = (PortletController)Class.forName(name).newInstance();
                    params = new Hashtable();
                }
            }
            else
            {
                pc = 
(PortletController)Class.forName(entry.getClassname()).newInstance();
                params = entry.getParameterMap();
            }
        }
        catch (Exception e)
        {
            Log.error("Unable to instanciate controller "+name+", using default");
        }

        if (   (pc == null)
            && (defaultController != null)
            && (!defaultController.equals(name)) )
        {
            return getController( defaultController );
        }

        PortletControllerConfig pcConf = new BasePortletControllerConfig();
        pcConf.setName( name );
        pcConf.setInitParameters(params);
        pc.setConfig(pcConf);
        pc.init();

        return pc;
    }

    /**
     * Instanciates a PortletController based on a PSML Controller object
     *
     * @param controller the PSML controller object
     * @return the created PortletController
     */
    public PortletController getController( Controller controller )
    {

        PortletController pc = null;

        if (controller!=null)
        {
            pc = getController(controller.getName());
            pc.getConfig().getInitParameters().putAll(getParameters(controller));
        }
        else
        {
            if (defaultController!=null)
            {
                pc = getController(this.defaultController);
            }
        }

        pc.init();

        return pc;
    }

    /**
     * Create a PortletSkin object based on a Registry skin name
     *
     * @param name the registry SkinEntry name
     * @return the new PortletSkin object
     */
    public PortletSkin getSkin( String name )
    {
        BasePortletSkin result = new BasePortletSkin();

        SkinEntry entry = null;

        if (name!=null)
        {
            entry = (SkinEntry)Registry.getEntry(Registry.SKIN, name);
        }

        // either we don't have any skin defined, the skin reference is null
        // or the skin reference is invalid, in all case, retrieve the default
        // skin entry
        if (entry == null)
        {
            entry = (SkinEntry)Registry.getEntry(Registry.SKIN, this.defaultSkin);
        }

        if (entry!=null)
        {
            // build the PortletSkin object
            result.setName(entry.getName());
            result.putAll(entry.getParameterMap());
        }

        return result;
    }

    /**
     * Create a PortletSkin object based on PSML skin description
     *
     * @param skin the PSML Skin object
     * @return the new PortletSkin object
     */
    public PortletSkin getSkin( Skin skin )
    {
        PortletSkin result = null;
        String name = null;

        if (skin != null)
        {
            name = skin.getName();

            // create the PortletSkin corresponding to this entry
            result = getSkin( name );

            // override the values with the locally defined properties
            result.putAll(getParameters(skin));

        }

        return result;
    }

    /**
     * Creates a PortletSet from a PSML portlets description
     *
     * @param portlets the PSML portlet set description
     * @return a new instance of PortletSet
     */
    public PortletSet getSet( Portlets portlets )
    {
        VariableInteger lastID = new VariableInteger(0);
        return getSet( portlets, new VariableInteger(0) );
    }

    /**
     * Creates a PortletSet from a PSML portlets description, updating
     * the portletset name based on its position within the tree
     *
     * @param portlets the PSML portlet set description
     * @param count the portletset number within the complete tree
     * @return a new instance of PortletSet
     */
    protected PortletSet getSet( Portlets portlets, VariableInteger theCount)
    {
        // Create a new BasePortletSet to handle the portlets
        BasePortletSet set = new BasePortletSet();
        PortletController controller = getController( portlets.getController() );
        set.setController( controller );
        String name = portlets.getName();
        if (name != null)
        {
            set.setName(name);
        }
        else
            set.setName(String.valueOf(theCount.getValue()));

        set.setID(portlets.getId());

        theCount.setValue(theCount.getValue()+1);

        //FIXME: this sucks ! we should either associate the portlet set
        //with its portlets peer or set the porpoerties directly on the portlet
        //set object
        //Unfortunately, this would change the API too drastically for now...
        set.setPortletConfig( getPortletConfig( portlets ) );

        // Add all sub portlet sets in the main set
//        Portlets[] subsets = portlets.getPortlets();
//        for (int i=0; i < subsets.length; i++ )

        for (Iterator it = portlets.getPortletsIterator(); it.hasNext(); )
        {
            Portlets subset = (Portlets)it.next();
            Map constraints = getParameters(subset.getLayout());
            int position = getPosition( subset.getLayout() );
            set.addPortlet( getSet( subset, theCount ),
                            controller.getConstraints(constraints),
                            position );
        }

        // Populate the PortletSet with Portlets
//        Entry[] entries = portlets.getEntry();
//        for( int i = 0; i < entries.length; ++i )

        for (Iterator eit = portlets.getEntriesIterator(); eit.hasNext(); )
        {
            try
            {

                Entry psmlEntry = (Entry)eit.next();
                PortletEntry entry = (PortletEntry)Registry.getEntry( 
Registry.PORTLET, psmlEntry.getParent() );

                if ( entry != null )
                {
                    Portlet p = PortletFactory.getPortlet( psmlEntry );

                    if (p != null)
                    {
                        Map constraints = getParameters(psmlEntry.getLayout());
                        int position = getPosition( psmlEntry.getLayout() );

                        PortletControl control =  getControl(psmlEntry.getControl(), 
entry);

                        set.addPortlet( initControl(control,p),
                                        controller.getConstraints( constraints ),
                                        position );
                    }
                }
                else
                {
                    Log.error(" The portlet "+psmlEntry.getParent()+" does not exist 
in the Registry ");
                    continue;
                }
            }
            catch ( JetspeedException e )
            {
                Log.error( e );
                continue;
            }

        }

        // Decorate with a control if required and return
        if ( portlets.getControl() != null )
        {
            PortletControl control = getControl(portlets.getControl());
            return initControl(control,set);
        }

        set.sortPortletSet();
        // Or return the set
        return set;
    }

    /**
     * Associates a PortletControl wit an existing Portlet and
     * returns the Control
     *
     * @param pc the existing PortletControl
     * @param portlet the existing Portlet to be associated with the control
     * @return first PortletControl associated with the portlet
     */
    protected PortletControl initControl( PortletControl pc, Portlet portlet )
    {

        if (portlet == null)
        {
            throw new IllegalArgumentException( "Portlet not specified" );
        }

        if ( pc == null )
        {
            throw new IllegalArgumentException( "PortletControl not specified" );
        }

        pc.init( portlet );

        return pc;

    }

    /**
    Given a PSML Portlets, get the value of what its PortletConfig would be.

    @param entry the Portlets containing the config
    @return the newly created PortletConfig object
    */
    protected PortletConfig getPortletConfig( Portlets portlets )
    {

        PortletConfig pc = new BasePortletConfig();

        pc.setName( portlets.getName() );
        pc.setInitParameters( getParameters( portlets ) );

        if (portlets.getSkin()!=null)
        {
            pc.setPortletSkin( getSkin( portlets.getSkin() ) );
        }

        pc.setSecurityRef( portlets.getSecurityRef() );
        pc.setMetainfo( getMetaData( portlets ) );

        return pc;
    }

    /**
     * Fetches the parameters out of a PSML Portlets entry
     *
     * @param portlets the Portlets entry to check for parameters
     * @return a Map containing the parameters names/values, an empty Dictionary
     *        is returned if there are no parameters
     */
    protected static Map getParameters( Portlets portlets )
    {
        Hashtable hash = new Hashtable();

        if (portlets != null)
        {
            Parameter[] props = portlets.getParameter();

            for(int i = 0; i < props.length; ++i)
            {
                hash.put(props[i].getName(), props[i].getValue() );
            }
        }

        return hash;
    }

    /**
     * Retrieves the parameters from a PSML Control object
     *
     * @param control the PSML object to explore
     * @return a Map of the existing control parameters or an empty map
     */
    protected static Map getParameters(Control control)
    {
        Hashtable hash = new Hashtable();

        if (control!=null)
        {
            Parameter[] params = control.getParameter();

            for (int i=0; i < params.length; i++ )
            {
                hash.put(params[i].getName(),params[i].getValue());
            }
        }
        return hash;
    }

    /**
     * Retrieves the parameters from a PSML Controller object
     *
     * @param controller the PSML object to explore
     * @return a Map of the existing controller parameters or an empty map
     */
    protected static Map getParameters(Controller controller)
    {
        Hashtable hash = new Hashtable();

        if (controller!=null)
        {
            Parameter[] params = controller.getParameter();

            for (int i=0; i < params.length; i++ )
            {
                hash.put(params[i].getName(),params[i].getValue());
            }
        }
        return hash;
    }

    /**
     * Retrieves a parameter Map from an array of PSML Layout object
     *
     * @param layout the Layout object to use
     * @return a Map containing the names/values, an empty map
     *  is returned if there are no properties
     */
    protected static Map getParameters(Layout layout)
    {
        Hashtable hash = new Hashtable();

        if (layout!=null)
        {
            Parameter[] props = layout.getParameter();

            for(int i = 0; i < props.length; ++i)
            {
                hash.put(props[i].getName(), props[i].getValue() );
            }
        }

        return hash;
    }

    /**
     * Retrieves a parameter Map from a PSML skin object
     *
     * @param skin the Skin object to use
     * @return a Map containing the names/values, an empty map
     *  is returned if there are no properties
     */
    protected static Map getParameters(Skin skin)
    {
        Hashtable hash = new Hashtable();

        if (skin!=null)
        {
            Parameter[] props = skin.getParameter();

            for(int i = 0; i < props.length; ++i)
            {
                hash.put(props[i].getName(), props[i].getValue() );
            }
        }

        return hash;
    }

    /**
    Create a MetaData object from a PSML Metainfo object

    @param meta the Metainfo to copy

    @return the new MetaData object, empty if meta is null
    */
    protected static MetaData getMetaData(Portlets portlets)
    {
        MetaData data = new MetaData();
        MetaInfo meta = portlets.getMetaInfo();

        if ( meta != null )
        {
            if ( meta.getTitle() != null )
            {
                data.setTitle( meta.getTitle() );
            }

            if ( meta.getDescription() != null )
            {
                data.setDescription( meta.getDescription() );
            }

            if ( meta.getImage() != null )
            {
                data.setImage( meta.getImage() );
            }
        }

        return data;

    }

    /**
     * Get the position value in a Layout object
     *
     * @param layout the Layout object to use
     *
     * @return the defined position or -1 if undefined
     */
    protected static int getPosition(Layout layout)
    {
        int pos=-1;

        try {
            pos=(int)layout.getPosition();
        } catch (RuntimeException e) {
            // either layout is null or the position isn't an integer
            // keep the default value
        }

        return pos;
    }

    protected static class VariableInteger
    {
        int value;

        public VariableInteger(int value)
        {
            this.value = value;
        }

        public int getValue()
        {
            return this.value;
        }

        public void setValue(int value)
        {
            this.value=value;
        }
    }

    /**
     * Given a locator String path, returns a Portlets collecton
     *
     * @param locatorPath ProfileLocator resource path identifier
     * @return a portlets collection from the PSML resource
     */
    public Portlets getReference(String locatorPath)
    {
        ProfileLocator locator = Profiler.createLocator();
        locator.createFromPath(locatorPath);
        String id = locator.getId();

        try
        {
            Profile profile = Profiler.getProfile(locator);
            PSMLDocument doc = profile.getDocument();
            if (doc == null)
            {
                return null;
            }
            Portlets portlets = doc.getPortlets();
            return portlets;
        }
        catch (Exception e)
        {
            Log.error( e );
            return null;
        }
    }
}

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to