CFocusAnother

This channel was written to explore having one channel focus another.

CFocusAnother
package org.jasig.portal.channels.iccdemo;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import javax.naming.Context;
import javax.naming.NamingException;

import org.jasig.portal.ChannelRuntimeData;
import org.jasig.portal.ChannelRuntimeProperties;
import org.jasig.portal.ChannelStaticData;
import org.jasig.portal.IChannel;
import org.jasig.portal.PortalEvent;
import org.jasig.portal.PortalException;
import org.jasig.portal.channels.CAbstractXSLT;
import org.jasig.portal.utils.DocumentFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Demonstration of ability to open other channels in focus mode.
 * @author andrew.petro@yale.edu
 * @version $Revision:$ $Date:$
 */
public class CFocusAnotherChannel 
    extends CAbstractXSLT
    implements IChannel {

    /**
     * The name of the channel static data parameter the value of which must be
     * the fname of the channel to which we should render a URL which launches it
     * in detach mode.
     */
    public static final String TARGET_FNAME_PARAM = "target_fname";
    
    private Map fnamesToSubscribeIds = new HashMap();
    
    private Map parameters = new HashMap();
    
    private String xslLocation = "focusAnother.xsl";
    
    public void setRuntimeDataInternal() {
        ChannelRuntimeData runtimeData = getRuntimeData();
        
     

        
        String paramName = runtimeData.getParameter("paramName");
        String paramValue = runtimeData.getParameter("paramValue");


        if (paramName != null && paramValue != null) {
            this.parameters.put(paramName, paramValue);
            if (log.isTraceEnabled()) {
                log.trace("recorded parameter name [" + 
                      paramName + "] with value [" + paramValue + "]");
            }
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Parameters paramName and paramValue not set.");
            }
        }

    }
    
    /* (non-Javadoc)
     * @see org.jasig.portal.IChannel#setStaticData(org.jasig.portal.ChannelStaticData)
     */
    public void setStaticData(ChannelStaticData sd) throws PortalException {
        
        try {
            Context context = (Context) sd.getJNDIContext().lookup("/channel-ids");
            
            // whitespace delimited list of fnames
            String fnamesWdl = sd.getParameter(TARGET_FNAME_PARAM);
            

            for (StringTokenizer tokens = new StringTokenizer(fnamesWdl);
                tokens.hasMoreTokens(); ) {
                String fname = tokens.nextToken();
                try {
                    this.fnamesToSubscribeIds.put(fname, context.lookup(fname));
                } catch (NamingException nex) {
                    log.error("We are configured to provide a link to channel" +
                      " with fname [" + fname + 
                      "] but looking up that name in context /channel-ids failed", nex);
                }
                
                
            }
            
        } catch (NamingException e) {
                log.error("Problem getting context [/channel-ids]", e);
        }
        
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.IChannel#receiveEvent(org.jasig.portal.PortalEvent)
     */
    public void receiveEvent(PortalEvent ev) {
        // do nothing
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.IChannel#getRuntimeProperties()
     */
    public ChannelRuntimeProperties getRuntimeProperties() {
        return new ChannelRuntimeProperties();
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.channels.CAbstractXSLT#getXml()
     */
    protected Document getXml() {
        // Get a new DOM instance
        Document doc = DocumentFactory.getNewDocument();
        
        Element focusEl = doc.createElement("focus");
        
        Element paramsEl = doc.createElement("params");
        for (Iterator paramIter = this.parameters.keySet().iterator();
            paramIter.hasNext() ; ) {
            String paramName = (String) paramIter.next();
            String paramValue = (String) this.parameters.get(paramName);
            Element paramEl = doc.createElement("param");
            paramEl.setAttribute("name", paramName);
            paramEl.setAttribute("value", paramValue);
            paramsEl.appendChild(paramEl);
        }
        
        focusEl.appendChild(paramsEl);
        
        Element channelsEl = doc.createElement("channels");
        
        for(Iterator chanIter = this.fnamesToSubscribeIds.keySet().iterator(); 
            chanIter.hasNext();) {
            
            String fname = (String) chanIter.next();
            String subscribeId = (String) this.fnamesToSubscribeIds.get(fname);
            Element channelEl=doc.createElement("channel");
            channelEl.setAttribute("fname", fname);
            channelEl.setAttribute("subscribeId", subscribeId);
            channelsEl.appendChild(channelEl);
        }
        
        focusEl.appendChild(channelsEl);
        
        doc.appendChild(focusEl);
        
        return doc;
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.channels.CAbstractXSLT#getXsltUri()
     */
    protected String getXsltUri() {
        return this.xslLocation;
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.channels.CAbstractXSLT#getStylesheetParams()
     */
    protected Map getStylesheetParams() {
        Map map = new HashMap();
        map.put("baseActionURL", getRuntimeData().getBaseActionURL());
        return map;
    }

}

An example channel publishing fragment for this channel:

focusAnother.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE channel-definition SYSTEM "channelDefinition.dtd">

<channel-definition>

    <title>Focus Another</title>
    <name>Focus Another</name>
    <fname>focus</fname>
    <desc>Channel demonstrating providing a link that focuses another channel.</desc>
    <type>Custom</type>
    <class>org.jasig.portal.channels.iccdemo.CFocusAnotherChannel</class>
    <timeout>5000</timeout>
    
    <hasedit>N</hasedit>
    <hashelp>N</hashelp>
    <hasabout>N</hasabout>

    <secure>N</secure>
    <locale>en_US</locale>
    
    <categories>
        <category>Development</category>
    </categories>
    
    <groups>
        <group>Developers</group>
    </groups>
    
    <parameters>
		<parameter>
		<name>target_fname</name>
		<value>cparams google-portlet 
                daily-business-cartoon snooper uportal-powered-sites</value>
		<description>The fnames of the channel to be opened in focus mode.</description>
		<ovrd>N</ovrd>
		</parameter>
	</parameters>
    
</channel-definition>

This is the XSLT that CFocusAnother uses to render its information:

focusAnother.xsl
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:param name="baseActionURL">base url not set</xsl:param>
  <xsl:param name="channelId">target channelId not set</xsl:param>

  <xsl:template match="focus">
	<div class='portlet-msg-info'>
		<p class='portlet-text'>
This channel provides a staging area for accumulating parameters 
	and then a link to launch another channel in focus mode with the accumulated parameters.</p>
	</div>


	<div class='portlet-section-header'>
		Parameter staging area
	</div>

	<div class='portlet-section-subheader'>
		Staged parameters
	</div>
	
	<xsl:apply-templates select='params'/>

	 <form action="{$baseActionURL}">
		<div class='portlet-form-label'>
			Add a parameter
		</div>
		<div class='portlet-form-field-label'>
			parameter name
		</div>
          <input name="paramName" type="text" size="30" />
		<div class='portlet-form-field-label'>
			parameter value
		</div>
		  <input name='paramValue' type="text" size="30" />
		  
		  <input value='submit' type='submit'/>
     </form>


	<div class='portlet-section-header'>
		Channel launching area.
	</div>
	<div class='portlet-menu'>
		<div class='portlet-menu-caption'>
			Which channel would you like to open in focus mode, 
                        passing along any staged parameters from above?
		</div>
		<xsl:apply-templates select="channels"/>
	</div>



    
  </xsl:template>
  
  <xsl:template match="channel">
		<div class='portlet-menu-item'>
			
		<form action="{$baseActionURL}">
			<input type="hidden" name="uP_root" value="{@subscribeId}"/>

			<xsl:for-each select="../../params/param">
				<input type="hidden" name="{@name}" value="{@value}"/>
			</xsl:for-each>

			<div class='portlet-form-field-label'>
				<xsl:value-of select="@fname"/>

				<input type="submit"/>
			</div>
	
		</form>
		</div>
  </xsl:template>
  
  <xsl:template match='params'>
	<xsl:apply-templates select='param'/>
  </xsl:template>
  
  <xsl:template match='param'>
	<div class='portlet-section-body'>
			<xsl:value-of select="@name"/>
			=
			<xsl:value-of select="@value"/>
	</div>
  </xsl:template>
</xsl:stylesheet>
focusExample.xml
<?xml version="1.0" encoding="UTF-8"?>
<focus>
	<params>
		<param name='paramName' value='paramValue'/>
		<param name='paramName2' value='paramValue2'/>
	</params>
	<channels>
		<channel fname='fname' subscribeId='subscribeId'/>
		<channel fname='fname2' subscribeId='subscribeId2'/>
	</channels>
</focus>