portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tay...@apache.org
Subject cvs commit: jakarta-jetspeed/webapp/WEB-INF/templates/jsp/controllers/html x-multicolumn-customize.jsp
Date Sun, 02 Nov 2003 20:07:17 GMT
taylor      2003/11/02 12:07:17

  Modified:    src/java/org/apache/jetspeed/portal/portlets
                        GenericMVCPortlet.java
               webapp/WEB-INF/conf JetspeedSecurity.properties
                        demo-portlets.xreg
  Added:       src/java/org/apache/jetspeed/modules/actions/controllers
                        XMultiColumnControllerAction.java
               src/java/org/apache/jetspeed/util/template JspTemplate.java
               webapp/WEB-INF/conf enhancedPortletControllers.xreg
               webapp/WEB-INF/templates/jsp/controllers/html
                        x-multicolumn-customize.jsp
  Log:
  drag and drop multicolumn controller contributed by Jun Yang
  delayed rendering feature contributed by Jun Yang
  
  Revision  Changes    Path
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/modules/actions/controllers/XMultiColumnControllerAction.java
  
  Index: XMultiColumnControllerAction.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2003 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "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.modules.actions.controllers;
  
  import java.util.List;
  import java.util.Map;
  
  import javax.servlet.ServletRequest;
  
  import org.apache.jetspeed.om.profile.psml.PsmlEntry;
  import org.apache.jetspeed.portal.Portlet;
  import org.apache.jetspeed.portal.PortletController;
  import org.apache.jetspeed.services.rundata.JetspeedRunData;
  import org.apache.jetspeed.services.statemanager.SessionState;
  import org.apache.jetspeed.util.template.JetspeedTool;
  import org.apache.jetspeed.util.template.JspTemplate;
  import org.apache.jetspeed.util.StringUtils;
  import org.apache.turbine.util.RunData;
  import org.apache.velocity.context.Context;
  
  /**
   * XMultiColumnControllerAction
   *
   * @author <a href="mailto:junyang@cisco.com">Jun Yang</a>
   * @version $Id: XMultiColumnControllerAction.java,v 1.1 2003/11/02 20:07:16 taylor Exp $
   */
  public class XMultiColumnControllerAction extends MultiColumnControllerAction
  {
      protected void buildCustomizeContext(
          PortletController controller,
          Context context,
          RunData rundata
      )
      {
          super.buildCustomizeContext(controller, context, rundata);
          context.put("template", "x-multicolumn-customize.vm");
          context.put("action", "controllers.XMultiColumnControllerAction");
  
          context.put("includedContent", new JspTemplate(rundata, "/controllers/html/x-multicolumn-customize.jsp"));
          ServletRequest request = rundata.getRequest();
          request.setAttribute("jspContext", context);
  
          // debug
          Object[] columns = (Object[]) context.get("portlets");
          Map portletTitleMap = (Map) context.get("titles");
          for (int i = 0; i < columns.length; i++)
          {
              List portletList = (List) columns[i];
              for (int j = 0; j < portletList.size(); j++)
              {
                  PsmlEntry entry = (PsmlEntry) portletList.get(j);
                  String portletTitle = (String) portletTitleMap.get(entry.getId());
                  String portletSkinName = entry.getSkin() == null ? "-- Default --" : entry.getSkin().getName();
                  String portletSecurityId =
                      entry.getSecurityRef() == null ?
                      "-- Default --" :
                      entry.getSecurityRef().getParent();
                  String controlListBox =
                  (entry.getControl() != null && entry.getControl().getName() != null) ?
                      JetspeedTool.getPortletParameter(rundata, 
                                                       (Portlet) rundata.getUser().getTemp("customizer"),
                                                        "control", entry.getControl().getName()) :
                      JetspeedTool.getPortletParameter(rundata, (Portlet) rundata.getUser().getTemp("customizer"), "control");
                  controlListBox = controlListBox.substring(12);
                  controlListBox = controlListBox.replace('\n', ' ');
                  controlListBox = controlListBox.replace('\r', ' ');
                  int z = 0;
              }
          }
      }
      
      public void doSave(RunData data, Context context)
      {
          applyModelChanges(data, context);
          super.doSave(data, context);
      }
  
      public void doDelete(RunData data, Context context)
      {
          applyModelChanges(data, context);
          super.doDelete(data, context);
      }
  
      public void doControl(RunData data, Context context)
      {
          applyModelChanges(data, context);
          super.doControl(data, context);
      }
  
      protected void applyModelChanges(RunData data, Context context)
      {
          ServletRequest request = data.getRequest();
          String[] modelChangeList = request.getParameterValues("modelChangeList");
          if (modelChangeList != null)
          {
              String[] moves = StringUtils.stringToArray(modelChangeList[0], ";");
  
              SessionState customizationState = ((JetspeedRunData) data).getPageSessionState();
              List[] columns = (List[]) customizationState.getAttribute("customize-columns");
  
              for (int i = 0; i < moves.length; i++)
              {
                  String[] values = StringUtils.stringToArray(moves[i], ",");
                  int originCol = Integer.parseInt(values[0]);
                  int originRow = Integer.parseInt(values[1]);
                  int destCol = Integer.parseInt(values[2]);
                  int destRow = Integer.parseInt(values[3]);
  
                  Object portletEntry = columns[originCol].get(originRow);
                  columns[originCol].remove(originRow);
                  columns[destCol].add(destRow, portletEntry);
              }
          }
      }
  }    
  
  
  
  
  1.6       +448 -365  jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/GenericMVCPortlet.java
  
  Index: GenericMVCPortlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/GenericMVCPortlet.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- GenericMVCPortlet.java	5 Aug 2003 19:07:00 -0000	1.5
  +++ GenericMVCPortlet.java	2 Nov 2003 20:07:16 -0000	1.6
  @@ -1,365 +1,448 @@
  -/* ====================================================================
  - * 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 apache@apache.org.
  - *
  - * 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/>.
  - */
  -/*
  - * GenericMVCPortlet.java
  - *
  - * Created on January 27, 2003, 5:10 PM
  - */
  -package org.apache.jetspeed.portal.portlets;
  -
  -import javax.servlet.http.HttpServletRequest;
  -
  -import org.apache.ecs.ConcreteElement;
  -
  -import org.apache.jetspeed.portal.PortletException;
  -import org.apache.jetspeed.portal.portlets.viewprocessor.ViewProcessor;
  -import org.apache.jetspeed.portal.portlets.viewprocessor.ViewProcessorFactory;
  -//import org.apache.jetspeed.portal.portlets.viewprocessor.*;
  -// using the * form due to the puggable nature
  -//ie no recompile to support new view processors
  -// The above * form removed. No need, as imports are only used at compile time
  -// Pluggable will work fine anyway. (HO)
  -import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
  -import org.apache.jetspeed.services.logging.JetspeedLogger;
  -import org.apache.jetspeed.util.PortletSessionState;
  -import org.apache.jetspeed.util.template.JetspeedLink;
  -import org.apache.jetspeed.util.template.JetspeedTemplateLink;
  -
  -import org.apache.turbine.modules.ActionLoader;
  -import org.apache.turbine.services.pull.TurbinePull;
  -import org.apache.turbine.util.RunData;
  -
  -/**
  - * Provides the basic MVC Portlet functionality independant of any
  - * specific view technology (ie jsp, velocity, xslt, etc).  It handles
  - * the views via a ViewProcessor, which is a pluggable, factory
  - * created, run time module for which ever view technology your portlet
  - * uses.
  - * 
  - * There is no need to extend this portlet class, just define your porlet
  - * entry in the registy as a child of this class and provide your template
  - * and action class (extened from GenericMVCAction of course) and you
  - * are good to go.
  - * 
  - * Example .xreg entry:
  - * 
  - *  <portlet-entry name="GenericMVCPortlet" hidden="false"
  - *       type="abstract" application="false">
  - *       <security-ref parent="default"/>
  - *       <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
  - *      <media-type ref="html"/>
  - *      <url cachedOnURL="true"/>
  - *  </portlet-entry>
  - *  <portlet-entry name="VelocityMVCExample" hidden="false" type="ref"
  - *      parent="GenericMVCPortlet" application="false">
  - *      <meta-info>
  - *          <title>Velocity MVC Portlet</title>
  - *          <description>Velocity Generic MVC Portlet</description>
  - *      </meta-info>
  - *      <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
  - *      <parameter name="template" value="mvc-example" hidden="true"
  - *          cachedOnName="true" cachedOnValue="true"/>
  - *      <parameter name="viewtype" value="Velocity" hidden="true"
  - *          cachedOnName="true" cachedOnValue="true"/>
  - *      <parameter name="action"
  - *          value="portlets.ExampleGenericMVCAction" hidden="true"
  - *          cachedOnName="true" cachedOnValue="true"/>
  - *      <url cachedOnURL="true"/>
  - *  </portlet-entry>
  - * 
  - * See the Velocity and JSP MVC Portlet examples for template and action class clues.
  - * 
  - * To add new view processor types, simply implement the ViewProcessor
  - * interface and add your type into the <b>viewprocessor.properties</b> file as
  - * shown in the example below:
  - * 
  - * mvc.viewprocessor.Velocity = org.apache.jetspeedportlets.viewprocessors.VelocityViewProcessor
  - * mvc.viewprocessor.JSP = org.apache.jetspeedportlets.viewprocessors.JSPViewProcessor
  - * mvc.viewprocessor.XSL = org.apache.jetspeedportlets.viewprocessors.XSLViewProcessor
  - * 
  - * @stereotype role
  - * @author tkuebler
  - * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
  - * @version $Id$
  - */
  -public class GenericMVCPortlet extends AbstractInstancePortlet
  -{
  -    
  -    /**
  -     * Static initialization of the logger for this class
  -     */    
  -    private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(GenericMVCPortlet.class.getName());    
  -    
  -    // STW: Context keys
  -    public static final String PORTLET = "portlet";
  -    public static final String TEMPLATE = "template";
  -    public static final String RUNDATA = "data";
  -    public static final String PORTLET_CONFIG = "conf";
  -    public static final String SKIN = "skin";
  -    public static final String VIEW_TYPE = "viewType";	
  -    public static final String IS_CACHEABLE = "_IsCacheable";	
  -
  -    // need cache timer, etc
  -    private String viewType = "ERROR: not set in config";
  -    private String actionName = "ERROR: not set in config";
  -    private String template = "ERROR: not set in config";
  -    private String configureTemplate;
  -    private String maximizedTemplate;
  -    private ViewProcessor processor = null;
  -    private boolean providesCustomization;
  -
  -    public void init() throws PortletException
  -    {
  -        
  -        //STW: check custimization attribute
  -        String provConf = getPortletConfig().getInitParameter("provides.customization", "false");
  -        providesCustomization = new Boolean(provConf).booleanValue();
  -        
  -        // pull the important info out of the portlet config
  -        actionName = getPortletConfig().getInitParameter("action");
  -        // STW: Allow subclasses to set viewtype for backward compatibillity
  -        if (getPortletConfig().getInitParameter("viewtype") != null)
  -        {
  -            viewType = getPortletConfig().getInitParameter("viewtype");
  -        }
  -
  -        template = getPortletConfig().getInitParameter("template");
  -
  -        // get viewprocessor from factory
  -        logger.info(
  -            "GenericMVCPortlet - creating view processor for viewtype = "
  -                + viewType
  -                + ", template = "
  -                + template);
  -        processor = ViewProcessorFactory.getViewProcessor(viewType);
  -
  -        // initialize view processor with portlet info
  -        processor.init(this);
  -
  -        // should make this config file driven
  -        // STW removed this so subclasses can decide this for
  -        // themselves.
  -        // setCacheable(false);
  -    }
  -
  -    /**
  -     * By default MVCPortlets are cacheable. This can be overriden by specifying
  -     * "_IsCacheable" parameter.
  -     * 
  -     * @return 
  -     */
  -    public boolean isCacheable()
  -    {
  -        return getPortletConfig().getInitParameter(IS_CACHEABLE, "true").equalsIgnoreCase("true");
  -    }
  -
  -/**
  - * Whether or not this portlet provides it's own customizer.
  - * This can be set at the registry level by adding a 
  - * boolean paramter "provides.customization"
  - * Defaults to "false"
  - */
  -    public boolean providesCustomization()
  -    {
  -        return providesCustomization;
  -    }
  -
  -    public ConcreteElement getContent(RunData rundata)
  -    {
  -
  -        //if caching is turned off or no expiration time set, generate and return the content
  -        if (!isCacheable() || null == getExpirationMillis())
  -        {
  -            return buildContent(rundata);
  -        }
  -
  -        //is the cached content still valid, if not, generate and return the content
  -        if (getExpirationMillis().longValue() <= System.currentTimeMillis())
  -        {
  -            return buildContent(rundata);
  -        }
  -
  -        //else, the cached content is fine to be returned
  -        return getContent(rundata, null, true);
  -
  -    }
  -
  -    protected ConcreteElement buildContent(RunData rundata)
  -    {
  -        // create a new context
  -        // populate it with data
  -        GenericMVCContext context = new GenericMVCContext(TurbinePull.getGlobalContext());
  -        context.put(RUNDATA, rundata);
  -        context.put(PORTLET, this);
  -        context.put(PORTLET_CONFIG, this.getPortletConfig());
  -        context.put(SKIN, this.getPortletConfig().getPortletSkin());
  -        context.put(TEMPLATE, getCurrentTemplate(rundata));
  -        context.put(VIEW_TYPE, viewType);
  -        populateRequest(rundata);
  -
  -        // put references to the pull tools in the context
  -        TurbinePull.populateContext(context, rundata);
  -        // Initialize jlink and jslink tools with ourselves
  -        // to enable links between portlets
  -        Object jlink = context.get("jlink");
  -
  -        if (jlink instanceof JetspeedTemplateLink)
  -        {
  -            ((JetspeedTemplateLink) jlink).setPortlet(this);
  -        }
  -
  -        Object jslink = context.get("jslink");
  -
  -        if (jslink instanceof JetspeedLink)
  -        {
  -            ((JetspeedLink) jslink).setPortlet(this);
  -        }
  -
  -        // Handle Action
  -        if (actionName != null)
  -        {
  -
  -            try
  -            {
  -
  -                // store the context so that the action can retrieve it
  -                //Log.debug("VelocityPortlet found action "+actionName+" context "+context);
  -                // note: the name it is stored under is legacy, leaving it this way
  -                // because some of the routines fall back to old default behavior
  -                // of the velocity portlet and might depend on the name
  -                rundata.getTemplateInfo().setTemplateContext("VelocityPortletContext", context);
  -
  -                if (logger.isDebugEnabled())
  -                {
  -                    logger.debug(
  -                        "GenericMVCPortlet: Executing action ["
  -                            + actionName
  -                            + "] for portlet ["
  -                            + this.getName()
  -                            + "]");
  -                }
  -
  -                ActionLoader.getInstance().exec(rundata, actionName);
  -            }
  -            catch (Exception e)
  -            {
  -                logger.error("GenericMVCPortlet - error executing action",  e);
  -            }
  -        }
  -
  -        // Process View
  -        // call processView method
  -        logger.info("GenericMVCPortlet - calling processView on processor");
  -
  -        ConcreteElement result = (ConcreteElement) processor.processView(context);
  -        logger.info("GenericMVCPortlet - setting this portlet's content");
  -        clearContent();
  -        setContent(result); // only needed when caching is true I believe
  -
  -        // return result
  -        return result;
  -    }
  -    /**
  -     * @see setViewType()
  -     * @return String
  -     */
  -    protected String getViewType()
  -    {
  -        return viewType;
  -    }
  -
  -    /**
  -    * STW: Added for backward compatibility when using this
  -     * class to subclass the existing Jsp and Velocity portlets
  -     * so they can set their view prior to super.init();
  -     * @param viewType The viewType to set
  -     */
  -    protected void setViewType(String viewType)
  -    {
  -        this.viewType = viewType;
  -    }
  -
  -    /**
  -     * This is called before any action execution happens.
  -     * This provides backward compatibility to JspPortletActions
  -     * who retreive  information, like Portlet, from the request
  -     * BEFORE the ViewProcessor.processView() is called
  -     * which normally populates the request with Context objects.
  -     * @author <a href="mailto:sweaver@rippe.com">Scott Weaver</a>
  -     */
  -    protected void populateRequest(RunData rundata)
  -    {
  -        HttpServletRequest request = rundata.getRequest();
  -        request.setAttribute("data", rundata);
  -        request.setAttribute("portlet", this);
  -        request.setAttribute("conf", this.getPortletConfig());
  -        request.setAttribute("skin", this.getPortletConfig().getPortletSkin());
  -        request.setAttribute("template", getCurrentTemplate(rundata));
  -        request.setAttribute("viewType", viewType);
  -    }
  -    
  -    /**
  -     * 
  -     */
  -    protected String getCurrentTemplate( RunData data)
  -    {
  -    	String useTemplate = (String) PortletSessionState.getAttribute(this, data, TEMPLATE);
  -    	if(useTemplate == null)
  -    	{
  -    		useTemplate = this.template;
  -    	}
  -    	
  -    	return useTemplate;
  -    }
  -}
  +/* ====================================================================
  + * The Apache Software License, Version 1.1
  + *
  + * Copyright (c) 2000-2003 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 apache@apache.org.
  + *
  + * 5. Products derived from this software may not be called "Apache",
  + *    "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.portal.portlets;
  +
  +import java.io.IOException;
  +import java.io.PrintWriter;
  +import java.io.UnsupportedEncodingException;
  +import java.net.URLEncoder;
  +
  +import javax.servlet.http.HttpServletRequest;
  +
  +import org.apache.ecs.ConcreteElement;
  +import org.apache.jetspeed.om.profile.Profile;
  +import org.apache.jetspeed.portal.PortletException;
  +import org.apache.jetspeed.portal.portlets.viewprocessor.ViewProcessor;
  +import org.apache.jetspeed.portal.portlets.viewprocessor.ViewProcessorFactory;
  +import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
  +import org.apache.jetspeed.services.logging.JetspeedLogger;
  +import org.apache.jetspeed.services.rundata.JetspeedRunData;
  +import org.apache.jetspeed.util.PortletSessionState;
  +import org.apache.jetspeed.util.template.JetspeedLink;
  +import org.apache.jetspeed.util.template.JetspeedTemplateLink;
  +import org.apache.jetspeed.util.template.JspTemplate;
  +import org.apache.turbine.modules.ActionLoader;
  +import org.apache.turbine.services.pull.TurbinePull;
  +import org.apache.turbine.util.RunData;
  +
  +/**
  + * Provides the basic MVC Portlet functionality independant of any
  + * specific view technology (ie jsp, velocity, xslt, etc).  It handles
  + * the views via a ViewProcessor, which is a pluggable, factory
  + * created, run time module for which ever view technology your portlet
  + * uses.
  + * 
  + * There is no need to extend this portlet class, just define your porlet
  + * entry in the registy as a child of this class and provide your template
  + * and action class (extened from GenericMVCAction of course) and you
  + * are good to go.
  + * 
  + * Example .xreg entry:
  + * 
  + *  <portlet-entry name="GenericMVCPortlet" hidden="false"
  + *       type="abstract" application="false">
  + *       <security-ref parent="default"/>
  + *       <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
  + *      <media-type ref="html"/>
  + *      <url cachedOnURL="true"/>
  + *  </portlet-entry>
  + *  <portlet-entry name="VelocityMVCExample" hidden="false" type="ref"
  + *      parent="GenericMVCPortlet" application="false">
  + *      <meta-info>
  + *          <title>Velocity MVC Portlet</title>
  + *          <description>Velocity Generic MVC Portlet</description>
  + *      </meta-info>
  + *      <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
  + *      <parameter name="template" value="mvc-example" hidden="true"
  + *          cachedOnName="true" cachedOnValue="true"/>
  + *      <parameter name="viewtype" value="Velocity" hidden="true"
  + *          cachedOnName="true" cachedOnValue="true"/>
  + *      <parameter name="action"
  + *          value="portlets.ExampleGenericMVCAction" hidden="true"
  + *          cachedOnName="true" cachedOnValue="true"/>
  + *      <url cachedOnURL="true"/>
  + *  </portlet-entry>
  + * 
  + * See the Velocity and JSP MVC Portlet examples for template and action class clues.
  + * 
  + * To add new view processor types, simply implement the ViewProcessor
  + * interface and add your type into the <b>viewprocessor.properties</b> file as
  + * shown in the example below:
  + * 
  + * mvc.viewprocessor.Velocity = org.apache.jetspeedportlets.viewprocessors.VelocityViewProcessor
  + * mvc.viewprocessor.JSP = org.apache.jetspeedportlets.viewprocessors.JSPViewProcessor
  + * mvc.viewprocessor.XSL = org.apache.jetspeedportlets.viewprocessors.XSLViewProcessor
  + * 
  + * @stereotype role
  + * @author tkuebler
  + * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
  + * @version $Id$
  + */
  +public class GenericMVCPortlet extends AbstractInstancePortlet
  +{
  +    
  +    /**
  +     * Static initialization of the logger for this class
  +     */    
  +    private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(GenericMVCPortlet.class.getName());    
  +    
  +    // STW: Context keys
  +    public static final String PORTLET = "portlet";
  +    public static final String TEMPLATE = "template";
  +    public static final String RUNDATA = "data";
  +    public static final String PORTLET_CONFIG = "conf";
  +    public static final String SKIN = "skin";
  +    public static final String VIEW_TYPE = "viewType";
  +    public static final String IS_CACHEABLE = "_IsCacheable";
  +
  +    // need cache timer, etc
  +    private String viewType = "ERROR: not set in config";
  +    private String actionName = "ERROR: not set in config";
  +    private String template = "ERROR: not set in config";
  +    private String configureTemplate;
  +    private String maximizedTemplate;
  +    private ViewProcessor processor = null;
  +    private boolean providesCustomization;
  +
  +    public static final String RENDERING_DELAYED = "renderingDelayed";
  +    public static final String SIMULATE_DELAY = "simulateDelay";
  +    public static final String PORTLET_ID = "__portletId";
  +    public static final String DOC_URL = "__docUrl";
  +  
  +    public void init() throws PortletException
  +    {
  +        
  +        //STW: check custimization attribute
  +        String provConf = getPortletConfig().getInitParameter("provides.customization", "false");
  +        providesCustomization = new Boolean(provConf).booleanValue();
  +        
  +        // pull the important info out of the portlet config
  +        actionName = getPortletConfig().getInitParameter("action");
  +        // STW: Allow subclasses to set viewtype for backward compatibillity
  +        if (getPortletConfig().getInitParameter("viewtype") != null)
  +        {
  +            viewType = getPortletConfig().getInitParameter("viewtype");
  +        }
  +
  +        template = getPortletConfig().getInitParameter("template");
  +
  +        // get viewprocessor from factory
  +        logger.info(
  +            "GenericMVCPortlet - creating view processor for viewtype = "
  +                + viewType
  +                + ", template = "
  +                + template);
  +        processor = ViewProcessorFactory.getViewProcessor(viewType);
  +
  +        // initialize view processor with portlet info
  +        processor.init(this);
  +
  +        // should make this config file driven
  +        // STW removed this so subclasses can decide this for
  +        // themselves.
  +        // setCacheable(false);
  +    }
  +
  +    /**
  +     * By default MVCPortlets are cacheable. This can be overriden by specifying
  +     * "_IsCacheable" parameter.
  +     * 
  +     * @return 
  +     */
  +    public boolean isCacheable()
  +    {
  +        return getPortletConfig().getInitParameter(IS_CACHEABLE, "true").equalsIgnoreCase("true");
  +    }
  +
  +/**
  + * Whether or not this portlet provides it's own customizer.
  + * This can be set at the registry level by adding a 
  + * boolean paramter "provides.customization"
  + * Defaults to "false"
  + */
  +    public boolean providesCustomization()
  +    {
  +        return providesCustomization;
  +    }
  +
  +    public ConcreteElement getContent(RunData rundata)
  +    {
  +        if (useDelayedRendering(rundata))
  +        {
  +            Profile profile = ((JetspeedRunData) rundata).getProfile();
  +            String path = profile.getPath();
  +            String portletId = getID();
  +            
  +            // FIXME: please use JetspeedLink to create Portal URLs           
  +            String docUrl = "portal/" + path + "/js_peid/" + portletId + "?action=controls.Print";
  +            try 
  +            {
  +                docUrl = URLEncoder.encode(docUrl, "UTF-8");
  +            } 
  +            catch (UnsupportedEncodingException e)   
  +            {
  +                e.printStackTrace();
  +            }
  +            // END FIXME:
  +            
  +            HttpServletRequest request = rundata.getRequest();
  +            request.setAttribute(PORTLET_ID, portletId);
  +            request.setAttribute(DOC_URL, docUrl);
  +
  +            // render content that pulls
  +            return renderJspTemplate(rundata, "delayedContent.jsp");          
  +        }
  +        
  +        simulateDelay();             
  +            
  +        //if caching is turned off or no expiration time set, generate and return the content
  +        if (!isCacheable() || null == getExpirationMillis())
  +        {
  +            return buildContent(rundata);
  +        }
  +
  +        //is the cached content still valid, if not, generate and return the content
  +        if (getExpirationMillis().longValue() <= System.currentTimeMillis())
  +        {
  +            return buildContent(rundata);
  +        }
  +
  +        //else, the cached content is fine to be returned
  +        return getContent(rundata, null, true);
  +
  +    }
  +
  +    protected ConcreteElement buildContent(RunData rundata)
  +    {
  +        // create a new context
  +        // populate it with data
  +        GenericMVCContext context = new GenericMVCContext(TurbinePull.getGlobalContext());
  +        context.put(RUNDATA, rundata);
  +        context.put(PORTLET, this);
  +        context.put(PORTLET_CONFIG, this.getPortletConfig());
  +        context.put(SKIN, this.getPortletConfig().getPortletSkin());
  +        context.put(TEMPLATE, getCurrentTemplate(rundata));
  +        context.put(VIEW_TYPE, viewType);
  +        populateRequest(rundata);
  +
  +        // put references to the pull tools in the context
  +        TurbinePull.populateContext(context, rundata);
  +        // Initialize jlink and jslink tools with ourselves
  +        // to enable links between portlets
  +        Object jlink = context.get("jlink");
  +
  +        if (jlink instanceof JetspeedTemplateLink)
  +        {
  +            ((JetspeedTemplateLink) jlink).setPortlet(this);
  +        }
  +
  +        Object jslink = context.get("jslink");
  +
  +        if (jslink instanceof JetspeedLink)
  +        {
  +            ((JetspeedLink) jslink).setPortlet(this);
  +        }
  +
  +        // Handle Action
  +        if (actionName != null)
  +        {
  +
  +            try
  +            {
  +
  +                // store the context so that the action can retrieve it
  +                //Log.debug("VelocityPortlet found action "+actionName+" context "+context);
  +                // note: the name it is stored under is legacy, leaving it this way
  +                // because some of the routines fall back to old default behavior
  +                // of the velocity portlet and might depend on the name
  +                rundata.getTemplateInfo().setTemplateContext("VelocityPortletContext", context);
  +
  +                if (logger.isDebugEnabled())
  +                {
  +                    logger.debug(
  +                        "GenericMVCPortlet: Executing action ["
  +                            + actionName
  +                            + "] for portlet ["
  +                            + this.getName()
  +                            + "]");
  +                }
  +
  +                ActionLoader.getInstance().exec(rundata, actionName);
  +            }
  +            catch (Exception e)
  +            {
  +                logger.error("GenericMVCPortlet - error executing action",  e);
  +            }
  +        }
  +
  +        // Process View
  +        // call processView method
  +        logger.info("GenericMVCPortlet - calling processView on processor");
  +
  +        ConcreteElement result = (ConcreteElement) processor.processView(context);
  +        logger.info("GenericMVCPortlet - setting this portlet's content");
  +        clearContent();
  +        setContent(result); // only needed when caching is true I believe
  +
  +        // return result
  +        return result;
  +    }
  +    /**
  +     * @see setViewType()
  +     * @return String
  +     */
  +    protected String getViewType()
  +    {
  +        return viewType;
  +    }
  +
  +    /**
  +    * STW: Added for backward compatibility when using this
  +     * class to subclass the existing Jsp and Velocity portlets
  +     * so they can set their view prior to super.init();
  +     * @param viewType The viewType to set
  +     */
  +    protected void setViewType(String viewType)
  +    {
  +        this.viewType = viewType;
  +    }
  +
  +    /**
  +     * This is called before any action execution happens.
  +     * This provides backward compatibility to JspPortletActions
  +     * who retreive  information, like Portlet, from the request
  +     * BEFORE the ViewProcessor.processView() is called
  +     * which normally populates the request with Context objects.
  +     * @author <a href="mailto:sweaver@rippe.com">Scott Weaver</a>
  +     */
  +    protected void populateRequest(RunData rundata)
  +    {
  +        HttpServletRequest request = rundata.getRequest();
  +        request.setAttribute("data", rundata);
  +        request.setAttribute("portlet", this);
  +        request.setAttribute("conf", this.getPortletConfig());
  +        request.setAttribute("skin", this.getPortletConfig().getPortletSkin());
  +        request.setAttribute("template", getCurrentTemplate(rundata));
  +        request.setAttribute("viewType", viewType);
  +    }
  +    
  +    /**
  +     * 
  +     */
  +    protected String getCurrentTemplate( RunData data)
  +    {
  +        String useTemplate = (String) PortletSessionState.getAttribute(this, data, TEMPLATE);
  +        if(useTemplate == null)
  +        {
  +            useTemplate = this.template;
  +        }
  +
  +        return useTemplate;
  +    }
  +    
  +    protected boolean useDelayedRendering(RunData rundata)
  +    {
  +        String renderingDelayedString = getPortletConfig().getInitParameter(RENDERING_DELAYED);
  +        boolean renderingDelayed = false;
  +        if (renderingDelayedString != null)
  +        {
  +            renderingDelayed = (Boolean.valueOf(renderingDelayedString) == Boolean.TRUE);
  +        }
  +
  +        HttpServletRequest request = rundata.getRequest();
  +        String action = rundata.getAction();
  +
  +        return renderingDelayed && (action == null || action.length() == 0 || "controls.Restore".equals(action));
  +    }
  +
  +    protected ConcreteElement renderJspTemplate(RunData rundata, String templateName)
  +    {
  +        JspTemplate t = new JspTemplate(rundata, "/portlets/html/" + templateName);
  +        PrintWriter out = null;
  +        try
  +        {
  +            out = rundata.getOut();
  +            out.println(t.getContent());
  +        }
  +        catch (IOException ioe)
  +        {
  +            logger.error(ioe);
  +        }
  +
  +        return null;
  +    }
  +    
  +    private void simulateDelay()
  +    {        
  +        String simulateDelayString = getPortletConfig().getInitParameter(SIMULATE_DELAY);
  +        int simulateDelay = 0;  // seconds
  +        if (simulateDelayString != null)
  +        {
  +            simulateDelay = Integer.parseInt(simulateDelayString);
  +        }
  +
  +        if (simulateDelay > 0)
  +        {
  +            long delayInMilliseconds = simulateDelay * 1000;
  +            try 
  +            { 
  +                Thread.sleep(delayInMilliseconds); 
  +            } 
  +            catch (InterruptedException e) 
  +            {
  +            }
  +        }
  +                
  +    }
  +}
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/util/template/JspTemplate.java
  
  Index: JspTemplate.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2003 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "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.util.template;
  
  import org.apache.log4j.Logger;
  import org.apache.turbine.services.TurbineServices;
  import org.apache.turbine.services.jsp.JspService;
  import org.apache.turbine.util.RunData;
  import org.apache.turbine.util.TurbineException;
  
  /**
   * JspTemplate
   *
   * @author <a href="mailto:junyang@cisco.com">Jun Yang</a>
   * @version $Id: JspTemplate.java,v 1.1 2003/11/02 20:07:17 taylor Exp $
   */
  public class JspTemplate 
  {
      protected RunData runData;
      protected String templateName;
      private static Logger logger = Logger.getLogger(JspTemplate.class);    
      public JspTemplate(RunData runData, String templateName)
      {
          this.runData = runData;
          this.templateName = templateName;
      }
  
      public String getContent()
      {
          JspService jsp = (JspService) TurbineServices.getInstance().getService(JspService.SERVICE_NAME);
          try
          {
              jsp.handleRequest(this.runData, this.templateName);
          }
          catch (TurbineException te1)
          {
              if (!this.templateName.endsWith(".jsp"))
              {
                  try
                  {
                      jsp.handleRequest(this.runData, this.templateName + ".jsp");
                  }
                  catch (TurbineException te2)
                  {
                      logger.error("failed to invoke JSP Template '" + 
                                      this.templateName + "' and '" + this.templateName + ".jsp'", te2);
                  }
              }
              else
              {
                  logger.error("failed to invoke JSP Template '" + this.templateName + "'", te1);            
              }
          }
          
          return "";
      }
  }
  
  
  
  1.70      +0 -0      jakarta-jetspeed/webapp/WEB-INF/conf/JetspeedSecurity.properties
  
  Index: JetspeedSecurity.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/webapp/WEB-INF/conf/JetspeedSecurity.properties,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  
  
  
  1.44      +9 -0      jakarta-jetspeed/webapp/WEB-INF/conf/demo-portlets.xreg
  
  Index: demo-portlets.xreg
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/webapp/WEB-INF/conf/demo-portlets.xreg,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -r1.43 -r1.44
  --- demo-portlets.xreg	29 Sep 2003 18:07:52 -0000	1.43
  +++ demo-portlets.xreg	2 Nov 2003 20:07:17 -0000	1.44
  @@ -765,4 +765,13 @@
   		<url>/examples/organized.html</url>
   		<category>sites</category>
   	</portlet-entry>
  +    <portlet-entry name="DelayRenderedStockQuote" hidden="false" type="ref" parent="StockQuote" application="false">
  +        <meta-info>
  +            <title>Delay-rendered Stock Portfolio</title>
  +	    <description>Delay-rendered Stock Portfolio Portlet</description>
  +        </meta-info>
  +        <parameter name="renderingDelayed" value="true" hidden="false" cachedOnName="true" cachedOnValue="true"/>
  +        <parameter name="simulateDelay" value="2" hidden="false" cachedOnName="true" cachedOnValue="true"/>
  +        <category group="Jetspeed">finance.stocks</category>
  +    </portlet-entry>
   </registry>
  
  
  
  1.1                  jakarta-jetspeed/webapp/WEB-INF/conf/enhancedPortletControllers.xreg
  
  Index: enhancedPortletControllers.xreg
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <registry>
      <portlet-controller-entry name="XTwoColumns1" hidden="false">
          <meta-info>
              <title>Enhanced Two columns (50/50)</title>
          </meta-info>
          <classname>org.apache.jetspeed.portal.controllers.VelocityPortletController</classname>
          <parameter name="template" value="multicolumn.vm" hidden="false"/>
          <parameter name="action"
              value="controllers.XMultiColumnControllerAction" hidden="false"/>
          <parameter name="sizes" value="50%,50%" hidden="false"/>
          <parameter name="cols" value="2" hidden="false"/>
          <media-type ref="html"/>
      </portlet-controller-entry>
      <portlet-controller-entry name="XTwoColumns2" hidden="false">
          <meta-info>
              <title>Enhanced Two columns (25/75)</title>
          </meta-info>
          <classname>org.apache.jetspeed.portal.controllers.VelocityPortletController</classname>
          <parameter name="template" value="multicolumn.vm" hidden="false"/>
          <parameter name="action"
              value="controllers.XMultiColumnControllerAction" hidden="false"/>
          <parameter name="sizes" value="25%,75%" hidden="false"/>
          <parameter name="cols" value="2" hidden="false"/>
          <media-type ref="html"/>
      </portlet-controller-entry>
      <portlet-controller-entry name="XTwoColumns3" hidden="false">
          <meta-info>
              <title>Enhanced Two columns (75/25)</title>
          </meta-info>
          <classname>org.apache.jetspeed.portal.controllers.VelocityPortletController</classname>
          <parameter name="template" value="multicolumn.vm" hidden="false"/>
          <parameter name="action"
              value="controllers.XMultiColumnControllerAction" hidden="false"/>
          <parameter name="sizes" value="75%,25%" hidden="false"/>
          <parameter name="cols" value="2" hidden="false"/>
          <media-type ref="html"/>
      </portlet-controller-entry>
      <portlet-controller-entry name="XThreeColumns1" hidden="false">
          <meta-info>
              <title>Enhanced Three columns (33/34/33)</title>
          </meta-info>
          <classname>org.apache.jetspeed.portal.controllers.VelocityPortletController</classname>
          <parameter name="template" value="multicolumn.vm" hidden="false"/>
          <parameter name="action"
              value="controllers.XMultiColumnControllerAction" hidden="false"/>
          <parameter name="sizes" value="33%,34%,33%" hidden="false"/>
          <parameter name="cols" value="3" hidden="false"/>
          <media-type ref="html"/>
      </portlet-controller-entry>
      <portlet-controller-entry name="XThreeColumns2" hidden="false">
          <meta-info>
              <title>Enhanced Three columns (25/50/25)</title>
          </meta-info>
          <classname>org.apache.jetspeed.portal.controllers.VelocityPortletController</classname>
          <parameter name="template" value="multicolumn.vm" hidden="false"/>
          <parameter name="action"
              value="controllers.XMultiColumnControllerAction" hidden="false"/>
          <parameter name="sizes" value="25%,50%,25%" hidden="false"/>
          <parameter name="cols" value="3" hidden="false"/>
          <media-type ref="html"/>
      </portlet-controller-entry>
  </registry>
  
  
  
  1.1                  jakarta-jetspeed/webapp/WEB-INF/templates/jsp/controllers/html/x-multicolumn-customize.jsp
  
  Index: x-multicolumn-customize.jsp
  ===================================================================
  <%@ page import = "java.util.*" %>
  <%@ page import = "org.apache.turbine.util.*" %>
  <%@ page import = "org.apache.velocity.context.Context" %>
  <%@ page import = "org.apache.jetspeed.util.Config" %>
  <%@ page import = "org.apache.jetspeed.portal.*" %>
  <%@ page import = "org.apache.jetspeed.om.profile.psml.PsmlEntry" %>
  <%@ page import = "org.apache.jetspeed.om.SecurityReference" %>
  <%@ page import = "org.apache.jetspeed.util.template.*" %>
  <%@ page import = "org.apache.jetspeed.modules.actions.controllers.Util" %>
  <%@ page import = "org.apache.jetspeed.services.customlocalization.CustomLocalizationTool" %>
  
  <%
  Context context = (Context) request.getAttribute("jspContext");
  Object[] columns = (Object[]) context.get("portlets");
  PortletController controller = (PortletController) context.get("controller");
  Config myConfig = controller.getConfig();
  String[] sizes = Util.convertStringsToArray(myConfig.getInitParameter("sizes"), ",");
  JetspeedLink jslink = (JetspeedLink) context.get("jslink");
  String action = (String) context.get("action");
  CustomLocalizationTool l10n = (CustomLocalizationTool) context.get("l10n");
  Map portletTitleMap = (Map) context.get("titles");
  RunData runData = (RunData) context.get("data");
  JetspeedTool jetspeed = (JetspeedTool) context.get("jetspeed");
  %>
  
  <style>
  .drag-block {
  	position: relative;
  	border: solid gray;
  	cursor: pointer;
  	height: 120px;
  }
  .drag-sink {
  	position: relative;
  	border: solid #EEEEEE;
  }
  </style>
  
  <script type="text/javascript" src="js/util.js"></script>
  <script type="text/javascript">
  
  // global variables
  
  dragBlockTemplate = '<div class="drag-block" name="{col:${col},row:${row}}"><form name="decoration-${portletId}" action="${jslinkTemplate}" method="post" onSubmit="javascript:submitFormWithModelChanges(this)"><table border="0" width="100%"><tr><td align="center" colspan="2"><b>${portletTitle}</b></td><td align="right"><input type="image" src="${closeImageSrc}" border="0" name="eventSubmit_doDelete" title="remove"></td></tr><tr><td valign="top" width="45%">Skin : ${portletSkinName}</td><td valign="top">Security ID : ${portletSecurityId}</td><td></td></tr><tr><td colspan="2">Decoration : ${portletDecoration}</td><td></td></tr></table><input type="hidden" name="js_peid" value="${portletId}"><input type="hidden" name="col" value="${originalCol}"><input type="hidden" name="row" value="${originalRow}"><input type="hidden" name="eventSubmit_doControl" value="doControl"><input type="hidden" name="<%= jslink.getActionKey() %>" value="<%= action %>" ><input type="hidden" name="modelChangeList"></form></div>';
  
  dragSinkTemplate = '<div class="drag-sink" name="{col:${col},row:${row}}"></div>';
  
  layoutPlaygroundTableColumnTemplate = '<td valign="top" width="${width}">${columnContent}</td>';
  
  var modelRoot = [
  <%
  for (int i = 0; i < columns.length; i++)
  {
  %>
  	<%= i > 0 ? "," : "" %>[
  <%
  	List portletList = (List) columns[i];
  	for (int j = 0; j < portletList.size(); j++)
  	{
  %>
  		<%= j > 0 ? "," : "" %>
  <%
  		PsmlEntry entry = (PsmlEntry) portletList.get(j);
  		String portletId = entry.getId();
  		String portletTitle = (String) portletTitleMap.get(entry.getId());
  		String portletSkinName = entry.getSkin() == null ? "-- Default --" : entry.getSkin().getName();
  
  		// security reference
  		SecurityReference securityReference = jetspeed.getSecurityReference(entry);
  		String portletSecurityRef;
  		if (securityReference != null)
  		{
  			portletSecurityRef = securityReference.getParent();
  			if (jetspeed.getSecuritySource(entry) == 1)
  			{
  				portletSecurityRef = portletSecurityRef  + "<span style=\"color:red\"><br/>" + l10n.get("SECURITY_IS_REGISTRY_LEVEL") + ".</span>";
  			}
  			else if (jetspeed.getSecuritySource(entry) == 2)
  			{
  				portletSecurityRef = portletSecurityRef  + "<span style=\"color:red\"><br/>" + l10n.get("SECURITY_IS_SYSTEM_DEFAULT") + ".</span>";
  			}
  		}
  		else
  		{
  			portletSecurityRef = "-- Default --";
  		}
  
  		// decoration
  		String controlListBox =
  			(entry.getControl() != null && entry.getControl().getName() != null) ?
  			JetspeedTool.getPortletParameter(runData, (Portlet) runData.getUser().getTemp("customizer"), "control", entry.getControl().getName()) :
  			JetspeedTool.getPortletParameter(runData, (Portlet) runData.getUser().getTemp("customizer"), "control");
  		controlListBox = controlListBox.substring(12);
  		controlListBox = controlListBox.replace('\n', ' ');
  		controlListBox = controlListBox.replace('\r', ' ');
  %>
  		{id:'<%= portletId %>', parent:'<%= entry.getParent() %>',title:'<%= portletTitle %>',description:'<%= entry.getDescription() %>',skinName:'<%= portletSkinName %>',securityId:'<%= portletSecurityRef %>',controlListBox:'<%= controlListBox %>'}
  <%
  	}
  %>
  	]
  <%
  }
  %>
  ];
  var sizes = [
  <%
  for (int i = 0; i < sizes.length; i++)
  {
  %>
  	<%= i > 0 ? "," : "" %>'<%= sizes[i] %>'
  <%
  }
  %>
  ];
  
  var dragBlockList;
  var dragSinkList;
  
  function renderLayoutPlayground(columns)
  {
  	var content = '<table border="0" width="100%" id="layoutPlaygroundTable"><tr>';
  
  	for (var i = 0; i < columns.length; i++)
  	{
  		var columnContent = fillTemplate(
  			dragSinkTemplate,
  			'col', i,
  			'row', 0
  		);
  		var portletList = columns[i];
  		for (var j = 0; j < portletList.length; j++)
  		{
  			var psmlEntry = portletList[j];
  			var controlListBox = psmlEntry.controlListBox.replace(/this.form.submit\(\)/gi, 'submitFormWithModelChanges(this.form)');
  			columnContent += fillTemplate(
  				dragBlockTemplate,
  				'portletId', psmlEntry.id,
  				'portletTitle', psmlEntry.title,
  				'portletSkinName', psmlEntry.skinName,
  				'portletSecurityId', psmlEntry.securityId,
  				'portletDecoration', controlListBox,
  				'closeImageSrc', 'images/close.gif',
  				'jslinkTemplate', '<%= jslink.getTemplate() %>',
  				'col', i,
  				'row', j,
  				'originalCol', i,
  				'originalRow', j
  			);
  			columnContent += fillTemplate(
  				dragSinkTemplate,
  				'col', i,
  				'row', j + 1
  			);
  		}
  		content += fillTemplate(
  			layoutPlaygroundTableColumnTemplate,
  			'width', sizes[i],
  			'columnContent', columnContent
  		);
  	}
  
  	content += '</tr></table>';
  	var layoutPlaygroundDiv = document.getElementById('layoutPlayground');
  	layoutPlaygroundDiv.innerHTML = content;
  
  	buildDragBlockList();
  	buildDragSinkList();
  }
  
  var target = null;
  var highlightedDragSink = null;
  var previousX = 0;
  var previousY = 0;
  
  function elementGetTop(elem)
  {
  	var top = parseInt(elem.style.top);
  	if (isNaN(top))
  		return 0;
  	else
  		return top;
  }
  
  function elementGetLeft(elem)
  {
  	var left = parseInt(elem.style.left);
  	if (isNaN(left))
  		return 0;
  	else
  		return left;
  }
  
  function elementMoveBy(elem, point)
  {
  	var newTop = elementGetTop(elem) + point.y;
  	var newLeft = elementGetLeft(elem) + point.x;
  	elem.style.top = newTop + 'px';
  	elem.style.left = newLeft + 'px';
  }
  
  function elementMoveTo(elem, point)
  {
  	elem.style.top = point.x + 'px';
  	elem.style.left = point.y + 'px';
  }
  
  function getEventPositionX(e)
  {
  	if (!e)
  	{
  		// IE
  		e = window.event;
  		return e.clientX + document.body.scrollLeft;
  	}
  	else
  	{
  		// standard
  		return e.clientX + document.body.scrollLeft;
  	}
  }
  
  function getEventPositionY(e)
  {
  	if (!e)
  	{
  		// IE
  		e = window.event;
  		return e.clientY + document.body.scrollTop;
  	}
  	else
  	{
  		// standard
  		return e.clientY + document.body.scrollTop;
  	}
  }
  
  function findTargetDragBlock(e)
  {
  	var x = getEventPositionX(e);
  	var y = getEventPositionY(e);
  
  	for (var i = 0; i < dragBlockList.length; i++)
  	{
  		var dragBlock = dragBlockList[i];
  		if (elementContainsPoint(dragBlock, x, y))
  		{
  			return dragBlock;
  		}
  	}
  
  	return null;
  }
  
  function handleMouseDown(event)
  {
  	if (!event)	// IE
  	{
  		event = window.event;
  //		event.target = event.srcElement;
  	}
  
  	target = findTargetDragBlock(event);
  
  	if (target)
  	{
  		previousX = getEventPositionX(event);
  		previousY = getEventPositionY(event);
  		target.originalPosition = {x:elementGetLeft(target), y:elementGetTop(target)};
  		target.style.borderColor = 'black';
  		event.cancelBubble = true;
  		event.returnValue = false;
  		return false;
  	}
  	else
  	{
  		return true;
  	}
  }
  
  function handleMouseMove(event)
  {
  	if (!event)	// IE
  	{
  		event = window.event;
  //		event.target = event.srcElement;
  	}
  
  	if (target)
  	{
  		var currentX = getEventPositionX(event);
  		var currentY = getEventPositionY(event);
  		var dx = currentX - previousX;
  		var dy = currentY - previousY;
  		target.style.cursor = 'move';
  		elementMoveBy(target, {x:dx, y:dy});
  		highlightDragSink(currentX, currentY);
  		previousX = currentX;
  		previousY = currentY;
  		event.cancelBubble = true;
  		event.returnValue = false;
  		return false;
  	}
  	else
  	{
  		return true;
  	}
  }
  
  function handleMouseUp(event)
  {
  	if (!event)	// IE
  	{
  		event = window.event;
  //		event.target = event.srcElement;
  	}
  
  	if (target)
  	{
  		target.style.cursor = 'pointer';
  		target.style.borderColor = 'gray';
  		if (highlightedDragSink)
  		{
  			drop(target, highlightedDragSink);
  			unhighlight(highlightedDragSink);
  			highlightedDragSink = null;
  		}
  		else
  		{
  			elementMoveTo(target, target.originalPosition);
  		}
  		target.originalPosition = null;
  		target = null;
  		previousX = 0;
  		previousY = 0;
  		event.cancelBubble = true;
  		event.returnValue = false;
  		return false;
  	}
  	else
  	{
  		return true;
  	}
  }
  
  document.onmousedown = handleMouseDown;
  document.onmousemove = handleMouseMove;
  document.onmouseup = handleMouseUp;
  
  function highlightDragSink(x, y)
  {
  	for (var i = 0; i < dragSinkList.length; i++)
  	{
  		var dragSink = dragSinkList[i];
  		if (elementContainsPoint(dragSink, x, y))
  		{
  			if (highlightedDragSink)
  				unhighlight(highlightedDragSink);
  			highlight(dragSink);
  			highlightedDragSink = dragSink;
  			return;
  		}
  	}
  
  	if (highlightedDragSink)
  	{
  		unhighlight(highlightedDragSink);
  		highlightedDragSink = null;
  	}
  }
  
  function elementContainsPoint(elem, x, y)
  {
  	var top = elem.offsetTop;
  	var left = elem.offsetLeft;
  	var height = elem.offsetHeight;
  	var width = elem.offsetWidth;
  	return	(0 <= x - left && x - left <= width) &&
  		(0 <= y - top && y - top <= height);
  }
  
  function highlight(elem)
  {
  	elem.style.borderColor = '#FF0000';
  }
  
  function unhighlight(elem)
  {
  	elem.style.borderColor = '#EEEEEE';
  }
  
  function buildDragBlockList()
  {
  	var layoutPlaygroundTable = document.getElementById('layoutPlaygroundTable');
  	var dragBlockCandidateList = layoutPlaygroundTable.getElementsByTagName("div");
  	dragBlockList = new Array();
  	for (var i = 0; i < dragBlockCandidateList.length; i++)
  	{
  		var dragBlockCandidate = dragBlockCandidateList[i];
  		if (dragBlockCandidate.className == 'drag-block')
  			dragBlockList[dragBlockList.length] = dragBlockCandidate;
  	}
  }
  
  function buildDragSinkList()
  {
  	var layoutPlaygroundTable = document.getElementById('layoutPlaygroundTable');
  	var dragSinkCandidateList = layoutPlaygroundTable.getElementsByTagName("div");
  	dragSinkList = new Array();
  	for (var i = 0; i < dragSinkCandidateList.length; i++)
  	{
  		var dragSinkCandidate = dragSinkCandidateList[i];
  		if (dragSinkCandidate.className == 'drag-sink')
  			dragSinkList[dragSinkList.length] = dragSinkCandidate;
  	}
  }
  
  function drop(target, dragSink)
  {
  	var targetRowCol = eval('_rowcol=' + target.attributes['name'].value);
  	var dragSinkRowCol = eval('_rowcol=' + dragSink.attributes['name'].value);
  
  	if (destSameAsOrigin(targetRowCol, dragSinkRowCol))
  		return;
  
  	// get reference to portletEtnry
  	var portletEntry = modelRoot[targetRowCol.col][targetRowCol.row];
  
  	// remove from old position
  	modelRoot[targetRowCol.col].splice(targetRowCol.row, 1);
  
  	// insert into new position
  	modelRoot[dragSinkRowCol.col].splice(dragSinkRowCol.row, 0, portletEntry);
  
  	recordModelChange(targetRowCol, dragSinkRowCol);
  
  	renderLayoutPlayground(modelRoot);
  }
  
  function destSameAsOrigin(origin, dest)
  {
  	return
  		(origin.col == dest.col) &&
  		(origin.row == dest.row || origin.row + 1 == dest.row);
  }
  
  function recordModelChange(origin, dest)
  {
  	var change = origin.col + ',' + origin.row + ',' + dest.col + ',' + dest.row;	
  	var f = document.forms['xform'];
  	if (f.modelChangeList.value == '')
  		f.modelChangeList.value = change;
  	else
  		f.modelChangeList.value += ';' + change;
  }
  
  function submitFormWithModelChanges(form)
  {
  	var modelChangeList = document.forms.xform.modelChangeList.value;
  	form.modelChangeList.value = modelChangeList;
  	form.submit();
  }
  
  function getPrintString(o)
  {
  	var s = '{';
  	for (p in o)
  	{
  		s += p + ':' + o[p] + ', ';
  	}
  	s += '}';
  	return s;
  }
  </script>
  
  <!-- layout table -->
  <br>
  
  <div id='layoutPlayground'></div>
  <script type="text/javascript">
  renderLayoutPlayground(modelRoot);
  </script>
  
  <br>
  
  <!-- buttons -->
    <form name="xform" action="<%= jslink.getTemplate() %>" method="post">
    <input type="hidden" name="<%= jslink.getActionKey() %>" value="<%= action %>" >
    <input type="hidden" name="modelChangeList" value="">
    <center>
      <table cellspacing="2">
        <tr>
          <td>
            <input type="submit" name="eventSubmit_doSave" value="<%= l10n.get("CUSTOMIZER_SAVEAPPLY") %>">
          </td>
          <td>
            <input type="submit" name="eventSubmit_doCancel" value="<%= l10n.get("CUSTOMIZER_CANCEL") %>">
          </td>
        </tr>
      </table>
    </center>
  </form>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jetspeed-dev-help@jakarta.apache.org


Mime
View raw message