📄 referencemanager.java
字号:
} /** * After the page has been saved, updates the reference lists. */ public void postSave( WikiContext context, String content ) { WikiPage page = context.getPage(); updateReferences( page.getName(), context.getEngine().scanWikiLinks( page, content ) ); serializeToDisk(); } /** * 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. */ public synchronized void updateReferences( String page, Collection references ) { // // Create a new entry in m_refersTo. // Collection oldRefTo = (Collection)m_refersTo.get( page ); m_refersTo.remove( page ); m_refersTo.put( page, references ); // // We know the page exists, since it's making references somewhere. // If an entry for it didn't exist previously in m_referredBy, make // sure one is added now. // if( !m_referredBy.containsKey( page ) ) { m_referredBy.put( page, new TreeSet() ); } // // Get all pages that used to be referred to by 'page' and // remove that reference. (We don't want to try to figure out // which particular references were removed...) // cleanReferredBy( page, oldRefTo, references ); // // Notify all referred pages of their referinesshoodicity. // Iterator it = references.iterator(); while( it.hasNext() ) { String referredPageName = (String)it.next(); updateReferredBy( referredPageName, page ); } } /** * Returns the refers-to list. For debugging. */ protected Map getRefersTo() { return( m_refersTo ); } /** * Returns the referred-by list. For debugging. */ protected Map getReferredBy() { return( m_referredBy ); } /** * Cleans the 'referred by' list, removing references by 'referrer' to * any other page. Called after 'referrer' is removed. */ private void cleanReferredBy( String referrer, Collection oldReferred, Collection newReferred ) { // Two ways to go about this. One is to look up all pages previously // referred by referrer and remove referrer from their lists, and let // the update put them back in (except possibly removed ones). // The other is to get the old referred to list, compare to the new, // and tell the ones missing in the latter to remove referrer from // their list. Hm. We'll just try the first for now. Need to come // back and optimize this a bit. if( oldReferred == null ) return; Iterator it = oldReferred.iterator(); while( it.hasNext() ) { String referredPage = (String)it.next(); Set oldRefBy = (Set)m_referredBy.get( referredPage ); if( oldRefBy != null ) { 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() ); // 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; } Set referrers = (Set)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(); m_referredBy.put( page, referrers ); } referrers.add( referrer ); } /** * Finds all unreferenced pages. This requires a linear scan through * m_referredBy to locate keys with null or empty values. */ public synchronized Collection findUnreferenced() { ArrayList unref = new ArrayList(); Set keys = m_referredBy.keySet(); Iterator it = keys.iterator(); while( it.hasNext() ) { String key = (String) it.next(); //Set refs = (Set) m_referredBy.get( key ); 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. */ public synchronized Collection findUncreated() { TreeSet uncreated = new TreeSet(); // 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 allReferences = m_refersTo.values(); Iterator it = allReferences.iterator(); while( it.hasNext() ) { Collection refs = (Collection)it.next(); if( refs != null ) { Iterator rit = refs.iterator(); while( rit.hasNext() ) { String aReference = (String)rit.next(); if( m_engine.pageExists( aReference ) == false ) { uncreated.add( aReference ); } } } } return uncreated; } /** * Searches for the given page in the given Map. */ private Set getReferenceList( Map coll, String pagename ) { Set refs = (Set)coll.get( pagename ); if( (refs == null || refs.size() == 0) && m_matchEnglishPlurals ) { if( pagename.endsWith("s") ) { refs = (Set)coll.get( pagename.substring(0,pagename.length()-1) ); } else { refs = (Set)coll.get( pagename+"s" ); } } 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. */ public synchronized Collection findReferrers( String pagename ) { Set refs = getReferenceList( m_referredBy, pagename ); if( refs == null || refs.isEmpty() ) { return null; } else { return refs; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -