001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki; 020 021import java.security.Permission; 022import java.security.Principal; 023import java.util.HashMap; 024 025import javax.servlet.http.HttpServletRequest; 026import javax.servlet.http.HttpSession; 027import javax.servlet.jsp.PageContext; 028 029import org.apache.log4j.Logger; 030import org.apache.wiki.auth.NoSuchPrincipalException; 031import org.apache.wiki.auth.UserManager; 032import org.apache.wiki.auth.WikiPrincipal; 033import org.apache.wiki.auth.permissions.AllPermission; 034import org.apache.wiki.auth.user.UserDatabase; 035import org.apache.wiki.tags.WikiTagBase; 036import org.apache.wiki.ui.Command; 037import org.apache.wiki.ui.CommandResolver; 038import org.apache.wiki.ui.GroupCommand; 039import org.apache.wiki.ui.Installer; 040import org.apache.wiki.ui.PageCommand; 041import org.apache.wiki.ui.WikiCommand; 042import org.apache.wiki.util.TextUtil; 043 044/** 045 * <p>Provides state information throughout the processing of a page. A 046 * WikiContext is born when the JSP pages that are the main entry 047 * points, are invoked. The JSPWiki engine creates the new 048 * WikiContext, which basically holds information about the page, the 049 * handling engine, and in which context (view, edit, etc) the 050 * call was done.</p> 051 * <p>A WikiContext also provides request-specific variables, which can 052 * be used to communicate between plugins on the same page, or 053 * between different instances of the same plugin. A WikiContext 054 * variable is valid until the processing of the page has ended. For 055 * an example, please see the Counter plugin.</p> 056 * <p>When a WikiContext is created, it automatically associates a 057 * {@link WikiSession} object with the user's HttpSession. The 058 * WikiSession contains information about the user's authentication 059 * status, and is consulted by {@link #getCurrentUser()}. 060 * object</p> 061 * <p>Do not cache the page object that you get from the WikiContext; always 062 * use getPage()!</p> 063 * 064 * @see org.apache.wiki.plugin.Counter 065 * 066 */ 067public class WikiContext 068 implements Cloneable, Command 069{ 070 private Command m_command = null; 071 072 private WikiPage m_page; 073 private WikiPage m_realPage; 074 private WikiEngine m_engine; 075 private String m_template = "default"; 076 077 private HashMap<String,Object> m_variableMap = new HashMap<String,Object>(); 078 079 /** 080 * Stores the HttpServletRequest. May be null, if the request did not 081 * come from a servlet. 082 */ 083 protected HttpServletRequest m_request = null; 084 085 private WikiSession m_session = null; 086 087 /** User is administering JSPWiki (Install, SecurityConfig). */ 088 public static final String INSTALL = WikiCommand.INSTALL.getRequestContext(); 089 090 /** The VIEW context - the user just wants to view the page 091 contents. */ 092 public static final String VIEW = PageCommand.VIEW.getRequestContext(); 093 094 /** User wants to view or administer workflows. */ 095 public static final String WORKFLOW = WikiCommand.WORKFLOW.getRequestContext(); 096 097 /** The EDIT context - the user is editing the page. */ 098 public static final String EDIT = PageCommand.EDIT.getRequestContext(); 099 100 /** User is preparing for a login/authentication. */ 101 public static final String LOGIN = WikiCommand.LOGIN.getRequestContext(); 102 103 /** User is preparing to log out. */ 104 public static final String LOGOUT = WikiCommand.LOGOUT.getRequestContext(); 105 106 /** JSPWiki wants to display a message. */ 107 public static final String MESSAGE = WikiCommand.MESSAGE.getRequestContext(); 108 109 /** User is viewing a DIFF between the two versions of the page. */ 110 public static final String DIFF = PageCommand.DIFF.getRequestContext(); 111 112 /** User is viewing page history. */ 113 public static final String INFO = PageCommand.INFO.getRequestContext(); 114 115 /** User is previewing the changes he just made. */ 116 public static final String PREVIEW = PageCommand.PREVIEW.getRequestContext(); 117 118 /** User has an internal conflict, and does quite not know what to 119 do. Please provide some counseling. */ 120 public static final String CONFLICT = PageCommand.CONFLICT.getRequestContext(); 121 122 /** An error has been encountered and the user needs to be informed. */ 123 public static final String ERROR = WikiCommand.ERROR.getRequestContext(); 124 125 /** User is uploading something. */ 126 public static final String UPLOAD = PageCommand.UPLOAD.getRequestContext(); 127 128 /** User is commenting something. */ 129 public static final String COMMENT = PageCommand.COMMENT.getRequestContext(); 130 131 /** User is searching for content. */ 132 public static final String FIND = WikiCommand.FIND.getRequestContext(); 133 134 /** User wishes to create a new group */ 135 public static final String CREATE_GROUP = WikiCommand.CREATE_GROUP.getRequestContext(); 136 137 /** User is deleting an existing group. */ 138 public static final String DELETE_GROUP = GroupCommand.DELETE_GROUP.getRequestContext(); 139 140 /** User is editing an existing group. */ 141 public static final String EDIT_GROUP = GroupCommand.EDIT_GROUP.getRequestContext(); 142 143 /** User is viewing an existing group */ 144 public static final String VIEW_GROUP = GroupCommand.VIEW_GROUP.getRequestContext(); 145 146 /** User is editing preferences */ 147 public static final String PREFS = WikiCommand.PREFS.getRequestContext(); 148 149 /** User is renaming a page. */ 150 public static final String RENAME = PageCommand.RENAME.getRequestContext(); 151 152 /** User is deleting a page or an attachment. */ 153 public static final String DELETE = PageCommand.DELETE.getRequestContext(); 154 155 /** User is downloading an attachment. */ 156 public static final String ATTACH = PageCommand.ATTACH.getRequestContext(); 157 158 /** RSS feed is being generated. */ 159 public static final String RSS = PageCommand.RSS.getRequestContext(); 160 161 /** This is not a JSPWiki context, use it to access static files. */ 162 public static final String NONE = PageCommand.NONE.getRequestContext(); 163 164 /** Same as NONE; this is just a clarification. */ 165 public static final String OTHER = PageCommand.OTHER.getRequestContext(); 166 167 /** User is doing administrative things. */ 168 public static final String ADMIN = WikiCommand.ADMIN.getRequestContext(); 169 170 private static final Logger log = Logger.getLogger( WikiContext.class ); 171 172 private static final Permission DUMMY_PERMISSION = new java.util.PropertyPermission( "os.name", "read" ); 173 174 /** 175 * Create a new WikiContext for the given WikiPage. Delegates to 176 * {@link #WikiContext(WikiEngine, HttpServletRequest, WikiPage)}. 177 * @param engine The WikiEngine that is handling the request. 178 * @param page The WikiPage. If you want to create a 179 * WikiContext for an older version of a page, you must use this 180 * constructor. 181 */ 182 public WikiContext( WikiEngine engine, WikiPage page ) 183 { 184 this( engine, null, findCommand( engine, null, page ) ); 185 } 186 187 /** 188 * <p> 189 * Creates a new WikiContext for the given WikiEngine, Command and 190 * HttpServletRequest. 191 * </p> 192 * <p> 193 * This constructor will also look up the HttpSession associated with the 194 * request, and determine if a WikiSession object is present. If not, a new 195 * one is created. 196 * </p> 197 * @param engine The WikiEngine that is handling the request 198 * @param request The HttpServletRequest that should be associated with this 199 * context. This parameter may be <code>null</code>. 200 * @param command the command 201 * @throws IllegalArgumentException if <code>engine</code> or 202 * <code>command</code> are <code>null</code> 203 */ 204 public WikiContext( WikiEngine engine, HttpServletRequest request, Command command ) 205 throws IllegalArgumentException 206 { 207 super(); 208 if ( engine == null || command == null ) 209 { 210 throw new IllegalArgumentException( "Parameter engine and command must not be null." ); 211 } 212 213 m_engine = engine; 214 m_request = request; 215 m_session = WikiSession.getWikiSession( engine, request ); 216 m_command = command; 217 218 // If PageCommand, get the WikiPage 219 if( command instanceof PageCommand ) 220 { 221 m_page = (WikiPage)((PageCommand)command).getTarget(); 222 } 223 224 // If page not supplied, default to front page to avoid NPEs 225 if( m_page == null ) 226 { 227 m_page = m_engine.getPage( m_engine.getFrontPage() ); 228 229 // Front page does not exist? 230 if( m_page == null ) 231 { 232 m_page = new WikiPage( m_engine, m_engine.getFrontPage() ); 233 } 234 } 235 236 m_realPage = m_page; 237 238 // Special case: retarget any empty 'view' PageCommands to the front page 239 if ( PageCommand.VIEW.equals( command ) && command.getTarget() == null ) 240 { 241 m_command = command.targetedCommand( m_page ); 242 } 243 244 // Debugging... 245 if( log.isDebugEnabled() ) 246 { 247 HttpSession session = ( request == null ) ? null : request.getSession( false ); 248 String sid = ( session == null ) ? "(null)" : session.getId(); 249 log.debug( "Creating WikiContext for session ID=" + sid + "; target=" + getName() ); 250 } 251 252 // Figure out what template to use 253 setDefaultTemplate( request ); 254 } 255 256 /** 257 * Creates a new WikiContext for the given WikiEngine, WikiPage and 258 * HttpServletRequest. This method simply looks up the appropriate Command 259 * using {@link #findCommand(WikiEngine, HttpServletRequest, WikiPage)} and 260 * delegates to 261 * {@link #WikiContext(WikiEngine, HttpServletRequest, Command)}. 262 * @param engine The WikiEngine that is handling the request 263 * @param request The HttpServletRequest that should be associated with this 264 * context. This parameter may be <code>null</code>. 265 * @param page The WikiPage. If you want to create a WikiContext for an 266 * older version of a page, you must supply this parameter 267 */ 268 public WikiContext(WikiEngine engine, HttpServletRequest request, WikiPage page) 269 { 270 this( engine, request, findCommand( engine, request, page ) ); 271 } 272 273 /** 274 * {@inheritDoc} 275 * @see org.apache.wiki.ui.Command#getContentTemplate() 276 */ 277 public String getContentTemplate() 278 { 279 return m_command.getContentTemplate(); 280 } 281 282 /** 283 * {@inheritDoc} 284 * @see org.apache.wiki.ui.Command#getJSP() 285 */ 286 public String getJSP() 287 { 288 return m_command.getContentTemplate(); 289 } 290 291 /** 292 * Sets a reference to the real page whose content is currently being 293 * rendered. 294 * <p> 295 * Sometimes you may want to render the page using some other page's context. 296 * In those cases, it is highly recommended that you set the setRealPage() 297 * to point at the real page you are rendering. Please see InsertPageTag 298 * for an example. 299 * <p> 300 * Also, if your plugin e.g. does some variable setting, be aware that if it 301 * is embedded in the LeftMenu or some other page added with InsertPageTag, 302 * you should consider what you want to do - do you wish to really reference 303 * the "master" page or the included page. 304 * 305 * @param page The real page which is being rendered. 306 * @return The previous real page 307 * @since 2.3.14 308 * @see org.apache.wiki.tags.InsertPageTag 309 */ 310 public WikiPage setRealPage( WikiPage page ) 311 { 312 WikiPage old = m_realPage; 313 m_realPage = page; 314 updateCommand( m_command.getRequestContext() ); 315 return old; 316 } 317 318 /** 319 * Gets a reference to the real page whose content is currently being rendered. 320 * If your plugin e.g. does some variable setting, be aware that if it 321 * is embedded in the LeftMenu or some other page added with InsertPageTag, 322 * you should consider what you want to do - do you wish to really reference 323 * the "master" page or the included page. 324 * <p> 325 * For example, in the default template, there is a page called "LeftMenu". 326 * Whenever you access a page, e.g. "Main", the master page will be Main, and 327 * that's what the getPage() will return - regardless of whether your plugin 328 * resides on the LeftMenu or on the Main page. However, getRealPage() 329 * will return "LeftMenu". 330 * 331 * @return A reference to the real page. 332 * @see org.apache.wiki.tags.InsertPageTag 333 * @see org.apache.wiki.parser.JSPWikiMarkupParser 334 */ 335 public WikiPage getRealPage() 336 { 337 return m_realPage; 338 } 339 340 /** 341 * Figure out to which page we are really going to. Considers 342 * special page names from the jspwiki.properties, and possible aliases. 343 * This method forwards requests to 344 * {@link org.apache.wiki.ui.CommandResolver#getSpecialPageReference(String)}. 345 * @return A complete URL to the new page to redirect to 346 * @since 2.2 347 */ 348 349 public String getRedirectURL() 350 { 351 String pagename = m_page.getName(); 352 String redirURL = null; 353 354 redirURL = m_engine.getCommandResolver().getSpecialPageReference( pagename ); 355 356 if( redirURL == null ) 357 { 358 String alias = (String)m_page.getAttribute( WikiPage.ALIAS ); 359 360 if( alias != null ) 361 { 362 redirURL = getViewURL( alias ); 363 } 364 else 365 { 366 redirURL = (String)m_page.getAttribute( WikiPage.REDIRECT ); 367 } 368 } 369 370 return redirURL; 371 } 372 373 /** 374 * Returns the handling engine. 375 * 376 * @return The wikiengine owning this context. 377 */ 378 public WikiEngine getEngine() 379 { 380 return m_engine; 381 } 382 383 /** 384 * Returns the page that is being handled. 385 * 386 * @return the page which was fetched. 387 */ 388 public WikiPage getPage() 389 { 390 return m_page; 391 } 392 393 /** 394 * Sets the page that is being handled. 395 * 396 * @param page The wikipage 397 * @since 2.1.37. 398 */ 399 public void setPage( WikiPage page ) 400 { 401 m_page = page; 402 updateCommand( m_command.getRequestContext() ); 403 } 404 405 /** 406 * Returns the request context. 407 * @return The name of the request context (e.g. VIEW). 408 */ 409 public String getRequestContext() 410 { 411 return m_command.getRequestContext(); 412 } 413 414 /** 415 * Sets the request context. See above for the different 416 * request contexts (VIEW, EDIT, etc.) 417 * 418 * @param arg The request context (one of the predefined contexts.) 419 */ 420 public void setRequestContext( String arg ) 421 { 422 updateCommand( arg ); 423 } 424 425 /** 426 * {@inheritDoc} 427 * @see org.apache.wiki.ui.Command#getTarget() 428 */ 429 public Object getTarget() 430 { 431 return m_command.getTarget(); 432 } 433 434 /** 435 * {@inheritDoc} 436 * @see org.apache.wiki.ui.Command#getURLPattern() 437 */ 438 public String getURLPattern() 439 { 440 return m_command.getURLPattern(); 441 } 442 443 /** 444 * Gets a previously set variable. 445 * 446 * @param key The variable name. 447 * @return The variable contents. 448 */ 449 public Object getVariable( String key ) 450 { 451 return m_variableMap.get( key ); 452 } 453 454 /** 455 * Sets a variable. The variable is valid while the WikiContext is valid, 456 * i.e. while page processing continues. The variable data is discarded 457 * once the page processing is finished. 458 * 459 * @param key The variable name. 460 * @param data The variable value. 461 */ 462 public void setVariable( String key, Object data ) 463 { 464 m_variableMap.put( key, data ); 465 updateCommand( m_command.getRequestContext() ); 466 } 467 468 /** 469 * This is just a simple helper method which will first check the context 470 * if there is already an override in place, and if there is not, 471 * it will then check the given properties. 472 * 473 * @param key What key are we searching for? 474 * @param defValue Default value for the boolean 475 * @return {@code true} or {@code false}. 476 */ 477 public boolean getBooleanWikiProperty( final String key, final boolean defValue ) { 478 Object bool = getVariable( key ); 479 if( bool != null ) { 480 return TextUtil.isPositive( (String) bool ); 481 } 482 483 return TextUtil.getBooleanProperty( getEngine().getWikiProperties(), key, defValue ); 484 } 485 486 /** 487 * This method will safely return any HTTP parameters that 488 * might have been defined. You should use this method instead 489 * of peeking directly into the result of getHttpRequest(), since 490 * this method is smart enough to do all of the right things, 491 * figure out UTF-8 encoded parameters, etc. 492 * 493 * @since 2.0.13. 494 * @param paramName Parameter name to look for. 495 * @return HTTP parameter, or null, if no such parameter existed. 496 */ 497 public String getHttpParameter( String paramName ) 498 { 499 String result = null; 500 501 if( m_request != null ) 502 { 503 result = m_request.getParameter( paramName ); 504 } 505 506 return result; 507 } 508 509 /** 510 * If the request did originate from a HTTP request, 511 * then the HTTP request can be fetched here. However, it the request 512 * did NOT originate from a HTTP request, then this method will 513 * return null, and YOU SHOULD CHECK FOR IT! 514 * 515 * @return Null, if no HTTP request was done. 516 * @since 2.0.13. 517 */ 518 public HttpServletRequest getHttpRequest() 519 { 520 return m_request; 521 } 522 523 /** 524 * Sets the template to be used for this request. 525 * 526 * @param dir The template name 527 * @since 2.1.15. 528 */ 529 public void setTemplate( String dir ) 530 { 531 m_template = dir; 532 } 533 534 /** 535 * Returns the target of this wiki context: a page, group name or JSP. If 536 * the associated Command is a PageCommand, this method returns the page's 537 * name. Otherwise, this method delegates to the associated Command's 538 * {@link org.apache.wiki.ui.Command#getName()} method. Calling classes 539 * can rely on the results of this method for looking up canonically-correct 540 * page or group names. Because it does not automatically assume that the 541 * wiki context is a PageCommand, calling this method is inherently safer 542 * than calling <code>getPage().getName()</code>. 543 * @return the name of the target of this wiki context 544 * @see org.apache.wiki.ui.PageCommand#getName() 545 * @see org.apache.wiki.ui.GroupCommand#getName() 546 */ 547 public String getName() 548 { 549 if ( m_command instanceof PageCommand ) 550 { 551 return m_page != null ? m_page.getName() : "<no page>"; 552 } 553 return m_command.getName(); 554 } 555 556 /** 557 * Gets the template that is to be used throughout this request. 558 * @since 2.1.15. 559 * @return template name 560 */ 561 public String getTemplate() 562 { 563 return m_template; 564 } 565 566 /** 567 * Convenience method that gets the current user. Delegates the 568 * lookup to the WikiSession associated with this WikiContect. 569 * May return null, in case the current 570 * user has not yet been determined; or this is an internal system. 571 * If the WikiSession has not been set, <em>always</em> returns null. 572 * 573 * @return The current user; or maybe null in case of internal calls. 574 */ 575 public Principal getCurrentUser() 576 { 577 if (m_session == null) 578 { 579 // This shouldn't happen, really... 580 return WikiPrincipal.GUEST; 581 } 582 return m_session.getUserPrincipal(); 583 } 584 585 /** 586 * A shortcut to generate a VIEW url. 587 * 588 * @param page The page to which to link. 589 * @return An URL to the page. This honours the current absolute/relative setting. 590 */ 591 public String getViewURL( String page ) 592 { 593 return getURL( VIEW, page, null ); 594 } 595 596 /** 597 * Creates an URL for the given request context. 598 * 599 * @param context e.g. WikiContext.EDIT 600 * @param page The page to which to link 601 * @return An URL to the page, honours the absolute/relative setting in jspwiki.properties 602 */ 603 public String getURL( String context, 604 String page ) 605 { 606 return getURL( context, page, null ); 607 } 608 609 /** 610 * Returns an URL from a page. It this WikiContext instance was constructed 611 * with an actual HttpServletRequest, we will attempt to construct the 612 * URL using HttpUtil, which preserves the HTTPS portion if it was used. 613 * 614 * @param context The request context (e.g. WikiContext.UPLOAD) 615 * @param page The page to which to link 616 * @param params A list of parameters, separated with "&" 617 * 618 * @return An URL to the given context and page. 619 */ 620 public String getURL( String context, 621 String page, 622 String params ) 623 { 624 boolean absolute = "absolute".equals(m_engine.getVariable( this, WikiEngine.PROP_REFSTYLE )); 625 626 // FIXME: is rather slow 627 return m_engine.getURL( context, 628 page, 629 params, 630 absolute ); 631 632 } 633 634 /** 635 * Returns the Command associated with this WikiContext. 636 * @return the command 637 */ 638 public Command getCommand() 639 { 640 return m_command; 641 } 642 643 /** 644 * Returns a shallow clone of the WikiContext. 645 * 646 * @since 2.1.37. 647 * @return A shallow clone of the WikiContext 648 */ 649 public Object clone() 650 { 651 try 652 { 653 // super.clone() must always be called to make sure that inherited objects 654 // get the right type 655 WikiContext copy = (WikiContext)super.clone(); 656 657 copy.m_engine = m_engine; 658 copy.m_command = m_command; 659 660 copy.m_template = m_template; 661 copy.m_variableMap = m_variableMap; 662 copy.m_request = m_request; 663 copy.m_session = m_session; 664 copy.m_page = m_page; 665 copy.m_realPage = m_realPage; 666 return copy; 667 } 668 catch( CloneNotSupportedException e ){} // Never happens 669 670 return null; 671 } 672 673 /** 674 * Creates a deep clone of the WikiContext. This is useful when you want 675 * to be sure that you don't accidentally mess with page attributes, etc. 676 * 677 * @since 2.8.0 678 * @return A deep clone of the WikiContext. 679 */ 680 public WikiContext deepClone() 681 { 682 try 683 { 684 // super.clone() must always be called to make sure that inherited objects 685 // get the right type 686 WikiContext copy = (WikiContext)super.clone(); 687 688 // No need to deep clone these 689 copy.m_engine = m_engine; 690 copy.m_command = m_command; // Static structure 691 692 copy.m_template = m_template; 693 copy.m_variableMap = (HashMap<String,Object>)m_variableMap.clone(); 694 copy.m_request = m_request; 695 copy.m_session = m_session; 696 copy.m_page = (WikiPage)m_page.clone(); 697 copy.m_realPage = (WikiPage)m_realPage.clone(); 698 return copy; 699 } 700 catch( CloneNotSupportedException e ){} // Never happens 701 702 return null; 703 } 704 705 /** 706 * Returns the WikiSession associated with the context. 707 * This method is guaranteed to always return a valid WikiSession. 708 * If this context was constructed without an associated 709 * HttpServletRequest, it will return {@link WikiSession#guestSession(WikiEngine)}. 710 * 711 * @return The WikiSession associate with this context. 712 */ 713 public WikiSession getWikiSession() 714 { 715 return m_session; 716 } 717 718 /** 719 * This method can be used to find the WikiContext programmatically 720 * from a JSP PageContext. We check the request context. 721 * The wiki context, if it exists, 722 * is looked up using the key 723 * {@link org.apache.wiki.tags.WikiTagBase#ATTR_CONTEXT}. 724 * 725 * @since 2.4 726 * @param pageContext the JSP page context 727 * @return Current WikiContext, or null, of no context exists. 728 */ 729 public static WikiContext findContext( PageContext pageContext ) 730 { 731 HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); 732 WikiContext context = (WikiContext)request.getAttribute( WikiTagBase.ATTR_CONTEXT ); 733 return context; 734 } 735 736 /** 737 * Returns the permission required to successfully execute this context. 738 * For example, the a wiki context of VIEW for a certain page means that 739 * the PagePermission "view" is required for the page. In some cases, no 740 * particular permission is required, in which case a dummy permission will 741 * be returned ({@link java.util.PropertyPermission}<code> "os.name", 742 * "read"</code>). This method is guaranteed to always return a valid, 743 * non-null permission. 744 * @return the permission 745 * @since 2.4 746 */ 747 public Permission requiredPermission() 748 { 749 // This is a filthy rotten hack -- absolutely putrid 750 if ( WikiCommand.INSTALL.equals( m_command ) ) 751 { 752 // See if admin users exists 753 boolean adminExists = false; 754 try 755 { 756 UserManager userMgr = m_engine.getUserManager(); 757 UserDatabase userDb = userMgr.getUserDatabase(); 758 userDb.findByLoginName( Installer.ADMIN_ID ); 759 adminExists = true; 760 } 761 catch ( NoSuchPrincipalException e ) 762 { 763 return DUMMY_PERMISSION; 764 } 765 if ( adminExists ) 766 { 767 return new AllPermission( m_engine.getApplicationName() ); 768 } 769 } 770 771 // TODO: we should really break the contract so that this 772 // method returns null, but until then we will use this hack 773 if ( m_command.requiredPermission() == null ) 774 { 775 return DUMMY_PERMISSION; 776 } 777 778 return m_command.requiredPermission(); 779 } 780 781 /** 782 * Associates a target with the current Command and returns 783 * the new targeted Command. If the Command associated with this 784 * WikiContext is already "targeted", it is returned instead. 785 * @see org.apache.wiki.ui.Command#targetedCommand(java.lang.Object) 786 * 787 * {@inheritDoc} 788 */ 789 public Command targetedCommand( Object target ) 790 { 791 if ( m_command.getTarget() == null ) 792 { 793 return m_command.targetedCommand( target ); 794 } 795 return m_command; 796 } 797 798 /** 799 * Returns true, if the current user has administrative permissions (i.e. the omnipotent 800 * AllPermission). 801 * 802 * @since 2.4.46 803 * @return true, if the user has all permissions. 804 */ 805 public boolean hasAdminPermissions() 806 { 807 boolean admin = false; 808 809 admin = m_engine.getAuthorizationManager().checkPermission( getWikiSession(), 810 new AllPermission(m_engine.getApplicationName()) ); 811 812 return admin; 813 } 814 815 /** 816 * Figures out which template a new WikiContext should be using. 817 * @param request the HTTP request 818 */ 819 protected void setDefaultTemplate( HttpServletRequest request ) 820 { 821 // FIXME: Most definitely this should be checked for 822 // existence, or else it is possible to create pages that 823 // cannot be shown. 824 String defaultTemplate = m_engine.getTemplateDir(); 825 826 // Figure out which template we should be using for this page. 827 String template = null; 828 if ( request != null ) 829 { 830 template = request.getParameter( "skin" ); 831 } 832 833 // If request doesn't supply the value, extract from wiki page 834 if( template == null ) 835 { 836 WikiPage page = getPage(); 837 if ( page != null ) 838 { 839 template = (String)page.getAttribute( WikiEngine.PROP_TEMPLATEDIR ); 840 } 841 842 } 843 844 // If something over-wrote the default, set the new value. 845 if ( template != null ) 846 { 847 setTemplate( template ); 848 } 849 else 850 { 851 setTemplate( defaultTemplate ); 852 } 853 } 854 855 /** 856 * Looks up and returns a PageCommand based on a supplied WikiPage and HTTP 857 * request. First, the appropriate Command is obtained by examining the HTTP 858 * request; the default is {@link PageCommand#VIEW}. If the Command is a 859 * PageCommand (and it should be, in most cases), a targeted Command is 860 * created using the (non-<code>null</code>) WikiPage as target. 861 * @param engine the wiki engine 862 * @param request the HTTP request 863 * @param page the wiki page 864 * @return the correct command 865 */ 866 protected static Command findCommand( WikiEngine engine, HttpServletRequest request, WikiPage page ) 867 { 868 String defaultContext = PageCommand.VIEW.getRequestContext(); 869 Command command = engine.getCommandResolver().findCommand( request, defaultContext ); 870 if ( command instanceof PageCommand && page != null ) 871 { 872 command = command.targetedCommand( page ); 873 } 874 return command; 875 } 876 877 /** 878 * Protected method that updates the internally cached Command. 879 * Will always be called when the page name, request context, or variable 880 * changes. 881 * @param requestContext the desired request context 882 * @since 2.4 883 */ 884 protected void updateCommand( String requestContext ) 885 { 886 if ( requestContext == null ) 887 { 888 m_command = PageCommand.NONE; 889 } 890 else 891 { 892 CommandResolver resolver = m_engine.getCommandResolver(); 893 m_command = resolver.findCommand( m_request, requestContext ); 894 } 895 896 if ( m_command instanceof PageCommand && m_page != null ) 897 { 898 m_command = m_command.targetedCommand( m_page ); 899 } 900 } 901 902}