You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by ja...@apache.org on 2008/12/10 23:57:18 UTC

svn commit: r725479 - in /incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH: ./ lib/ src/com/ecyrd/jspwiki/ src/com/ecyrd/jspwiki/action/ src/com/ecyrd/jspwiki/content/

Author: jalkanen
Date: Wed Dec 10 14:57:18 2008
New Revision: 725479

URL: http://svn.apache.org/viewvc?rev=725479&view=rev
Log:
Switched PageManager to be a facade for ContentManager.
Implemented rest of ContentManager methods.

Added:
    incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/lib/priha-0.1.12.jar   (with props)
Removed:
    incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/lib/priha-0.1.11.jar
Modified:
    incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/.classpath
    incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/PageManager.java
    incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/WikiEngine.java
    incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/action/WikiContextFactory.java
    incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/content/ContentManager.java

Modified: incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/.classpath
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/.classpath?rev=725479&r1=725478&r2=725479&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/.classpath (original)
+++ incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/.classpath Wed Dec 10 14:57:18 2008
@@ -41,7 +41,7 @@
 	<classpathentry kind="lib" path="lib/slf4j-log4j12-1.5.6.jar"/>
 	<classpathentry kind="lib" path="lib/log4j-1.2.14.jar"/>
 	<classpathentry kind="lib" path="lib/jcr-1.0.jar"/>
-	<classpathentry kind="lib" path="lib/priha-0.1.11.jar"/>
+	<classpathentry kind="lib" path="lib/priha-0.1.12.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="lib" path="lib/slf4j-api-1.5.6.jar"/>
 	<classpathentry kind="lib" path="lib/jul-to-slf4j-1.5.6.jar"/>

Added: incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/lib/priha-0.1.12.jar
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/lib/priha-0.1.12.jar?rev=725479&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/lib/priha-0.1.12.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/PageManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/PageManager.java?rev=725479&r1=725478&r2=725479&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/PageManager.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/PageManager.java Wed Dec 10 14:57:18 2008
@@ -59,10 +59,8 @@
  *  actual save.  See the descriptions of the tasks for further information.
  *
  *  @since 2.0
+ *  @deprecated
  */
