/* ====================================================================
 * 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" 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.modules.actions.portlets;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.jetspeed.modules.actions.portlets.security.SecurityConstants;
import org.apache.jetspeed.om.BaseSecurityReference;
import org.apache.jetspeed.om.SecurityReference;
import org.apache.jetspeed.om.registry.PortletEntry;
import org.apache.jetspeed.om.registry.base.BaseCachedParameter;
import org.apache.jetspeed.om.registry.base.BasePortletEntry;
import org.apache.jetspeed.om.registry.base.BaseSecurity;
import org.apache.jetspeed.portal.portlets.VelocityPortlet;
import org.apache.jetspeed.services.Registry;
import org.apache.jetspeed.services.security.JetspeedRoleManagement;
import org.apache.jetspeed.util.template.JetspeedLink;
import org.apache.jetspeed.util.template.JetspeedLinkFactory;
import org.apache.turbine.util.DynamicURI;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
import org.apache.turbine.util.security.EntityExistsException;
import org.apache.velocity.context.Context;

/**
 * This action enables the creation and editing of portlets
 *
 * @author <a href="mailto:caius1440@hotmail.com">Jeremy Ford</a>
 * @version $Id: PortletUpdateAction.java,v 1.2 2003/03/19 23:03:22 morciuch Exp $
 */
public class PortletUpdateAction extends VelocityPortletAction
{
    private static final String PARAMETER = "parameter.";
    private static final String PORTLET_UPDATE_PANE = "portlet-form";

    private static final String PORTLET_NAME = "portlet_name";
    private static final String TAB_PARAMETER = "tab";

    /**
     * Subclasses must override this method to provide default behavior
     * for the portlet action
     */
    /**
     * Build the normal state content for this portlet.
     *
     * @param portlet The velocity-based portlet that is being built.
     * @param context The velocity context for this request.
     * @param rundata The turbine rundata context for this request.
     */
    protected void buildNormalContext(
        VelocityPortlet portlet,
        Context context,
        RunData rundata)
        throws Exception
    {
        String msgid =
            rundata.getParameters().getString(SecurityConstants.PARAM_MSGID);
        if (msgid != null)
        {
            int id = Integer.parseInt(msgid);
            if (id < SecurityConstants.MESSAGES.length)
                context.put(
                    SecurityConstants.PARAM_MSG,
                    SecurityConstants.MESSAGES[id]);
        }

        String mode =
            rundata.getParameters().getString(SecurityConstants.PARAM_MODE);
        context.put(SecurityConstants.PARAM_MODE, mode);

        if (mode != null && mode.equals(SecurityConstants.PARAM_MODE_INSERT))
        {
            Set parentSet = new HashSet();

            org.apache.jetspeed.om.registry.Registry registry =
                Registry.get(Registry.PORTLET);
            Enumeration entries = registry.getEntries();
            while (entries.hasMoreElements())
            {
                PortletEntry regEntry = (PortletEntry) entries.nextElement();

                String regType = regEntry.getType();
                if (regType.equalsIgnoreCase("abstract"))
                {
                    parentSet.add(regEntry.getName());
                }
            }

            Iterator roleIter = JetspeedRoleManagement.getRoles();
            context.put("roles", roleIter);

            context.put("parents", parentSet);
            context.put(
                "securitys",
                CustomizeSetAction.buildList(rundata, Registry.SECURITY));
        }

        if (mode != null && mode.equals(SecurityConstants.PARAM_MODE_UPDATE))
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);

            Iterator roleIter = JetspeedRoleManagement.getRoles();
            context.put("roles", roleIter);

            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            context.put("currentTab", tab);

            context.put(
                "securitys",
                CustomizeSetAction.buildList(rundata, Registry.SECURITY));

