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 org.apache.commons.lang3.StringUtils; 022import org.apache.log4j.Logger; 023import org.apache.wiki.api.Release; 024import org.apache.wiki.api.core.Engine; 025import org.apache.wiki.api.core.Page; 026import org.apache.wiki.api.engine.Initializable; 027import org.apache.wiki.api.exceptions.ProviderException; 028import org.apache.wiki.api.exceptions.WikiException; 029import org.apache.wiki.attachment.AttachmentManager; 030import org.apache.wiki.auth.AuthenticationManager; 031import org.apache.wiki.auth.AuthorizationManager; 032import org.apache.wiki.auth.UserManager; 033import org.apache.wiki.auth.acl.AclManager; 034import org.apache.wiki.auth.authorize.GroupManager; 035import org.apache.wiki.content.PageRenamer; 036import org.apache.wiki.diff.DifferenceManager; 037import org.apache.wiki.event.WikiEngineEvent; 038import org.apache.wiki.event.WikiEventListener; 039import org.apache.wiki.event.WikiEventManager; 040import org.apache.wiki.event.WikiPageEvent; 041import org.apache.wiki.filters.FilterManager; 042import org.apache.wiki.i18n.InternationalizationManager; 043import org.apache.wiki.pages.PageManager; 044import org.apache.wiki.plugin.PluginManager; 045import org.apache.wiki.references.ReferenceManager; 046import org.apache.wiki.render.RenderingManager; 047import org.apache.wiki.rss.RSSGenerator; 048import org.apache.wiki.search.SearchManager; 049import org.apache.wiki.tasks.TasksManager; 050import org.apache.wiki.ui.CommandResolver; 051import org.apache.wiki.ui.EditorManager; 052import org.apache.wiki.ui.TemplateManager; 053import org.apache.wiki.ui.admin.AdminBeanManager; 054import org.apache.wiki.ui.progress.ProgressManager; 055import org.apache.wiki.url.URLConstructor; 056import org.apache.wiki.util.ClassUtil; 057import org.apache.wiki.util.PropertyReader; 058import org.apache.wiki.util.TextUtil; 059import org.apache.wiki.variables.VariableManager; 060import org.apache.wiki.workflow.WorkflowManager; 061 062import javax.servlet.ServletConfig; 063import javax.servlet.ServletContext; 064import java.io.File; 065import java.io.UnsupportedEncodingException; 066import java.net.MalformedURLException; 067import java.net.URL; 068import java.net.URLDecoder; 069import java.net.URLEncoder; 070import java.nio.charset.Charset; 071import java.nio.charset.StandardCharsets; 072import java.util.ArrayList; 073import java.util.Collection; 074import java.util.Date; 075import java.util.Enumeration; 076import java.util.List; 077import java.util.Locale; 078import java.util.Map; 079import java.util.Properties; 080import java.util.TimeZone; 081import java.util.concurrent.ConcurrentHashMap; 082import java.util.stream.Collectors; 083 084 085/** 086 * Main implementation for {@link Engine}. 087 * 088 * <P> 089 * Using this class: Always get yourself an instance from JSP page by using the {@code WikiEngine.getInstance(..)} method. Never create 090 * a new WikiEngine() from scratch, unless you're writing tests. 091 * 092 * <p> 093 * {@inheritDoc} 094 */ 095public class WikiEngine implements Engine { 096 097 private static final String ATTR_WIKIENGINE = "org.apache.wiki.WikiEngine"; 098 private static final Logger log = Logger.getLogger( WikiEngine.class ); 099 100 /** Stores properties. */ 101 private Properties m_properties; 102 103 /** Should the user info be saved with the page data as well? */ 104 private boolean m_saveUserInfo = true; 105 106 /** If true, uses UTF8 encoding for all data */ 107 private boolean m_useUTF8 = true; 108 109 /** Store the file path to the basic URL. When we're not running as a servlet, it defaults to the user's current directory. */ 110 private String m_rootPath = System.getProperty( "user.dir" ); 111 112 /** Store the ServletContext that we're in. This may be null if WikiEngine is not running inside a servlet container (i.e. when testing). */ 113 private ServletContext m_servletContext = null; 114 115 /** Stores the template path. This is relative to "templates". */ 116 private String m_templateDir; 117 118 /** The default front page name. Defaults to "Main". */ 119 private String m_frontPage; 120 121 /** The time when this engine was started. */ 122 private Date m_startTime; 123 124 /** The location where the work directory is. */ 125 private String m_workDir; 126 127 /** Each engine has their own application id. */ 128 private String m_appid = ""; 129 130 /** engine is up and running or not */ 131 private boolean m_isConfigured = false; 132 133 /** Stores wikiengine attributes. */ 134 private Map< String, Object > m_attributes = new ConcurrentHashMap<>(); 135 136 /** Stores WikiEngine's associated managers. */ 137 protected Map< Class< ? >, Object > managers = new ConcurrentHashMap<>(); 138 139 /** 140 * Gets a WikiEngine related to this servlet. Since this method is only called from JSP pages (and JspInit()) to be specific, 141 * we throw a RuntimeException if things don't work. 142 * 143 * @param config The ServletConfig object for this servlet. 144 * @return A WikiEngine instance. 145 * @throws InternalWikiException in case something fails. This is a RuntimeException, so be prepared for it. 146 */ 147 public static synchronized WikiEngine getInstance( final ServletConfig config ) throws InternalWikiException { 148 return getInstance( config.getServletContext(), null ); 149 } 150 151 /** 152 * Gets a WikiEngine related to the servlet. Works like getInstance(ServletConfig), but does not force the Properties object. 153 * This method is just an optional way of initializing a WikiEngine for embedded JSPWiki applications; normally, you 154 * should use getInstance(ServletConfig). 155 * 156 * @param config The ServletConfig of the webapp servlet/JSP calling this method. 157 * @param props A set of properties, or null, if we are to load JSPWiki's default jspwiki.properties (this is the usual case). 158 * 159 * @return One well-behaving WikiEngine instance. 160 */ 161 public static synchronized WikiEngine getInstance( final ServletConfig config, final Properties props ) { 162 return getInstance( config.getServletContext(), props ); 163 } 164 165 /** 166 * Gets a WikiEngine related to the servlet. Works just like getInstance( ServletConfig ) 167 * 168 * @param context The ServletContext of the webapp servlet/JSP calling this method. 169 * @param props A set of properties, or null, if we are to load JSPWiki's default jspwiki.properties (this is the usual case). 170 * @return One fully functional, properly behaving WikiEngine. 171 * @throws InternalWikiException If the WikiEngine instantiation fails. 172 */ 173 public static synchronized WikiEngine getInstance( final ServletContext context, Properties props ) throws InternalWikiException { 174 WikiEngine engine = ( WikiEngine )context.getAttribute( ATTR_WIKIENGINE ); 175 if( engine == null ) { 176 final String appid = Integer.toString( context.hashCode() ); 177 context.log(" Assigning new engine to "+appid); 178 try { 179 if( props == null ) { 180 props = PropertyReader.loadWebAppProps( context ); 181 } 182 183 engine = new WikiEngine( context, appid, props ); 184 context.setAttribute( ATTR_WIKIENGINE, engine ); 185 } catch( final Exception e ) { 186 context.log( "ERROR: Failed to create a Wiki engine: " + e.getMessage() ); 187 log.error( "ERROR: Failed to create a Wiki engine, stacktrace follows ", e ); 188 throw new InternalWikiException( "No wiki engine, check logs.", e ); 189 } 190 } 191 return engine; 192 } 193 194 /** 195 * Instantiate the WikiEngine using a given set of properties. Use this constructor for testing purposes only. 196 * 197 * @param properties A set of properties to use to initialize this WikiEngine. 198 * @throws WikiException If the initialization fails. 199 */ 200 public WikiEngine( final Properties properties ) throws WikiException { 201 initialize( properties ); 202 } 203 204 /** 205 * Instantiate using this method when you're running as a servlet and WikiEngine will figure out where to look for the property file. 206 * Do not use this method - use WikiEngine.getInstance() instead. 207 * 208 * @param context A ServletContext. 209 * @param appid An Application ID. This application is an unique random string which is used to recognize this WikiEngine. 210 * @param props The WikiEngine configuration. 211 * @throws WikiException If the WikiEngine construction fails. 212 */ 213 protected WikiEngine( final ServletContext context, final String appid, final Properties props ) throws WikiException { 214 m_servletContext = context; 215 m_appid = appid; 216 217 // Stash the WikiEngine in the servlet context 218 if ( context != null ) { 219 context.setAttribute( ATTR_WIKIENGINE, this ); 220 m_rootPath = context.getRealPath("/"); 221 } 222 223 try { 224 // Note: May be null, if JSPWiki has been deployed in a WAR file. 225 initialize( props ); 226 log.info( "Root path for this Wiki is: '" + m_rootPath + "'" ); 227 } catch( final Exception e ) { 228 final String msg = Release.APPNAME+": Unable to load and setup properties from jspwiki.properties. "+e.getMessage(); 229 if ( context != null ) { 230 context.log( msg ); 231 } 232 throw new WikiException( msg, e ); 233 } 234 } 235 236 /** 237 * Does all the real initialization. 238 */ 239 private void initialize( final Properties props ) throws WikiException { 240 m_startTime = new Date(); 241 m_properties = props; 242 243 log.info( "*******************************************" ); 244 log.info( Release.APPNAME + " " + Release.getVersionString() + " starting. Whee!" ); 245 246 fireEvent( WikiEngineEvent.INITIALIZING ); // begin initialization 247 248 log.debug( "Java version: " + System.getProperty( "java.runtime.version" ) ); 249 log.debug( "Java vendor: " + System.getProperty( "java.vm.vendor" ) ); 250 log.debug( "OS: " + System.getProperty( "os.name" ) + " " + System.getProperty( "os.version" ) + " " + System.getProperty( "os.arch" ) ); 251 log.debug( "Default server locale: " + Locale.getDefault() ); 252 log.debug( "Default server timezone: " + TimeZone.getDefault().getDisplayName( true, TimeZone.LONG ) ); 253 254 if( m_servletContext != null ) { 255 log.info( "Servlet container: " + m_servletContext.getServerInfo() ); 256 if( m_servletContext.getMajorVersion() < 3 || ( m_servletContext.getMajorVersion() == 3 && m_servletContext.getMinorVersion() < 1 ) ) { 257 throw new InternalWikiException( "JSPWiki requires a container which supports at least version 3.1 of Servlet specification" ); 258 } 259 } 260 261 log.debug( "Configuring WikiEngine..." ); 262 263 // Create and find the default working directory. 264 m_workDir = TextUtil.getStringProperty( props, PROP_WORKDIR, null ); 265 266 if( m_workDir == null ) { 267 m_workDir = System.getProperty( "java.io.tmpdir", "." ); 268 m_workDir += File.separator + Release.APPNAME + "-" + m_appid; 269 } 270 271 try { 272 final File f = new File( m_workDir ); 273 f.mkdirs(); 274 275 // 276 // A bunch of sanity checks 277 // 278 if( !f.exists() ) { 279 throw new WikiException( "Work directory does not exist: " + m_workDir ); 280 } 281 if( !f.canRead() ) { 282 throw new WikiException( "No permission to read work directory: " + m_workDir ); 283 } 284 if( !f.canWrite() ) { 285 throw new WikiException( "No permission to write to work directory: " + m_workDir ); 286 } 287 if( !f.isDirectory() ) { 288 throw new WikiException( "jspwiki.workDir does not point to a directory: " + m_workDir ); 289 } 290 } catch( final SecurityException e ) { 291 log.fatal( "Unable to find or create the working directory: "+m_workDir, e ); 292 throw new IllegalArgumentException( "Unable to find or create the working dir: " + m_workDir, e ); 293 } 294 295 log.info( "JSPWiki working directory is '" + m_workDir + "'" ); 296 297 m_saveUserInfo = TextUtil.getBooleanProperty( props, PROP_STOREUSERNAME, m_saveUserInfo ); 298 m_useUTF8 = StandardCharsets.UTF_8.name().equals( TextUtil.getStringProperty( props, PROP_ENCODING, StandardCharsets.ISO_8859_1.name() ) ); 299 m_templateDir = TextUtil.getStringProperty( props, PROP_TEMPLATEDIR, "default" ); 300 enforceValidTemplateDirectory(); 301 m_frontPage = TextUtil.getStringProperty( props, PROP_FRONTPAGE, "Main" ); 302 303 // 304 // Initialize the important modules. Any exception thrown by the managers means that we will not start up. 305 // 306 try { 307 final String aclClassName = m_properties.getProperty( PROP_ACL_MANAGER_IMPL, ClassUtil.getMappedClass( AclManager.class.getName() ).getName() ); 308 final String urlConstructorClassName = TextUtil.getStringProperty( props, PROP_URLCONSTRUCTOR, "DefaultURLConstructor" ); 309 final Class< ? > urlclass = ClassUtil.findClass( "org.apache.wiki.url", urlConstructorClassName ); 310 311 initComponent( CommandResolver.class, this, props ); 312 initComponent( urlclass.getName(), URLConstructor.class ); 313 initComponent( PageManager.class, this, props ); 314 initComponent( PluginManager.class, this, props ); 315 initComponent( DifferenceManager.class, this, props ); 316 initComponent( AttachmentManager.class, this, props ); 317 initComponent( VariableManager.class, props ); 318 initComponent( SearchManager.class, this, props ); 319 initComponent( AuthenticationManager.class ); 320 initComponent( AuthorizationManager.class ); 321 initComponent( UserManager.class ); 322 initComponent( GroupManager.class ); 323 initComponent( EditorManager.class, this ); 324 initComponent( ProgressManager.class, this ); 325 initComponent( aclClassName, AclManager.class ); 326 initComponent( WorkflowManager.class ); 327 initComponent( TasksManager.class ); 328 initComponent( InternationalizationManager.class, this ); 329 initComponent( TemplateManager.class, this, props ); 330 initComponent( FilterManager.class, this, props ); 331 initComponent( AdminBeanManager.class, this ); 332 initComponent( PageRenamer.class, this, props ); 333 334 // RenderingManager depends on FilterManager events. 335 initComponent( RenderingManager.class ); 336 337 // ReferenceManager has the side effect of loading all pages. Therefore after this point, all page attributes are available. 338 // initReferenceManager is indirectly using m_filterManager, therefore it has to be called after it was initialized. 339 initReferenceManager(); 340 341 // Hook the different manager routines into the system. 342 getManager( FilterManager.class ).addPageFilter( getManager( ReferenceManager.class ), -1001 ); 343 getManager( FilterManager.class ).addPageFilter( getManager( SearchManager.class ), -1002 ); 344 } catch( final RuntimeException e ) { 345 // RuntimeExceptions may occur here, even if they shouldn't. 346 log.fatal( "Failed to start managers.", e ); 347 throw new WikiException( "Failed to start managers: " + e.getMessage(), e ); 348 } catch( final ClassNotFoundException e ) { 349 log.fatal( "JSPWiki could not start, URLConstructor was not found: " + e.getMessage(), e ); 350 throw new WikiException( e.getMessage(), e ); 351 } catch( final InstantiationException e ) { 352 log.fatal( "JSPWiki could not start, URLConstructor could not be instantiated: " + e.getMessage(), e ); 353 throw new WikiException( e.getMessage(), e ); 354 } catch( final IllegalAccessException e ) { 355 log.fatal( "JSPWiki could not start, URLConstructor cannot be accessed: " + e.getMessage(), e ); 356 throw new WikiException( e.getMessage(), e ); 357 } catch( final Exception e ) { 358 // Final catch-all for everything 359 log.fatal( "JSPWiki could not start, due to an unknown exception when starting.",e ); 360 throw new WikiException( "Failed to start. Caused by: " + e.getMessage() + "; please check log files for better information.", e ); 361 } 362 363 // Initialize the good-to-have-but-not-fatal modules. 364 try { 365 if( TextUtil.getBooleanProperty( props, RSSGenerator.PROP_GENERATE_RSS,false ) ) { 366 initComponent( RSSGenerator.class, this, props ); 367 } 368 } catch( final Exception e ) { 369 log.error( "Unable to start RSS generator - JSPWiki will still work, but there will be no RSS feed.", e ); 370 } 371 372 final Map< String, String > extraComponents = ClassUtil.getExtraClassMappings(); 373 initExtraComponents( extraComponents ); 374 375 fireEvent( WikiEngineEvent.INITIALIZED ); // initialization complete 376 377 log.info( "WikiEngine configured." ); 378 m_isConfigured = true; 379 } 380 381 void initExtraComponents( final Map< String, String > extraComponents ) { 382 for( final Map.Entry< String, String > extraComponent : extraComponents.entrySet() ) { 383 try { 384 log.info( "Registering on WikiEngine " + extraComponent.getKey() + " as " + extraComponent.getValue() ); 385 initComponent( extraComponent.getKey(), Class.forName( extraComponent.getValue() ) ); 386 } catch( final Exception e ) { 387 log.error( "Unable to start " + extraComponent.getKey(), e ); 388 } 389 } 390 } 391 392 < T > void initComponent( final Class< T > componentClass, final Object... initArgs ) throws Exception { 393 initComponent( componentClass.getName(), componentClass, initArgs ); 394 } 395 396 < T > void initComponent( final String componentInitClass, final Class< T > componentClass, final Object... initArgs ) throws Exception { 397 final T component; 398 if( initArgs == null || initArgs.length == 0 ) { 399 component = ClassUtil.getMappedObject( componentInitClass ); 400 } else { 401 component = ClassUtil.getMappedObject( componentInitClass, initArgs ); 402 } 403 managers.put( componentClass, component ); 404 if( Initializable.class.isAssignableFrom( componentClass ) ) { 405 ( ( Initializable )component ).initialize( this, m_properties ); 406 } 407 } 408 409 /** {@inheritDoc} */ 410 @Override 411 @SuppressWarnings( "unchecked" ) 412 public < T > T getManager( final Class< T > manager ) { 413 return ( T )managers.entrySet().stream() 414 .filter( e -> manager.isAssignableFrom( e.getKey() ) ) 415 .map( Map.Entry::getValue ) 416 .findFirst().orElse( null ); 417 } 418 419 /** {@inheritDoc} */ 420 @Override 421 @SuppressWarnings( "unchecked" ) 422 public < T > List< T > getManagers( final Class< T > manager ) { 423 return ( List< T > )managers.entrySet().stream() 424 .filter( e -> manager.isAssignableFrom( e.getKey() ) ) 425 .map( Map.Entry::getValue ) 426 .collect( Collectors.toList() ); 427 } 428 429 /** {@inheritDoc} */ 430 @Override 431 public boolean isConfigured() { 432 return m_isConfigured; 433 } 434 435 /** 436 * Checks if the template directory specified in the wiki's properties actually exists. If it doesn't, then {@code m_templateDir} is 437 * set to {@link #DEFAULT_TEMPLATE_NAME}. 438 * <p> 439 * This checks the existence of the <tt>ViewTemplate.jsp</tt> file, which exists in every template using {@code m_servletContext.getRealPath("/")}. 440 * <p> 441 * {@code m_servletContext.getRealPath("/")} can return {@code null} on certain servers/conditions (f.ex, packed wars), an extra check 442 * against {@code m_servletContext.getResource} is made. 443 */ 444 void enforceValidTemplateDirectory() { 445 if( m_servletContext != null ) { 446 final String viewTemplate = "templates" + File.separator + getTemplateDir() + File.separator + "ViewTemplate.jsp"; 447 boolean exists = new File( m_servletContext.getRealPath("/") + viewTemplate ).exists(); 448 if( !exists ) { 449 try { 450 final URL url = m_servletContext.getResource( viewTemplate ); 451 exists = url != null && StringUtils.isNotEmpty( url.getFile() ); 452 } catch( final MalformedURLException e ) { 453 log.warn( "template not found with viewTemplate " + viewTemplate ); 454 } 455 } 456 if( !exists ) { 457 log.warn( getTemplateDir() + " template not found, updating WikiEngine's default template to " + DEFAULT_TEMPLATE_NAME ); 458 m_templateDir = DEFAULT_TEMPLATE_NAME; 459 } 460 } 461 } 462 463 /** 464 * Initializes the reference manager. Scans all existing WikiPages for 465 * internal links and adds them to the ReferenceManager object. 466 * 467 * @throws WikiException If the reference manager initialization fails. 468 */ 469 public void initReferenceManager() throws WikiException { 470 try { 471 // Build a new manager with default key lists. 472 if( getManager( ReferenceManager.class ) == null ) { 473 final ArrayList< Page > pages = new ArrayList<>(); 474 pages.addAll( getManager( PageManager.class ).getAllPages() ); 475 pages.addAll( getManager( AttachmentManager.class ).getAllAttachments() ); 476 initComponent( ReferenceManager.class, this ); 477 478 getManager( ReferenceManager.class ).initialize( pages ); 479 } 480 481 } catch( final ProviderException e ) { 482 log.fatal("PageProvider is unable to list pages: ", e); 483 } catch( final Exception e ) { 484 throw new WikiException( "Could not instantiate ReferenceManager: " + e.getMessage(), e ); 485 } 486 } 487 488 /** {@inheritDoc} */ 489 @Override 490 public Properties getWikiProperties() { 491 return m_properties; 492 } 493 494 /** {@inheritDoc} */ 495 @Override 496 public String getWorkDir() { 497 return m_workDir; 498 } 499 500 /** {@inheritDoc} */ 501 @Override 502 public String getTemplateDir() { 503 return m_templateDir; 504 } 505 506 /** {@inheritDoc} */ 507 @Override 508 public Date getStartTime() { 509 return ( Date )m_startTime.clone(); 510 } 511 512 /** {@inheritDoc} */ 513 @Override 514 public String getBaseURL() { 515 return m_servletContext.getContextPath(); 516 } 517 518 /** {@inheritDoc} */ 519 @Override 520 public String getGlobalRSSURL() { 521 final RSSGenerator rssGenerator = getManager( RSSGenerator.class ); 522 if( rssGenerator != null && rssGenerator.isEnabled() ) { 523 return getBaseURL() + "/" + rssGenerator.getRssFile(); 524 } 525 526 return null; 527 } 528 529 /** {@inheritDoc} */ 530 @Override 531 public String getInterWikiURL( final String wikiName ) { 532 return TextUtil.getStringProperty( m_properties,PROP_INTERWIKIREF + wikiName,null ); 533 } 534 535 /** {@inheritDoc} */ 536 @Override 537 public String getURL( final String context, String pageName, final String params ) { 538 if( pageName == null ) { 539 pageName = getFrontPage(); 540 } 541 final URLConstructor urlConstructor = getManager( URLConstructor.class ); 542 return urlConstructor.makeURL( context, pageName, params ); 543 } 544 545 /** {@inheritDoc} */ 546 @Override 547 public String getFrontPage() { 548 return m_frontPage; 549 } 550 551 /** {@inheritDoc} */ 552 @Override 553 public ServletContext getServletContext() { 554 return m_servletContext; 555 } 556 557 /** {@inheritDoc} */ 558 @Override 559 public Collection< String > getAllInterWikiLinks() { 560 final ArrayList< String > list = new ArrayList<>(); 561 for( final Enumeration< ? > i = m_properties.propertyNames(); i.hasMoreElements(); ) { 562 final String prop = ( String )i.nextElement(); 563 if( prop.startsWith( PROP_INTERWIKIREF ) ) { 564 list.add( prop.substring( prop.lastIndexOf( "." ) + 1 ) ); 565 } 566 } 567 568 return list; 569 } 570 571 /** {@inheritDoc} */ 572 @Override 573 public Collection< String > getAllInlinedImagePatterns() { 574 final ArrayList< String > ptrnlist = new ArrayList<>(); 575 for( final Enumeration< ? > e = m_properties.propertyNames(); e.hasMoreElements(); ) { 576 final String name = ( String )e.nextElement(); 577 if( name.startsWith( PROP_INLINEIMAGEPTRN ) ) { 578 ptrnlist.add( TextUtil.getStringProperty( m_properties, name, null ) ); 579 } 580 } 581 582 if( ptrnlist.isEmpty() ) { 583 ptrnlist.add( DEFAULT_INLINEPATTERN ); 584 } 585 586 return ptrnlist; 587 } 588 589 /** {@inheritDoc} */ 590 @Override 591 public String getSpecialPageReference( final String original ) { 592 return getManager( CommandResolver.class ).getSpecialPageReference( original ); 593 } 594 595 /** {@inheritDoc} */ 596 @Override 597 public String getApplicationName() { 598 final String appName = TextUtil.getStringProperty( m_properties, PROP_APPNAME, Release.APPNAME ); 599 return TextUtil.cleanString( appName, TextUtil.PUNCTUATION_CHARS_ALLOWED ); 600 } 601 602 /** {@inheritDoc} */ 603 @Override 604 public String getFinalPageName( final String page ) throws ProviderException { 605 return getManager( CommandResolver.class ).getFinalPageName( page ); 606 } 607 608 /** {@inheritDoc} */ 609 @Override 610 public String encodeName( final String pagename ) { 611 try { 612 return URLEncoder.encode( pagename, m_useUTF8 ? "UTF-8" : "ISO-8859-1" ); 613 } catch( final UnsupportedEncodingException e ) { 614 throw new InternalWikiException( "ISO-8859-1 not a supported encoding!?! Your platform is borked." , e); 615 } 616 } 617 618 /** {@inheritDoc} */ 619 @Override 620 public String decodeName( final String pagerequest ) { 621 try { 622 return URLDecoder.decode( pagerequest, m_useUTF8 ? "UTF-8" : "ISO-8859-1" ); 623 } catch( final UnsupportedEncodingException e ) { 624 throw new InternalWikiException("ISO-8859-1 not a supported encoding!?! Your platform is borked.", e); 625 } 626 } 627 628 /** {@inheritDoc} */ 629 @Override 630 public Charset getContentEncoding() { 631 if( m_useUTF8 ) { 632 return StandardCharsets.UTF_8; 633 } 634 return StandardCharsets.ISO_8859_1; 635 } 636 637 /** 638 * {@inheritDoc} 639 * <p>It is called by {@link WikiServlet#destroy()}. When this method is called, it fires a "shutdown" WikiEngineEvent to 640 * all registered listeners. 641 */ 642 @Override 643 public void shutdown() { 644 fireEvent( WikiEngineEvent.SHUTDOWN ); 645 getManager( FilterManager.class ).destroy(); 646 } 647 648 /** 649 * Returns the current TemplateManager. 650 * 651 * @return A TemplateManager instance. 652 * @deprecated use {@code getManager( TemplateManager.class )} instead. 653 */ 654 @Deprecated 655 public TemplateManager getTemplateManager() { 656 return getManager( TemplateManager.class ); 657 } 658 659 /** 660 * Returns the {@link org.apache.wiki.workflow.WorkflowManager} associated with this WikiEngine. If the WikiEngine has not been 661 * initialized, this method will return <code>null</code>. 662 * 663 * @return the task queue 664 * @deprecated use {@code getManager( WorkflowManager.class )} instead. 665 */ 666 @Deprecated 667 public WorkflowManager getWorkflowManager() { 668 return getManager( WorkflowManager.class ); 669 } 670 671 /** 672 * Returns this object's ReferenceManager. 673 * 674 * @return The current ReferenceManager instance. 675 * @since 1.6.1 676 * @deprecated use {@code getManager( ReferenceManager.class )} instead. 677 */ 678 @Deprecated 679 public ReferenceManager getReferenceManager() { 680 return getManager( ReferenceManager.class ); 681 } 682 683 /** 684 * Returns the current rendering manager for this wiki application. 685 * 686 * @since 2.3.27 687 * @return A RenderingManager object. 688 * @deprecated use {@code getManager( RenderingManager.class )} instead. 689 */ 690 @Deprecated 691 public RenderingManager getRenderingManager() { 692 return getManager( RenderingManager.class ); 693 } 694 695 /** 696 * Returns the current plugin manager. 697 * 698 * @since 1.6.1 699 * @return The current PluginManager instance 700 * @deprecated use {@code getManager( PluginManager.class )} instead. 701 */ 702 @Deprecated 703 public PluginManager getPluginManager() { 704 return getManager( PluginManager.class ); 705 } 706 707 /** 708 * Returns the current variable manager. 709 * 710 * @return The current VariableManager. 711 * @deprecated use {@code getManager( VariableManager.class )} instead. 712 */ 713 @Deprecated 714 public VariableManager getVariableManager() { 715 return getManager( VariableManager.class ); 716 } 717 718 /** 719 * Returns the current PageManager which is responsible for storing and managing WikiPages. 720 * 721 * @return The current PageManager instance. 722 * @deprecated use {@code getManager( PageManager.class )} instead. 723 */ 724 @Deprecated 725 public PageManager getPageManager() { 726 return getManager( PageManager.class ); 727 } 728 729 /** 730 * Returns the CommandResolver for this wiki engine. 731 * 732 * @return the resolver 733 * @deprecated use {@code getManager( CommandResolver.class )} instead. 734 */ 735 @Deprecated 736 public CommandResolver getCommandResolver() { 737 return getManager( CommandResolver.class ); 738 } 739 740 /** 741 * Returns the current AttachmentManager, which is responsible for storing and managing attachments. 742 * 743 * @since 1.9.31. 744 * @return The current AttachmentManager instance 745 * @deprecated use {@code getManager( AttachmentManager.class )} instead. 746 */ 747 @Deprecated 748 public AttachmentManager getAttachmentManager() { 749 return getManager( AttachmentManager.class ); 750 } 751 752 /** 753 * Returns the currently used authorization manager. 754 * 755 * @return The current AuthorizationManager instance. 756 * @deprecated use {@code getManager( AuthorizationManager.class )} instead. 757 */ 758 @Deprecated 759 public AuthorizationManager getAuthorizationManager() { 760 return getManager( AuthorizationManager.class ); 761 } 762 763 /** 764 * Returns the currently used authentication manager. 765 * 766 * @return The current AuthenticationManager instance. 767 * @deprecated use {@code getManager( AuthenticationManager.class )} instead. 768 */ 769 @Deprecated 770 public AuthenticationManager getAuthenticationManager() { 771 return getManager( AuthenticationManager.class ); 772 } 773 774 /** 775 * Returns the manager responsible for the filters. 776 * 777 * @since 2.1.88 778 * @return The current FilterManager instance. 779 * @deprecated use {@code getManager( FilterManager.class )} instead. 780 */ 781 @Deprecated 782 public FilterManager getFilterManager() { 783 return getManager( FilterManager.class ); 784 } 785 786 /** 787 * Returns the manager responsible for searching the Wiki. 788 * 789 * @since 2.2.21 790 * @return The current SearchManager instance. 791 * @deprecated use {@code getManager( SearchManager.class )} instead. 792 */ 793 @Deprecated 794 public SearchManager getSearchManager() { 795 return getManager( SearchManager.class ); 796 } 797 798 /** 799 * Returns the progress manager we're using 800 * 801 * @return A ProgressManager. 802 * @since 2.6 803 * @deprecated use {@code getManager( ProgressManager.class )} instead. 804 */ 805 @Deprecated 806 public ProgressManager getProgressManager() { 807 return getManager( ProgressManager.class ); 808 } 809 810 /** {@inheritDoc} */ 811 @Override 812 public String getRootPath() { 813 return m_rootPath; 814 } 815 816 /** 817 * @since 2.2.6 818 * @return the URL constructor. 819 * @deprecated use {@code getManager( URLConstructor.class )} instead. 820 */ 821 @Deprecated 822 public URLConstructor getURLConstructor() { 823 return getManager( URLConstructor.class ); 824 } 825 826 /** 827 * Returns the RSSGenerator. If the property <code>jspwiki.rss.generate</code> has not been set to <code>true</code>, this method 828 * will return <code>null</code>, <em>and callers should check for this value.</em> 829 * 830 * @since 2.1.165 831 * @return the RSS generator 832 * @deprecated use {@code getManager( RSSGenerator.class )} instead. 833 */ 834 @Deprecated 835 public RSSGenerator getRSSGenerator() { 836 return getManager( RSSGenerator.class ); 837 } 838 839 /** 840 * Returns the PageRenamer employed by this WikiEngine. 841 * 842 * @since 2.5.141 843 * @return The current PageRenamer instance. 844 * @deprecated use {@code getManager( PageRenamer.class )} instead. 845 */ 846 @Deprecated 847 public PageRenamer getPageRenamer() { 848 return getManager( PageRenamer.class ); 849 } 850 851 /** 852 * Returns the UserManager employed by this WikiEngine. 853 * 854 * @since 2.3 855 * @return The current UserManager instance. 856 * @deprecated use {@code getManager( UserManager.class )} instead. 857 */ 858 @Deprecated 859 public UserManager getUserManager() { 860 return getManager( UserManager.class ); 861 } 862 863 /** 864 * Returns the TasksManager employed by this WikiEngine. 865 * 866 * @return The current TasksManager instance. 867 * @deprecated use {@code getManager( TaskManager.class )} instead. 868 */ 869 @Deprecated 870 public TasksManager getTasksManager() { 871 return getManager( TasksManager.class ); 872 } 873 874 /** 875 * Returns the GroupManager employed by this WikiEngine. 876 * 877 * @since 2.3 878 * @return The current GroupManager instance. 879 * @deprecated use {@code getManager( GroupManager.class )} instead. 880 */ 881 @Deprecated 882 public GroupManager getGroupManager() { 883 return getManager( GroupManager.class ); 884 } 885 886 /** 887 * Returns the current {@link AdminBeanManager}. 888 * 889 * @return The current {@link AdminBeanManager}. 890 * @since 2.6 891 * @deprecated use {@code getManager( AdminBeanManager.class )} instead. 892 */ 893 @Deprecated 894 public AdminBeanManager getAdminBeanManager() { 895 return getManager( AdminBeanManager.class ); 896 } 897 898 /** 899 * Returns the AclManager employed by this WikiEngine. The AclManager is lazily initialized. 900 * <p> 901 * The AclManager implementing class may be set by the System property {@link #PROP_ACL_MANAGER_IMPL}. 902 * </p> 903 * 904 * @since 2.3 905 * @return The current AclManager. 906 * @deprecated use {@code getManager( AclManager.class )} instead. 907 */ 908 @Deprecated 909 public AclManager getAclManager() { 910 return getManager( AclManager.class ); 911 } 912 913 /** 914 * Returns the DifferenceManager so that texts can be compared. 915 * 916 * @return the difference manager. 917 * @deprecated use {@code getManager( DifferenceManager.class )} instead. 918 */ 919 @Deprecated 920 public DifferenceManager getDifferenceManager() { 921 return getManager( DifferenceManager.class ); 922 } 923 924 /** 925 * Returns the current EditorManager instance. 926 * 927 * @return The current EditorManager. 928 * @deprecated use {@code getManager( EditorManager.class )} instead. 929 */ 930 @Deprecated 931 public EditorManager getEditorManager() { 932 return getManager( EditorManager.class ); 933 } 934 935 /** 936 * Returns the current i18n manager. 937 * 938 * @return The current Intertan... Interante... Internatatializ... Whatever. 939 * @deprecated use {@code getManager( InternationalizationManager.class )} instead. 940 */ 941 @Deprecated 942 public InternationalizationManager getInternationalizationManager() { 943 return getManager( InternationalizationManager.class ); 944 } 945 946 /** {@inheritDoc} */ 947 @Override 948 public final synchronized void addWikiEventListener( final WikiEventListener listener ) { 949 WikiEventManager.addWikiEventListener( this, listener ); 950 } 951 952 /** {@inheritDoc} */ 953 @Override 954 public final synchronized void removeWikiEventListener( final WikiEventListener listener ) { 955 WikiEventManager.removeWikiEventListener( this, listener ); 956 } 957 958 /** 959 * Fires a WikiEngineEvent to all registered listeners. 960 * 961 * @param type the event type 962 */ 963 protected final void fireEvent( final int type ) { 964 if( WikiEventManager.isListening(this ) ) { 965 WikiEventManager.fireEvent( this, new WikiEngineEvent(this, type ) ); 966 } 967 } 968 969 /** 970 * Fires a WikiPageEvent to all registered listeners. 971 * 972 * @param type the event type 973 */ 974 protected final void firePageEvent( final int type, final String pageName ) { 975 if( WikiEventManager.isListening(this ) ) { 976 WikiEventManager.fireEvent(this,new WikiPageEvent(this, type, pageName ) ); 977 } 978 } 979 980 /** {@inheritDoc} */ 981 @Override 982 public void setAttribute( final String key, final Object value ) { 983 m_attributes.put( key, value ); 984 } 985 986 /** {@inheritDoc} */ 987 @Override 988 @SuppressWarnings( "unchecked" ) 989 public < T > T getAttribute( final String key ) { 990 return ( T )m_attributes.get( key ); 991 } 992 993 /** {@inheritDoc} */ 994 @Override 995 @SuppressWarnings( "unchecked" ) 996 public < T > T removeAttribute( final String key ) { 997 return ( T )m_attributes.remove( key ); 998 } 999 1000}