This is an automated email from the ASF dual-hosted git repository. juanpablo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/jspwiki.git
commit 558e4916f7f956bfb99475c1de006a030d728776 Author: juanpablo <[email protected]> AuthorDate: Wed Feb 26 21:41:11 2020 +0100 JSPWIKI-120: rename + extract interfaces from InternationalizationManager, SearchManager, EditorManager and TemplateManager --- .../i18n/DefaultInternationalizationManager.java | 39 ++ .../wiki/i18n/InternationalizationManager.java | 24 +- ...earchManager.java => DefaultSearchManager.java} | 106 +----- .../java/org/apache/wiki/search/SearchManager.java | 289 +-------------- ...ditorManager.java => DefaultEditorManager.java} | 97 +---- .../org/apache/wiki/ui/DefaultTemplateManager.java | 353 +++++++++++++++++++ .../java/org/apache/wiki/ui/EditorManager.java | 162 +-------- .../java/org/apache/wiki/ui/TemplateManager.java | 392 +++------------------ .../src/main/resources/ini/classmappings.xml | 8 +- .../wiki/i18n/InternationalizationManagerTest.java | 10 +- 10 files changed, 518 insertions(+), 962 deletions(-) diff --git a/jspwiki-main/src/main/java/org/apache/wiki/i18n/DefaultInternationalizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/i18n/DefaultInternationalizationManager.java new file mode 100644 index 0000000..a05ba13 --- /dev/null +++ b/jspwiki-main/src/main/java/org/apache/wiki/i18n/DefaultInternationalizationManager.java @@ -0,0 +1,39 @@ +/* + 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. + */ +package org.apache.wiki.i18n; + +import org.apache.wiki.api.core.Engine; + + +/** + * Manages all internationalization in JSPWiki. + * + * @since 2.6 + */ +public class DefaultInternationalizationManager implements InternationalizationManager { + + /** + * Constructs a new InternationalizationManager. + * + * @param engine To which engine this belongs to + */ + public DefaultInternationalizationManager( final Engine engine ) { + } + +} diff --git a/jspwiki-main/src/main/java/org/apache/wiki/i18n/InternationalizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/i18n/InternationalizationManager.java index 6d2e07d..1feb01c 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/i18n/InternationalizationManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/i18n/InternationalizationManager.java @@ -18,8 +18,6 @@ */ package org.apache.wiki.i18n; -import org.apache.wiki.api.core.Engine; - import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; @@ -31,32 +29,24 @@ import java.util.ResourceBundle; * * @since 2.6 */ -public class InternationalizationManager { +public interface InternationalizationManager { /** The name of the ResourceBundle which contains any and all JSPWiki core resource strings. It's value is {@value}. */ - public static final String CORE_BUNDLE = "CoreResources"; + String CORE_BUNDLE = "CoreResources"; /** The name of the ResourceBundle which contains any and all JSPWiki default templates resource strings. It's value is {@value}. */ - public static final String DEF_TEMPLATE = "templates.default"; + String DEF_TEMPLATE = "templates.default"; // public static final String JSPWIKI_BUNDLE = "jspwiki"; // public static final String PLUGINS_BUNDLE = "plugins"; /** - * Constructs a new InternationalizationManager. - * - * @param engine To which engine this belongs to - */ - public InternationalizationManager( final Engine engine ) { - } - - /** * Returns a String from the CORE_BUNDLE using English as the default locale. * * @param key Key to find * @return The English string * @throws MissingResourceException If there is no such key */ - public String get( final String key ) throws MissingResourceException { + default String get( final String key ) throws MissingResourceException { return get( CORE_BUNDLE, Locale.ENGLISH, key ); } @@ -68,7 +58,7 @@ public class InternationalizationManager { * @return A localized string * @throws MissingResourceException If the key cannot be located at all, even from the default locale. */ - public ResourceBundle getBundle( final String bundle, Locale locale ) throws MissingResourceException { + default ResourceBundle getBundle( final String bundle, Locale locale ) throws MissingResourceException { if( locale == null ) { locale = Locale.getDefault(); } @@ -85,7 +75,7 @@ public class InternationalizationManager { * @return A localized string (or from the default language, if not found) * @throws MissingResourceException If the key cannot be located at all, even from the default locale. */ - public String get( final String bundle, final Locale locale, final String key ) throws MissingResourceException { + default String get( final String bundle, final Locale locale, final String key ) throws MissingResourceException { return getBundle( bundle, locale ).getString( key ); } @@ -99,7 +89,7 @@ public class InternationalizationManager { * @return A localized string (or from the default language, if not found) * @throws MissingResourceException If the key cannot be located at all, even from the default locale. */ - public String get( final String bundle, final Locale locale, final String key, final Object... args ) throws MissingResourceException { + default String get( final String bundle, final Locale locale, final String key, final Object... args ) throws MissingResourceException { final MessageFormat mf = new MessageFormat( get( bundle, locale, key ), locale ); return mf.format( args ); } diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java b/jspwiki-main/src/main/java/org/apache/wiki/search/DefaultSearchManager.java similarity index 75% copy from jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java copy to jspwiki-main/src/main/java/org/apache/wiki/search/DefaultSearchManager.java index dcc0eae..1831d92 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/search/DefaultSearchManager.java @@ -29,19 +29,15 @@ import org.apache.wiki.ajax.WikiAjaxServlet; import org.apache.wiki.api.core.Engine; import org.apache.wiki.api.exceptions.FilterException; import org.apache.wiki.api.exceptions.NoRequiredPropertyException; -import org.apache.wiki.api.exceptions.ProviderException; import org.apache.wiki.api.filters.BasicPageFilter; import org.apache.wiki.event.WikiEvent; -import org.apache.wiki.event.WikiEventListener; import org.apache.wiki.event.WikiEventManager; import org.apache.wiki.event.WikiPageEvent; -import org.apache.wiki.modules.InternalModule; import org.apache.wiki.pages.PageManager; import org.apache.wiki.parser.MarkupParser; import org.apache.wiki.references.ReferenceManager; import org.apache.wiki.util.ClassUtil; -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -54,24 +50,17 @@ import java.util.Map; import java.util.Properties; import java.util.Set; + /** * Manages searching the Wiki. * * @since 2.2.21. */ -public class SearchManager extends BasicPageFilter implements InternalModule, WikiEventListener { - - private static final Logger log = Logger.getLogger( SearchManager.class ); - - private static final String DEFAULT_SEARCHPROVIDER = "org.apache.wiki.search.LuceneSearchProvider"; +public class DefaultSearchManager extends BasicPageFilter implements SearchManager { - /** Property name for setting the search provider. Value is <tt>{@value}</tt>. */ - public static final String PROP_SEARCHPROVIDER = "jspwiki.searchProvider"; + private static final Logger log = Logger.getLogger( DefaultSearchManager.class ); - private SearchProvider m_searchProvider; - - /** The name of the JSON object that manages search. */ - public static final String JSON_SEARCH = "search"; + private SearchProvider m_searchProvider; /** * Creates a new SearchManager. @@ -80,16 +69,16 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi * @param properties The list of Properties. * @throws FilterException If it cannot be instantiated. */ - public SearchManager( final Engine engine, final Properties properties ) throws FilterException { + public DefaultSearchManager( final Engine engine, final Properties properties ) throws FilterException { initialize( engine, properties ); WikiEventManager.getInstance().addWikiEventListener( m_engine.getManager( PageManager.class ), this ); - //TODO: Replace with custom annotations. See JSPWIKI-566 + // TODO: Replace with custom annotations. See JSPWIKI-566 WikiAjaxDispatcherServlet.registerServlet( JSON_SEARCH, new JSONSearch() ); } /** - * Provides a JSON RPC API to the JSPWiki Search Engine. + * Provides a JSON AJAX API to the JSPWiki Search Engine. */ public class JSONSearch implements WikiAjaxServlet { @@ -98,16 +87,18 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi public static final int DEFAULT_MAX_RESULTS = 20; public int maxResults = DEFAULT_MAX_RESULTS; + /** {@inheritDoc} */ @Override public String getServletMapping() { return JSON_SEARCH; } + /** {@inheritDoc} */ @Override public void service( final HttpServletRequest req, final HttpServletResponse resp, final String actionName, - final List< String > params ) throws ServletException, IOException { + final List< String > params ) throws IOException { String result = ""; if( StringUtils.isNotBlank( actionName ) ) { if( params.size() < 1 ) { @@ -152,7 +143,6 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi final StopWatch sw = new StopWatch(); sw.start(); final List< String > list = new ArrayList<>( maxLength ); - if( wikiName.length() > 0 ) { // split pagename and attachment filename String filename = ""; @@ -199,7 +189,6 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi if( searchString.length() > 0 ) { try { final Collection< SearchResult > c; - if( m_searchProvider instanceof LuceneSearchProvider ) { c = ( ( LuceneSearchProvider )m_searchProvider ).findPages( searchString, 0, wikiContext ); } else { @@ -228,14 +217,7 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi } - /** - * This particular method starts off indexing and all sorts of various activities, - * so you need to run this last, after things are done. - * - * @param engine the wiki engine - * @param properties the properties used to initialize the wiki engine - * @throws FilterException if the search provider failed to initialize - */ + /** {@inheritDoc} */ @Override public void initialize( final Engine engine, final Properties properties ) throws FilterException { m_engine = engine; @@ -249,14 +231,12 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi } private void loadSearchProvider( final Properties properties ) { - // // See if we're using Lucene, and if so, ensure that its index directory is up to date. - // final String providerClassName = properties.getProperty( PROP_SEARCHPROVIDER, DEFAULT_SEARCHPROVIDER ); try { final Class<?> providerClass = ClassUtil.findClass( "org.apache.wiki.search", providerClassName ); - m_searchProvider = (SearchProvider)providerClass.newInstance(); + m_searchProvider = ( SearchProvider )providerClass.newInstance(); } catch( final ClassNotFoundException | InstantiationException | IllegalAccessException e ) { log.warn("Failed loading SearchProvider, will use BasicSearchProvider.", e); } @@ -268,70 +248,14 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi log.debug("Loaded search provider " + m_searchProvider); } - /** - * Returns the SearchProvider used. - * - * @return The current SearchProvider. - */ + /** {@inheritDoc} */ + @Override public SearchProvider getSearchEngine() { return m_searchProvider; } - /** - * Sends a search to the current search provider. The query is is whatever native format - * the query engine wants to use. - * - * @param query The query. Null is safe, and is interpreted as an empty query. - * @param wikiContext the context within which to run the search - * @return A collection of WikiPages that matched. - * @throws ProviderException If the provider fails and a search cannot be completed. - * @throws IOException If something else goes wrong. - */ - public Collection< SearchResult > findPages( String query, final WikiContext wikiContext ) throws ProviderException, IOException { - if( query == null ) { - query = ""; - } - return m_searchProvider.findPages( query, wikiContext ); - } - - /** - * Removes the page from the search cache (if any). - * @param page The page to remove - */ - public void pageRemoved( final WikiPage page ) - { - m_searchProvider.pageRemoved(page); - } - - /** - * Reindexes the page. - * - * @param wikiContext {@inheritDoc} - * @param content {@inheritDoc} - */ - @Override - public void postSave( final WikiContext wikiContext, final String content ) { - // Makes sure that we're indexing the latest version of this page. - final WikiPage p = m_engine.getManager( PageManager.class ).getPage( wikiContext.getPage().getName() ); - reindexPage( p ); - } - - /** - * Forces the reindex of the given page. - * - * @param page The page. - */ - public void reindexPage( final WikiPage page ) - { - m_searchProvider.reindexPage( page ); - } - - /** - * If the page has been deleted, removes it from the index. - * - * @param event {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public void actionPerformed( final WikiEvent event ) { if( event instanceof WikiPageEvent && event.getType() == WikiPageEvent.PAGE_DELETE_REQUEST ) { diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java b/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java index dcc0eae..131be40 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java @@ -18,269 +18,41 @@ */ package org.apache.wiki.search; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.StopWatch; -import org.apache.log4j.Logger; import org.apache.wiki.WikiContext; import org.apache.wiki.WikiPage; -import org.apache.wiki.ajax.AjaxUtil; -import org.apache.wiki.ajax.WikiAjaxDispatcherServlet; -import org.apache.wiki.ajax.WikiAjaxServlet; -import org.apache.wiki.api.core.Engine; -import org.apache.wiki.api.exceptions.FilterException; -import org.apache.wiki.api.exceptions.NoRequiredPropertyException; import org.apache.wiki.api.exceptions.ProviderException; -import org.apache.wiki.api.filters.BasicPageFilter; -import org.apache.wiki.event.WikiEvent; +import org.apache.wiki.api.filters.PageFilter; import org.apache.wiki.event.WikiEventListener; -import org.apache.wiki.event.WikiEventManager; -import org.apache.wiki.event.WikiPageEvent; import org.apache.wiki.modules.InternalModule; -import org.apache.wiki.pages.PageManager; -import org.apache.wiki.parser.MarkupParser; -import org.apache.wiki.references.ReferenceManager; -import org.apache.wiki.util.ClassUtil; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; + /** * Manages searching the Wiki. * * @since 2.2.21. */ -public class SearchManager extends BasicPageFilter implements InternalModule, WikiEventListener { - - private static final Logger log = Logger.getLogger( SearchManager.class ); +public interface SearchManager extends PageFilter, InternalModule, WikiEventListener { - private static final String DEFAULT_SEARCHPROVIDER = "org.apache.wiki.search.LuceneSearchProvider"; + String DEFAULT_SEARCHPROVIDER = "org.apache.wiki.search.LuceneSearchProvider"; /** Property name for setting the search provider. Value is <tt>{@value}</tt>. */ - public static final String PROP_SEARCHPROVIDER = "jspwiki.searchProvider"; - - private SearchProvider m_searchProvider; + String PROP_SEARCHPROVIDER = "jspwiki.searchProvider"; /** The name of the JSON object that manages search. */ - public static final String JSON_SEARCH = "search"; - - /** - * Creates a new SearchManager. - * - * @param engine The Engine that owns this SearchManager. - * @param properties The list of Properties. - * @throws FilterException If it cannot be instantiated. - */ - public SearchManager( final Engine engine, final Properties properties ) throws FilterException { - initialize( engine, properties ); - WikiEventManager.getInstance().addWikiEventListener( m_engine.getManager( PageManager.class ), this ); - - //TODO: Replace with custom annotations. See JSPWIKI-566 - WikiAjaxDispatcherServlet.registerServlet( JSON_SEARCH, new JSONSearch() ); - } - - /** - * Provides a JSON RPC API to the JSPWiki Search Engine. - */ - public class JSONSearch implements WikiAjaxServlet { - - public static final String AJAX_ACTION_SUGGESTIONS = "suggestions"; - public static final String AJAX_ACTION_PAGES = "pages"; - public static final int DEFAULT_MAX_RESULTS = 20; - public int maxResults = DEFAULT_MAX_RESULTS; - - @Override - public String getServletMapping() { - return JSON_SEARCH; - } - - @Override - public void service( final HttpServletRequest req, - final HttpServletResponse resp, - final String actionName, - final List< String > params ) throws ServletException, IOException { - String result = ""; - if( StringUtils.isNotBlank( actionName ) ) { - if( params.size() < 1 ) { - return; - } - final String itemId = params.get( 0 ); - log.debug( "itemId=" + itemId ); - if( params.size() > 1 ) { - final String maxResultsParam = params.get( 1 ); - log.debug( "maxResultsParam=" + maxResultsParam ); - if( StringUtils.isNotBlank( maxResultsParam ) && StringUtils.isNumeric( maxResultsParam ) ) { - maxResults = Integer.parseInt( maxResultsParam ); - } - } - - if( actionName.equals( AJAX_ACTION_SUGGESTIONS ) ) { - log.debug( "Calling getSuggestions() START" ); - final List< String > callResults = getSuggestions( itemId, maxResults ); - log.debug( "Calling getSuggestions() DONE. " + callResults.size() ); - result = AjaxUtil.toJson( callResults ); - } else if( actionName.equals( AJAX_ACTION_PAGES ) ) { - log.debug("Calling findPages() START"); - final WikiContext wikiContext = new WikiContext( m_engine, req, WikiContext.VIEW ); - final List< Map< String, Object > > callResults = findPages( itemId, maxResults, wikiContext ); - log.debug( "Calling findPages() DONE. " + callResults.size() ); - result = AjaxUtil.toJson( callResults ); - } - } - log.debug( "result=" + result ); - resp.getWriter().write( result ); - } - - /** - * Provides a list of suggestions to use for a page name. Currently the algorithm just looks into the value parameter, - * and returns all page names from that. - * - * @param wikiName the page name - * @param maxLength maximum number of suggestions - * @return the suggestions - */ - public List< String > getSuggestions( String wikiName, final int maxLength ) { - final StopWatch sw = new StopWatch(); - sw.start(); - final List< String > list = new ArrayList<>( maxLength ); - - if( wikiName.length() > 0 ) { - // split pagename and attachment filename - String filename = ""; - final int pos = wikiName.indexOf("/"); - if( pos >= 0 ) { - filename = wikiName.substring( pos ).toLowerCase(); - wikiName = wikiName.substring( 0, pos ); - } - - final String cleanWikiName = MarkupParser.cleanLink(wikiName).toLowerCase() + filename; - final String oldStyleName = MarkupParser.wikifyLink(wikiName).toLowerCase() + filename; - final Set< String > allPages = m_engine.getManager( ReferenceManager.class ).findCreated(); - - int counter = 0; - for( final Iterator< String > i = allPages.iterator(); i.hasNext() && counter < maxLength; ) { - final String p = i.next(); - final String pp = p.toLowerCase(); - if( pp.startsWith( cleanWikiName) || pp.startsWith( oldStyleName ) ) { - list.add( p ); - counter++; - } - } - } - - sw.stop(); - if( log.isDebugEnabled() ) { - log.debug( "Suggestion request for " + wikiName + " done in " + sw ); - } - return list; - } - - /** - * Performs a full search of pages. - * - * @param searchString The query string - * @param maxLength How many hits to return - * @return the pages found - */ - public List< Map< String, Object > > findPages( final String searchString, final int maxLength, final WikiContext wikiContext ) { - final StopWatch sw = new StopWatch(); - sw.start(); - - final List< Map< String, Object > > list = new ArrayList<>( maxLength ); - if( searchString.length() > 0 ) { - try { - final Collection< SearchResult > c; - - if( m_searchProvider instanceof LuceneSearchProvider ) { - c = ( ( LuceneSearchProvider )m_searchProvider ).findPages( searchString, 0, wikiContext ); - } else { - c = m_searchProvider.findPages( searchString, wikiContext ); - } - - int count = 0; - for( final Iterator< SearchResult > i = c.iterator(); i.hasNext() && count < maxLength; count++ ) { - final SearchResult sr = i.next(); - final HashMap< String, Object > hm = new HashMap<>(); - hm.put( "page", sr.getPage().getName() ); - hm.put( "score", sr.getScore() ); - list.add( hm ); - } - } catch( final Exception e ) { - log.info( "AJAX search failed; ", e ); - } - } - - sw.stop(); - if( log.isDebugEnabled() ) { - log.debug( "AJAX search complete in " + sw ); - } - return list; - } - } - - - /** - * This particular method starts off indexing and all sorts of various activities, - * so you need to run this last, after things are done. - * - * @param engine the wiki engine - * @param properties the properties used to initialize the wiki engine - * @throws FilterException if the search provider failed to initialize - */ - @Override - public void initialize( final Engine engine, final Properties properties ) throws FilterException { - m_engine = engine; - loadSearchProvider(properties); - - try { - m_searchProvider.initialize( engine, properties ); - } catch( final NoRequiredPropertyException | IOException e ) { - log.error( e.getMessage(), e ); - } - } - - private void loadSearchProvider( final Properties properties ) { - // - // See if we're using Lucene, and if so, ensure that its index directory is up to date. - // - final String providerClassName = properties.getProperty( PROP_SEARCHPROVIDER, DEFAULT_SEARCHPROVIDER ); - - try { - final Class<?> providerClass = ClassUtil.findClass( "org.apache.wiki.search", providerClassName ); - m_searchProvider = (SearchProvider)providerClass.newInstance(); - } catch( final ClassNotFoundException | InstantiationException | IllegalAccessException e ) { - log.warn("Failed loading SearchProvider, will use BasicSearchProvider.", e); - } - - if( null == m_searchProvider ) { - // FIXME: Make a static with the default search provider - m_searchProvider = new BasicSearchProvider(); - } - log.debug("Loaded search provider " + m_searchProvider); - } + String JSON_SEARCH = "search"; /** * Returns the SearchProvider used. * * @return The current SearchProvider. */ - public SearchProvider getSearchEngine() - { - return m_searchProvider; - } + SearchProvider getSearchEngine(); /** - * Sends a search to the current search provider. The query is is whatever native format - * the query engine wants to use. + * Sends a search to the current search provider. The query is is whatever native format the query engine wants to use. * * @param query The query. Null is safe, and is interpreted as an empty query. * @param wikiContext the context within which to run the search @@ -288,33 +60,20 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi * @throws ProviderException If the provider fails and a search cannot be completed. * @throws IOException If something else goes wrong. */ - public Collection< SearchResult > findPages( String query, final WikiContext wikiContext ) throws ProviderException, IOException { + default Collection< SearchResult > findPages( String query, final WikiContext wikiContext ) throws ProviderException, IOException { if( query == null ) { query = ""; } - return m_searchProvider.findPages( query, wikiContext ); + return getSearchEngine().findPages( query, wikiContext ); } /** * Removes the page from the search cache (if any). - * @param page The page to remove - */ - public void pageRemoved( final WikiPage page ) - { - m_searchProvider.pageRemoved(page); - } - - /** - * Reindexes the page. * - * @param wikiContext {@inheritDoc} - * @param content {@inheritDoc} + * @param page The page to remove */ - @Override - public void postSave( final WikiContext wikiContext, final String content ) { - // Makes sure that we're indexing the latest version of this page. - final WikiPage p = m_engine.getManager( PageManager.class ).getPage( wikiContext.getPage().getName() ); - reindexPage( p ); + default void pageRemoved( final WikiPage page ) { + getSearchEngine().pageRemoved( page ); } /** @@ -322,26 +81,8 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi * * @param page The page. */ - public void reindexPage( final WikiPage page ) - { - m_searchProvider.reindexPage( page ); - } - - /** - * If the page has been deleted, removes it from the index. - * - * @param event {@inheritDoc} - */ - @Override - public void actionPerformed( final WikiEvent event ) { - if( event instanceof WikiPageEvent && event.getType() == WikiPageEvent.PAGE_DELETE_REQUEST ) { - final String pageName = ( ( WikiPageEvent ) event ).getPageName(); - - final WikiPage p = m_engine.getManager( PageManager.class ).getPage( pageName ); - if( p != null ) { - pageRemoved( p ); - } - } + default void reindexPage( final WikiPage page ) { + getSearchEngine().reindexPage( page ); } } diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/EditorManager.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultEditorManager.java similarity index 63% copy from jspwiki-main/src/main/java/org/apache/wiki/ui/EditorManager.java copy to jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultEditorManager.java index 9d173fd..71a1cb4 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/ui/EditorManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultEditorManager.java @@ -29,7 +29,6 @@ import org.apache.wiki.util.XmlUtil; import org.apache.wiki.variables.VariableManager; import org.jdom2.Element; -import javax.servlet.jsp.PageContext; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -56,55 +55,28 @@ import java.util.Set; * * @since 2.4 */ -public class EditorManager extends ModuleManager { - - /** The property name for setting the editor. Current value is "jspwiki.editor" - not used anymore: replaced by defaultpref.template.editor */ - public static final String PROP_EDITORTYPE = "jspwiki.editor"; - - /** Parameter for changing editors at run-time */ - public static final String PARA_EDITOR = "editor"; - - /** Known name for the plain wikimarkup editor. */ - public static final String EDITOR_PLAIN = "plain"; - - /** Known name for the preview editor component. */ - public static final String EDITOR_PREVIEW = "preview"; - - /** Known attribute name for storing the user edited text inside a HTTP parameter. */ - public static final String REQ_EDITEDTEXT = "_editedtext"; - - /** Known attribute name for storing the user edited text inside a session or a page context */ - public static final String ATTR_EDITEDTEXT = REQ_EDITEDTEXT; +public class DefaultEditorManager extends ModuleManager implements EditorManager { private Map< String, WikiEditorInfo > m_editors; - private static final Logger log = Logger.getLogger( EditorManager.class ); + private static final Logger log = Logger.getLogger( DefaultEditorManager.class ); - public EditorManager( final Engine engine ) { + public DefaultEditorManager( final Engine engine ) { super( engine ); } - /** - * Initializes the EditorManager. It also registers any editors it can find. - * - * @param props Properties for setup. - */ + /** {@inheritDoc} */ + @Override public void initialize( final Properties props ) { registerEditors(); } - /** - * This method goes through the jspwiki_module.xml files and hunts for editors. Any editors found are put in the registry. - */ + /** This method goes through the jspwiki_module.xml files and hunts for editors. Any editors found are put in the registry. */ private void registerEditors() { log.info( "Registering editor modules" ); m_editors = new HashMap<>(); - // - // Register all editors which have created a resource containing its properties. - // - // Get all resources of all modules - // + // Register all editors which have created a resource containing its properties. Get all resources of all modules final List< Element > editors = XmlUtil.parse( PLUGIN_RESOURCE_LOCATION, "/modules/editor" ); for( final Element pluginEl : editors ) { final String name = pluginEl.getAttributeValue( "name" ); @@ -119,19 +91,8 @@ public class EditorManager extends ModuleManager { } } - /** - * Returns an editor for the current context. The editor names are matched in a case insensitive manner. At the moment, the only - * place that this method looks in is the property file, but in the future this will also look at user preferences. - * <p> - * Determines the editor to use by the following order of conditions: - * 1. Editor set in User Preferences - * 2. Default Editor set in jspwiki.properties - * <p> - * For the PREVIEW context, this method returns the "preview" editor. - * - * @param context The context that is chosen. - * @return The name of the chosen editor. If no match could be found, will revert to the default "plain" editor. - */ + /** {@inheritDoc} */ + @Override public String getEditorName( final WikiContext context ) { if( context.getRequestContext().equals( WikiContext.PREVIEW ) ) { return EDITOR_PREVIEW; @@ -161,11 +122,8 @@ public class EditorManager extends ModuleManager { return EDITOR_PLAIN; } - /** - * Returns a list of editors as Strings of editor names. - * - * @return the list of available editors - */ + /** {@inheritDoc} */ + @Override public String[] getEditorList() { final String[] editors = new String[ m_editors.size() ]; final Set< String > keys = m_editors.keySet(); @@ -173,12 +131,8 @@ public class EditorManager extends ModuleManager { return keys.toArray( editors ); } - /** - * Convenience method for getting the path to the editor JSP file. - * - * @param context WikiContext from where the editor name is retrieved. - * @return e.g. "editors/plain.jsp" - */ + /** {@inheritDoc} */ + @Override public String getEditorPath( final WikiContext context ) { final String editor = getEditorName( context ); final WikiEditorInfo ed = m_editors.get( editor ); @@ -192,22 +146,6 @@ public class EditorManager extends ModuleManager { return path; } - /** - * Convenience function which examines the current context and attempts to figure out whether the edited text is in the HTTP - * request parameters or somewhere in the session. - * - * @param ctx the JSP page context - * @return the edited text, if present in the session page context or as a parameter - */ - public static String getEditedText( final PageContext ctx ) { - String usertext = ctx.getRequest().getParameter( REQ_EDITEDTEXT ); - if( usertext == null ) { - usertext = ( String )ctx.findAttribute( ATTR_EDITEDTEXT ); - } - - return usertext; - } - /** Contains info about an editor. */ private static final class WikiEditorInfo extends WikiModuleInfo { private String m_path; @@ -221,6 +159,7 @@ public class EditorManager extends ModuleManager { return info; } + /** {@inheritDoc} */ @Override protected void initializeFromXML( final Element el ) { super.initializeFromXML( el ); @@ -236,17 +175,13 @@ public class EditorManager extends ModuleManager { } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public Collection< WikiModuleInfo > modules() { return modules( m_editors.values().iterator() ); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public WikiEditorInfo getModuleInfo( final String moduleName ) { return m_editors.get( moduleName ); diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultTemplateManager.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultTemplateManager.java new file mode 100644 index 0000000..85065fe --- /dev/null +++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultTemplateManager.java @@ -0,0 +1,353 @@ +/* + 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. + */ +package org.apache.wiki.ui; + +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.apache.wiki.InternalWikiException; +import org.apache.wiki.WikiContext; +import org.apache.wiki.api.core.Engine; +import org.apache.wiki.modules.ModuleManager; +import org.apache.wiki.modules.WikiModuleInfo; +import org.apache.wiki.preferences.Preferences; +import org.apache.wiki.preferences.Preferences.TimeFormat; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.jsp.PageContext; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; + + +/** + * This class takes care of managing JSPWiki templates. This class also provides the ResourceRequest mechanism. + * + * @since 2.1.62 + */ +public class DefaultTemplateManager extends ModuleManager implements TemplateManager { + + private static final Logger log = Logger.getLogger( DefaultTemplateManager.class ); + + /** + * Creates a new TemplateManager. There is typically one manager per engine. + * + * @param engine The owning engine. + * @param properties The property list used to initialize this. + */ + public DefaultTemplateManager( final Engine engine, final Properties properties ) { + super( engine ); + } + + /** {@inheritDoc} */ + @Override + // FIXME: Does not work yet + public boolean templateExists( final String templateName ) { + final ServletContext context = m_engine.getServletContext(); + try( final InputStream in = context.getResourceAsStream( getPath( templateName ) + "ViewTemplate.jsp" ) ) { + if( in != null ) { + return true; + } + } catch( final IOException e ) { + log.error( e.getMessage(), e ); + } + return false; + } + + /** + * Tries to locate a given resource from the template directory. If the given resource is not found under the current name, returns the + * path to the corresponding one in the default template. + * + * @param sContext The servlet context + * @param name The name of the resource + * @return The name of the resource which was found. + */ + private static String findResource( final ServletContext sContext, final String name ) { + String resourceName = name; + try( final InputStream is = sContext.getResourceAsStream( resourceName ) ) { + if( is == null ) { + final String defname = makeFullJSPName( DEFAULT_TEMPLATE, removeTemplatePart( resourceName ) ); + try( final InputStream iis = sContext.getResourceAsStream( defname ) ) { + resourceName = iis != null ? defname : null; + } + } + } catch( final IOException e ) { + log.error( "unable to open " + name + " as resource stream", e ); + } + return resourceName; + } + + /** + * Attempts to find a resource from the given template, and if it's not found + * attempts to locate it from the default template. + * @param sContext servlet context used to search for the resource + * @param template template used to search for the resource + * @param name resource name + * @return the Resource for the given template and name. + */ + private static String findResource( final ServletContext sContext, final String template, final String name ) { + if( name.charAt(0) == '/' ) { + // This is already a full path + return findResource( sContext, name ); + } + final String fullname = makeFullJSPName( template, name ); + return findResource( sContext, fullname ); + } + + /** {@inheritDoc} */ + @Override + public String findJSP( final PageContext pageContext, final String name ) { + final ServletContext sContext = pageContext.getServletContext(); + return findResource( sContext, name ); + } + + /** + * Removes the template part of a name. + */ + private static String removeTemplatePart( String name ) { + int idx = 0; + if( name.startsWith( "/" ) ) { + idx = 1; + } + + idx = name.indexOf('/', idx); + if( idx != -1 ) { + idx = name.indexOf('/', idx+1); // Find second "/" + if( idx != -1 ) { + name = name.substring( idx+1 ); + } + } + + if( log.isDebugEnabled() ) { + log.debug( "Final name = "+name ); + } + return name; + } + + /** + * Returns the full name (/templates/foo/bar) for name=bar, template=foo. + * + * @param template The name of the template. + * @param name The name of the resource. + * @return The full name for a template. + */ + private static String makeFullJSPName( final String template, final String name ) { + return "/" + DIRECTORY + "/" + template + "/" + name; + } + + /** {@inheritDoc} */ + @Override + public String findJSP( final PageContext pageContext, final String template, final String name ) { + if( name == null || template == null ) { + log.fatal("findJSP() was asked to find a null template or name (" + template + "," + name + ")." + " JSP page '" + + ( ( HttpServletRequest )pageContext.getRequest() ).getRequestURI() + "'" ); + throw new InternalWikiException( "Illegal arguments to findJSP(); please check logs." ); + } + + return findResource( pageContext.getServletContext(), template, name ); + } + + /** {@inheritDoc} */ + @Override + public String findResource( final WikiContext ctx, final String template, final String name ) { + if( m_engine.getServletContext() != null ) { + return findResource( m_engine.getServletContext(), template, name ); + } + + return getPath(template)+"/"+name; + } + + /* + * Returns a property, as defined in the template. The evaluation is lazy, i.e. the properties are not loaded until the template is + * actually used for the first time. + */ + /* + public String getTemplateProperty( WikiContext context, String key ) + { + String template = context.getTemplate(); + + try + { + Properties props = (Properties)m_propertyCache.getFromCache( template, -1 ); + + if( props == null ) + { + try + { + props = getTemplateProperties( template ); + + m_propertyCache.putInCache( template, props ); + } + catch( IOException e ) + { + log.warn("IO Exception while reading template properties",e); + + return null; + } + } + + return props.getProperty( key ); + } + catch( NeedsRefreshException ex ) + { + // FIXME + return null; + } + } +*/ + /** + * Returns an absolute path to a given template. + */ + private static String getPath( final String template ) { + return "/" + DIRECTORY + "/" + template + "/"; + } + + /** {@inheritDoc} */ + @Override + public Set< String > listSkins( final PageContext pageContext, final String template ) { + final String place = makeFullJSPName( template, SKIN_DIRECTORY ); + final ServletContext sContext = pageContext.getServletContext(); + final Set< String > skinSet = sContext.getResourcePaths( place ); + final Set< String > resultSet = new TreeSet<>(); + + if( log.isDebugEnabled() ) { + log.debug( "Listings skins from " + place ); + } + + if( skinSet != null ) { + final String[] skins = skinSet.toArray( new String[]{} ); + for( final String skin : skins ) { + final String[] s = StringUtils.split( skin, "/" ); + if( s.length > 2 && skin.endsWith( "/" ) ) { + final String skinName = s[ s.length - 1 ]; + resultSet.add( skinName ); + if( log.isDebugEnabled() ) { + log.debug( "...adding skin '" + skinName + "'" ); + } + } + } + } + + return resultSet; + } + + + /** {@inheritDoc} */ + @Override + public Map< String, String > listTimeFormats( final PageContext pageContext ) { + final WikiContext context = WikiContext.findContext( pageContext ); + final Properties props = m_engine.getWikiProperties(); + final ArrayList< String > tfArr = new ArrayList<>(40); + final LinkedHashMap< String, String > resultMap = new LinkedHashMap<>(); + + /* filter timeformat properties */ + for( final Enumeration< ? > e = props.propertyNames(); e.hasMoreElements(); ) { + final String name = ( String )e.nextElement(); + if( name.startsWith( TIMEFORMATPROPERTIES ) ) { + tfArr.add( name ); + } + } + + /* fetch actual formats */ + if( tfArr.size() == 0 ) {/* no props found - make sure some default formats are avail */ + tfArr.add( "dd-MMM-yy" ); + tfArr.add( "d-MMM-yyyy" ); + tfArr.add( "EEE, dd-MMM-yyyy, zzzz" ); + } else { + Collections.sort( tfArr ); + + for (int i = 0; i < tfArr.size(); i++) { + tfArr.set(i, props.getProperty(tfArr.get(i))); + } + } + + final String prefTimeZone = Preferences.getPreference( context, "TimeZone" ); + final TimeZone tz = TimeZone.getTimeZone( prefTimeZone ); + + final Date d = new Date(); // current date + try { + // dummy format pattern + final SimpleDateFormat fmt = Preferences.getDateFormat( context, TimeFormat.DATETIME ); + fmt.setTimeZone( tz ); + + for( final String s : tfArr ) { + try { + final String f = s; + fmt.applyPattern( f ); + resultMap.put( f, fmt.format( d ) ); + } catch( final IllegalArgumentException e ) { + } // skip parameter + } + } catch( final IllegalArgumentException e ) {} // skip parameter + + return resultMap; + } + + /* + * Always returns a valid property map. + */ + /* + private Properties getTemplateProperties( String templateName ) + throws IOException + { + Properties p = new Properties(); + + ServletContext context = m_engine.getServletContext(); + + InputStream propertyStream = context.getResourceAsStream(getPath(templateName)+PROPERTYFILE); + + if( propertyStream != null ) + { + p.load( propertyStream ); + + propertyStream.close(); + } + else + { + log.debug("Template '"+templateName+"' does not have a propertyfile '"+PROPERTYFILE+"'."); + } + + return p; + } +*/ + + /** {@inheritDoc} */ + @Override + public Collection< WikiModuleInfo > modules() { + return new ArrayList<>(); + } + + /** {@inheritDoc} */ + @Override + public WikiModuleInfo getModuleInfo( final String moduleName ) { + return null; + } + +} diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/EditorManager.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/EditorManager.java index 9d173fd..31b0c80 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/ui/EditorManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/EditorManager.java @@ -18,24 +18,12 @@ */ package org.apache.wiki.ui; -import org.apache.log4j.Logger; import org.apache.wiki.WikiContext; -import org.apache.wiki.api.core.Engine; -import org.apache.wiki.api.exceptions.NoSuchVariableException; -import org.apache.wiki.modules.ModuleManager; import org.apache.wiki.modules.WikiModuleInfo; -import org.apache.wiki.preferences.Preferences; -import org.apache.wiki.util.XmlUtil; -import org.apache.wiki.variables.VariableManager; -import org.jdom2.Element; import javax.servlet.jsp.PageContext; import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Properties; -import java.util.Set; /** @@ -56,68 +44,32 @@ import java.util.Set; * * @since 2.4 */ -public class EditorManager extends ModuleManager { +public interface EditorManager { /** The property name for setting the editor. Current value is "jspwiki.editor" - not used anymore: replaced by defaultpref.template.editor */ - public static final String PROP_EDITORTYPE = "jspwiki.editor"; + String PROP_EDITORTYPE = "jspwiki.editor"; /** Parameter for changing editors at run-time */ - public static final String PARA_EDITOR = "editor"; + String PARA_EDITOR = "editor"; /** Known name for the plain wikimarkup editor. */ - public static final String EDITOR_PLAIN = "plain"; + String EDITOR_PLAIN = "plain"; /** Known name for the preview editor component. */ - public static final String EDITOR_PREVIEW = "preview"; + String EDITOR_PREVIEW = "preview"; /** Known attribute name for storing the user edited text inside a HTTP parameter. */ - public static final String REQ_EDITEDTEXT = "_editedtext"; + String REQ_EDITEDTEXT = "_editedtext"; /** Known attribute name for storing the user edited text inside a session or a page context */ - public static final String ATTR_EDITEDTEXT = REQ_EDITEDTEXT; - - private Map< String, WikiEditorInfo > m_editors; - - private static final Logger log = Logger.getLogger( EditorManager.class ); - - public EditorManager( final Engine engine ) { - super( engine ); - } + String ATTR_EDITEDTEXT = REQ_EDITEDTEXT; /** * Initializes the EditorManager. It also registers any editors it can find. * * @param props Properties for setup. */ - public void initialize( final Properties props ) { - registerEditors(); - } - - /** - * This method goes through the jspwiki_module.xml files and hunts for editors. Any editors found are put in the registry. - */ - private void registerEditors() { - log.info( "Registering editor modules" ); - m_editors = new HashMap<>(); - - // - // Register all editors which have created a resource containing its properties. - // - // Get all resources of all modules - // - final List< Element > editors = XmlUtil.parse( PLUGIN_RESOURCE_LOCATION, "/modules/editor" ); - for( final Element pluginEl : editors ) { - final String name = pluginEl.getAttributeValue( "name" ); - final WikiEditorInfo info = WikiEditorInfo.newInstance( name, pluginEl ); - - if( checkCompatibility( info ) ) { - m_editors.put( name, info ); - log.debug( "Registered editor " + name ); - } else { - log.info( "Editor '" + name + "' not compatible with this version of JSPWiki." ); - } - } - } + void initialize( Properties props ); /** * Returns an editor for the current context. The editor names are matched in a case insensitive manner. At the moment, the only @@ -132,46 +84,14 @@ public class EditorManager extends ModuleManager { * @param context The context that is chosen. * @return The name of the chosen editor. If no match could be found, will revert to the default "plain" editor. */ - public String getEditorName( final WikiContext context ) { - if( context.getRequestContext().equals( WikiContext.PREVIEW ) ) { - return EDITOR_PREVIEW; - } - - // User has set an editor in preferences - String editor = Preferences.getPreference( context, PARA_EDITOR ); - - /* FIXME: actual default 'editor' property is read by the Preferences class */ - if( editor == null ) { - // or use the default editor in jspwiki.properties - try { - editor = m_engine.getManager( VariableManager.class ).getValue( context, PROP_EDITORTYPE ); - } catch( final NoSuchVariableException e ) {} // This is fine - } - - if( editor != null ) { - final String[] editorlist = getEditorList(); - editor = editor.trim(); - for( final String s : editorlist ) { - if( s.equalsIgnoreCase( editor ) ) { - return s; - } - } - } - - return EDITOR_PLAIN; - } + String getEditorName( WikiContext context ); /** * Returns a list of editors as Strings of editor names. * * @return the list of available editors */ - public String[] getEditorList() { - final String[] editors = new String[ m_editors.size() ]; - final Set< String > keys = m_editors.keySet(); - - return keys.toArray( editors ); - } + String[] getEditorList(); /** * Convenience method for getting the path to the editor JSP file. @@ -179,18 +99,7 @@ public class EditorManager extends ModuleManager { * @param context WikiContext from where the editor name is retrieved. * @return e.g. "editors/plain.jsp" */ - public String getEditorPath( final WikiContext context ) { - final String editor = getEditorName( context ); - final WikiEditorInfo ed = m_editors.get( editor ); - final String path; - if( ed != null ) { - path = ed.getPath(); - } else { - path = "editors/"+editor+".jsp"; - } - - return path; - } + String getEditorPath( WikiContext context ); /** * Convenience function which examines the current context and attempts to figure out whether the edited text is in the HTTP @@ -199,7 +108,7 @@ public class EditorManager extends ModuleManager { * @param ctx the JSP page context * @return the edited text, if present in the session page context or as a parameter */ - public static String getEditedText( final PageContext ctx ) { + static String getEditedText( final PageContext ctx ) { String usertext = ctx.getRequest().getParameter( REQ_EDITEDTEXT ); if( usertext == null ) { usertext = ( String )ctx.findAttribute( ATTR_EDITEDTEXT ); @@ -208,48 +117,13 @@ public class EditorManager extends ModuleManager { return usertext; } - /** Contains info about an editor. */ - private static final class WikiEditorInfo extends WikiModuleInfo { - private String m_path; - - protected static WikiEditorInfo newInstance( final String name, final Element el ) { - if( name == null || name.length() == 0 ) { - return null; - } - final WikiEditorInfo info = new WikiEditorInfo( name ); - info.initializeFromXML( el ); - return info; - } - - @Override - protected void initializeFromXML( final Element el ) { - super.initializeFromXML( el ); - m_path = el.getChildText("path"); - } - - private WikiEditorInfo( final String name ) { - super( name ); - } - - public String getPath() { - return m_path; - } - } - /** - * {@inheritDoc} - */ - @Override - public Collection< WikiModuleInfo > modules() { - return modules( m_editors.values().iterator() ); - } - - /** - * {@inheritDoc} + * Returns a collection of modules currently managed by this ModuleManager. Each + * entry is an instance of the WikiModuleInfo class. This method should return something + * which is safe to iterate over, even if the underlying collection changes. + * + * @return A Collection of WikiModuleInfo instances. */ - @Override - public WikiEditorInfo getModuleInfo( final String moduleName ) { - return m_editors.get( moduleName ); - } + Collection< WikiModuleInfo > modules(); } diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/TemplateManager.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/TemplateManager.java index 68441f9..57114d1 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/ui/TemplateManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/TemplateManager.java @@ -18,40 +18,25 @@ */ package org.apache.wiki.ui; -import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; -import org.apache.wiki.InternalWikiException; import org.apache.wiki.WikiContext; -import org.apache.wiki.api.core.Engine; import org.apache.wiki.i18n.InternationalizationManager; -import org.apache.wiki.modules.ModuleManager; import org.apache.wiki.modules.WikiModuleInfo; import org.apache.wiki.preferences.Preferences; -import org.apache.wiki.preferences.Preferences.TimeFormat; import org.apache.wiki.util.ClassUtil; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.jstl.fmt.LocaleSupport; -import java.io.IOException; -import java.io.InputStream; -import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; import java.util.TimeZone; -import java.util.TreeSet; import java.util.Vector; @@ -60,132 +45,62 @@ import java.util.Vector; * * @since 2.1.62 */ -public class TemplateManager extends ModuleManager { +public interface TemplateManager { - private static final String SKIN_DIRECTORY = "skins"; + String SKIN_DIRECTORY = "skins"; /** Requests a JavaScript function to be called during window.onload. Value is {@value}. */ - public static final String RESOURCE_JSFUNCTION = "jsfunction"; + String RESOURCE_JSFUNCTION = "jsfunction"; /** Requests a JavaScript associative array with all localized strings. */ - public static final String RESOURCE_JSLOCALIZEDSTRINGS = "jslocalizedstrings"; + String RESOURCE_JSLOCALIZEDSTRINGS = "jslocalizedstrings"; /** Requests a stylesheet to be inserted. Value is {@value}. */ - public static final String RESOURCE_STYLESHEET = "stylesheet"; + String RESOURCE_STYLESHEET = "stylesheet"; /** Requests a script to be loaded. Value is {@value}. */ - public static final String RESOURCE_SCRIPT = "script"; + String RESOURCE_SCRIPT = "script"; /** Requests inlined CSS. Value is {@value}. */ - public static final String RESOURCE_INLINECSS = "inlinecss"; + String RESOURCE_INLINECSS = "inlinecss"; /** The default directory for the properties. Value is {@value}. */ - public static final String DIRECTORY = "templates"; + String DIRECTORY = "templates"; /** The name of the default template. Value is {@value}. */ - public static final String DEFAULT_TEMPLATE = "default"; + String DEFAULT_TEMPLATE = "default"; /** Name of the file that contains the properties. */ - public static final String PROPERTYFILE = "template.properties"; + String PROPERTYFILE = "template.properties"; /** Location of I18N Resource bundles, and path prefix and suffixes */ - public static final String I18NRESOURCE_PREFIX = "templates/default_"; + String I18NRESOURCE_PREFIX = "templates/default_"; - public static final String I18NRESOURCE_SUFFIX = ".properties"; + String I18NRESOURCE_SUFFIX = ".properties"; /** The default (en) RESOURCE name and id. */ - public static final String I18NRESOURCE_EN = "templates/default.properties"; - public static final String I18NRESOURCE_EN_ID = "en"; + String I18NRESOURCE_EN = "templates/default.properties"; + String I18NRESOURCE_EN_ID = "en"; /** I18N string to mark the default locale */ - public static final String I18NDEFAULT_LOCALE = "prefs.user.language.default"; + String I18NDEFAULT_LOCALE = "prefs.user.language.default"; /** I18N string to mark the server timezone */ - public static final String I18NSERVER_TIMEZONE = "prefs.user.timezone.server"; + String I18NSERVER_TIMEZONE = "prefs.user.timezone.server"; /** Prefix of the default timeformat properties. */ - public static final String TIMEFORMATPROPERTIES = "jspwiki.defaultprefs.timeformat."; + String TIMEFORMATPROPERTIES = "jspwiki.defaultprefs.timeformat."; /** The name under which the resource includes map is stored in the WikiContext. */ - public static final String RESOURCE_INCLUDES = "jspwiki.resourceincludes"; - - // private Cache m_propertyCache; - - private static final Logger log = Logger.getLogger( TemplateManager.class ); + String RESOURCE_INCLUDES = "jspwiki.resourceincludes"; /** Requests a HTTP header. Value is {@value}. */ - public static final String RESOURCE_HTTPHEADER = "httpheader"; - - /** - * Creates a new TemplateManager. There is typically one manager per engine. - * - * @param engine The owning engine. - * @param properties The property list used to initialize this. - */ - public TemplateManager( final Engine engine, final Properties properties ) { - super( engine ); - - // - // Uses the unlimited cache. - // - // m_propertyCache = new Cache( true, false ); - } + String RESOURCE_HTTPHEADER = "httpheader"; /** * Check the existence of a template. */ - // FIXME: Does not work yet - public boolean templateExists( final String templateName ) { - final ServletContext context = m_engine.getServletContext(); - try( final InputStream in = context.getResourceAsStream( getPath( templateName ) + "ViewTemplate.jsp" ) ) { - if( in != null ) { - return true; - } - } catch( final IOException e ) { - log.error( e.getMessage(), e ); - } - return false; - } - - /** - * Tries to locate a given resource from the template directory. If the given resource is not found under the current name, returns the - * path to the corresponding one in the default template. - * - * @param sContext The servlet context - * @param name The name of the resource - * @return The name of the resource which was found. - */ - private static String findResource( final ServletContext sContext, final String name ) { - String resourceName = name; - try( final InputStream is = sContext.getResourceAsStream( resourceName ) ) { - if( is == null ) { - final String defname = makeFullJSPName( DEFAULT_TEMPLATE, removeTemplatePart( resourceName ) ); - try( final InputStream iis = sContext.getResourceAsStream( defname ) ) { - resourceName = iis != null ? defname : null; - } - } - } catch( final IOException e ) { - log.error( "unable to open " + name + " as resource stream", e ); - } - return resourceName; - } - - /** - * Attempts to find a resource from the given template, and if it's not found - * attempts to locate it from the default template. - * @param sContext - * @param template - * @param name - * @return the Resource for the given template and name. - */ - private static String findResource( final ServletContext sContext, final String template, final String name ) { - if( name.charAt(0) == '/' ) { - // This is already a full path - return findResource( sContext, name ); - } - final String fullname = makeFullJSPName( template, name ); - return findResource( sContext, fullname ); - } + boolean templateExists( String templateName ); /** * An utility method for finding a JSP page. It searches only under either current context or by the absolute name. @@ -194,44 +109,7 @@ public class TemplateManager extends ModuleManager { * @param name The name of the JSP page to look for (e.g "Wiki.jsp") * @return The context path to the resource */ - public String findJSP( final PageContext pageContext, final String name ) { - final ServletContext sContext = pageContext.getServletContext(); - return findResource( sContext, name ); - } - - /** - * Removes the template part of a name. - */ - private static String removeTemplatePart( String name ) { - int idx = 0; - if( name.startsWith( "/" ) ) { - idx = 1; - } - - idx = name.indexOf('/', idx); - if( idx != -1 ) { - idx = name.indexOf('/', idx+1); // Find second "/" - if( idx != -1 ) { - name = name.substring( idx+1 ); - } - } - - if( log.isDebugEnabled() ) { - log.debug( "Final name = "+name ); - } - return name; - } - - /** - * Returns the full name (/templates/foo/bar) for name=bar, template=foo. - * - * @param template The name of the template. - * @param name The name of the resource. - * @return The full name for a template. - */ - private static String makeFullJSPName( final String template, final String name ) { - return "/" + DIRECTORY + "/" + template + "/" + name; - } + String findJSP( PageContext pageContext, String name ); /** * Attempts to locate a resource under the given template. If that template does not exist, or the page does not exist under that @@ -244,15 +122,7 @@ public class TemplateManager extends ModuleManager { * @param name Which resource are we looking for (e.g. "ViewTemplate.jsp") * @return path to the JSP page; null, if it was not found. */ - public String findJSP( final PageContext pageContext, final String template, final String name ) { - if( name == null || template == null ) { - log.fatal("findJSP() was asked to find a null template or name (" + template + "," + name + ")." + " JSP page '" + - ( ( HttpServletRequest )pageContext.getRequest() ).getRequestURI() + "'" ); - throw new InternalWikiException( "Illegal arguments to findJSP(); please check logs." ); - } - - return findResource( pageContext.getServletContext(), template, name ); - } + String findJSP( PageContext pageContext, String template, String name ); /** * Attempts to locate a resource under the given template. This matches the functionality findJSP(), but uses the WikiContext as @@ -266,58 +136,7 @@ public class TemplateManager extends ModuleManager { * @param name the name of the resource to fine * @return the path to the resource */ - public String findResource( final WikiContext ctx, final String template, final String name ) { - if( m_engine.getServletContext() != null ) { - return findResource( m_engine.getServletContext(), template, name ); - } - - return getPath(template)+"/"+name; - } - - /** - * Returns a property, as defined in the template. The evaluation is lazy, i.e. the properties are not loaded until the template is - * actually used for the first time. - */ - /* - public String getTemplateProperty( WikiContext context, String key ) - { - String template = context.getTemplate(); - - try - { - Properties props = (Properties)m_propertyCache.getFromCache( template, -1 ); - - if( props == null ) - { - try - { - props = getTemplateProperties( template ); - - m_propertyCache.putInCache( template, props ); - } - catch( IOException e ) - { - log.warn("IO Exception while reading template properties",e); - - return null; - } - } - - return props.getProperty( key ); - } - catch( NeedsRefreshException ex ) - { - // FIXME - return null; - } - } -*/ - /** - * Returns an absolute path to a given template. - */ - private static String getPath( final String template ) { - return "/" + DIRECTORY + "/" + template + "/"; - } + String findResource( WikiContext ctx, String template, String name ); /** * Lists the skins available under this template. Returns an empty Set, if there are no extra skins available. Note that @@ -329,43 +148,18 @@ public class TemplateManager extends ModuleManager { * @return Set of Strings with the skin names. * @since 2.3.26 */ - public Set< String > listSkins( final PageContext pageContext, final String template ) { - final String place = makeFullJSPName( template, SKIN_DIRECTORY ); - final ServletContext sContext = pageContext.getServletContext(); - final Set< String > skinSet = sContext.getResourcePaths( place ); - final Set< String > resultSet = new TreeSet<>(); - - if( log.isDebugEnabled() ) { - log.debug( "Listings skins from " + place ); - } - - if( skinSet != null ) { - final String[] skins = skinSet.toArray( new String[]{} ); - for( final String skin : skins ) { - final String[] s = StringUtils.split( skin, "/" ); - if( s.length > 2 && skin.endsWith( "/" ) ) { - final String skinName = s[ s.length - 1 ]; - resultSet.add( skinName ); - if( log.isDebugEnabled() ) { - log.debug( "...adding skin '" + skinName + "'" ); - } - } - } - } - - return resultSet; - } + Set< String > listSkins( PageContext pageContext, String template ); /** * List all installed i18n language properties by classpath searching for files like : * templates/default_*.properties * templates/default.properties * - * @param pageContext + * @param pageContext page context * @return map of installed Languages * @since 2.7.x */ - public Map< String, String > listLanguages( final PageContext pageContext ) { + default Map< String, String > listLanguages( final PageContext pageContext ) { final Map< String, String > resultMap = new LinkedHashMap<>(); final String clientLanguage = pageContext.getRequest().getLocale().toString(); final List< String > entries = ClassUtil.classpathEntriesUnder( DIRECTORY ); @@ -376,7 +170,7 @@ public class TemplateManager extends ModuleManager { } else { name = name.substring( I18NRESOURCE_PREFIX.length(), name.lastIndexOf( I18NRESOURCE_SUFFIX ) ); } - final Locale locale = new Locale( name.substring( 0, 2 ), ( ( name.indexOf( "_" ) == -1 ) ? "" : name.substring( 3, 5 ) ) ); + final Locale locale = new Locale( name.substring( 0, 2 ), !name.contains( "_" ) ? "" : name.substring( 3, 5 ) ); String defaultLanguage = ""; if( clientLanguage.startsWith( name ) ) { defaultLanguage = LocaleSupport.getLocalizedMessage( pageContext, I18NDEFAULT_LOCALE ); @@ -392,76 +186,30 @@ public class TemplateManager extends ModuleManager { /** * List all available timeformats, read from the jspwiki.properties * - * @param pageContext + * @param pageContext page context * @return map of TimeFormats * @since 2.7.x */ - public Map< String, String > listTimeFormats( final PageContext pageContext ) { - final WikiContext context = WikiContext.findContext( pageContext ); - final Properties props = m_engine.getWikiProperties(); - final ArrayList< String > tfArr = new ArrayList<>(40); - final LinkedHashMap< String, String > resultMap = new LinkedHashMap<>(); - - /* filter timeformat properties */ - for( final Enumeration< ? > e = props.propertyNames(); e.hasMoreElements(); ) { - final String name = ( String )e.nextElement(); - if( name.startsWith( TIMEFORMATPROPERTIES ) ) { - tfArr.add( name ); - } - } - - /* fetch actual formats */ - if( tfArr.size() == 0 ) {/* no props found - make sure some default formats are avail */ - tfArr.add( "dd-MMM-yy" ); - tfArr.add( "d-MMM-yyyy" ); - tfArr.add( "EEE, dd-MMM-yyyy, zzzz" ); - } else { - Collections.sort( tfArr ); - - for (int i = 0; i < tfArr.size(); i++) { - tfArr.set(i, props.getProperty(tfArr.get(i))); - } - } - - final String prefTimeZone = Preferences.getPreference( context, "TimeZone" ); - //TimeZone tz = TimeZone.getDefault(); - final TimeZone tz = TimeZone.getTimeZone(prefTimeZone); - /*try - { - tz.setRawOffset(Integer.parseInt(prefTimeZone)); - } - catch (Exception e) - { - }*/ - - final Date d = new Date(); // current date - try { - // dummy format pattern - final SimpleDateFormat fmt = Preferences.getDateFormat( context, TimeFormat.DATETIME ); - fmt.setTimeZone( tz ); - - for( int i = 0; i < tfArr.size(); i++ ) { - try { - final String f = tfArr.get( i ); - fmt.applyPattern( f ); - resultMap.put( f, fmt.format( d ) ); - } catch( final IllegalArgumentException e ) {} // skip parameter - } - } - catch( final IllegalArgumentException e ) {} // skip parameter + Map< String, String > listTimeFormats( final PageContext pageContext ); - return resultMap; - } + /** + * Returns a collection of modules currently managed by this ModuleManager. Each + * entry is an instance of the WikiModuleInfo class. This method should return something + * which is safe to iterate over, even if the underlying collection changes. + * + * @return A Collection of WikiModuleInfo instances. + */ + Collection< WikiModuleInfo > modules(); /** * List all timezones, with special marker for server timezone * - * @param pageContext + * @param pageContext page context * @return map of TimeZones * @since 2.7.x */ - public Map< String, String > listTimeZones( final PageContext pageContext ) { - final Map<String,String> resultMap = new LinkedHashMap<>(); + default Map< String, String > listTimeZones( final PageContext pageContext ) { + final Map< String, String > resultMap = new LinkedHashMap<>(); final String[][] tzs = { { "GMT-12", "Enitwetok, Kwajalien" }, { "GMT-11", "Nome, Midway Island, Samoa" }, @@ -511,33 +259,6 @@ public class TemplateManager extends ModuleManager { } /** - * Always returns a valid property map. - */ - /* - private Properties getTemplateProperties( String templateName ) - throws IOException - { - Properties p = new Properties(); - - ServletContext context = m_engine.getServletContext(); - - InputStream propertyStream = context.getResourceAsStream(getPath(templateName)+PROPERTYFILE); - - if( propertyStream != null ) - { - p.load( propertyStream ); - - propertyStream.close(); - } - else - { - log.debug("Template '"+templateName+"' does not have a propertyfile '"+PROPERTYFILE+"'."); - } - - return p; - } -*/ - /** * Returns the include resources marker for a given type. This is in a * HTML or Javascript comment format. * @@ -545,7 +266,7 @@ public class TemplateManager extends ModuleManager { * @param type the marker * @return the generated marker comment */ - public static String getMarker( final WikiContext context, final String type ) { + static String getMarker( final WikiContext context, final String type ) { if( type.equals( RESOURCE_JSLOCALIZEDSTRINGS ) ) { return getJSLocalizedStrings( context ); } else if( type.equals( RESOURCE_JSFUNCTION ) ) { @@ -561,7 +282,7 @@ public class TemplateManager extends ModuleManager { * @return Javascript snippet which defines the LocalizedStrings array * @since 2.5.108 */ - private static String getJSLocalizedStrings( final WikiContext context ) { + static String getJSLocalizedStrings( final WikiContext context ) { final StringBuilder sb = new StringBuilder(); sb.append( "var LocalizedStrings = {\n"); final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.DEF_TEMPLATE ); @@ -575,7 +296,7 @@ public class TemplateManager extends ModuleManager { } else { sb.append( ",\n" ); } - sb.append( "\""+key+"\":\""+rb.getString(key)+"\"" ); + sb.append( "\"" ).append( key ).append( "\":\"" ).append( rb.getString( key ) ).append( "\"" ); } } sb.append("\n};\n"); @@ -604,7 +325,7 @@ public class TemplateManager extends ModuleManager { * @param resource The resource to add. */ @SuppressWarnings("unchecked") - public static void addResourceRequest( final WikiContext ctx, final String type, final String resource ) { + static void addResourceRequest( final WikiContext ctx, final String type, final String resource ) { HashMap< String, Vector< String > > resourcemap = ( HashMap< String, Vector< String > > ) ctx.getVariable( RESOURCE_INCLUDES ); if( resourcemap == null ) { resourcemap = new HashMap<>(); @@ -636,7 +357,7 @@ public class TemplateManager extends ModuleManager { resources.add( resourceString ); } - log.debug( "Request to add a resource: " + resourceString ); + Logger.getLogger( TemplateManager.class ).debug( "Request to add a resource: " + resourceString ); resourcemap.put( type, resources ); ctx.setVariable( RESOURCE_INCLUDES, resourcemap ); @@ -650,7 +371,7 @@ public class TemplateManager extends ModuleManager { * @return a String array for the resource requests */ @SuppressWarnings("unchecked") - public static String[] getResourceRequests( final WikiContext ctx, final String type ) { + static String[] getResourceRequests( final WikiContext ctx, final String type ) { final HashMap< String, Vector< String > > hm = ( HashMap< String, Vector< String > > ) ctx.getVariable( RESOURCE_INCLUDES ); if( hm == null ) { return new String[0]; @@ -672,7 +393,7 @@ public class TemplateManager extends ModuleManager { * @return the array of types requested */ @SuppressWarnings("unchecked") - public static String[] getResourceTypes( final WikiContext ctx ) { + static String[] getResourceTypes( final WikiContext ctx ) { String[] res = new String[0]; if( ctx != null ) { final HashMap< String, String > hm = ( HashMap< String, String > ) ctx.getVariable( RESOURCE_INCLUDES ); @@ -685,23 +406,4 @@ public class TemplateManager extends ModuleManager { return res; } - /** - * Returns an empty collection, since at the moment the TemplateManager does not manage any modules. - * - * @return {@inheritDoc} - */ - @Override - public Collection< WikiModuleInfo > modules() { - return new ArrayList<>(); - } - - /** - * Returns null! - * {@inheritDoc} - */ - @Override - public WikiModuleInfo getModuleInfo( final String moduleName ) { - return null; - } - } diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml index da8d88f..a1817fb 100644 --- a/jspwiki-main/src/main/resources/ini/classmappings.xml +++ b/jspwiki-main/src/main/resources/ini/classmappings.xml @@ -97,7 +97,7 @@ </mapping> <mapping> <requestedClass>org.apache.wiki.i18n.InternationalizationManager</requestedClass> - <mappedClass>org.apache.wiki.i18n.InternationalizationManager</mappedClass> + <mappedClass>org.apache.wiki.i18n.DefaultInternationalizationManager</mappedClass> </mapping> <mapping> <requestedClass>org.apache.wiki.references.ReferenceManager</requestedClass> @@ -109,7 +109,7 @@ </mapping> <mapping> <requestedClass>org.apache.wiki.search.SearchManager</requestedClass> - <mappedClass>org.apache.wiki.search.SearchManager</mappedClass> + <mappedClass>org.apache.wiki.search.DefaultSearchManager</mappedClass> </mapping> <mapping> <requestedClass>org.apache.wiki.tasks.TasksManager</requestedClass> @@ -121,11 +121,11 @@ </mapping> <mapping> <requestedClass>org.apache.wiki.ui.EditorManager</requestedClass> - <mappedClass>org.apache.wiki.ui.EditorManager</mappedClass> + <mappedClass>org.apache.wiki.ui.DefaultEditorManager</mappedClass> </mapping> <mapping> <requestedClass>org.apache.wiki.ui.TemplateManager</requestedClass> - <mappedClass>org.apache.wiki.ui.TemplateManager</mappedClass> + <mappedClass>org.apache.wiki.ui.DefaultTemplateManager</mappedClass> </mapping> <mapping> <requestedClass>org.apache.wiki.ui.progress.ProgressManager</requestedClass> diff --git a/jspwiki-main/src/test/java/org/apache/wiki/i18n/InternationalizationManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/i18n/InternationalizationManagerTest.java index a397fea..7ede665 100644 --- a/jspwiki-main/src/test/java/org/apache/wiki/i18n/InternationalizationManagerTest.java +++ b/jspwiki-main/src/test/java/org/apache/wiki/i18n/InternationalizationManagerTest.java @@ -17,17 +17,15 @@ under the License. */ package org.apache.wiki.i18n; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; - import org.junit.jupiter.api.Test; import java.util.Locale; -import org.junit.jupiter.api.Assertions; - public class InternationalizationManagerTest { - InternationalizationManager i18n = new InternationalizationManager( null ); + InternationalizationManager i18n = new DefaultInternationalizationManager( null ); @BeforeEach public void setUp() throws Exception @@ -41,7 +39,7 @@ public class InternationalizationManagerTest @Test public void testGetFromCoreWithArgs() { - String str = i18n.get( InternationalizationManager.CORE_BUNDLE, + final String str = i18n.get( InternationalizationManager.CORE_BUNDLE, Locale.ENGLISH, "security.error.cannot.rename", "Test User" ); @@ -51,7 +49,7 @@ public class InternationalizationManagerTest @Test public void testGetFromDefTemplateWithArgs() { - String str = i18n.get( InternationalizationManager.DEF_TEMPLATE, + final String str = i18n.get( InternationalizationManager.DEF_TEMPLATE, Locale.ENGLISH, "notification.createUserProfile.accept.content", "JSPWiki", "testUser", "Test User", "[email protected]", "www.foo.com" );
