1 48 49 50 package com.caucho.portal.generic; 51 52 import javax.portlet.PortletMode; 53 import javax.portlet.WindowState; 54 import java.util.HashSet ; 55 import java.util.Iterator ; 56 import java.util.LinkedHashMap ; 57 import java.util.Map ; 58 import java.util.Set ; 59 import java.util.logging.Level ; 60 import java.util.logging.Logger ; 61 62 63 65 public class MapBasedInvocationFactory 66 implements InvocationFactory, Cloneable 67 { 68 static protected final Logger log = 69 Logger.getLogger(MapBasedInvocationFactory.class.getName()); 70 71 private String _reservedNamespace = "__"; 72 private String _actionTargetParameterName = "A"; 73 private String _windowStateParameterName = "W"; 74 private String _portletModeParameterName = "M"; 75 76 77 private LinkedHashMap <String , MapBasedInvocation> _invocationMap 78 = new LinkedHashMap <String , MapBasedInvocation>(); 79 80 private String _actionNamespace; 81 82 private Set <WindowState> _windowStatesUsed; 83 private Set <PortletMode> _portletModesUsed; 84 85 private StringBuffer _buffer = new StringBuffer (256); 87 88 96 public void setReservedNamespace(String namespace) 97 { 98 _reservedNamespace = namespace; 99 } 100 101 105 public String getReservedNamespace() 106 { 107 return _reservedNamespace; 108 } 109 110 114 public void setActionTargetParameterName(String name) 115 { 116 _actionTargetParameterName = name; 117 } 118 119 123 public String getActionTargetParameterName() 124 { 125 return _actionTargetParameterName; 126 } 127 128 131 public void setWindowStateParameterName(String name) 132 { 133 _windowStateParameterName = name; 134 } 135 136 139 public String getWindowStateParameterName() 140 { 141 return _windowStateParameterName; 142 } 143 144 147 public void setPortletModeParameterName(String name) 148 { 149 _portletModeParameterName = name; 150 } 151 152 155 public String getPortletModeParameterName() 156 { 157 return _portletModeParameterName; 158 } 159 160 public void start(Map <String , String []> rawParameters) 161 { 162 if (rawParameters != null) 163 decodeRawParameters(rawParameters); 164 } 165 166 public void finish() 167 { 168 _windowStatesUsed = null; 169 _portletModesUsed = null; 170 171 _actionNamespace = null; 172 _invocationMap.clear(); 173 } 174 175 public boolean isActionTarget(String namespace) 176 { 177 return namespace == _actionNamespace; 178 } 179 180 185 protected MapBasedInvocationFactory clone(String namespace) 186 { 187 try { 188 MapBasedInvocationFactory clone 189 = (MapBasedInvocationFactory) super.clone(); 190 191 clone._windowStatesUsed = null; 192 clone._portletModesUsed = null; 193 clone._actionNamespace = null; 194 195 clone._invocationMap = new LinkedHashMap <String , MapBasedInvocation>(); 196 197 Iterator <Map.Entry <String , MapBasedInvocation>> iter 198 = _invocationMap.entrySet().iterator(); 199 200 while (iter.hasNext()) { 201 Map.Entry <String , MapBasedInvocation> entry = iter.next(); 202 String invocationNamespace = entry.getKey(); 203 MapBasedInvocation invocation = entry.getValue(); 204 205 boolean keepParameters = !namespace.equals(invocationNamespace); 206 207 clone._invocationMap.put( invocationNamespace, 208 invocation.clone(keepParameters) ); 209 } 210 211 return clone; 212 } 213 catch (CloneNotSupportedException ex) { 214 throw new RuntimeException (ex); 215 } 216 } 217 218 protected void decodeRawParameters(Map <String , String []> raw) 219 { 220 _buffer.setLength(0); 221 StringBuffer buf = _buffer; 222 223 buf.append(_reservedNamespace); 224 int len = buf.length(); 225 226 buf.append(_reservedNamespace); 227 buf.append(_actionTargetParameterName); 228 String actionTargetParameterName = buf.toString(); 229 230 buf.setLength(len); 231 buf.append(_windowStateParameterName); 232 String windowStateParameterName = buf.toString(); 233 234 buf.setLength(len); 235 buf.append(_portletModeParameterName); 236 String portletModeParameterName = buf.toString(); 237 238 MapBasedInvocation invocation = null; 239 240 String [] action = raw.get(actionTargetParameterName); 242 _actionNamespace = action == null || action.length == 0 ? null : action[0]; 243 244 if (_actionNamespace != null) 245 getInvocation(_actionNamespace); 246 247 253 Iterator <Map.Entry <String , String []>> iter = raw.entrySet().iterator(); 254 255 while (iter.hasNext()) { 256 Map.Entry <String , String []> entry = iter.next(); 257 String key = entry.getKey(); 258 String [] values = entry.getValue(); 259 260 261 String namespace = null; 262 263 if (key.startsWith(_reservedNamespace)) { 264 265 int keyLen = key.length(); 266 267 int st = _reservedNamespace.length(); 268 int nd = key.indexOf('.', st); 269 if (nd > -1) { 270 namespace = key.substring(st, nd); 271 nd++; 272 } 273 else { 274 if ( log.isLoggable(Level.FINE) 275 && !key.equals(actionTargetParameterName) ) 276 log.fine("unusable raw parameter name `" + key + "'"); 277 continue; 278 } 279 280 if (nd < keyLen) 281 key = key.substring(nd); 282 else { 283 if ( log.isLoggable(Level.FINE) ) 284 log.fine("unusable . raw parameter name `" + key + "'"); 285 continue; 286 } 287 } 288 else { 289 if (_actionNamespace == null) { 290 log.finer("unusable raw action parameter name `" + key + "'"); 291 continue; 292 } else 293 namespace = _actionNamespace; 294 } 295 296 if (invocation == null || !invocation.getNamespace().equals(namespace)) 297 invocation = getInvocation(namespace); 298 299 if (windowStateParameterName.equals(key)) { 300 invocation.setWindowStateName(values); 301 } 302 else if (portletModeParameterName.equals(key)) { 303 invocation.setPortletModeName(values); 304 } 305 else { 306 invocation.getParameterMap().put(key, values); 307 } 308 } 309 310 } 311 312 313 public String getURL() 314 { 315 _buffer.setLength(0); 316 StringBuffer buf = _buffer; 317 318 StringBuffer url = _buffer; 319 320 if (_actionNamespace != null) 321 appendReserved(url, null, _actionTargetParameterName, _actionNamespace); 322 323 Iterator <Map.Entry <String , MapBasedInvocation>> iter 324 = _invocationMap.entrySet().iterator(); 325 326 335 String viewPortletModeNamespace = null; 336 String normalWindowStateNamespace = null; 337 boolean needViewPortletMode = false; 338 boolean needNormalWindowState = false; 339 340 boolean sawActionNamespace = false; 341 342 while (iter.hasNext()) { 343 Map.Entry <String , MapBasedInvocation> entry = iter.next(); 344 String namespace = entry.getKey(); 345 MapBasedInvocation invocation = entry.getValue(); 346 347 String paramNamespace = namespace == _actionNamespace ? null : namespace; 350 351 PortletMode portletMode = invocation.getPortletMode(); 352 WindowState windowState = invocation.getWindowState(); 353 Map <String , String []> parameterMap = invocation._parameterMap; 354 355 boolean hasParameters = parameterMap != null && !parameterMap.isEmpty(); 356 357 if (portletMode == PortletMode.VIEW) { 358 if (viewPortletModeNamespace == null && !hasParameters) 359 viewPortletModeNamespace = namespace; 360 } 361 else { 362 needViewPortletMode = true; 363 364 String key = _portletModeParameterName; 365 String value = portletMode.toString(); 366 367 appendReserved( url, namespace, key, value ); 368 } 369 370 371 if (windowState == WindowState.NORMAL) { 372 if (normalWindowStateNamespace == null && !hasParameters) 373 normalWindowStateNamespace = namespace; 374 } 375 else { 376 needNormalWindowState = true; 377 378 String key = _windowStateParameterName; 379 String value = windowState.toString(); 380 381 appendReserved( url, namespace, key, value ); 382 } 383 384 if (parameterMap != null && !parameterMap.isEmpty()) 385 { 386 Iterator <Map.Entry <String , String []>> paramIter 387 = parameterMap.entrySet().iterator(); 388 389 while (paramIter.hasNext()) { 390 Map.Entry <String , String []> paramEntry = paramIter.next(); 391 392 String paramKey = paramEntry.getKey(); 393 String [] paramValues = paramEntry.getValue(); 394 395 if (paramValues == null || paramValues.length == 0) 396 continue; 397 398 appendParameter( url, paramNamespace, paramKey, paramValues ); 399 } 400 } 401 402 } 404 if (needViewPortletMode && viewPortletModeNamespace != null) { 405 String key = _portletModeParameterName; 406 407 if (viewPortletModeNamespace == _actionNamespace) 408 viewPortletModeNamespace = null; 409 410 appendReserved( url, viewPortletModeNamespace, key, "view" ); 411 } 412 413 if (needNormalWindowState && normalWindowStateNamespace != null) { 414 String key = _windowStateParameterName; 415 416 if (normalWindowStateNamespace == _actionNamespace) 417 normalWindowStateNamespace = null; 418 419 appendReserved( url, normalWindowStateNamespace, key, "normal" ); 420 } 421 422 return url.toString(); 423 } 424 425 private void appendReserved( StringBuffer url, String namespace, 426 String key, String value ) 427 { 428 url.append(url.length() == 0 ? '?' : '&'); 429 430 url.append(_reservedNamespace); 431 432 if (namespace != null) { 433 url.append(namespace); 434 url.append('.'); 435 } 436 437 url.append(_reservedNamespace); 438 url.append(key); 439 url.append('='); 440 HttpUtil.encode(value, url); 441 } 442 443 private void appendParameter( StringBuffer url, String namespace, 444 String key, String values[] ) 445 { 446 for (int i = 0; i < values.length; i++) { 447 url.append(url.length() == 0 ? '?' : '&'); 448 449 if (namespace != null) { 450 url.append(_reservedNamespace); 451 url.append(namespace); 452 url.append('.'); 453 } 454 455 HttpUtil.encode(key, url); 456 url.append('='); 457 HttpUtil.encode(values[i], url); 458 } 459 } 460 461 462 465 public Set <WindowState> getWindowStatesUsed() 466 { 467 if (_windowStatesUsed == null) { 468 _windowStatesUsed = new HashSet <WindowState>(); 469 470 if (_invocationMap != null) { 471 Iterator <Map.Entry <String , MapBasedInvocation>> iter 472 = _invocationMap.entrySet().iterator(); 473 474 while (iter.hasNext()) { 475 Map.Entry <String , MapBasedInvocation> entry = iter.next(); 476 _windowStatesUsed.add(entry.getValue().getWindowState()); 477 } 478 } 479 } 480 481 if (_windowStatesUsed.isEmpty()) 482 _windowStatesUsed.add(WindowState.NORMAL); 483 484 return _windowStatesUsed; 485 } 486 487 private void addWindowStateUsed(WindowState windowState) 488 { 489 if (_windowStatesUsed != null) 490 _windowStatesUsed.add(windowState); 491 } 492 493 496 public Set <PortletMode> getPortletModesUsed() 497 { 498 if (_portletModesUsed == null) { 499 _portletModesUsed = new HashSet <PortletMode>(); 500 501 if (_invocationMap != null) { 502 Iterator <Map.Entry <String , MapBasedInvocation>> iter 503 = _invocationMap.entrySet().iterator(); 504 505 while (iter.hasNext()) { 506 Map.Entry <String , MapBasedInvocation> entry = iter.next(); 507 _portletModesUsed.add(entry.getValue().getPortletMode()); 508 } 509 } 510 } 511 512 if (_portletModesUsed.isEmpty()) 513 _portletModesUsed.add(PortletMode.VIEW); 514 515 return _portletModesUsed; 516 } 517 518 private void addPortletModeUsed(PortletMode portletMode) 519 { 520 if (_portletModesUsed != null) 521 _portletModesUsed.add(portletMode); 522 } 523 524 527 public MapBasedInvocation getInvocation(String namespace) 528 { 529 if (namespace == null) 530 throw new NullPointerException ("namespace cannot be null"); 531 532 MapBasedInvocation invocation = _invocationMap.get(namespace); 533 534 if (invocation == null) { 535 invocation = new MapBasedInvocation(this); 536 537 invocation.start(namespace); 538 _invocationMap.put(namespace, invocation); 539 } 540 541 return invocation; 542 } 543 544 protected InvocationURL createActionURL(String namespace) 545 { 546 MapBasedInvocationFactory clone = clone(namespace); 547 clone._actionNamespace = namespace; 548 return new MapBasedInvocationURL(clone, namespace); 549 } 550 551 protected InvocationURL createRenderURL(String namespace) 552 { 553 MapBasedInvocationFactory clone = clone(namespace); 554 clone._actionNamespace = null; 555 return new MapBasedInvocationURL(clone, namespace); 556 } 557 558 public String toString() 559 { 560 return "[MapBasedInvocationFactory actionNamespace=" + _actionNamespace 561 + " invocationMap=" + _invocationMap 562 + "]"; 563 } 564 565 private static class MapBasedInvocation implements Invocation, Cloneable 566 { 567 private MapBasedInvocationFactory _factory; 568 569 private String _namespace; 570 private WindowState _windowState = WindowState.NORMAL; 571 private PortletMode _portletMode = PortletMode.VIEW; 572 private Map <String , String []> _parameterMap; 573 574 public MapBasedInvocation(MapBasedInvocationFactory factory) 575 { 576 _factory = factory; 577 } 578 579 public void start(String namespace) 580 { 581 if (_namespace != null) 582 throw new IllegalStateException ("missing finish()?"); 583 584 _namespace = namespace; 585 } 586 587 public void finish() 588 { 589 _windowState = WindowState.NORMAL; 590 _portletMode = PortletMode.VIEW; 591 if (_parameterMap != null) 592 _parameterMap.clear(); 593 _namespace = null; 594 } 595 596 public MapBasedInvocation clone(boolean keepParameters) 597 { 598 try { 599 MapBasedInvocation clone = (MapBasedInvocation) super.clone(); 600 601 if (keepParameters && _parameterMap != null) 602 clone._parameterMap 603 = new LinkedHashMap <String , String []>(_parameterMap); 604 else 605 clone._parameterMap = null; 606 607 return clone; 608 } 609 catch (CloneNotSupportedException ex) { 610 throw new RuntimeException (ex); 611 } 612 } 613 614 public String getNamespace() 615 { 616 return _namespace; 617 } 618 619 public boolean isActionTarget() 620 { 621 return _factory.isActionTarget(_namespace); 622 } 623 624 public Map <String , String []> getParameterMap() 625 { 626 if (_parameterMap == null) 627 _parameterMap = new LinkedHashMap <String , String []>(); 628 629 return _parameterMap; 630 } 631 632 public Map <String , String []> releaseParameterMap() 633 { 634 Map <String , String []> map = getParameterMap(); 635 _parameterMap = null; 636 return map; 637 } 638 639 public WindowState getWindowState() 640 { 641 return _windowState; 642 } 643 644 public void setWindowState(WindowState windowState) 645 { 646 _windowState = windowState == null ? WindowState.NORMAL : windowState; 647 _factory.addWindowStateUsed(_windowState); 648 } 649 650 void setWindowStateName(String [] values) 651 { 652 String windowStateName 653 = values == null || values.length == 0 ? null : values[0]; 654 655 if (windowStateName == null) 656 setWindowState(WindowState.NORMAL); 657 else if (windowStateName.equals("normal")) 658 setWindowState(WindowState.NORMAL); 659 else if (windowStateName.equals("minimized")) 660 setWindowState(WindowState.MINIMIZED); 661 else if (windowStateName.equals("maximized")) 662 setWindowState(WindowState.MAXIMIZED); 663 else 664 setWindowState(new WindowState(windowStateName)); 665 } 666 667 public PortletMode getPortletMode() 668 { 669 return _portletMode; 670 } 671 672 public void setPortletMode(PortletMode portletMode) 673 { 674 _portletMode = portletMode == null ? PortletMode.VIEW : portletMode; 675 _factory.addPortletModeUsed(_portletMode); 676 } 677 678 void setPortletModeName(String [] values) 679 { 680 String portletModeName 681 = values == null || values.length == 0 ? null : values[0]; 682 683 if (portletModeName == null) 684 setPortletMode(PortletMode.VIEW); 685 else if (portletModeName.equals("view")) 686 setPortletMode(PortletMode.VIEW); 687 else if (portletModeName.equals("edit")) 688 setPortletMode(PortletMode.EDIT); 689 else if (portletModeName.equals("help")) 690 setPortletMode(PortletMode.HELP); 691 else 692 setPortletMode(new PortletMode(portletModeName)); 693 } 694 695 public InvocationURL createActionURL() 696 { 697 return _factory.createActionURL(_namespace); 698 } 699 700 public InvocationURL createRenderURL() 701 { 702 return _factory.createRenderURL(_namespace); 703 } 704 705 public String toString() 706 { 707 return "[MapBasedInvocationFactory " 708 + " namespace=" + _namespace 709 + " windowState=" + _windowState 710 + " portletMode=" + _portletMode 711 + " parameters=" + _parameterMap 712 + "]"; 713 714 } 715 } 716 717 static class MapBasedInvocationURL 718 extends InvocationURL 719 { 720 MapBasedInvocationFactory _factory; 721 722 MapBasedInvocationURL(MapBasedInvocationFactory factory, String namespace) 723 { 724 super(factory, namespace); 725 _factory = factory; 726 } 727 728 public String getURL() 729 { 730 return _factory.getURL(); 731 } 732 733 } 734 } 735 736 | Popular Tags |