⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 referencemanager.java

📁 jspwiki source code,jspwiki source code
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                oldRefBy.remove( referrer );            }            // If the page is referred to by no one AND it doesn't even            // exist, we might just as well forget about this entry.            // It will be added again elsewhere if new references appear.            if( ( ( oldRefBy == null ) || ( oldRefBy.isEmpty() ) ) &&                ( m_engine.pageExists( referredPage ) == false ) )            {                m_referredBy.remove( referredPage );            }        }    }    /**     *  When initially building a ReferenceManager from scratch, call this method     * BEFORE calling updateReferences() with a full list of existing page names.     * It builds the refersTo and referredBy key lists, thus enabling     * updateReferences() to function correctly.     * <P>     * This method should NEVER be called after initialization. It clears all mappings     * from the reference tables.     *     * @param pages   a Collection containing WikiPage objects.     */    private synchronized void buildKeyLists( Collection pages )    {        m_refersTo.clear();        m_referredBy.clear();        if( pages == null )            return;        Iterator it = pages.iterator();        try        {            while( it.hasNext() )            {                WikiPage page = (WikiPage)it.next();                // We add a non-null entry to referredBy to indicate the referred page exists                m_referredBy.put( page.getName(), new TreeSet<String>() );                // Just add a key to refersTo; the keys need to be in sync with referredBy.                m_refersTo.put( page.getName(), null );            }        }        catch( ClassCastException e )        {            log.fatal( "Invalid collection entry in ReferenceManager.buildKeyLists().", e );        }    }    /**     * Marks the page as referred to by the referrer. If the page does not     * exist previously, nothing is done. (This means that some page, somewhere,     * has a link to a page that does not exist.)     * <P>     * This method is NOT synchronized. It should only be referred to from     * within a synchronized method, or it should be made synced if necessary.     */    private void updateReferredBy( String page, String referrer )    {        // We're not really interested in first level self-references.        /*        if( page.equals( referrer ) )        {            return;        }        */        // Neither are we interested if plural forms refer to each other.        if( m_matchEnglishPlurals )        {            String p2 = page.endsWith("s") ? page.substring(0,page.length()-1) : page+"s";            if( referrer.equals(p2) )            {                return;            }        }        Set<String> referrers = m_referredBy.get( page );        // Even if 'page' has not been created yet, it can still be referenced.        // This requires we don't use m_referredBy keys when looking up missing        // pages, of course.        if(referrers == null)        {            referrers = new TreeSet<String>();            m_referredBy.put( page, referrers );        }        referrers.add( referrer );    }    /**     * 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.     */    public synchronized void clearPageEntries( String pagename )    {        pagename = getFinalPageName(pagename);        //        //  Remove this item from the referredBy list of any page        //  which this item refers to.        //        Collection<String> c = m_refersTo.get( pagename );        if( c != null )        {            for( String key : c )            {                Collection<?> dref = m_referredBy.get( key );                dref.remove( pagename );            }        }        //        //  Finally, remove direct references.        //        m_referredBy.remove( pagename );        m_refersTo.remove( 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     */    public synchronized Collection findUnreferenced()    {        ArrayList<String> unref = new ArrayList<String>();        for( String key : m_referredBy.keySet() )        {            Set<?> refs = getReferenceList( m_referredBy, key );                        if( refs == null || refs.isEmpty() )            {                unref.add( key );            }        }        return unref;    }    /**     * 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     */    public synchronized Collection findUncreated()    {        TreeSet<String> uncreated = new TreeSet<String>();        // Go through m_refersTo values and check that m_refersTo has the corresponding keys.        // We want to reread the code to make sure our HashMaps are in sync...        Collection<Collection<String>> allReferences = m_refersTo.values();        for( Collection<String> refs : allReferences )        {            if( refs != null )            {                for( String aReference : refs )                {                    if( m_engine.pageExists( aReference ) == false )                    {                        uncreated.add( aReference );                    }                }            }        }        return uncreated;    }    /**     *  Searches for the given page in the given Map, and returns     *  the set of references.  This method also takes care of English plural     *  matching.     *       *  @param coll The Map to search in     *  @param pagename The name to find.     *  @return The references list.     */    private <T> Set<T> getReferenceList( Map<String,Set<T>> coll, String pagename )    {        Set<T> refs = coll.get( pagename );        if( m_matchEnglishPlurals )        {            //            //  We'll add also matches from the "other" page.            //            Set<T> refs2;            if( pagename.endsWith("s") )            {                refs2 = coll.get( pagename.substring(0,pagename.length()-1) );            }            else            {                refs2 = coll.get( pagename+"s" );            }            if( refs2 != null )            {                if( refs != null )                    refs.addAll( refs2 );                else                    refs = refs2;            }        }        return refs;    }    /**     * 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 Collection of Strings.  (This is, in fact, a Set, and is likely     *         to change at some point to a Set).  May return null, if the page     *         does not exist, or if it has no references.     */    // FIXME: Return a Set instead of a Collection.    public synchronized Collection findReferrers( String pagename )    {        Set<String> refs = getReferenceList( m_referredBy, pagename );        if( refs == null || refs.isEmpty() )        {            return null;        }        return refs;    }    /**     *  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     */    public Set findReferredBy( String pageName )    {        return m_unmutableReferredBy.get( getFinalPageName(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     */    public Collection findRefersTo( String pageName )    {        return m_unmutableRefersTo.get( getFinalPageName(pageName) );    }    /**     * This 'deepHashCode' can be used to determine if there were any     * modifications made to the underlying to and by maps of the     * ReferenceManager. The maps of the ReferenceManager are not     * synchronized, so someone could add/remove entries in them while the     * hashCode is being computed.     *     * @return Sum of the hashCodes for the to and by maps of the     *         ReferenceManager     * @since 2.3.24     */    //    //   This method traps and retries if a concurrent    //   modifcaition occurs.    //   TODO: It is unnecessary to calculate the hashcode; it should be calculated only    //         when the hashmaps are changed.  This is slow.    //    public int deepHashCode()    {        boolean failed = true;        int signature = 0;        while (failed)        {            signature = 0;            try            {                signature ^= m_referredBy.hashCode();                signature ^= m_refersTo.hashCode();                failed = false;            }            catch (ConcurrentModificationException e)            {                Thread.yield();            }        }        return signature;    }    /**     *  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     */    public Set findCreated()    {        return new HashSet<String>( m_refersTo.keySet() );    }    private String getFinalPageName( String orig )    {        try        {            String s = m_engine.getFinalPageName( orig );            if( s == null ) s = orig;            return s;        }        catch( ProviderException e )        {            log.error("Error while trying to fetch a page name; trying to cope with the situation.",e);            return orig;        }    }    /**     *  {@inheritDoc}     */    public void actionPerformed(WikiEvent event)    {        if( (event instanceof WikiPageEvent) && (event.getType() == WikiPageEvent.PAGE_DELETED) )        {            String pageName = ((WikiPageEvent) event).getPageName();            if( pageName != null )            {                pageRemoved( pageName );            }        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -