001// Copyright 2005 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry.portlet; 016 017import javax.portlet.PortletURL; 018 019import org.apache.hivemind.util.Defense; 020import org.apache.tapestry.engine.ILink; 021import org.apache.tapestry.util.QueryParameterMap; 022 023/** 024 * Wrapper around {@link javax.portlet.PortletURL}. 025 * 026 * @author Howard M. Lewis Ship 027 * @since 4.0 028 */ 029public class PortletLink implements ILink 030{ 031 private final PortletURL _portletURL; 032 033 private final QueryParameterMap _parameters; 034 035 public PortletLink(PortletURL portletURL, QueryParameterMap parameters) 036 { 037 Defense.notNull(portletURL, "portletURL"); 038 Defense.notNull(parameters, "parameters"); 039 040 _portletURL = portletURL; 041 _parameters = parameters; 042 } 043 044 public String getURL() 045 { 046 return getURL(null, true); 047 } 048 049 public String getURL(String anchor, boolean includeParameters) 050 { 051 if (includeParameters) 052 loadParameters(); 053 054 String url = _portletURL.toString(); 055 056 url = unencode(url); 057 058 if (anchor != null) 059 url = url + "#" + anchor; 060 061 return url; 062 } 063 064 /** 065 * The PortletURL class returns a url that's already XML-escaped, ready for inclusion directly 066 * into the response stream. However, the IMarkupWriter expects to do that encoding too ... and 067 * double encoding is bad. So we back out the most likely encoding (convert '&amp;' to just 068 * '&'). 069 */ 070 071 private String unencode(String url) 072 { 073 StringBuffer buffer = new StringBuffer(url.length()); 074 String text = url; 075 076 while (true) 077 { 078 int ampx = text.indexOf("&"); 079 080 if (ampx < 0) 081 break; 082 083 // Take up to and including the '&' 084 085 buffer.append(text.substring(0, ampx + 1)); 086 087 text = text.substring(ampx + 5); 088 } 089 090 buffer.append(text); 091 092 return buffer.toString(); 093 } 094 095 private void loadParameters() 096 { 097 String[] names = _parameters.getParameterNames(); 098 099 for (int i = 0; i < names.length; i++) 100 { 101 String name = names[i]; 102 String[] values = _parameters.getParameterValues(name); 103 104 if (values != null) 105 _portletURL.setParameter(name, values); 106 } 107 } 108 109 public String getURL(String scheme, String server, int port, String anchor, 110 boolean includeParameters) 111 { 112 // Ignore scheme, server and port ... those are under the control of the portlet container. 113 114 return getURL(anchor, includeParameters); 115 } 116 117 public String getAbsoluteURL() 118 { 119 throw new UnsupportedOperationException(PortletMessages.unsupportedMethod("getAbsoluteURL")); 120 } 121 122 public String getAbsoluteURL(String scheme, String server, int port, String anchor, 123 boolean includeParameters) 124 { 125 throw new UnsupportedOperationException(PortletMessages.unsupportedMethod("getAbsoluteURL")); 126 } 127 128 public String[] getParameterNames() 129 { 130 return _parameters.getParameterNames(); 131 } 132 133 public String[] getParameterValues(String name) 134 { 135 return _parameters.getParameterValues(name); 136 } 137 138}