-// FIXME: This class currently only functions just as an extra layer over providers,
-//        complicating things.  We need to move more provider-specific functionality
-//        from WikiEngine (which is too big now) into this class.
 public class PageManager extends ModuleManager implements WikiEventListener
 {
     private static final long serialVersionUID = 1L;
@@ -112,18 +110,8 @@
     /** Fact name for storing whether the user is authenticated or not.  Value is {@value}. */
     public static final String FACT_IS_AUTHENTICATED = "fact.isAuthenticated";
 
-    static Logger log = LoggerFactory.getLogger( PageManager.class );
-
-    private WikiPageProvider m_provider;
-
-    protected HashMap<String,PageLock> m_pageLocks = new HashMap<String,PageLock>();
-
     private WikiEngine m_engine;
 
-    private int m_expiryTime = 60;
-
-    private LockReaper m_reaper = null;
-
     /**
      *  Creates a new PageManager.
      *  
@@ -135,66 +123,7 @@
         throws WikiException
     {
         super( engine );
-
-        String classname;
-
         m_engine = engine;
-
-        boolean useCache = "true".equals(props.getProperty( PROP_USECACHE ));
-
-        m_expiryTime = TextUtil.parseIntParameter( props.getProperty( PROP_LOCKEXPIRY ), 60 );
-
-        //
-        //  If user wants to use a cache, then we'll use the CachingProvider.
-        //
-        if( useCache )
-        {
-            classname = "com.ecyrd.jspwiki.providers.CachingProvider";
-        }
-        else
-        {
-            classname = WikiEngine.getRequiredProperty( props, PROP_PAGEPROVIDER );
-        }
-
-        try
-        {
-            log.debug("Page provider class: '"+classname+"'");
-
-            Class providerclass = ClassUtil.findClass( "com.ecyrd.jspwiki.providers",
-                                                       classname );
-
-            m_provider = (WikiPageProvider)providerclass.newInstance();
-
-            log.debug("Initializing page provider class "+m_provider);
-            m_provider.initialize( m_engine, props );
-        }
-        catch( ClassNotFoundException e )
-        {
-            log.error("Unable to locate provider class '"+classname+"'",e);
-            throw new WikiException("no provider class");
-        }
-        catch( InstantiationException e )
-        {
-            log.error("Unable to create provider class '"+classname+"'",e);
-            throw new WikiException("faulty provider class");
-        }
-        catch( IllegalAccessException e )
-        {
-            log.error("Illegal access to provider class '"+classname+"'",e);
-            throw new WikiException("illegal provider class");
-        }
-        catch( NoRequiredPropertyException e )
-        {
-            log.error("Provider did not found a property it was looking for: "+e.getMessage(),
-                      e);
-            throw e;  // Same exception works.
-        }
-        catch( IOException e )
-        {
-            log.error("An I/O exception occurred while trying to create a new page provider: "+classname, e );
-            throw new WikiException("Unable to start page provider: "+e.getMessage());
-        }
-
     }
 
 
@@ -205,7 +134,7 @@
      */
     public WikiPageProvider getProvider()
     {
-        return m_provider;
+        return null;
     }
 
     /**
@@ -219,7 +148,8 @@
     public Collection getAllPages()
         throws ProviderException
     {
-        return m_provider.getAllPages();
+        return m_engine.getContentManager().getAllPages( m_engine.getWikiContextFactory().newEmptyContext(), 
+                                                         null );
     }
 
     /**
@@ -235,49 +165,14 @@
     public String getPageText( String pageName, int version )
         throws ProviderException
     {
-        if( pageName == null || pageName.length() == 0 )
-        {
-            throw new ProviderException("Illegal page name");
-        }
-
-        String text = null;
-
         try
         {
-            text = m_provider.getPageText( pageName, version );
+            return m_engine.getContentManager().getPageText( pageName, version );
         }
-        catch( RepositoryModifiedException e )
+        catch( WikiException e )
         {
-            //
-            //  This only occurs with the latest version.
-            //
-            log.info("Repository has been modified externally while fetching page "+pageName );
-
-            //
-            //  Empty the references and yay, it shall be recalculated
-            //
-            //WikiPage p = new WikiPage( pageName );
-            WikiPage p = m_provider.getPageInfo( pageName, version );
-
-            m_engine.updateReferences( p );
-
-            if( p != null )
-            {
-                m_engine.getSearchManager().reindexPage( p );
-                text = m_provider.getPageText( pageName, version );
-            }
-            else
-            {
-                //
-                //  Make sure that it no longer exists in internal data structures either.
-                //
-                WikiPage dummy = new WikiPage(m_engine,pageName);
-                m_engine.getSearchManager().pageRemoved(dummy);
-                m_engine.getReferenceManager().pageRemoved(dummy);
-            }
+            throw new ProviderException("");
         }
-
-        return text;
     }
 
     /**
@@ -301,12 +196,15 @@
     public void putPageText( WikiPage page, String content )
         throws ProviderException
     {
-        if( page == null || page.getName() == null || page.getName().length() == 0 )
+        try
         {
-            throw new ProviderException("Illegal page name");
+            page.setContent( content );
+            page.save();
+        }
+        catch( WikiException e )
+        {
+            throw new ProviderException("",e);
         }
-
-        m_provider.putPageText( page, content );
     }
 
     /**
@@ -320,47 +218,7 @@
      */
     public PageLock lockPage( WikiPage page, String user )
     {
-        PageLock lock = null;
-
-        if( m_reaper == null )
-        {
-            //
-            //  Start the lock reaper lazily.  We don't want to start it in
-            //  the constructor, because starting threads in constructors
-            //  is a bad idea when it comes to inheritance.  Besides,
-            //  laziness is a virtue.
-            //
-            m_reaper = new LockReaper( m_engine );
-            m_reaper.start();
-        }
-
-        synchronized( m_pageLocks )
-        {
-            fireEvent( WikiPageEvent.PAGE_LOCK, page.getName() ); // prior to or after actual lock?
-
-            lock = m_pageLocks.get( page.getName() );
-
-            if( lock == null )
-            {
-                //
-                //  Lock is available, so make a lock.
-                //
-                Date d = new Date();
-                lock = new PageLock( page, user, d,
-                                     new Date( d.getTime() + m_expiryTime*60*1000L ) );
-
-                m_pageLocks.put( page.getName(), lock );
-
-                log.debug( "Locked page "+page.getName()+" for "+user);
-            }
-            else
-            {
-                log.debug( "Page "+page.getName()+" already locked by "+lock.getLocker() );
-                lock = null; // Nothing to return
-            }
-        }
-
-        return lock;
+        return m_engine.getContentManager().lockPage( page, user );
     }
 
     /**
@@ -371,16 +229,7 @@
      */
     public void unlockPage( PageLock lock )
     {
-        if( lock == null ) return;
-
-        synchronized( m_pageLocks )
-        {
-            m_pageLocks.remove( lock.getPage() );
-
-            log.debug( "Unlocked page "+lock.getPage() );
-        }
-
-        fireEvent( WikiPageEvent.PAGE_UNLOCK, lock.getPage() );
+        m_engine.getContentManager().unlockPage( lock );
     }
 
     /**
@@ -392,14 +241,7 @@
      */
     public PageLock getCurrentLock( WikiPage page )
     {
-        PageLock lock = null;
-
-        synchronized( m_pageLocks )
-        {
-            lock = m_pageLocks.get( page.getName() );
-        }
-
-        return lock;
+        return m_engine.getContentManager().getCurrentLock( page );
     }
 
     /**
@@ -412,17 +254,7 @@
      */
     public List getActiveLocks()
     {
-        ArrayList<PageLock> result = new ArrayList<PageLock>();
-
-        synchronized( m_pageLocks )
-        {
-            for( PageLock lock : m_pageLocks.values() )
-            {
-                result.add( lock );
-            }
-        }
-
-        return result;
+        return m_engine.getContentManager().getActiveLocks();
     }
 
     /**
@@ -437,47 +269,18 @@
     public WikiPage getPageInfo( String pageName, int version )
         throws ProviderException
     {
-        if( pageName == null || pageName.length() == 0 )
-        {
-            throw new ProviderException("Illegal page name '"+pageName+"'");
-        }
-
-        WikiPage page = null;
-
+        WikiContext context = m_engine.getWikiContextFactory().newViewContext( null, 
+                                                                               null, 
+                                                                               new WikiPage(m_engine,pageName) );
+        
         try
         {
-            page = m_provider.getPageInfo( pageName, version );
+            return m_engine.getContentManager().getPage( context, pageName, version );
         }
-        catch( RepositoryModifiedException e )
-        {
-            //
-            //  This only occurs with the latest version.
-            //
-            log.info("Repository has been modified externally while fetching info for "+pageName );
-
-            page = m_provider.getPageInfo( pageName, version );
-
-            if( page != null )
-            {
-                m_engine.updateReferences( page );
-            }
-            else
-            {
-                m_engine.getReferenceManager().pageRemoved( new WikiPage(m_engine,pageName) );
-            }
-        }
-
-        //
-        //  Should update the metadata.
-        //
-        /*
-        if( page != null && !page.hasMetadata() )
+        catch( WikiException e )
         {
-            WikiContext ctx = new WikiContext(m_engine,page);
-            m_engine.textToHTML( ctx, getPageText(pageName,version) );
+            throw new ProviderException("");
         }
-        */
-        return page;
     }
 
     /**
@@ -492,12 +295,11 @@
     public List getVersionHistory( String pageName )
         throws ProviderException
     {
-        if( pageExists( pageName ) )
-        {
-            return m_provider.getVersionHistory( pageName );
-        }
+        WikiContext context = m_engine.getWikiContextFactory().newViewContext( null, 
+                                                                               null, 
+                                                                               new WikiPage(m_engine,pageName) );
 
-        return null;
+        return m_engine.getContentManager().getVersionHistory( context, pageName );
     }
 
     /**
@@ -507,7 +309,7 @@
      */
     public String getProviderDescription()
     {
-        return m_provider.getProviderInfo();
+        return m_engine.getContentManager().getProviderDescription();
     }
 
     /**
@@ -522,11 +324,10 @@
     {
         try
         {
-            return m_provider.getAllPages().size();
+            return getAllPages().size();
         }
         catch( ProviderException e )
         {
-            log.error( "Unable to count pages: ",e );
             return -1;
         }
     }
@@ -541,12 +342,11 @@
     public boolean pageExists( String pageName )
         throws ProviderException
     {
-        if( pageName == null || pageName.length() == 0 )
-        {
-            throw new ProviderException("Illegal page name");
-        }
+        WikiContext ctx = m_engine.getWikiContextFactory().newViewContext( null, 
+                                                                           null, 
+                                                                           new WikiPage(m_engine,pageName) );
 
-        return m_provider.pageExists( pageName );
+        return m_engine.getContentManager().pageExists( ctx, pageName );
     }
 
     /**
@@ -561,20 +361,18 @@
     public boolean pageExists( String pageName, int version )
         throws ProviderException
     {
-        if( pageName == null || pageName.length() == 0 )
-        {
-            throw new ProviderException("Illegal page name");
-        }
-
-        if( version == WikiProvider.LATEST_VERSION )
-            return pageExists( pageName );
+        WikiContext ctx = m_engine.getWikiContextFactory().newViewContext( null, 
+                                                                           null, 
+                                                                           new WikiPage(m_engine,pageName) );
 
-        if( m_provider instanceof CachingProvider )
+        try
         {
-            return ((CachingProvider)m_provider).pageExists( pageName , version );
+            return m_engine.getContentManager().pageExists( ctx, pageName, version );
         }
-
-        return m_provider.getPageInfo( pageName, version ) != null;
+        catch( WikiException e )
+        {
+            throw new ProviderException("");
+        }        
     }
 
     /**
@@ -586,10 +384,14 @@
     public void deleteVersion( WikiPage page )
         throws ProviderException
     {
-        m_provider.deleteVersion( page.getName(), page.getVersion() );
-
-        // FIXME: If this was the latest, reindex Lucene
-        // FIXME: Update RefMgr
+        try
+        {
+            m_engine.getContentManager().deleteVersion( page );
+        }
+        catch( WikiException e )
+        {
+            throw new ProviderException("");
+        }
     }
 
     /**
@@ -601,193 +403,17 @@
     public void deletePage( WikiPage page )
         throws ProviderException
     {
-        fireEvent( WikiPageEvent.PAGE_DELETE_REQUEST, page.getName() );
-
-        m_provider.deletePage( page.getName() );
-
-        fireEvent( WikiPageEvent.PAGE_DELETED, page.getName() );
-    }
-
-    /**
-     *  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()
+        try
         {
-            super( SAVE_TASK_MESSAGE_KEY );
+            m_engine.getContentManager().deletePage( page );
         }
-
-        /** {@inheritDoc} */
-        @Override
-        public Outcome execute() throws WikiException
+        catch( WikiException e )
         {
-            // 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;
+            throw new ProviderException("");
         }
     }
 
-    // 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()
     {
@@ -796,116 +422,10 @@
     }
 
 
-    /**
-     *  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;
+    public void actionPerformed( WikiEvent event )
+    {
+        // TODO Auto-generated method stub
+        
     }
 
 }

Modified: incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/WikiEngine.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/WikiEngine.java?rev=725479&r1=725478&r2=725479&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/WikiEngine.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/WikiEngine.java Wed Dec 10 14:57:18 2008
@@ -1741,21 +1741,21 @@
         // If submitter is authenticated, any reject messages will appear in his/her workflow inbox.
         WorkflowBuilder builder = WorkflowBuilder.getBuilder( this );
         Principal submitter = context.getCurrentUser();
-        Task prepTask = new PageManager.PreSaveWikiPageTask( context, proposedText );
-        Task completionTask = new PageManager.SaveWikiPageTask();
+        Task prepTask = new ContentManager.PreSaveWikiPageTask( context, proposedText );
+        Task completionTask = new ContentManager.SaveWikiPageTask();
         String diffText = m_differenceManager.makeDiff( context, oldText, proposedText );
         boolean isAuthenticated = context.getWikiSession().isAuthenticated();
         Fact[] facts = new Fact[5];
-        facts[0] = new Fact( PageManager.FACT_PAGE_NAME, page.getName() );
-        facts[1] = new Fact( PageManager.FACT_DIFF_TEXT, diffText );
-        facts[2] = new Fact( PageManager.FACT_PROPOSED_TEXT, proposedText );
-        facts[3] = new Fact( PageManager.FACT_CURRENT_TEXT, oldText);
-        facts[4] = new Fact( PageManager.FACT_IS_AUTHENTICATED, Boolean.valueOf( isAuthenticated ) );
-        String rejectKey = isAuthenticated ? PageManager.SAVE_REJECT_MESSAGE_KEY : null;
+        facts[0] = new Fact( ContentManager.FACT_PAGE_NAME, page.getName() );
+        facts[1] = new Fact( ContentManager.FACT_DIFF_TEXT, diffText );
+        facts[2] = new Fact( ContentManager.FACT_PROPOSED_TEXT, proposedText );
+        facts[3] = new Fact( ContentManager.FACT_CURRENT_TEXT, oldText);
+        facts[4] = new Fact( ContentManager.FACT_IS_AUTHENTICATED, Boolean.valueOf( isAuthenticated ) );
+        String rejectKey = isAuthenticated ? ContentManager.SAVE_REJECT_MESSAGE_KEY : null;
         Workflow workflow = builder.buildApprovalWorkflow( submitter,
-                                                           PageManager.SAVE_APPROVER,
+                                                           ContentManager.SAVE_APPROVER,
                                                            prepTask,
-                                                           PageManager.SAVE_DECISION_MESSAGE_KEY,
+                                                           ContentManager.SAVE_DECISION_MESSAGE_KEY,
                                                            facts,
                                                            completionTask,
                                                            rejectKey );

Modified: incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/action/WikiContextFactory.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/action/WikiContextFactory.java?rev=725479&r1=725478&r2=725479&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/action/WikiContextFactory.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/action/WikiContextFactory.java Wed Dec 10 14:57:18 2008
@@ -649,4 +649,20 @@
         }
         return m_engine.getPageManager().pageExists( page );
     }
+
+    /**
+     *  Creates an "empty" wiki context which is used internally sometimes when
+     *  access to the repository is desired outside of a request.  This is
+     *  really just shorthand of getting a new VIEW context with an imaginary
+     *  page.
+     *  
+     *  @return A valid WikiContext.
+     */
+    // TODO: Should this be better called "newVirtualContext()" or something?  "Empty" is not
+    //       very descriptive.
+    public WikiContext newEmptyContext()
+    {
+        WikiPage page = new WikiPage(m_engine,"__DUMMY__");
+        return newViewContext( null, null, page );
+    }
 }

