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 ab8d3d47484b87fef6cce906d6030c4d70fd62d5 Author: juanpablo <[email protected]> AuthorDate: Thu Jan 2 16:38:28 2020 +0100 JSPWIKI-120: move ReferenceManager to its own package, as DefaultReferenceManager; extract there new ReferenceManager interface from it --- .../src/main/java/org/apache/wiki/WikiEngine.java | 23 +-- .../DefaultReferenceManager.java} | 18 ++- .../apache/wiki/references/ReferenceManager.java | 171 +++++++++++++++++++++ .../java/org/apache/wiki/references/package.html | 34 ++++ .../src/main/resources/ini/classmappings.xml | 8 +- .../test/java/org/apache/wiki/WikiEngineTest.java | 1 + .../{ => references}/ReferenceManagerTest.java | 14 +- 7 files changed, 238 insertions(+), 31 deletions(-) diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java index 5d0a7d2..227ec74 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java @@ -47,6 +47,7 @@ import org.apache.wiki.pages.PageTimeComparator; import org.apache.wiki.parser.MarkupParser; import org.apache.wiki.parser.WikiDocument; import org.apache.wiki.providers.WikiPageProvider; +import org.apache.wiki.references.ReferenceManager; import org.apache.wiki.render.RenderingManager; import org.apache.wiki.rss.RSSGenerator; import org.apache.wiki.rss.RSSThread; @@ -148,9 +149,7 @@ public class WikiEngine { Double negative, cause for most servers you don't need the property */ public static final String PROP_NO_FILTER_ENCODING = "jspwiki.nofilterencoding"; - /** The name for the property which allows you to set the current reference - * style. The value is {@value}. - */ + /** The name for the property which allows you to set the current reference style. The value is {@value}. */ public static final String PROP_REFSTYLE = "jspwiki.referenceStyle"; /** Property name for the "spaces in titles" -hack. */ @@ -173,7 +172,6 @@ public class WikiEngine { public static final String PROP_FRONTPAGE = "jspwiki.frontPage"; /** Property name for setting the url generator instance */ - public static final String PROP_URLCONSTRUCTOR = "jspwiki.urlConstructor"; /** If this property is set to false, all filters are disabled when translating. */ @@ -182,22 +180,20 @@ public class WikiEngine { /** Does the work in renaming pages. */ private PageRenamer m_pageRenamer = null; - /** The name of the property containing the ACLManager implementing class. - * The value is {@value}. */ + /** The name of the property containing the ACLManager implementing class. The value is {@value}. */ public static final String PROP_ACL_MANAGER_IMPL = "jspwiki.aclManager"; /** If this property is set to false, we don't allow the creation of empty pages */ public static final String PROP_ALLOW_CREATION_OF_EMPTY_PAGES = "jspwiki.allowCreationOfEmptyPages"; /** Should the user info be saved with the page data as well? */ - private boolean m_saveUserInfo = true; + private boolean m_saveUserInfo = true; /** If true, uses UTF8 encoding for all data */ - private boolean m_useUTF8 = true; + private boolean m_useUTF8 = true; - /** Store the file path to the basic URL. When we're not running as - a servlet, it defaults to the user's current directory. */ - private String m_rootPath = System.getProperty("user.dir"); + /** Store the file path to the basic URL. When we're not running as a servlet, it defaults to the user's current directory. */ + private String m_rootPath = System.getProperty("user.dir"); /** Stores references between wikipages. */ private ReferenceManager m_referenceManager = null; @@ -303,13 +299,10 @@ public class WikiEngine { * @param config The ServletConfig object for this servlet. * * @return A WikiEngine instance. - * @throws InternalWikiException in case something fails. This - * is a RuntimeException, so be prepared for it. + * @throws InternalWikiException in case something fails. This is a RuntimeException, so be prepared for it. */ - // FIXME: It seems that this does not work too well, jspInit() // does not react to RuntimeExceptions, or something... - public static synchronized WikiEngine getInstance( ServletConfig config ) throws InternalWikiException { diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ReferenceManager.java b/jspwiki-main/src/main/java/org/apache/wiki/references/DefaultReferenceManager.java similarity index 98% rename from jspwiki-main/src/main/java/org/apache/wiki/ReferenceManager.java rename to jspwiki-main/src/main/java/org/apache/wiki/references/DefaultReferenceManager.java index ea09f2d..3360c9a 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/ReferenceManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/references/DefaultReferenceManager.java @@ -16,18 +16,22 @@ specific language governing permissions and limitations under the License. */ -package org.apache.wiki; +package org.apache.wiki.references; import org.apache.commons.lang3.time.StopWatch; import org.apache.log4j.Logger; +import org.apache.wiki.InternalWikiException; +import org.apache.wiki.LinkCollector; +import org.apache.wiki.WikiContext; +import org.apache.wiki.WikiEngine; +import org.apache.wiki.WikiPage; +import org.apache.wiki.WikiProvider; import org.apache.wiki.api.exceptions.ProviderException; import org.apache.wiki.api.filters.BasicPageFilter; import org.apache.wiki.attachment.Attachment; import org.apache.wiki.event.WikiEvent; -import org.apache.wiki.event.WikiEventListener; import org.apache.wiki.event.WikiEventUtils; import org.apache.wiki.event.WikiPageEvent; -import org.apache.wiki.modules.InternalModule; import org.apache.wiki.providers.WikiPageProvider; import org.apache.wiki.util.TextUtil; @@ -106,13 +110,13 @@ import java.util.TreeSet; * The owning class must take responsibility of filling in any pre-existing information, probably by loading each and every WikiPage * and calling this class to update the references when created. * - * @since 1.6.1 + * @since 1.6.1 (as of 2.11.0, moved to org.apache.wiki.references) */ // FIXME: The way that we save attributes is now a major booboo, and must be // replace forthwith. However, this is a workaround for the great deal // of problems that occur here... -public class ReferenceManager extends BasicPageFilter implements InternalModule, WikiEventListener { +public class DefaultReferenceManager extends BasicPageFilter implements ReferenceManager { /** * Maps page wikiname to a Collection of pages it refers to. The Collection must contain Strings. The Collection may contain @@ -130,7 +134,7 @@ public class ReferenceManager extends BasicPageFilter implements InternalModule, private boolean m_matchEnglishPlurals; - private static final Logger log = Logger.getLogger(ReferenceManager.class); + private static final Logger log = Logger.getLogger( DefaultReferenceManager.class); private static final String SERIALIZATION_FILE = "refmgr.ser"; private static final String SERIALIZATION_DIR = "refmgr-attr"; @@ -142,7 +146,7 @@ public class ReferenceManager extends BasicPageFilter implements InternalModule, * * @param engine The WikiEngine to which this is managing references to. */ - public ReferenceManager( final WikiEngine engine ) { + public DefaultReferenceManager( final WikiEngine engine ) { m_refersTo = new HashMap<>(); m_referredBy = new HashMap<>(); m_engine = engine; diff --git a/jspwiki-main/src/main/java/org/apache/wiki/references/ReferenceManager.java b/jspwiki-main/src/main/java/org/apache/wiki/references/ReferenceManager.java new file mode 100644 index 0000000..5e97420 --- /dev/null +++ b/jspwiki-main/src/main/java/org/apache/wiki/references/ReferenceManager.java @@ -0,0 +1,171 @@ +/* + 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.references; + +import org.apache.wiki.WikiPage; +import org.apache.wiki.api.exceptions.ProviderException; +import org.apache.wiki.api.filters.PageFilter; +import org.apache.wiki.event.WikiEventListener; +import org.apache.wiki.modules.InternalModule; + +import java.util.Collection; +import java.util.Set; + +/** + * Keeps track of wikipage references: + * <ul> + * <li>What pages a given page refers to</li> + * <li>What pages refer to a given page</li> + * </ul> + * + * When a page is added or edited, its references are parsed, a Collection is received, and we crudely replace anything previous with + * this new Collection. We then check each referenced page name and make sure they know they are referred to by the new page. + * <p> + * Based on this information, we can perform non-optimal searches for e.g. unreferenced pages, top ten lists, etc. + * <p> + * The owning class must take responsibility of filling in any pre-existing information, probably by loading each and every WikiPage + * and calling this class to update the references when created. + */ +public interface ReferenceManager extends PageFilter, InternalModule, WikiEventListener { + + /** + * Initializes the entire reference manager with the initial set of pages from the collection. + * + * @param pages A collection of all pages you want to be included in the reference count. + * @since 2.2 + * @throws ProviderException If reading of pages fails. + */ + void initialize( final Collection<WikiPage> pages ) throws ProviderException; + + /** + * Reads a WikiPageful of data from a String and returns all links internal to this Wiki in a Collection. + * + * @param page The WikiPage to scan + * @param pagedata The page contents + * @return a Collection of Strings + */ + Collection< String > scanWikiLinks( final WikiPage page, final String pagedata ); + + /** + * Updates the m_referedTo and m_referredBy hashmaps when a page has been deleted. + * <P> + * Within the m_refersTo map the pagename is a key. The whole key-value-set has to be removed to keep the map clean. + * Within the m_referredBy map the name is stored as a value. Since a key can have more than one value we have to + * delete just the key-value-pair referring page:deleted page. + * + * @param page Name of the page to remove from the maps. + */ + void pageRemoved( final WikiPage page ); + + /** + * Updates all references for the given page. + * + * @param page wiki page for which references should be updated + */ + void updateReferences( final WikiPage page ); + + /** + * Updates the referred pages of a new or edited WikiPage. If a refersTo entry for this page already exists, it is removed + * and a new one is built from scratch. Also calls updateReferredBy() for each referenced page. + * <P> + * This is the method to call when a new page has been created and we want to a) set up its references and b) notify the + * referred pages of the references. Use this method during run-time. + * + * @param page Name of the page to update. + * @param references A Collection of Strings, each one pointing to a page this page references. + */ + void updateReferences( final String page, final Collection<String> references ); + + /** + * Clears the references to a certain page so it's no longer in the map. + * + * @param pagename Name of the page to clear references for. + */ + void clearPageEntries( String pagename ); + + + /** + * Finds all unreferenced pages. This requires a linear scan through m_referredBy to locate keys with null or empty values. + * + * @return The Collection of Strings + */ + Collection< String > findUnreferenced(); + + /** + * Finds all references to non-existant pages. This requires a linear scan through m_refersTo values; each value + * must have a corresponding key entry in the reference Maps, otherwise such a page has never been created. + * <P> + * Returns a Collection containing Strings of unreferenced page names. Each non-existant page name is shown only + * once - we don't return information on who referred to it. + * + * @return A Collection of Strings + */ + Collection< String > findUncreated(); + + /** + * Find all pages that refer to this page. Returns null if the page does not exist or is not referenced at all, + * otherwise returns a collection containing page names (String) that refer to this one. + * <p> + * @param pagename The page to find referrers for. + * @return A Set of Strings. May return null, if the page does not exist, or if it has no references. + */ + Set< String > findReferrers( String pagename ); + + /** + * Returns all pages that refer to this page. Note that this method returns an unmodifiable Map, which may be abruptly changed. + * So any access to any iterator may result in a ConcurrentModificationException. + * <p> + * The advantages of using this method over findReferrers() is that it is very fast, as it does not create a new object. + * The disadvantages are that it does not do any mapping between plural names, and you may end up getting a + * ConcurrentModificationException. + * + * @param pageName Page name to query. + * @return A Set of Strings containing the names of all the pages that refer to this page. May return null, if the page does + * not exist or has not been indexed yet. + * @since 2.2.33 + */ + Set< String > findReferredBy( String pageName ); + + /** + * Returns all pages that this page refers to. You can use this as a quick way of getting the links from a page, but note + * that it does not link any InterWiki, image, or external links. It does contain attachments, though. + * <p> + * The Collection returned is unmutable, so you cannot change it. It does reflect the current status and thus is a live + * object. So, if you are using any kind of an iterator on it, be prepared for ConcurrentModificationExceptions. + * <p> + * The returned value is a Collection, because a page may refer to another page multiple times. + * + * @param pageName Page name to query + * @return A Collection of Strings containing the names of the pages that this page refers to. May return null, if the page + * does not exist or has not been indexed yet. + * @since 2.2.33 + */ + Collection< String > findRefersTo( String pageName ); + + /** + * Returns a list of all pages that the ReferenceManager knows about. This should be roughly equivalent to + * PageManager.getAllPages(), but without the potential disk access overhead. Note that this method is not guaranteed + * to return a Set of really all pages (especially during startup), but it is very fast. + * + * @return A Set of all defined page names that ReferenceManager knows about. + * @since 2.3.24 + */ + Set< String > findCreated(); + +} diff --git a/jspwiki-main/src/main/java/org/apache/wiki/references/package.html b/jspwiki-main/src/main/java/org/apache/wiki/references/package.html new file mode 100644 index 0000000..61ac2e8 --- /dev/null +++ b/jspwiki-main/src/main/java/org/apache/wiki/references/package.html @@ -0,0 +1,34 @@ +<!-- + 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. +--> + +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>org.apache.wiki.references</title> +</head> +<body> +Provides the JSPWiki track of pages' references. + +<h3>Package Specification</h3> + +<h3>Related Documentation</h3> + +</body> +</html> \ No newline at end of file diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml index 7a2ca54..dbd3cdb 100644 --- a/jspwiki-main/src/main/resources/ini/classmappings.xml +++ b/jspwiki-main/src/main/resources/ini/classmappings.xml @@ -52,10 +52,6 @@ <mappedClass>org.apache.wiki.pages.DefaultPageManager</mappedClass> </mapping> <mapping> - <requestedClass>org.apache.wiki.ReferenceManager</requestedClass> - <mappedClass>org.apache.wiki.ReferenceManager</mappedClass> - </mapping> - <mapping> <requestedClass>org.apache.wiki.VariableManager</requestedClass> <mappedClass>org.apache.wiki.WikiVariableManager</mappedClass> </mapping> @@ -108,6 +104,10 @@ <mappedClass>org.apache.wiki.i18n.InternationalizationManager</mappedClass> </mapping> <mapping> + <requestedClass>org.apache.wiki.references.ReferenceManager</requestedClass> + <mappedClass>org.apache.wiki.references.DefaultReferenceManager</mappedClass> + </mapping> + <mapping> <requestedClass>org.apache.wiki.render.RenderingManager</requestedClass> <mappedClass>org.apache.wiki.render.RenderingManager</mappedClass> </mapping> diff --git a/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java b/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java index 6f7f9c8..6bbddce 100644 --- a/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java +++ b/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java @@ -27,6 +27,7 @@ import org.apache.wiki.providers.BasicAttachmentProvider; import org.apache.wiki.providers.CachingProvider; import org.apache.wiki.providers.FileSystemProvider; import org.apache.wiki.providers.VerySimpleProvider; +import org.apache.wiki.references.ReferenceManager; import org.apache.wiki.util.TextUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; diff --git a/jspwiki-main/src/test/java/org/apache/wiki/ReferenceManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/references/ReferenceManagerTest.java similarity index 96% rename from jspwiki-main/src/test/java/org/apache/wiki/ReferenceManagerTest.java rename to jspwiki-main/src/test/java/org/apache/wiki/references/ReferenceManagerTest.java index 80d7e6a..ff58d40 100644 --- a/jspwiki-main/src/test/java/org/apache/wiki/ReferenceManagerTest.java +++ b/jspwiki-main/src/test/java/org/apache/wiki/references/ReferenceManagerTest.java @@ -11,8 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.wiki; +package org.apache.wiki.references; import net.sf.ehcache.CacheManager; +import org.apache.wiki.TestEngine; +import org.apache.wiki.Util; +import org.apache.wiki.WikiPage; import org.apache.wiki.api.exceptions.WikiException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -325,14 +328,15 @@ public class ReferenceManagerTest { * with one user, one WikiEngine only. */ public static String dumpReferenceManager( final ReferenceManager rm ) { + final DefaultReferenceManager drm = ( DefaultReferenceManager )rm; final StringBuilder buf = new StringBuilder(); try { buf.append( "================================================================\n" ); buf.append( "Referred By list:\n" ); - Set< String > keys = rm.getReferredBy().keySet(); + Set< String > keys = drm.getReferredBy().keySet(); for( final String key : keys ) { buf.append( key ).append( " referred by: " ); - final Set< String > refs = rm.getReferredBy().get( key ); + final Set< String > refs = drm.getReferredBy().get( key ); for( final String aRef : refs ) { buf.append( aRef ).append( " " ); } @@ -342,10 +346,10 @@ public class ReferenceManagerTest { buf.append( "----------------------------------------------------------------\n" ); buf.append( "Refers To list:\n" ); - keys = rm.getRefersTo().keySet(); + keys = drm.getRefersTo().keySet(); for( final String key : keys ) { buf.append( key ).append( " refers to: " ); - final Collection< String > refs = rm.getRefersTo().get( key ); + final Collection< String > refs = drm.getRefersTo().get( key ); if(refs != null) { for( final String aRef : refs ) { buf.append( aRef ).append( " " );
