/*
 * @author <a href="mailto:novotny@aei.mpg.de">Jason Novotny</a>
 * @version $Id$
 */
package org.gridlab.gridsphere.portlet.impl;

import org.gridlab.gridsphere.portlet.*;
import org.gridlab.gridsphere.portletcontainer.GridSphereProperties;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.*;


/**
 * A PortletURI represents a URI to a specific portlet function.
 * A URI is created through the PortletResponse  for a specific portlet mode.
 * Then additional parameter can be added to the URI.
 * The complete URI can be converted to a string which is ready for embedding into markup.
 * On top of the parameters, it is possible to add actions to a portlet URI.
 * Actions are portlet-specific activities that need to be performed as result of the incoming request,
 * but before the service() method of the portlet is called.
 * For example, the PERSONALIZE mode of the portlet is likely to have a "Save" button at the
 * end of its dialog. The "Save" button has to bring the user back to the DEFAULT mode of the portlet,
 * but to save the personalized portlet data, the portlet needs to be able to process the posted
 * data before the next markup is generated. This can be achieved by adding a "Save" action to the
 * URI that represents the "Save" button. The respective listener is attached the respective action listener
 * to the portlet response. This listener will be called when the next request comes and one of the
 * portlet URIs where the reason for the request. If more than one URI were part of the response, the listener
 * need to the check the action content. This depends on the definition of the actual action which is
 * the responsibility of the portlet developer.
 */
public class SportletURI implements PortletURI {

    private HttpServletResponse res = null;
    private PortletRequest req = null;
    private PortletSettings portletSettings = null;
    private String url;


    private Map store = new HashMap();
    private boolean redirect = true;
    private PortletWindow.State state;

    public SportletURI() {}

    public SportletURI(HttpServletResponse res, PortletRequest req) {
        store = new HashMap();
        this.res = res;
        this.req = req;
        url = req.getServerName();
    }

    public void setReturn(boolean redirect) {
        this.redirect = redirect;
    }

    /**
     * Adds the given parameter to this URI. A portlet container may wish to prefix the attribute names
     * internally, to preserve a unique namespace for the portlet.
     *
     * @param name the parameter name
     * @param value the parameter value
     */
    public void addParameter(String name, String value) {
        store.put(name, value);
    }

    /**
     * Adds the given action to this URI. The action is a portlet-defined implementation of the portlet action
     * interface. It can carry any information. How the information is recovered should the next request be for
     * this URI is at the discretion of the portlet container.
     *
     * Unless the ActionListener interface is implemented at the portlet this action will not be delivered.
     *
     * @param action the portlet action
     */
    public void addAction(PortletAction action) {
        if (action instanceof DefaultPortletAction) {
            DefaultPortletAction dpa = (DefaultPortletAction)action;
            store.put(GridSphereProperties.PORTLETNAME, dpa.getName());
            store.put(GridSphereProperties.PORTLETID, dpa.getPortletID());
            Map actionParams = dpa.getParameters();
            Set set = actionParams.keySet();
            Iterator it = set.iterator();
            while (it.hasNext()) {
                String name = (String)it.next();
                String value = (String)store.get(name);
                url += name + "&" + value;
            }
        }
    }

    public void setWindowState(PortletWindow.State state) {
        this.state = state;
    }

    /**
     * Returns the complete URI as a string. The string is ready to be embedded in markup.
     * Once the string has been created, adding more parameters or other listeners will not modify the string.
     * You have to call this method again, to create an updated string.
     *
     * @return the URI as a string
     */
    public String toString() {
        String newURL;
        Set set = store.keySet();
        if (!set.isEmpty()) {
            // add question mark
            url += "?";
        }
        Iterator it = set.iterator();
        while (it.hasNext()) {
            String name = (String)it.next();
            String value = (String)store.get(name);
            url += name + "&" + value;
        }
        if (redirect) {
            newURL = res.encodeRedirectURL(url);
        } else {
            newURL = res.encodeURL(url);
        }
        System.err.println("SportletURI: toString: " + newURL);
        return newURL;
    }

    public String encode(String clear) {
        return null;
    }

    public String decode(String encoded) {
        return null;
    }
}
@@ -1852,47 +1852,8 @@
 ll;%0A
-    private PortletRequest req = null;%0A
     
@@ -1904,32 +1904,8 @@
 ll;%0A
-    private String url;%0A
 %0A%0A  
@@ -2097,28 +2097,8 @@
  res
-, PortletRequest req
 ) %7B%0A
@@ -2156,67 +2156,8 @@
 es;%0A
-        this.req = req;%0A        url = req.getServerName();%0A
     
@@ -3299,19 +3299,14 @@
 ies.
-PORTLETNAME
+ACTION
 , dp
@@ -3323,83 +3323,8 @@
 ));%0A
-            store.put(GridSphereProperties.PORTLETID, dpa.getPortletID());%0A
     
@@ -3573,37 +3573,44 @@
 value = (String)
-store
+actionParams
 .get(name);%0A    
@@ -3625,33 +3625,30 @@
     
-url += name + %22&%22 +
+store.put(name,
  value
+)
 ;%0A  
@@ -4130,24 +4130,49 @@
 oString() %7B%0A
+        String url = %22%22;%0A
         Stri
@@ -4295,17 +4295,16 @@
     url 
-+
 = %22?%22;%0A 
@@ -4303,32 +4303,108 @@
 = %22?%22;%0A        %7D
+ else %7B%0A            return url;%0A        %7D%0A        boolean firstParam = true;
 %0A        Iterato
@@ -4449,32 +4449,89 @@
 it.hasNext()) %7B%0A
+            if (!firstParam)%0A                url += %22&%22;%0A
             Stri
@@ -4638,17 +4638,17 @@
 name + %22
-&
+=
 %22 + valu
@@ -4646,24 +4646,56 @@
 =%22 + value;%0A
+            firstParam = false;%0A
         %7D%0A  

clears out uri string