1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.pluto.driver.url.impl;
18
19 import java.io.UnsupportedEncodingException;
20 import java.net.URLDecoder;
21 import java.net.URLEncoder;
22 import java.util.Enumeration;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.StringTokenizer;
26
27 import javax.portlet.PortletMode;
28 import javax.portlet.WindowState;
29 import javax.servlet.http.HttpServletRequest;
30
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.apache.pluto.driver.url.PortalURL;
34 import org.apache.pluto.driver.url.PortalURLParameter;
35 import org.apache.pluto.driver.url.PortalURLParser;
36
37
38
39
40
41 public class PortalURLParserImpl implements PortalURLParser {
42
43
44 private static final Logger LOG = LoggerFactory.getLogger(PortalURLParserImpl.class);
45
46
47 private static final PortalURLParser PARSER = new PortalURLParserImpl();
48
49
50
51
52 private static final String PREFIX = "__";
53 private static final String DELIM = "_";
54 private static final String PORTLET_ID = "pd";
55 private static final String ACTION = "ac";
56 private static final String RESOURCE = "rs";
57 private static final String RESOURCE_ID = "ri";
58 private static final String CACHE_LEVEL = "cl";
59 private static final String RENDER_PARAM = "rp";
60 private static final String PRIVATE_RENDER_PARAM = "pr";
61 private static final String PUBLIC_RENDER_PARAM = "sp";
62 private static final String WINDOW_STATE = "ws";
63 private static final String PORTLET_MODE = "pm";
64 private static final String VALUE_DELIM = "0x0";
65
66
67
68 private static final String[][] ENCODINGS = new String[][] {
69 new String[] { "_", "_" },
70 new String[] { ".", "." },
71 new String[] { "/", "0x3" },
72 new String[] { "\r", "0x4" },
73 new String[] { "\n", "0x5" },
74 new String[] { "<", "0x6" },
75 new String[] { ">", "0x7" },
76 new String[] { " ", "0x8" },
77 new String[] { "#", "0x9" },
78 new String[] { "?", "0xa" },
79 new String[] { "\\", "0xb" },
80 new String[] { "%", "0xc" },
81 };
82
83
84
85
86
87
88 private PortalURLParserImpl() {
89
90 }
91
92
93
94
95
96 public static PortalURLParser getParser() {
97 return PARSER;
98 }
99
100
101
102
103
104
105
106
107
108 public PortalURL parse(HttpServletRequest request) {
109
110 if (LOG.isDebugEnabled()) {
111 LOG.debug("Parsing URL: " + request.getRequestURI());
112 }
113
114 String contextPath = request.getContextPath();
115 String servletName = request.getServletPath();
116
117 String urlBase = request.getScheme()+"://" + request.getServerName() + ":" + request.getServerPort();
118
119 PortalURL portalURL = new RelativePortalURLImpl(urlBase, contextPath, servletName, this);
120
121
122 String pathInfo = request.getPathInfo();
123
124
125
126
127
128
129
130
131
132
133
134 if (LOG.isDebugEnabled()) {
135 LOG.debug("Parsing request pathInfo: " + pathInfo);
136 }
137
138 StringBuffer renderPath = new StringBuffer();
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213 Enumeration<String> paramNames = request.getParameterNames();
214 while(paramNames.hasMoreElements())
215 {
216 String paramName = paramNames.nextElement();
217 if(paramName.startsWith("page_id")) {
218
219
220
221 portalURL.getPrivateRenderParameters().put(paramName, request.getParameterValues(paramName));
222 }
223 else
224 {
225
226 }
227 }
228
229
230 if (renderPath.length() > 0) {
231 portalURL.setRenderPath(renderPath.toString());
232 }
233
234
235 return portalURL;
236 }
237
238
239
240
241
242
243
244 public String toString(PortalURL portalURL) {
245
246 StringBuffer buffer = null;
247
248
249 if (portalURL.getRenderPath() != null) {
250 if(buffer == null)
251 {
252 buffer = new StringBuffer();
253
254 buffer.append(portalURL.getServletPath().startsWith("/")?"":"/")
255 .append(portalURL.getServletPath());
256 }
257 buffer.append(portalURL.getRenderPath());
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 boolean firstParam = true;
274 if (portalURL.getActionWindow() != null) {
275 buffer = new StringBuffer();
276 String strContextPath = portalURL.getServletPath();
277 strContextPath = strContextPath.substring(0, strContextPath.lastIndexOf("/"));
278 strContextPath = strContextPath.substring(0, strContextPath.lastIndexOf("/"));
279 buffer.append(strContextPath);
280 buffer.append("/");
281 buffer.append("DoAction.jsp?");
282 buffer.append(ACTION).append("=")
283 .append("true");
284 firstParam = false;
285 }
286
287 if (portalURL.getResourceWindow() != null)
288 {
289 if(buffer == null)
290 {
291 buffer = new StringBuffer();
292 String strContextPath = portalURL.getServletPath();
293 strContextPath = strContextPath.substring(0, strContextPath.lastIndexOf("/"));
294 strContextPath = strContextPath.substring(0, strContextPath.lastIndexOf("/"));
295 buffer.append(strContextPath);
296 buffer.append("/");
297 buffer.append("DoServeResource.jsp?");
298 }
299 }
300
301
302 if(buffer == null)
303 {
304 buffer = new StringBuffer();
305 String strContextPath = portalURL.getServletPath();
306 if(strContextPath.substring(strContextPath.lastIndexOf("/")).equals("/DoAction.jsp"))
307 {
308 strContextPath = strContextPath.substring(0, strContextPath.lastIndexOf("/"));
309 buffer.append(strContextPath);
310 buffer.append("/site/");
311 buffer.append("Portal.jsp?");
312 }
313 else
314 {
315 strContextPath = strContextPath.substring(0, strContextPath.lastIndexOf("/"));
316 strContextPath = strContextPath.substring(0, strContextPath.lastIndexOf("/"));
317 buffer.append(strContextPath);
318 buffer.append("/");
319 buffer.append("DoAction.jsp?");
320 }
321 }
322
323 for (Iterator it = portalURL.getPortletModes().entrySet().iterator();
324 it.hasNext(); ) {
325
326
327
328
329
330
331
332
333
334
335 Map.Entry entry = (Map.Entry) it.next();
336 if ( firstParam ) {
337 firstParam = false;
338 } else {
339 buffer.append("&");
340 }
341 buffer.append(
342 encodeControlParameter(PORTLET_MODE, entry.getKey().toString(),
343 entry.getValue().toString()));
344 }
345
346
347 for (Iterator it = portalURL.getWindowStates().entrySet().iterator();
348 it.hasNext(); ) {
349
350 Map.Entry entry = (Map.Entry) it.next();
351 if ( firstParam ) {
352 firstParam = false;
353 } else {
354 buffer.append("&");
355 }
356 buffer.append(
357 encodeControlParameter(WINDOW_STATE, entry.getKey().toString(),
358 entry.getValue().toString()));
359 }
360
361
362
363
364 StringBuffer query = new StringBuffer();
365
366
367 String strId = ((RelativePortalURLImpl)portalURL).getLutecePortletId();
368 if(strId != null)
369 {
370 if ( firstParam ) {
371 firstParam = false;
372 } else {
373 buffer.append("&");
374 }
375 buffer.append("rp_pid").append("=").append(strId);
376 }
377
378 for (Iterator it = portalURL.getParameters().iterator();
379 it.hasNext(); ) {
380
381 PortalURLParameter param = (PortalURLParameter) it.next();
382
383
384 if (portalURL.getActionWindow() != null
385 && portalURL.getActionWindow().equals(param.getWindowId())
386 || (portalURL.getResourceWindow() != null
387 && portalURL.getResourceWindow().equals(param.getWindowId()))) {
388 for (int i = 0; i < param.getValues().length; i++) {
389
390 if ( firstParam ) {
391 firstParam = false;
392 } else {
393 query.append("&");
394 }
395 query.append(encodeQueryParam(param.getName())).append("=")
396 .append(encodeQueryParam(param.getValues()[i]));
397 }
398 }
399
400
401
402
403 else if (param.getValues() != null
404 && param.getValues().length > 0) {
405 String valueString = encodeMultiValues(param.getValues());
406 if (valueString.length() > 0) {
407
408
409
410 if ( firstParam ) {
411 firstParam = false;
412 } else {
413 buffer.append("&");
414 }
415 buffer.append(
416 encodeControlParameter( param.getName(),
417 valueString));
418 }
419 }
420 }
421
422
423 encode(buffer);
424
425 if (portalURL.getResourceWindow() != null)
426 {
427 Map<String, String[]> privateParamList = portalURL.getPrivateRenderParameters();
428 if (privateParamList!=null){
429 for (Iterator iter = privateParamList.keySet().iterator();iter.hasNext();){
430 String paramname = (String)iter.next();
431 String[] tmp = privateParamList.get(paramname);
432
433 for(int i = 0; i < tmp.length; i++)
434 {
435 if (tmp[i].length()>0){
436 if ( firstParam ) {
437 firstParam = false;
438 } else {
439 buffer.append("&");
440 }
441 buffer.append( paramname ).append("=");
442 buffer.append(tmp[i]);
443 }
444 }
445
446 }
447 }
448 }
449
450 Map<String, String[]> publicParamList = portalURL.getPublicParameters();
451 if (publicParamList!=null){
452 for (Iterator iter = publicParamList.keySet().iterator();iter.hasNext();){
453 String paramname = (String)iter.next();
454 String[] tmp = publicParamList.get(paramname);
455
456 for(int i = 0; i < tmp.length; i++)
457 {
458 if (tmp[i].length()>0){
459 if ( firstParam ) {
460 firstParam = false;
461 } else {
462 buffer.append("&");
463 }
464 buffer.append( paramname ).append("=");
465 buffer.append(tmp[i]);
466 }
467 }
468
469 }
470 }
471
472 Map<String, String[]> privateParamList = portalURL.getPrivateRenderParameters();
473 if (privateParamList!=null){
474 for (Iterator iter = privateParamList.keySet().iterator();iter.hasNext();){
475 String paramname = (String)iter.next();
476 String[] tmp = privateParamList.get(paramname);
477
478 for(int i = 0; i < tmp.length; i++)
479 {
480 if (tmp[i].length()>0){
481 if ( firstParam ) {
482 firstParam = false;
483 } else {
484 buffer.append("&");
485 }
486 buffer.append( paramname ).append("=");
487 buffer.append(tmp[i]);
488 }
489 }
490 }
491 }
492
493
494
495 if ( query.length() > 1 ) {
496 return buffer.append(query).toString();
497 }
498
499
500 return buffer.append(query).toString();
501 }
502
503 public static void encode(StringBuffer url){
504 replaceChar(url,"|","%7C");
505 replaceChar(url,"\"","%22");
506 }
507 private static void replaceChar(StringBuffer url, String character, String change){
508 boolean contains = url.toString().contains(character);
509 while (contains){
510 int index = url.indexOf(character);
511 url.deleteCharAt(index);
512 url.insert(index, change, 0, 3);
513 contains = url.toString().contains(character);
514 }
515 }
516
517 private String encodeQueryParam(String param) {
518 try {
519 return URLEncoder.encode(param, "UTF-8");
520 }
521 catch (UnsupportedEncodingException e) {
522
523 throw new RuntimeException(e);
524 }
525 }
526
527
528
529
530
531
532
533
534
535
536
537
538 private String encodeControlParameter( String name,
539 String value) {
540 StringBuffer buffer = new StringBuffer();
541 buffer.append(name).append("=")
542 .append(encodeCharacters(value));
543 return buffer.toString();
544 }
545
546
547
548
549
550
551
552
553 private String encodeControlParameter(String type,
554 String windowId,
555 String name) {
556 StringBuffer buffer = new StringBuffer();
557 buffer.append(type)
558 .append("=").append(name);
559 return buffer.toString();
560 }
561
562 private String encodePublicParamname( String name ){
563 StringBuffer buffer = new StringBuffer();
564 buffer.append(name).append("=");
565 return buffer.toString();
566 }
567
568 private String encodePublicParamname(String type, String name){
569 StringBuffer buffer = new StringBuffer();
570 buffer.append(PREFIX).append(type)
571 .append(DELIM).append(name);
572 return buffer.toString();
573 }
574
575
576
577
578
579
580
581 private String encodeMultiValues(String[] values) {
582 StringBuffer buffer = new StringBuffer();
583 for (int i = 0; i < values.length; i++) {
584
585 String currentValue = values[i];
586 try {
587 if (currentValue != null)
588 currentValue = URLEncoder.encode(values[i], "UTF-8");
589 } catch (UnsupportedEncodingException e) {
590 LOG.warn(e.getMessage(),e);
591 }
592 buffer.append(currentValue != null ? currentValue : "");
593 if (i + 1 < values.length) {
594 buffer.append(VALUE_DELIM);
595 }
596 }
597 return encodeCharacters(buffer.toString());
598 }
599
600
601
602
603
604
605 private String encodeCharacters(String string) {
606 for (int i = 0; i < ENCODINGS.length; i++) {
607 string = string.replace(ENCODINGS[i][0], ENCODINGS[i][1]);
608 }
609 return string;
610 }
611
612
613
614
615
616
617
618 private String[] decodeControlParameter(String control) {
619 String[] valuePair = new String[2];
620 control = control.substring((PREFIX + PORTLET_ID).length());
621 int index = control.indexOf(DELIM);
622 if (index >= 0) {
623 valuePair[0] = control.substring(0, index);
624 valuePair[0] = decodeCharacters(valuePair[0]);
625 if (index + 1 <= control.length()) {
626 valuePair[1] = control.substring(index + 1);
627 valuePair[1] = decodeCharacters(valuePair[1]);
628 } else {
629 valuePair[1] = "";
630 }
631 } else {
632 valuePair[0] = decodeCharacters(control);
633 }
634 return valuePair;
635 }
636
637
638
639
640
641
642
643 private PortalURLParameter decodeParameter(String name, String value) {
644
645 if (LOG.isDebugEnabled()) {
646 LOG.debug("Decoding parameter: name=" + name
647 + ", value=" + value);
648 }
649
650
651 String noPrefix = name.substring((PREFIX + PORTLET_ID).length());
652 String windowId = noPrefix.substring(0, noPrefix.indexOf(DELIM));
653 String paramName = noPrefix.substring(noPrefix.indexOf(DELIM) + 1);
654
655
656 windowId = decodeCharacters(windowId);
657 if (value != null) {
658 value = decodeCharacters(value);
659 }
660
661
662 String[] paramValues = value.split(VALUE_DELIM);
663 for (int i = 0; i < paramValues.length;i++){
664 try {
665 paramValues[i] = URLDecoder.decode(paramValues[i], "UTF-8");
666 } catch (UnsupportedEncodingException e) {
667 LOG.warn(e.getMessage(),e);
668 }
669 }
670
671 return new PortalURLParameter(windowId, paramName, paramValues);
672 }
673
674 private PortalURLParameter decodePublicParameter(String name, String value) {
675
676 if (LOG.isDebugEnabled()) {
677 LOG.debug("Decoding parameter: name=" + name
678 + ", value=" + value);
679 }
680
681
682 String noPrefix = name.substring((PREFIX + PORTLET_ID).length());
683 String paramName = noPrefix.substring(noPrefix.indexOf(DELIM) + 1);
684
685
686
687 if (value != null) {
688 value = decodeCharacters(value);
689 }
690
691
692 String[] paramValues = value.split(VALUE_DELIM);
693
694
695 return new PortalURLParameter(null, paramName, paramValues);
696 }
697
698
699
700
701
702
703 private String decodeCharacters(String string) {
704 for (int i = 0; i < ENCODINGS.length; i++) {
705 string = string.replace(ENCODINGS[i][1], ENCODINGS[i][0]);
706 }
707 return string;
708 }
709
710 }
711