Modified: incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/content/ContentManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/content/ContentManager.java?rev=725479&r1=725478&r2=725479&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/content/ContentManager.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_JCR_BRANCH/src/com/ecyrd/jspwiki/content/ContentManager.java Wed Dec 10 14:57:18 2008
@@ -20,6 +20,8 @@
  */
 package com.ecyrd.jspwiki.content;
 
+import java.security.Permission;
+import java.security.Principal;
 import java.util.*;
 
 import javax.jcr.*;
@@ -33,18 +35,31 @@
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
 
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.jspwiki.api.FilterException;
 import org.apache.jspwiki.api.WikiException;
 import org.priha.RepositoryManager;
 import org.priha.util.ConfigurationException;
 
 import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.auth.WikiPrincipal;
+import com.ecyrd.jspwiki.auth.WikiSecurityException;
+import com.ecyrd.jspwiki.auth.acl.Acl;
+import com.ecyrd.jspwiki.auth.acl.AclEntry;
+import com.ecyrd.jspwiki.auth.acl.AclEntryImpl;
+import com.ecyrd.jspwiki.auth.user.UserProfile;
+import com.ecyrd.jspwiki.event.WikiEvent;
 import com.ecyrd.jspwiki.event.WikiEventManager;
 import com.ecyrd.jspwiki.event.WikiPageEvent;