            context.put("entry", portletEntry);
        }

        if (mode != null && mode.equals(SecurityConstants.PARAM_MODE_DELETE))
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);

            context.put("entry", portletEntry);
        }
    }

    /**
     * Sets the portlet entry's fields
     * @param rundata
     * @param portletEntry
     */
    private void setPortletEntryInfo(
        RunData rundata,
        PortletEntry portletEntry)
    {
        String parent = rundata.getParameters().getString("parent");
        String title = rundata.getParameters().getString("title");
        String description = rundata.getParameters().getString("description");
        String url = rundata.getParameters().getString("url");
        String type = rundata.getParameters().getString("portlet_type");

        String mediaType = rundata.getParameters().getString("media_type");

        //meta info
        String image = rundata.getParameters().getString("image");

        String className = rundata.getParameters().getString("class_name");

        boolean isApplication =
            rundata.getParameters().getBoolean("is_application", false);
        boolean isCachedOnURL =
            rundata.getParameters().getBoolean("is_cached_on_url", false);
        boolean isHidden =
            rundata.getParameters().getBoolean("is_hidden", false);
        boolean isAdmin = rundata.getParameters().getBoolean("is_admin", false);

        String newSecurityParent =
            rundata.getParameters().getString("security_ref");

        String newSecurityRole =
            rundata.getParameters().getString("security_role");

        portletEntry.setTitle(title);
        portletEntry.setDescription(description);
        portletEntry.setURL(url);
        portletEntry.setParent(parent);
        portletEntry.setType(type);

        //need to build media index before add media
        portletEntry.listMediaTypes();
        portletEntry.addMediaType(mediaType);

        if (className != null && className.length() > 0)
        {
            portletEntry.setClassname(className);
        }

        portletEntry.setApplication(isApplication);
        portletEntry.setCachedOnURL(isCachedOnURL);
        portletEntry.setHidden(isHidden);
        //portletEntry.

        if (newSecurityParent != null && newSecurityParent.length() > 0)
        {
            SecurityReference securityRef = new BaseSecurityReference();
            securityRef.setParent(newSecurityParent);
            portletEntry.setSecurityRef(securityRef);
        }

        if (newSecurityRole != null && newSecurityRole.length() > 0)
        {
            BaseSecurity securityRole = new BaseSecurity();
            securityRole.setRole(newSecurityRole);
            portletEntry.setSecurity(securityRole);
        }
    }

    /**
     * Insert a portlet in the registry
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doInsert(RunData rundata, Context context) throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            if (portletName == null || portletName.length() == 0)
            {
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_INSERT)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME);
                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
            else
            {
                PortletEntry existingEntry =
                    (PortletEntry) Registry.getEntry(
                        Registry.PORTLET,
                        portletName);
                if (existingEntry != null)
                {
                    throw new EntityExistsException(
                        "PortletEntry: " + portletName + " Already Exists!");
                }

                PortletEntry portletEntry = new BasePortletEntry();
                portletEntry.setName(portletName);
                setPortletEntryInfo(rundata, portletEntry);

                Registry.addEntry(Registry.PORTLET, portletEntry);
            }
        }
        catch (EntityExistsException e)
        {
            //
            // dup key found - display error message - bring back to same screen
            //
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_INSERT)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_ENTITY_ALREADY_EXISTS);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
        catch (Exception e)
        {
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_INSERT)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Update an existing portlet in the registry
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doUpdate(RunData rundata, Context context) throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry == null)
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
            else
            {
                setPortletEntryInfo(rundata, portletEntry);
                Registry.addEntry(Registry.PORTLET, portletEntry);
                clearUserData(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Add a category to a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doAddcategory(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String categoryName =
                    rundata.getParameters().getString("category_name");
                if (categoryName != null && categoryName.length() > 0)
                {
                    String categoryGroup =
                        rundata.getParameters().getString(
                            "category_group",
                            "Jetspeed");
                    portletEntry.addCategory(categoryName, categoryGroup);

                    Registry.addEntry(Registry.PORTLET, portletEntry);

                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);

                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }
            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Remove categories from a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doRemovecategories(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String[] categories =
                    rundata.getParameters().getStrings("category_name");
                if (categories != null && categories.length > 0)
                {
                    for (int i = 0; i < categories.length; i++)
                    {
                        String categoryName = categories[i];
                        String categoryGroup =
                            rundata.getParameters().getString(
                                categoryName + ".category_group",
                                "Jetspeed");
                        portletEntry.removeCategory(
                            categoryName,
                            categoryGroup);
                    }

                    Registry.addEntry(Registry.PORTLET, portletEntry);
                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);
                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }
            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Add a media type to a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doAddmediatype(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String mediaType =
                    rundata.getParameters().getString("media_type");
                if (mediaType != null && mediaType.length() > 0)
                {
                    portletEntry.addMediaType(mediaType);
                    Registry.addEntry(Registry.PORTLET, portletEntry);
                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);
                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }
            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Remove media types from a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doRemovemediatypes(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String[] mediaTypes =
                    rundata.getParameters().getStrings("media_type");
                if (mediaTypes != null && mediaTypes.length > 0)
                {
                    for (int i = 0; i < mediaTypes.length; i++)
                    {
                        String mediaType = mediaTypes[i];
                        portletEntry.removeMediaType(mediaType);
                    }

                    Registry.addEntry(Registry.PORTLET, portletEntry);
                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);
                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }

            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Delete a portlet from the registry
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doDelete(RunData rundata, Context context) throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                Registry.removeEntry(Registry.PORTLET, portletName);
                clearUserData(rundata);
            }
            else
            {
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Add a parameter to a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doAddparameter(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String parameterName =
                    rundata.getParameters().getString("parameter_name");
                if (parameterName != null && parameterName.length() > 0)
                {
                    String parameterValue =
                        rundata.getParameters().getString("parameter_value");
                    String description =
                        rundata.getParameters().getString("description");
                    String title = rundata.getParameters().getString("title");
                    String securityRole =
                        rundata.getParameters().getString("security_role");
                    String securityRef =
                        rundata.getParameters().getString("security_ref");
                    boolean isHidden =
                        rundata.getParameters().getBoolean("is_hidden", false);
                    boolean isCachedOnName =
                        rundata.getParameters().getBoolean(
                            "cached_on_name",
                            false);
                    boolean isCachedOnValue =
                        rundata.getParameters().getBoolean(
                            "cached_on_value",
                            false);

                    BaseCachedParameter parameter = new BaseCachedParameter();
                    parameter.setName(parameterName);
                    parameter.setValue(parameterValue);
                    parameter.setHidden(isHidden);
                    parameter.setCachedOnName(isCachedOnName);
                    parameter.setCachedOnValue(isCachedOnValue);
                    parameter.setDescription(description);
                    parameter.setTitle(title);

                    if (securityRole != null && securityRole.length() > 0)
                    {
                        BaseSecurity paramSecurity = new BaseSecurity();
                        paramSecurity.setRole(securityRole);
                        parameter.setSecurity(paramSecurity);
                    }

                    if (securityRef != null && securityRef.length() > 0)
                    {
                        BaseSecurityReference paramSecurityRef =
                            new BaseSecurityReference();
                        paramSecurityRef.setParent(securityRef);
                        parameter.setSecurityRef(paramSecurityRef);
                    }

                    portletEntry.addParameter(parameter);

                    Registry.addEntry(Registry.PORTLET, portletEntry);

                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);

                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }
            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Update parameters of a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doUpdateparameters(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String[] parameters =
                    rundata.getParameters().getStrings("update_parameter_name");
                if (parameters != null && parameters.length > 0)
                {
                    for (int i = 0; i < parameters.length; i++)
                    {
                        String parameterName = parameters[i];
                        String parameterValue =
                            rundata.getParameters().getString(
                                parameterName + ".parameter_value");
                        String description =
                            rundata.getParameters().getString(
                                parameterName + ".description");
                        String title =
                            rundata.getParameters().getString(
                                parameterName + ".title");
                        String securityRole =
                            rundata.getParameters().getString(
                                parameterName + ".security_role");
                        String securityRef =
                            rundata.getParameters().getString(
                                parameterName + ".security_ref");
                        boolean isHidden =
                            rundata.getParameters().getBoolean(
                                parameterName + ".is_hidden",
                                false);
                        boolean isCachedOnName =
                            rundata.getParameters().getBoolean(
                                parameterName + ".cached_on_name",
                                false);
                        boolean isCachedOnValue =
                            rundata.getParameters().getBoolean(
                                parameterName + ".cached_on_value",
                                false);

                        BaseCachedParameter parameter =
                            new BaseCachedParameter();
                        parameter.setName(parameterName);
                        parameter.setValue(parameterValue);
                        parameter.setHidden(isHidden);
                        parameter.setCachedOnName(isCachedOnName);
                        parameter.setCachedOnValue(isCachedOnValue);
                        parameter.setDescription(description);
                        parameter.setTitle(title);

                        if (securityRole != null && securityRole.length() > 0)
                        {
                            BaseSecurity paramSecurity = new BaseSecurity();
                            paramSecurity.setRole(securityRole);
                            parameter.setSecurity(paramSecurity);
                        }

                        if (securityRef != null && securityRef.length() > 0)
                        {
                            BaseSecurityReference paramSecurityRef =
                                new BaseSecurityReference();
                            paramSecurityRef.setParent(securityRef);
                            parameter.setSecurityRef(paramSecurityRef);
                        }

                        portletEntry.addParameter(parameter);
                    }

                    Registry.addEntry(Registry.PORTLET, portletEntry);
                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);

                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }
            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Update parameter's values of a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doUpdateparametervalues(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String[] parameters =
                    rundata.getParameters().getStrings("update_parameter_name");
                if (parameters != null && parameters.length > 0)
                {
                    for (int i = 0; i < parameters.length; i++)
                    {
                        String parameterName = parameters[i];
                        String parameterValue =
                            rundata.getParameters().getString(
                                parameterName + ".parameter_value");

                        BaseCachedParameter parameter =
                            (
                                BaseCachedParameter) portletEntry
                                    .getCachedParameter(
                                parameterName);
                        parameter.setValue(parameterValue);
                    }

                    Registry.addEntry(Registry.PORTLET, portletEntry);
                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);

                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }
            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);
            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Remove parameters from a portlet
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doRemoveparameters(RunData rundata, Context context)
        throws Exception
    {
        try
        {
            String portletName =
                rundata.getParameters().getString(PORTLET_NAME);
            PortletEntry portletEntry =
                (PortletEntry) Registry.getEntry(Registry.PORTLET, portletName);
            if (portletEntry != null)
            {
                String[] parameters =
                    rundata.getParameters().getStrings("parameter_name");
                if (parameters != null && parameters.length > 0)
                {
                    for (int i = 0; i < parameters.length; i++)
                    {
                        String parameterName = parameters[i];
                        portletEntry.removeParameter(parameterName);
                    }

                    Registry.addEntry(Registry.PORTLET, portletEntry);
                    clearUserData(rundata);
                }
                else
                {
                    String tab =
                        rundata.getParameters().getString(TAB_PARAMETER);
                    JetspeedLink link =
                        JetspeedLinkFactory.getInstance(rundata);
                    DynamicURI duri =
                        link
                            .getPaneByName(PORTLET_UPDATE_PANE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MODE,
                                SecurityConstants.PARAM_MODE_UPDATE)
                            .addPathInfo(
                                SecurityConstants.PARAM_MSGID,
                                SecurityConstants.MID_MISSING_PARAMETER)
                            .addQueryData(TAB_PARAMETER, tab)
                            .addQueryData(PORTLET_NAME, portletName);

                    JetspeedLinkFactory.putInstance(link);
                    rundata.setRedirectURI(duri.toString());

                    resetForm(rundata);
                }
            }
            else
            {
                String tab = rundata.getParameters().getString(TAB_PARAMETER);
                JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
                DynamicURI duri =
                    link
                        .getPaneByName(PORTLET_UPDATE_PANE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MODE,
                            SecurityConstants.PARAM_MODE_UPDATE)
                        .addPathInfo(
                            SecurityConstants.PARAM_MSGID,
                            SecurityConstants.MID_INVALID_ENTITY_NAME)
                        .addQueryData(TAB_PARAMETER, tab);

                JetspeedLinkFactory.putInstance(link);
                rundata.setRedirectURI(duri.toString());

                resetForm(rundata);
            }
        }
        catch (Exception e)
        {
            String tab = rundata.getParameters().getString(TAB_PARAMETER);
            JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
            DynamicURI duri =
                link
                    .getPaneByName(PORTLET_UPDATE_PANE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MODE,
                        SecurityConstants.PARAM_MODE_UPDATE)
                    .addPathInfo(
                        SecurityConstants.PARAM_MSGID,
                        SecurityConstants.MID_UPDATE_FAILED)
                    .addQueryData(TAB_PARAMETER, tab);

            JetspeedLinkFactory.putInstance(link);
            rundata.setRedirectURI(duri.toString());

            resetForm(rundata);
        }
    }

    /**
     * Cleans up
     * @param rundata The turbine rundata context for this request.
     * @param context The velocity context for this request.
     * @throws Exception
     */
    public void doCancel(RunData rundata, Context context) throws Exception
    {
        clearUserData(rundata);
    }

    /**
     * Populates the user's temp storage with form data
     * @param rundata The turbine rundata context for this request.
     */
    private void resetForm(RunData rundata)
    {
        String parent = rundata.getParameters().getString("parent");
        String title = rundata.getParameters().getString("title");
        String description = rundata.getParameters().getString("description");
        String url = rundata.getParameters().getString("url");
        String type = rundata.getParameters().getString("portlet_type");

        //meta info
        String image = rundata.getParameters().getString("image");

        String className = rundata.getParameters().getString("class_name");

        String isApplication =
            rundata.getParameters().getString("is_application");
        String isCachedOnURL =
            rundata.getParameters().getString("is_cached_on_url");
        String isHidden = rundata.getParameters().getString("is_hidden");
        String isAdmin = rundata.getParameters().getString("is_admin");

        String newSecurityParent =
            rundata.getParameters().getString("security_ref");

        String newSecurity = rundata.getParameters().getString("security_role");

        String portletName = rundata.getParameters().getString(PORTLET_NAME);
        rundata.getUser().setTemp(PORTLET_NAME, portletName);
        rundata.getUser().setTemp("parent", parent);
        rundata.getUser().setTemp("portlet_type", type);
        rundata.getUser().setTemp("class_name", className);
        rundata.getUser().setTemp("title", title);
        rundata.getUser().setTemp("description", description);
        rundata.getUser().setTemp("url", url);
        rundata.getUser().setTemp("image", image);
        rundata.getUser().setTemp("is_application", isApplication);
        rundata.getUser().setTemp("is_cached_on_url", isCachedOnURL);
        rundata.getUser().setTemp("is_hidden", isHidden);
        rundata.getUser().setTemp("is_admin", isAdmin);
        rundata.getUser().setTemp("security_ref", newSecurityParent);
        rundata.getUser().setTemp("security_role", newSecurity);
    }

    /**
     * Clears the temporary storage of any data that was used
     * @param rundata The turbine rundata context for this request.
     */
    private void clearUserData(RunData rundata)
    {
        try
        {
            rundata.getUser().removeTemp(PORTLET_NAME);
            rundata.getUser().removeTemp("parameter_name");
            rundata.getUser().removeTemp("paramter_value");
            rundata.getUser().removeTemp("parent");
            rundata.getUser().removeTemp("portlet_type");
            rundata.getUser().removeTemp("class_name");
            rundata.getUser().removeTemp("title");
            rundata.getUser().removeTemp("description");
            rundata.getUser().removeTemp("url");
            rundata.getUser().removeTemp("image");
            rundata.getUser().removeTemp("is_application");
            rundata.getUser().removeTemp("is_cached_on_url");
            rundata.getUser().removeTemp("is_hidden");
            rundata.getUser().removeTemp("is_admin");
            rundata.getUser().removeTemp("security_ref");
            rundata.getUser().removeTemp("security_role");
        }
        catch (Exception e)
        {
            if (Log.getLogger().isDebugEnabled())
            {
                Log.debug("PortletUpdateAction: Failed to clear user data");
            }
        }
    }
}
