EMMA Coverage Report (generated Fri Sep 15 10:32:43 EDT 2006)
[all classes][org.apache.pluto.driver.url]

COVERAGE SUMMARY FOR SOURCE FILE [PortalURLParser.java]

nameclass, %method, %block, %line, %
PortalURLParser.java0%   (0/1)0%   (0/11)0%   (0/718)0%   (0/120)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class PortalURLParser0%   (0/1)0%   (0/11)0%   (0/718)0%   (0/120)
<static initializer> 0%   (0/1)0%   (0/115)0%   (0/3)
PortalURLParser (): void 0%   (0/1)0%   (0/3)0%   (0/2)
decodeCharacters (String): String 0%   (0/1)0%   (0/23)0%   (0/3)
decodeControlParameter (String): String [] 0%   (0/1)0%   (0/65)0%   (0/14)
decodeParameter (String, String): PortalURLParameter 0%   (0/1)0%   (0/58)0%   (0/10)
encodeCharacters (String): String 0%   (0/1)0%   (0/23)0%   (0/3)
encodeControlParameter (String, String, String): String 0%   (0/1)0%   (0/21)0%   (0/3)
encodeMultiValues (String []): String 0%   (0/1)0%   (0/39)0%   (0/6)
getParser (): PortalURLParser 0%   (0/1)0%   (0/2)0%   (0/1)
parse (HttpServletRequest): PortalURL 0%   (0/1)0%   (0/187)0%   (0/43)
toString (PortalURL): String 0%   (0/1)0%   (0/182)0%   (0/32)