+import com.ecyrd.jspwiki.event.WikiSecurityEvent;
 import com.ecyrd.jspwiki.log.Logger;
 import com.ecyrd.jspwiki.log.LoggerFactory;
 import com.ecyrd.jspwiki.providers.ProviderException;
 import com.ecyrd.jspwiki.util.TextUtil;
 import com.ecyrd.jspwiki.util.WikiBackgroundThread;
+import com.ecyrd.jspwiki.workflow.Outcome;
+import com.ecyrd.jspwiki.workflow.Task;
+import com.ecyrd.jspwiki.workflow.Workflow;
 
 /**
  *  Provides access to the content repository.  Unlike previously, in JSPWiki
@@ -59,9 +74,16 @@
  *  and "jackrabbit" for <a href="http://jackrabbit.apache.org">Apache Jackrabbit</a>.
  *  <p>
  *  If there is no property defined, defaults to "priha".
+ *
+ *  FIXME:
+ *    * This class is currently designed to be a drop-in replacement for PageManager.
+ *      However, this brings in a lot of unfortunate side effects in complexity, and
+ *      it does not really take advantage of all of the JCR API.  Therefore, this
+ *      class should be treated as extremely volatile.
  *  
  *  @since 3.0
  */
+
 public class ContentManager
 {
     protected static final String DEFAULT_SPACE = "Main";
@@ -281,7 +303,7 @@
         
             QueryManager mgr = session.getWorkspace().getQueryManager();
             
-            Query q = mgr.createQuery( "/"+JCR_PAGES_NODE+"/"+((space != null) ? space : "")+"/*", Query.XPATH );
+            Query q = mgr.createQuery( "/jcr:root/"+JCR_PAGES_NODE+"/"+((space != null) ? space : "")+"/*", Query.XPATH );
             
             QueryResult qr = q.execute();
             
@@ -289,7 +311,9 @@
             {
                 Node n = ni.nextNode();
                 
-                result.add( new WikiPage(ctx.getEngine(), n ) );
+                // Hack to make sure we don't add the space root node. 
+                if( n.getDepth() != 2 )
+                    result.add( new WikiPage(ctx.getEngine(), n ) );
             }
         }
         catch( RepositoryException e )
