#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.

#
#  This file contains defaults for development.  If you are cross-
#  developing in multiple environments, just change the defaults
#  in this file.
#
#  Any changes in this file will be reflected in the default
#  jspwiki.properties-file when it is run.
#

1. JSPWiki API
==============

The package org.apache.wiki.api aims to provide an API to give access to JSPWiki internals.

1.1. API modules
----------------
api
 -> new package org.apache.wiki.api, which should compile without depending on other packages

api.exceptions
 -> new package org.apache.wiki.api.exceptions with copies of the original Exceptions declared by
    the API methods
 -> to retain backwards compatibility, "old" exceptions will inherit new ones, also the former ones 
    are marked as @Deprecated
      * e.g.: org.apache.wiki.plugin.PluginException will inherit 
        org.apache.wiki.api.exceptions.PluginException which (ultimately) inherits WikiException
      * note that, until the API is completed, regarding exceptions there will be an somewhat 
        awkward jump: org.apache.wiki.api.exceptions.*Exception -> org.apache.wiki.api.WikiException ->
        org.apache.wiki.WikiException. It allows us to achieve compatibility with 
        2.9 derived source (regarding exceptions).
        
api.filters
 -> Interface and base classes needed to develop WikiFilters
 -> cfr. with http://doc.jspwiki.org/2.4/wiki/WikiFilters
        
api.plugin
 -> Interfaces needed to develop WikiPlugins
 -> cfr. with http://www.jspwiki.org/wiki/WritingPlugins


1.2. Other classes affected
---------------------------
@Deprecated
 -> all classes / methods anotated with @Deprecated because of the API changes will be removed 
       in 2.10 timeframe

org.apache.wiki.WikiContext
 -> @Deprecated WikiContext.getBundle( String ) in favour of  
    Preferences.getBundle( String )
 -> @Deprecated WikiContext.getLocale( WikiContext ) in favour of  
    Preferences.getLocale( WikiContext )
 -> @Deprecated WikiContext.hasAccess( HttpServletResponse ) in favour of
    AuthorizationManager.hasAccess( HttpServletResponse )
 -> @Deprecated WikiContext.hasAccess( HttpServletResponse, boolean ) in favour of
    AuthorizationManager.hasAccess( HttpServletResponse, boolean )
    
org.apache.wiki.WikiEngine
 -> @Deprecated WikiEngine.getRequiredProperty( props, key ) in favour of  
    TextUtil.getRequiredProperty( props, key )
    
org.apache.wiki.FileUtil and org.apache.wiki.TextUtil
 -> Moved to org.apache.wiki.util.FileUtil and org.apache.wiki.util.TextUtil respectively
 -> original classes marked with @Deprecated and forwarding to the new ones until 2.10

org.apache.wiki.event.WorkflowEvent
 -> @Deprecated getWorkflow() in favour of the generified WikiEvent#getSrc()

org.apache.wiki.filters.FilterManager
 -> new interface org.apache.wiki.api.engine.FilterManager
 -> moved to org.apache.wiki.filters.DefaultFilterManager
 -> WikiEngine.getFilterManager returns org.apache.wiki.api.engine.FilterManager

org.apache.wiki.filters.BasicPageFilter
 -> moved to new class org.apache.wiki.api.filter.BasicPageFilter
 -> org.apache.wiki.filters.BasicPageFilter marked with @Deprecated + extends 
    org.apache.wiki.api.filter.BasicPageFilter
 
org.apache.wiki.filters.PageFilter
 -> moved to new interface org.apache.wiki.api.filter.PageFilter
 -> org.apache.wiki.filters.PageFilter marked with @Deprecated + extends 
    org.apache.wiki.api.filter.PageFilter
 -> all core wikifilters implementing the "old" interface now implement the new one

org.apache.wiki.parser.JSPWikiMarkupParser
 -> deprecated method public static Collection getImagePatterns( WikiEngine ) in favour of
    WikiEngine.getAllInlinedImagePatterns()
 -> deprecated constants DEFAULT_INLINEPATTERN and PROP_INLINEIMAGEPTRN. Consider using equivalent
    ones from WikiEngine

org.apache.wiki.parser.PluginContent
 -> getParameter returns String instead of Object (internally, it was returning a String)

org.apache.wiki.plugin.PluginManager
 -> new interface org.apache.wiki.api.engine.PluginManager
 -> moved to org.apache.wiki.plugin.DefaultPluginManager
 -> @Deprecated public static boolean isPluginLink( String link )
      * equivalent method on org.apache.wiki.parser.JSPWikiMarkupParser
 -> @Deprecated public void executeParse(PluginContent content, WikiContext context)
      * consider using PluginContent.executeParse(WikiContext) instead
 -> WikiPlugin newWikiPlugin( String pluginName, ResourceBundle rb ) is now public 
    and part of the org.apache.wiki.api.engine.PluginManager API
 -> WikiEngine.getPluginManager returns org.apache.wiki.api.engine.PluginManager

org.apache.wiki.plugin.InitializablePlugin
 -> new interface org.apache.wiki.api.plugin.InitializablePlugin
 -> all core wikiplugins and wikiforms implementing the "old" interface now implement the new one
 -> org.apache.wiki.plugin.InitializablePlugin marked with @Deprecated + extends
    org.apache.wiki.api.plugin.InitializablePlugin
 
org.apache.wiki.plugin.ParserStagePlugin
 -> new interface org.apache.wiki.api.plugins.ParserStagePlugin
 -> all core wikiplugins and wikiforms implementing the "old" interface now implement the new one
 -> org.apache.wiki.plugin.ParserStagePlugin marked with @Deprecated + extends
    org.apache.wiki.api.plugin.ParserStagePlugin
 
org.apache.wiki.plugin.WikiPlugin
 -> new interface org.apache.wiki.api.plugins.WikiPlugin
 -> all core wikiplugins and wikiforms implement the new interface
 -> org.apache.wiki.plugin.WikiPlugin marked with @Deprecated + extends 
    org.apache.wiki.api.plugin.WikiPlugin