| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.cocoon.portal.pluto; |
| |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| |
| import javax.portlet.PortletMode; |
| import javax.portlet.WindowState; |
| |
| import org.apache.pluto.util.StringUtils; |
| import org.apache.cocoon.portal.coplet.CopletInstanceData; |
| |
| /** |
| * Create the URL for a portlet |
| * |
| * @author <a href="mailto:rgoers@apache.org">Ralph Goers</a> |
| * @version SVN $Id: $ |
| */ |
| |
| public class PortletURLConverter { |
| |
| public static final String ACTION = "ac"; |
| public static final String MODE = "md"; |
| public static final String PORTLET_ID = "pid"; |
| public static final String PREFIX = "_"; |
| public static final String PARAM = "pm"; |
| public static final String STATE = "st"; |
| |
| private final Map urlData = new HashMap(); |
| private final Map parameters = new HashMap(); |
| private String portletId; |
| |
| /** |
| * Constructor used when the URL will be marshalled. |
| * @param cid The coplet id. |
| */ |
| public PortletURLConverter(CopletInstanceData cid) { |
| this.portletId = cid.getId(); |
| } |
| |
| /** |
| * Constructor used when the URL will be unmarshalled. |
| * @param eventData The url data. |
| */ |
| public PortletURLConverter(String eventData) { |
| StringTokenizer tokenizer = new StringTokenizer(eventData, "/"); |
| while (tokenizer.hasMoreTokens()) { |
| String token = tokenizer.nextToken(); |
| if (isParameter(token)) { |
| String name = decodeParameterName(token); |
| String key = encodeParameterName(name); |
| this.parameters.put(key, token.substring(key.length())); |
| } else { |
| StringTokenizer tokens = new StringTokenizer(token, PREFIX); |
| |
| if (tokens.countTokens() > 1) { |
| String key = tokens.nextToken(); |
| if (key.equals(PORTLET_ID)) { |
| this.portletId = tokens.nextToken(); |
| } else { |
| String value = tokens.nextToken(); |
| urlData.put(key, value); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Return the PortletMode |
| * @return The PortletMode |
| */ |
| public PortletMode getMode() { |
| String mode = (String)urlData.get(getModeKey()); |
| if (mode!=null) { |
| return new PortletMode(mode); |
| } |
| return PortletMode.VIEW; |
| } |
| |
| /** |
| * Return the WindowState |
| * @return The WindowState |
| */ |
| public WindowState getState() { |
| String state = (String) urlData.get(getStateKey()); |
| if (state != null) { |
| return new WindowState(state); |
| } |
| return WindowState.NORMAL; |
| } |
| |
| /** |
| * Return the indicator if this is an action. |
| * @return true if this is an action URL, false if a render URL. |
| */ |
| public boolean isAction() { |
| return (urlData.get(getActionKey()) != null); |
| } |
| |
| /** |
| * Indicates that the URL is an action. |
| */ |
| public void setAction() { |
| urlData.put(getActionKey(),ACTION.toUpperCase()); |
| } |
| |
| /** |
| * Sets the PortletMode. |
| * @param mode The PortletMode |
| */ |
| public void setMode(PortletMode mode) { |
| urlData.put(getModeKey(), mode.toString()); |
| } |
| |
| /** |
| * Sets the WindowState |
| * @param state The WindowState |
| */ |
| public void setState(WindowState state) { |
| urlData.put(getStateKey(), state.toString()); |
| } |
| |
| /** |
| * Returns the portlet id. |
| * @return The portlet id. |
| */ |
| public String getPortletId() { |
| return this.portletId; |
| } |
| |
| /** |
| * Returns the request parameters for this portlet URL. |
| * @return A Map containing the parameters for this URL. |
| */ |
| public Map getParameters() { |
| Map map = new HashMap(); |
| Iterator iter = this.parameters.entrySet().iterator(); |
| while (iter.hasNext()) { |
| Map.Entry entry = (Map.Entry)iter.next(); |
| String key = decodeParameterName((String) entry.getKey()); |
| String[] values = decodeParameterValues((String)entry.getValue()); |
| map.put(key, values); |
| } |
| return map; |
| } |
| |
| /** |
| * Adds the parameter, replacing a parameter with the same name. |
| * @param name The parameter name |
| * @param values An array of Strings. |
| */ |
| public void setParam(String name, String[] values) { |
| this.parameters.put(encodeParameterName(name), encodeParameterValues(values)); |
| } |
| |
| /** |
| * Returns the marshalled URL. |
| * @return A String containing the marshalled URL. |
| */ |
| public String toString() { |
| StringBuffer buffer = new StringBuffer(""); |
| buffer.append(PORTLET_ID).append(PREFIX).append(portletId); |
| Iterator iter = urlData.entrySet().iterator(); |
| while (iter.hasNext()) { |
| buffer.append("/"); |
| Map.Entry entry = (Map.Entry)iter.next(); |
| buffer.append(entry.getKey()).append(PREFIX).append(entry.getValue()); |
| } |
| iter = this.parameters.entrySet().iterator(); |
| while (iter.hasNext()) { |
| buffer.append("/"); |
| Map.Entry entry = (Map.Entry) iter.next(); |
| buffer.append(entry.getKey()).append(PREFIX).append(entry.getValue()); |
| } |
| return buffer.toString(); |
| } |
| |
| private String getActionKey() { |
| return ACTION; |
| } |
| |
| private String getModeKey() { |
| return MODE; |
| } |
| |
| private String getStateKey() { |
| return STATE; |
| } |
| |
| private String getParamKey() { |
| return PARAM + PREFIX; |
| } |
| |
| private boolean isParameter(String key) { |
| return key.startsWith(getParamKey()); |
| } |
| |
| private String decodeParameterName(String encodedParamName) { |
| StringTokenizer tokenizer = new StringTokenizer(encodedParamName, PREFIX); |
| if (!tokenizer.hasMoreTokens()) { |
| return null; |
| } |
| // Skip the key |
| tokenizer.nextToken(); |
| if (!tokenizer.hasMoreTokens()) { |
| return null; |
| } |
| String name = tokenizer.nextToken(); |
| return decodeValue(name); |
| } |
| |
| private String[] decodeParameterValues(String encodedParamValues) { |
| StringTokenizer tokenizer = new StringTokenizer(encodedParamValues, PREFIX); |
| if (!tokenizer.hasMoreTokens()) { |
| return null; |
| } |
| String _count = tokenizer.nextToken(); |
| int count = Integer.valueOf(_count).intValue(); |
| String[] values = new String[count]; |
| for (int i = 0; i < count; i++) { |
| if (!tokenizer.hasMoreTokens()) { |
| return null; |
| } |
| values[i] = decodeValue(tokenizer.nextToken()); |
| } |
| return values; |
| } |
| |
| private String decodeValue(String value) { |
| value = StringUtils.replace(value, "0x1", "_"); |
| value = StringUtils.replace(value, "0x2", "."); |
| value = StringUtils.replace(value, "0x3", "/"); |
| value = StringUtils.replace(value, "0x4", "\r"); |
| value = StringUtils.replace(value, "0x5", "\n"); |
| value = StringUtils.replace(value, "0x6", "<"); |
| value = StringUtils.replace(value, "0x7", ">"); |
| value = StringUtils.replace(value, "0x8", " "); |
| value = StringUtils.replace(value, "0x0", "0x"); |
| return value; |
| } |
| |
| private String encodeParameterName(String paramName) { |
| StringBuffer returnvalue = new StringBuffer(50); |
| returnvalue.append(getParamKey()).append(encodeValue(paramName)); |
| return returnvalue.toString(); |
| } |
| |
| private String encodeParameterValues(String[] paramValues) { |
| StringBuffer returnvalue = new StringBuffer(100); |
| if (paramValues == null) { |
| returnvalue.append("0"); |
| } else { |
| returnvalue.append(paramValues.length); |
| for (int i = 0; i < paramValues.length; i++) { |
| returnvalue.append("_"); |
| returnvalue.append(encodeValue(paramValues[i])); |
| } |
| } |
| return returnvalue.toString(); |
| } |
| |
| private String encodeValue(String value) { |
| value = StringUtils.replace(value, "0x", "0x0"); |
| value = StringUtils.replace(value, "_", "0x1"); |
| value = StringUtils.replace(value, ".", "0x2"); |
| value = StringUtils.replace(value, "/", "0x3"); |
| value = StringUtils.replace(value, "\r", "0x4"); |
| value = StringUtils.replace(value, "\n", "0x5"); |
| value = StringUtils.replace(value, "<", "0x6"); |
| value = StringUtils.replace(value, ">", "0x7"); |
| value = StringUtils.replace(value, " ", "0x8"); |
| return value; |
| } |
| } |