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 015 package org.apache.tapestry.portlet; 016 017 import javax.portlet.PortletURL; 018 019 import org.apache.hivemind.util.Defense; 020 import org.apache.tapestry.engine.ILink; 021 import 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 */ 029 public 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 }