@@ -320,7 +344,10 @@
             throw new WikiException("Illegal page name");
         }
 
-        WikiPage p = getPage( null, path, version );
+        WikiContext ctx = m_engine.getWikiContextFactory().newViewContext( null, 
+                                                                           null, 
+                                                                           new WikiPage(m_engine,path) );
+        WikiPage p = getPage( ctx, path, version );
         
         return p.getContentAsString();
     }
@@ -344,50 +371,51 @@
      *  @param user Username to use for locking
      *  @return null, if page could not be locked.
      */
-//    public PageLock lockPage( WikiPage page, String user )
-//    {
-//        PageLock lock = null;
-//
-//        if( m_reaper == null )
-//        {
-//            //
-//            //  Start the lock reaper lazily.  We don't want to start it in
-//            //  the constructor, because starting threads in constructors
-//            //  is a bad idea when it comes to inheritance.  Besides,
-//            //  laziness is a virtue.
-//            //
-//            m_reaper = new LockReaper( m_engine );
-//            m_reaper.start();
-//        }
-//
-//        synchronized( m_pageLocks )
-//        {
-//            fireEvent( WikiPageEvent.PAGE_LOCK, page.getName() ); // prior to or after actual lock?
-//
-//            lock = m_pageLocks.get( page.getName() );
-//
-//            if( lock == null )
-//            {
-//                //
-//                //  Lock is available, so make a lock.
-//                //
-//                Date d = new Date();
-//                lock = new PageLock( page, user, d,
-//                                     new Date( d.getTime() + m_expiryTime*60*1000L ) );
-//
-//                m_pageLocks.put( page.getName(), lock );
-//
-//                log.debug( "Locked page "+page.getName()+" for "+user);
-//            }
-//            else
-//            {
-//                log.debug( "Page "+page.getName()+" already locked by "+lock.getLocker() );
-//                lock = null; // Nothing to return
-//            }
-//        }
-//
-//        return lock;
-//    }
+    // FIXME: This should probably also cause a lock in the repository.
+    public PageLock lockPage( WikiPage page, String user )
+    {
+        PageLock lock = null;
+
+        if( m_reaper == null )
+        {
+            //
+            //  Start the lock reaper lazily.  We don't want to start it in
+            //  the constructor, because starting threads in constructors
+            //  is a bad idea when it comes to inheritance.  Besides,
+            //  laziness is a virtue.
+            //
+            m_reaper = new LockReaper( m_engine );
+            m_reaper.start();
+        }
+
+        synchronized( m_pageLocks )
+        {
+            fireEvent( WikiPageEvent.PAGE_LOCK, page.getName() ); // prior to or after actual lock?
+
+            lock = m_pageLocks.get( page.getName() );
+
+            if( lock == null )
+            {
+                //
+                //  Lock is available, so make a lock.
+                //
+                Date d = new Date();
+                lock = new PageLock( page, user, d,
+                                     new Date( d.getTime() + m_expiryTime*60*1000L ) );
+
+                m_pageLocks.put( page.getName(), lock );
+
+                log.debug( "Locked page "+page.getName()+" for "+user);
+            }
+            else
+            {
+                log.debug( "Page "+page.getName()+" already locked by "+lock.getLocker() );
+                lock = null; // Nothing to return
+            }
+        }
+
+        return lock;
+    }
     /**
      *  Marks a page free to be written again.  If there has not been a lock,
      *  will fail quietly.
@@ -435,7 +463,7 @@
      *          an empty list.
      *  @since 2.0.22.
      */
-    public List getActiveLocks()
+    public List<PageLock> getActiveLocks()
     {
         ArrayList<PageLock> result = new ArrayList<PageLock>();
 
@@ -460,7 +488,9 @@
      *                            name or the repository
      */
     /*
-    public WikiPage getPageInfo( String pageName, int version )
+    // FIXME: Remove.  Just exists to make sure that all the things that need
+    //        to be called are called.
+    public WikiPage getPage( String pageName, int version )
         throws ProviderException
     {
         if( pageName == null || pageName.length() == 0 )
@@ -515,29 +545,48 @@
      *          of WikiPages.
      *  @throws ProviderException If the repository fails.
      */
-    /*
-    public List getVersionHistory( String pageName )
+
+    public List<WikiPage> getVersionHistory( WikiContext ctx, String path )
         throws ProviderException
     {
-        if( pageExists( pageName ) )
+        List<WikiPage> result = new ArrayList<WikiPage>();
+        WikiPage base = getPage(ctx,path);
+
+        Node baseNode = base.getJCRNode();
+        
+        try
+        {
+            VersionHistory vh = baseNode.getVersionHistory();
+            
+            for( VersionIterator vi = vh.getAllVersions(); vi.hasNext(); )
+            {
+                Version v = vi.nextVersion();
+                
+                result.add( new WikiPage(m_engine,v) );
+            }
+        }
+        catch( RepositoryException e )
         {
-            return m_provider.getVersionHistory( pageName );
+            throw new ProviderException("Unable to get version history",e);
         }
-
-        return null;
+        catch( WikiException e )
+        {
+            throw new ProviderException("Unable to get version history",e);
+        }
+        
+        return result;
     }
-*/
+    
     /**
      *  Returns a human-readable description of the current provider.
      *  
      *  @return A human-readable description.
      */
-    /*
     public String getProviderDescription()
     {
-        return m_provider.getProviderInfo();
+        return m_repository.getDescriptor( Repository.REP_NAME_DESC );
     }
-*/
+
     /**
      *  Returns the total count of all pages in the repository. This
      *  method is equivalent of calling getAllPages().size(), but
@@ -546,12 +595,13 @@
      *  
      *  @return The number of pages, or -1, if there is an error.
      */
-    /*
-    public int getTotalPageCount()
+    // FIXME: Unfortunately this method is very slow, since it involves gobbling
+    //        up the entire repo.
+    public int getTotalPageCount(WikiContext context, String space)
     {
         try
         {
-            return m_provider.getAllPages().size();
+            return getAllPages(context, space).size();
         }
         catch( ProviderException e )
         {
@@ -559,26 +609,36 @@
             return -1;
         }
     }
-*/
     /**
      *  Returns true, if the page exists (any version).
      *  
-     *  @param pageName  Name of the page.
+     *  @param wikiPath  Name of the page.
      *  @return A boolean value describing the existence of a page
      *  @throws ProviderException If the backend fails or the name is illegal.
      */
-    /*
-    public boolean pageExists( String pageName )
+ 
+    public boolean pageExists( WikiContext ctx, String wikiPath )
         throws ProviderException
     {
-        if( pageName == null || pageName.length() == 0 )
+        if( wikiPath == null || wikiPath.length() == 0 )
         {
             throw new ProviderException("Illegal page name");
         }
 
-        return m_provider.pageExists( pageName );
+        try
+        {
+            Session session = getJCRSession( ctx );
+            
+            String jcrPath = getJCRPath( ctx, wikiPath ); 
+            
+            return session.getRootNode().hasNode( jcrPath );
+        }
+        catch( RepositoryException e )
+        {
+            throw new ProviderException( "Unable to check for page existence",e);
+        }
     }
-*/
+    
     /**
      *  Checks for existence of a specific page and version.
      *  
@@ -601,7 +661,7 @@
         {
             session = getJCRSession( ctx );
             
-            return session.itemExists( getJCRPath( (WikiContext) ctx, path ) );
+            return session.itemExists( getJCRPath( ctx, path ) );
         }
         catch( RepositoryException e )
         {
@@ -734,109 +794,109 @@
      *
      * @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;
-//        }
-//    }
+    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 .......................................................
 
@@ -876,9 +936,8 @@
      *  @param ctx The current WikiContext.  May be null, in which case the wikiName must be a FQN.
      *  @param wikiName The WikiName.
      *  @return A full JCR path
-     *  @throws WikiException If the conversion could not be done.
      */
-    protected static String getJCRPath( WikiContext ctx, String wikiName ) throws WikiException
+    protected static String getJCRPath( WikiContext ctx, String wikiName )
     {
         String spaceName;
         String spacePath;
@@ -927,11 +986,14 @@
 
             int firstSlash = wikiPath.indexOf( '/' );
             
-            return new WikiName(wikiPath.substring( 0, firstSlash ), 
-                                wikiPath.substring( firstSlash+1 ) );
+            if( firstSlash != -1 )
+            {
+                return new WikiName(wikiPath.substring( 0, firstSlash ), 
+                                    wikiPath.substring( firstSlash+1 ) );
+            }
         }
         
-        throw new WikiException("This is not a valid JCR path: "+jcrpath);
+        throw new WikiException("This is not a valid JSPWiki JCR path: "+jcrpath);
     }
     
     /**
@@ -967,7 +1029,7 @@
      *  @param path
      *  @return
      */
-    public WikiPage getPage( WikiContext context, String path ) throws WikiException
+    public WikiPage getPage( WikiContext context, String path ) throws ProviderException
     {
         try
         {
@@ -985,7 +1047,7 @@
         }
         catch( RepositoryException e )
         {
-            throw new WikiException( "Unable to get a page", e );
+            throw new ProviderException( "Unable to get a page", e );
         }
     }
 
@@ -1021,56 +1083,56 @@
      * 
      *  @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() );
-//            }
-//        }
-//    }
+    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( m_engine.getWikiContextFactory().newEmptyContext(), null );
+                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 
@@ -1082,46 +1144,46 @@
      *  @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;
-//    }
+    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;
+    }
 
 }