1/*
2 * Copyright 2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.apache.pluto.driver.url;
17 
18import java.util.Iterator;
19import java.util.Map;
20import java.util.StringTokenizer;
21 
22import javax.portlet.PortletMode;
23import javax.portlet.WindowState;
24import javax.servlet.http.HttpServletRequest;
25 
26import org.apache.pluto.util.StringUtils;
27import org.apache.commons.logging.Log;
28import org.apache.commons.logging.LogFactory;
29 
30/**
31 * @author <a href="mailto:zheng@apache.org">ZHENG Zhong</a>
32 * @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
33 * @version 1.0
34 * @since Sep 30, 2004
35 */
36class PortalURLParser {
37        
38        /** Logger. */
39    private static final Log LOG = LogFactory.getLog(PortalURLParser.class);
40    
41    /** The singleton parser instance. */
42    private static final PortalURLParser PARSER = new PortalURLParser();
43    
44    
45    // Constants used for Encoding/Decoding ------------------------------------
46    
47    private static final String PREFIX = "__";
48    private static final String DELIM = "_";
49    private static final String PORTLET_ID = "pd";
50    private static final String ACTION = "ac";
51    private static final String RENDER_PARAM = "rp";
52    private static final String WINDOW_STATE = "ws";
53    private static final String PORTLET_MODE = "pm";
54    private static final String VALUE_DELIM = "0x0";
55 
56    private static final String[][] ENCODINGS = new String[][] {
57                    new String[] { "_",  "0x1" },
58            new String[] { ".",  "0x2" },
59            new String[] { "/",  "0x3" },
60            new String[] { "\r", "0x4" },
61            new String[] { "\n", "0x5" },
62            new String[] { "<",  "0x6" },
63            new String[] { ">",  "0x7" },
64            new String[] { " ",  "0x8" },
65    };
66    
67    // Constructor -------------------------------------------------------------
68    
69    /**
70     * Private constructor that prevents external instantiation.
71     */
72    private PortalURLParser() {
73            // Do nothing.
74    }
75    
76    /**
77     * Returns the singleton parser instance.
78     * @return the singleton parser instance.
79     */
80    public static PortalURLParser getParser() {
81            return PARSER;
82    }
83    
84    
85    // Public Methods ----------------------------------------------------------
86    
87    /**
88     * Parse a servlet request to a portal URL.
89     * @param request  the servlet request to parse.
90     * @return the portal URL.
91     */
92    public PortalURL parse(HttpServletRequest request) {
93        
94            if (LOG.isDebugEnabled()) {
95            LOG.debug("Parsing URL: " + request.getRequestURI());
96        }
97        
98        String protocol = request.isSecure() ? "https://" : "http://";
99        String server = request.getServerName();
100        int port = request.getServerPort();
101        String contextPath = request.getContextPath();
102        String servletName = request.getServletPath();
103        
104        // Construct portal URL using info retrieved from servlet request.
105        PortalURL portalURL = null;
106        if ((request.isSecure() && port != 443)
107                        || (!request.isSecure() && port != 80)) {
108                portalURL = new PortalURL(protocol, server, port, contextPath, servletName);
109        } else {
110                portalURL = new PortalURL(protocol, server, contextPath, servletName);
111        }
112        
113        String pathInfo = request.getPathInfo();
114        if (pathInfo == null) {
115            return portalURL;
116        }
117        
118        if (LOG.isDebugEnabled()) {
119            LOG.debug("Parsing request pathInfo: " + pathInfo);
120        }
121        StringBuffer renderPath = new StringBuffer();
122        StringTokenizer st = new StringTokenizer(pathInfo, "/", false);
123        while (st.hasMoreTokens()) {
124                
125                String token = st.nextToken();
126                
127                // Part of the render path: append to renderPath.
128                if (!token.startsWith(PREFIX)) {
129                        renderPath.append(token);
130                }
131                // Action window definition: portalURL.setActionWindow().
132                else if (token.startsWith(PREFIX + ACTION)) {
133                        portalURL.setActionWindow(decodeControlParameter(token)[0]);
134                }
135                // Window state definition: portalURL.setWindowState().
136                else if (token.startsWith(PREFIX + WINDOW_STATE)) {
137                        String[] decoded = decodeControlParameter(token);
138                        portalURL.setWindowState(decoded[0], new WindowState(decoded[1]));
139                }
140                // Portlet mode definition: portalURL.setPortletMode().
141                else if (token.startsWith(PREFIX + PORTLET_MODE)) {
142                        String[] decoded = decodeControlParameter(token);
143                        portalURL.setPortletMode(decoded[0], new PortletMode(decoded[1]));
144                }
145                // Portal URL parameter: portalURL.addParameter().
146                else {
147                        String value = null;
148                        if (st.hasMoreTokens()) {
149                                value = st.nextToken();
150                        }
151                        portalURL.addParameter(decodeParameter(token, value));
152                }
153        }
154        if (renderPath.length() > 0) {
155            portalURL.setRenderPath(renderPath.toString());
156        }
157        
158        // Return the portal URL.
159        return portalURL;
160    }
161    
162    
163    /**
164     * Converts a portal URL to a URL string.
165     * @param portalURL  the portal URL to convert.
166     * @return a URL string representing the portal URL.
167     */
168    public String toString(PortalURL portalURL) {
169            
170            StringBuffer buffer = new StringBuffer();
171            
172        // Append the server URI and the servlet path.
173            buffer.append(portalURL.getServerURI())
174                            .append(portalURL.getServletPath());
175            
176        // Start the pathInfo with the path to the render URL (page).
177        if (portalURL.getRenderPath() != null) {
178                buffer.append("/").append(portalURL.getRenderPath());
179        }
180 
181        // Append the action window definition, if it exists.
182        if (portalURL.getActionWindow() != null) {
183                buffer.append("/");
184                buffer.append(PREFIX).append(ACTION)
185                                .append(encodeCharacters(portalURL.getActionWindow()));
186        }
187        
188        // Append portlet mode definitions.
189        for (Iterator it = portalURL.getPortletModes().entrySet().iterator();
190                        it.hasNext(); ) {
191            Map.Entry entry = (Map.Entry) it.next();
192            buffer.append("/").append(
193                            encodeControlParameter(PORTLET_MODE, entry.getKey().toString(),
194                       entry.getValue().toString()));
195        }
196        
197        // Append window state definitions.
198        for (Iterator it = portalURL.getWindowStates().entrySet().iterator();
199                        it.hasNext(); ) {
200            Map.Entry entry = (Map.Entry) it.next();
201            buffer.append("/").append(
202                            encodeControlParameter(WINDOW_STATE, entry.getKey().toString(),
203                       entry.getValue().toString()));
204        }
205        
206        // Append action and render parameters.
207        StringBuffer query = new StringBuffer("?");
208        for (Iterator it = portalURL.getParameters().iterator();
209                        it.hasNext(); ) {
210            
211                PortalURLParameter param = (PortalURLParameter) it.next();
212            
213            // Encode action params in the query appended at the end of the URL.
214            if (portalURL.getActionWindow() != null
215                            && portalURL.getActionWindow().equals(param.getWindowId())) {
216                for (int i = 0; i < param.getValues().length; i++) {
217                    query.append("&").append(param.getName()).append("=")
218                                    .append(param.getValues()[i]);
219                }
220            }
221            
222            // Encode render params as a part of the URL.
223            else if (param.getValues() != null
224                            && param.getValues().length > 0) {
225                String valueString = encodeMultiValues(param.getValues());
226                if (valueString.length() > 0) {
227                        buffer.append("/").append(
228                                        encodeControlParameter(RENDER_PARAM, param.getWindowId(),
229                               param.getName()));
230                        buffer.append("/").append(valueString);
231                }
232            }
233        }
234        
235        // Construct the string representing the portal URL.
236        return buffer.append(query).toString();
237    }
238    
239    
240    // Private Encoding/Decoding Methods ---------------------------------------
241    
242    /**
243     * Encode a control parameter.
244     * @param type  the type of the control parameter, which may be:
245     *              portlet mode, window state, or render parameter.
246     * @param windowId  the portlet window ID.
247     * @param name  the name to encode.
248     */
249    private String encodeControlParameter(String type,
250                                          String windowId,
251                                          String name) {
252            StringBuffer buffer = new StringBuffer();
253            buffer.append(PREFIX).append(type)
254                            .append(encodeCharacters(windowId))
255                            .append(DELIM).append(name);
256            return buffer.toString();
257    }
258    
259    /**
260     * Encode a string array containing multiple values into a single string.
261     * This method is used to encode multiple render parameter values.
262     * @param values  the string array to encode.
263     * @return a single string containing all the values.
264     */
265    private String encodeMultiValues(String[] values) {
266            StringBuffer buffer = new StringBuffer();
267        for (int i = 0; i < values.length; i++) {
268                buffer.append(values[i] != null ? values[i] : "");
269            if (i + 1 < values.length) {
270                    buffer.append(VALUE_DELIM);
271            }
272        }
273        return encodeCharacters(buffer.toString());
274    }
275    
276    /**
277     * Encode special characters contained in the string value.
278     * @param string  the string value to encode.
279     * @return the encoded string.
280     */
281    private String encodeCharacters(String string) {
282        for (int i = 0; i < ENCODINGS.length; i++) {
283            string = StringUtils.replace(string,
284                                         ENCODINGS[i][0],
285                                         ENCODINGS[i][1]);
286        }
287        return string;
288    }
289 
290 
291    /**
292     * Decode a control parameter.
293     * @param control  the control parameter to decode.
294     * @return values  a pair of decoded values.
295     */
296    private String[] decodeControlParameter(String control) {
297        String[] valuePair = new String[2];
298        control = control.substring((PREFIX + PORTLET_ID).length());
299        int index = control.indexOf(DELIM);
300        if (index >= 0) {
301                valuePair[0] = control.substring(0, index);
302                valuePair[0] = decodeCharacters(valuePair[0]);
303                if (index + 1 <= control.length()) {
304                        valuePair[1] = control.substring(index + 1);
305                        valuePair[1] = decodeCharacters(valuePair[1]);
306                } else {
307                        valuePair[1] = "";
308                }
309        } else {
310                valuePair[0] = decodeCharacters(control);
311        }
312        return valuePair;
313    }
314 
315    /**
316     * Decode a name-value pair into a portal URL parameter.
317     * @param name  the parameter name.
318     * @param value  the parameter value.
319     * @return the decoded portal URL parameter.
320     */
321    private PortalURLParameter decodeParameter(String name, String value) {
322            
323        if (LOG.isDebugEnabled()) {
324            LOG.debug("Decoding parameter: name=" + name
325                            + ", value=" + value);
326        }
327            
328            // Decode the name into window ID and parameter name.
329        String noPrefix = name.substring((PREFIX + PORTLET_ID).length());
330        String windowId = noPrefix.substring(0, noPrefix.indexOf(DELIM));
331        String paramName = noPrefix.substring(noPrefix.indexOf(DELIM) + 1);
332        
333        // Decode special characters in window ID and parameter value.
334        windowId = decodeCharacters(windowId);
335        if (value != null) {
336                value = decodeCharacters(value);
337        }
338        
339        // Split multiple values into a value array.
340        String[] paramValues = value.split(VALUE_DELIM);
341        
342        // Construct portal URL parameter and return.
343        return new PortalURLParameter(windowId, paramName, paramValues);
344    }
345    
346    /**
347     * Decode special characters contained in the string value.
348     * @param string  the string value to decode.
349     * @return the decoded string.
350     */
351    private String decodeCharacters(String string) {
352        for (int i = 0; i < ENCODINGS.length; i++) {
353                string = StringUtils.replace(string,
354                                             ENCODINGS[i][1],
355                                             ENCODINGS[i][0]);
356        }
357        return string;
358    }
359 
360}
361 

[all classes][org.apache.pluto.driver.url]
EMMA 2.0.5312 (C) Vladimir Roubtsov