📄 pagemanager.java
字号:
/** * This is a simple reaper thread that runs roughly every minute * or so (it's not really that important, as long as it runs), * and removes all locks that have expired. */ private class LockReaper extends WikiBackgroundThread { /** * Create a LockReaper for a given engine. * * @param engine WikiEngine to own this thread. */ public LockReaper( WikiEngine engine ) { super( engine, 60 ); setName("JSPWiki Lock Reaper"); } public void backgroundTask() throws Exception { synchronized( m_pageLocks ) { Collection entries = m_pageLocks.values(); Date now = new Date(); for( Iterator i = entries.iterator(); i.hasNext(); ) { PageLock p = (PageLock) i.next(); if( now.after( p.getExpiryTime() ) ) { i.remove(); log.debug( "Reaped lock: "+p.getPage()+ " by "+p.getLocker()+ ", acquired "+p.getAcquisitionTime()+ ", and expired "+p.getExpiryTime() ); } } } } } // workflow task inner classes.................................................... /** * Inner class that handles the page pre-save actions. If the proposed page * text is the same as the current version, the {@link #execute()} method * returns {@link com.ecyrd.jspwiki.workflow.Outcome#STEP_ABORT}. Any * WikiExceptions thrown by page filters will be re-thrown, and the workflow * will abort. * * @author Andrew Jaquith */ public static class PreSaveWikiPageTask extends Task { private static final long serialVersionUID = 6304715570092804615L; private final WikiContext m_context; private final String m_proposedText; /** * Creates the task. * * @param context The WikiContext * @param proposedText The text that was just saved. */ public PreSaveWikiPageTask( WikiContext context, String proposedText ) { super( PRESAVE_TASK_MESSAGE_KEY ); m_context = context; m_proposedText = proposedText; } /** * {@inheritDoc} */ @Override public Outcome execute() throws WikiException { // Retrieve attributes WikiEngine engine = m_context.getEngine(); Workflow workflow = getWorkflow(); // Get the wiki page WikiPage page = m_context.getPage(); // Figure out who the author was. Prefer the author // set programmatically; otherwise get from the // current logged in user if ( page.getAuthor() == null ) { Principal wup = m_context.getCurrentUser(); if ( wup != null ) page.setAuthor( wup.getName() ); } // Run the pre-save filters. If any exceptions, add error to list, abort, and redirect String saveText; try { saveText = engine.getFilterManager().doPreSaveFiltering( m_context, m_proposedText ); } catch ( FilterException e ) { throw e; } // Stash the wiki context, old and new text as workflow attributes workflow.setAttribute( PRESAVE_WIKI_CONTEXT, m_context ); workflow.setAttribute( FACT_PROPOSED_TEXT, saveText ); return Outcome.STEP_COMPLETE; } } /** * Inner class that handles the actual page save and post-save actions. Instances * of this class are assumed to have been added to an approval workflow via * {@link com.ecyrd.jspwiki.workflow.WorkflowBuilder#buildApprovalWorkflow(Principal, String, Task, String, com.ecyrd.jspwiki.workflow.Fact[], Task, String)}; * they will not function correctly otherwise. * * @author Andrew Jaquith */ public static class SaveWikiPageTask extends Task { private static final long serialVersionUID = 3190559953484411420L; /** * Creates the Task. */ public SaveWikiPageTask() { super( SAVE_TASK_MESSAGE_KEY ); } /** {@inheritDoc} */ @Override public Outcome execute() throws WikiException { // Retrieve attributes WikiContext context = (WikiContext) getWorkflow().getAttribute( PRESAVE_WIKI_CONTEXT ); String proposedText = (String) getWorkflow().getAttribute( FACT_PROPOSED_TEXT ); WikiEngine engine = context.getEngine(); WikiPage page = context.getPage(); // Let the rest of the engine handle actual saving. engine.getPageManager().putPageText( page, proposedText ); // Refresh the context for post save filtering. engine.getPage( page.getName() ); engine.textToHTML( context, proposedText ); engine.getFilterManager().doPostSaveFiltering( context, proposedText ); return Outcome.STEP_COMPLETE; } } // events processing ....................................................... /** * Fires a WikiPageEvent of the provided type and page name * to all registered listeners. * * @see com.ecyrd.jspwiki.event.WikiPageEvent * @param type the event type to be fired * @param pagename the wiki page name as a String */ protected final void fireEvent( int type, String pagename ) { if ( WikiEventManager.isListening(this) ) { WikiEventManager.fireEvent(this,new WikiPageEvent(m_engine,type,pagename)); } } /** * {@inheritDoc} */ @Override public Collection modules() { // TODO Auto-generated method stub return null; } /** * Listens for {@link com.ecyrd.jspwiki.event.WikiSecurityEvent#PROFILE_NAME_CHANGED} * events. If a user profile's name changes, each page ACL is inspected. If an entry contains * a name that has changed, it is replaced with the new one. No events are emitted * as a consequence of this method, because the page contents are still the same; it is * only the representations of the names within the ACL that are changing. * * @param event The event */ public void actionPerformed(WikiEvent event) { if (! ( event instanceof WikiSecurityEvent ) ) { return; } WikiSecurityEvent se = (WikiSecurityEvent)event; if ( se.getType() == WikiSecurityEvent.PROFILE_NAME_CHANGED ) { UserProfile[] profiles = (UserProfile[])se.getTarget(); Principal[] oldPrincipals = new Principal[] { new WikiPrincipal( profiles[0].getLoginName() ), new WikiPrincipal( profiles[0].getFullname() ), new WikiPrincipal( profiles[0].getWikiName() ) }; Principal newPrincipal = new WikiPrincipal( profiles[1].getFullname() ); // Examine each page ACL try { int pagesChanged = 0; Collection pages = getAllPages(); for ( Iterator it = pages.iterator(); it.hasNext(); ) { WikiPage page = (WikiPage)it.next(); boolean aclChanged = changeAcl( page, oldPrincipals, newPrincipal ); if ( aclChanged ) { // If the Acl needed changing, change it now try { m_engine.getAclManager().setPermissions( page, page.getAcl() ); } catch ( WikiSecurityException e ) { log.error( "Could not change page ACL for page " + page.getName() + ": " + e.getMessage() ); } pagesChanged++; } } log.info( "Profile name change for '" + newPrincipal.toString() + "' caused " + pagesChanged + " page ACLs to change also." ); } catch ( ProviderException e ) { // Oooo! This is really bad... log.error( "Could not change user name in Page ACLs because of Provider error:" + e.getMessage() ); } } } /** * For a single wiki page, replaces all Acl entries matching a supplied array of Principals * with a new Principal. * * @param page the wiki page whose Acl is to be modified * @param oldPrincipals an array of Principals to replace; all AclEntry objects whose * {@link AclEntry#getPrincipal()} method returns one of these Principals will be replaced * @param newPrincipal the Principal that should receive the old Principals' permissions * @return <code>true</code> if the Acl was actually changed; <code>false</code> otherwise */ protected boolean changeAcl( WikiPage page, Principal[] oldPrincipals, Principal newPrincipal ) { Acl acl = page.getAcl(); boolean pageChanged = false; if ( acl != null ) { Enumeration entries = acl.entries(); Collection<AclEntry> entriesToAdd = new ArrayList<AclEntry>(); Collection<AclEntry> entriesToRemove = new ArrayList<AclEntry>(); while ( entries.hasMoreElements() ) { AclEntry entry = (AclEntry)entries.nextElement(); if ( ArrayUtils.contains( oldPrincipals, entry.getPrincipal() ) ) { // Create new entry AclEntry newEntry = new AclEntryImpl(); newEntry.setPrincipal( newPrincipal ); Enumeration permissions = entry.permissions(); while ( permissions.hasMoreElements() ) { Permission permission = (Permission)permissions.nextElement(); newEntry.addPermission(permission); } pageChanged = true; entriesToRemove.add( entry ); entriesToAdd.add( newEntry ); } } for ( Iterator ix = entriesToRemove.iterator(); ix.hasNext(); ) { AclEntry entry = (AclEntry)ix.next(); acl.removeEntry( entry ); } for ( Iterator ix = entriesToAdd.iterator(); ix.hasNext(); ) { AclEntry entry = (AclEntry)ix.next(); acl.addEntry( entry ); } } return pageChanged; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -