Looking for help with groovy

classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Looking for help with groovy

DeHaynes
I am trying to modify the following code so when the user enters a new documentName, it will set the title and rename the document.  If I uncomment the saveDocument line, it works.  So I know the rest of the code is working.  Can anyone see what I am doing wrong?

{{groovy}}
import org.xwiki.observation.*
import org.xwiki.observation.event.*
import org.xwiki.bridge.event.*
import org.xwiki.context.*
import com.xpn.xwiki.web.*
import com.xpn.xwiki.*
import org.apache.velocity.VelocityContext;

class ProcessDocumentRenamer implements EventListener
{
    def xwiki
    def context
 
    ProcessDocumentRenamer(xwiki, context)
    {
        this.xwiki = xwiki
        this.context = context
    }

    String getName()
    {
        // The unique name of this event listener
        return "ProcessDocumentRenamer"
    }

    List<Event> getEvents()
    {
        // The list of events this listener listens to
        return Arrays.asList(new DocumentCreatedEvent(), new DocumentUpdatedEvent())
    }

    // Called by the Observation Manager when an event matches the list of events returned
    // by getEvents()
    void onEvent(Event event, Object source, Object data)
    {
        // Current context
        def crtContext = Utils.getComponent(Execution.class).getContext().getProperty('xwikicontext')

        // Defines the type of object that should be looked for
        def myObject = source.getObject("DocumentationTemplates.ProcessClass");

        // If the page has an object of the specified class, we get the value of the relevant property and assign it to our documentName variable
        if (myObject != null) {
          // Defines the variable that we will later use to update the title of the document
          def documentName = myObject.get("processName").value
          // Defines the Complete name we will use later when we rename the document.
          def FullDocumentName = source.getWikiName() + "!" + source.getSpaceName() + "." + documentName;
          // If the name has changed, we need to update and rename the document.
          if (source.getName() != documentName) {
            source.setTitle(documentName)
            // Force the storage to keep the same version number, so that this looks like a single save event
            source.setMetaDataDirty(false);
            source.setContentDirty(false);
            // crtContext.getWiki().saveDocument(source, source.getComment(), source.isMinorEdit(), crtContext);

            crtContext.getWiki().renamePage(source, FullDocumentName);
          }
        }        
    }
}

// Register against the Observation Manager
def observation = Utils.getComponent(ObservationManager.class)
observation.removeListener("ProcessDocumentRenamer")
def listener = new ProcessDocumentRenamer(xwiki, xcontext)
observation.addListener(listener)
{{/groovy}}
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
OK, I got the following groovy script to rename the document when it is saved.  My problem now is redirecting the browser to the new document.

{{groovy}}
import org.xwiki.observation.*
import org.xwiki.observation.event.*
import org.xwiki.bridge.event.*
import org.xwiki.context.*
import com.xpn.xwiki.web.*
import com.xpn.xwiki.*
import org.apache.velocity.VelocityContext;

class ProcessDocumentRenamer implements EventListener
{
    def xwiki
    def context
 
    ProcessDocumentRenamer(xwiki, context)
    {
        this.xwiki = xwiki
        this.context = context
    }

    String getName()
    {
        // The unique name of this event listener
        return "ProcessDocumentRenamer"
    }

    List<Event> getEvents()
    {
        // The list of events this listener listens to
        return Arrays.asList(new DocumentCreatedEvent(), new DocumentUpdatedEvent())
    }

    // Called by the Observation Manager when an event matches the list of events returned
    // by getEvents()
    void onEvent(Event event, Object source, Object data)
    {
        // Current context
        def crtContext = Utils.getComponent(Execution.class).getContext().getProperty('xwikicontext')

        // Defines the type of object that should be looked for
        def myObject = source.getObject("DocumentationTemplates.ProcessClass");

        // If the page has an object of the specified class, we get the value of the relevant property and assign it to our title variable
        if (myObject != null) {
          // Defines the variable that we will later use to update the title of the document
          def documentName = myObject.get("processName").value

          if (source.getName() != documentName) {
            // Build the new name for the document.
            def FullDocumentName = source.getSpaceName() + "." + documentName;

            // Set the document title to the new name.
            source.setTitle(documentName)

            // Force the storage to keep the same version number, so that this looks like a single save event
            source.setMetaDataDirty(false);
            source.setContentDirty(false);

            // Rename the document
            source.rename(FullDocumentName, crtContext);
          }
        }        
    }
}

// Register against the Observation Manager
def observation = Utils.getComponent(ObservationManager.class)
observation.removeListener("ProcessDocumentRenamer")
def listener = new ProcessDocumentRenamer(xwiki, xcontext)
observation.addListener(listener)
{{/groovy}}
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
Groovy runs at javascript in the browser?  Is that correct?

I added the redirect line below the rename line and it didn't work.

{{groovy}}
import org.xwiki.observation.*
import org.xwiki.observation.event.*
import org.xwiki.bridge.event.*
import org.xwiki.context.*
import com.xpn.xwiki.web.*
import com.xpn.xwiki.*
import org.apache.velocity.VelocityContext;

class ProcessDocumentRenamer implements EventListener
{
    def xwiki
    def context
 
    ProcessDocumentRenamer(xwiki, context)
    {
        this.xwiki = xwiki
        this.context = context
    }

    String getName()
    {
        // The unique name of this event listener
        return "ProcessDocumentRenamer"
    }

    List<Event> getEvents()
    {
        // The list of events this listener listens to
        return Arrays.asList(new DocumentCreatedEvent(), new DocumentUpdatedEvent())
    }

    // Called by the Observation Manager when an event matches the list of events returned
    // by getEvents()
    void onEvent(Event event, Object source, Object data)
    {
        // Current context
        def crtContext = Utils.getComponent(Execution.class).getContext().getProperty('xwikicontext')

        // Defines the type of object that should be looked for
        def myObject = source.getObject("DocumentationTemplates.ProcessClass");

        // If the page has an object of the specified class, we get the value of the relevant property and assign it to our title variable
        if (myObject != null) {
          // Defines the variable that we will later use to update the title of the document
          def documentName = myObject.get("processName").value

          if (source.getName() != documentName) {
            // Build the new name for the document.
            def FullDocumentName = source.getSpaceName() + "." + documentName;

            // Set the document title to the new name.
            source.setTitle(documentName)

            // Force the storage to keep the same version number, so that this looks like a single save event
            source.setMetaDataDirty(false);
            source.setContentDirty(false);

            // Rename the document
            source.rename(FullDocumentName, crtContext);
            response.sendRedirect($xwiki.getURL(FullDocumentName));
          }
        }        
    }
}

// Register against the Observation Manager
def observation = Utils.getComponent(ObservationManager.class)
observation.removeListener("ProcessDocumentRenamer")
def listener = new ProcessDocumentRenamer(xwiki, xcontext)
observation.addListener(listener)
{{/groovy}}

Anyone have any idea why?
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Guillaume "Louis-Marie" Delhumeau
2014-03-25 18:46 GMT+01:00 DeHaynes <[hidden email]>:

> Groovy runs at javascript in the browser?  Is that correct?
>

No, Groovy is server-side.

LM
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Sergiu Dumitriu-3
In reply to this post by DeHaynes
On 03/25/2014 01:46 PM, DeHaynes wrote:
>             response.sendRedirect($xwiki.getURL(FullDocumentName));

$xwiki is Velocity syntax. Just remove the $ and it should work.
--
Sergiu Dumitriu
http://purl.org/net/sergiu
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
Good catch, but it still doesn't work.  I am thinking that because it is setting up a listener that maybe it is a separate process from the save process and therefore it cannot perform a redirect?
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Sergiu Dumitriu-3
On 03/25/2014 02:19 PM, DeHaynes wrote:
> Good catch, but it still doesn't work.  I am thinking that because it is
> setting up a listener that maybe it is a separate process from the save
> process and therefore it cannot perform a redirect?
>

Yes.

You have to get the current response object. The quickest way is to use:

crtContext.response.sendRedirect(xwiki.getURL(FullDocumentName))

--
Sergiu Dumitriu
http://purl.org/net/sergiu
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
Didn't work either.  I even tried remarking the renaming line out and just do a redirect to a static page.

            // source.rename(FullDocumentName, crtContext);
            crtContext.response.sendRedirect(xwiki.getURL("Main.WebHome"))

Still didn't work.
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Marius Dumitru Florea
On Tue, Mar 25, 2014 at 8:28 PM, DeHaynes <[hidden email]> wrote:
> Didn't work either.  I even tried remarking the renaming line out and just do
> a redirect to a static page.
>
>             // source.rename(FullDocumentName, crtContext);
>             crtContext.response.sendRedirect(xwiki.getURL("Main.WebHome"))
>
> Still didn't work.

Save action does its own redirect to view mode at the end (after your
listener is called) which overwrites, I think, your redirect. See
https://github.com/xwiki/xwiki-platform/blob/master/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/SaveAction.java#L190
. The redirect done by the Save action take into account the xredirect
request parameter though, so an option is to wrap the request and to
"overwrite/add" the value of this parameter.

Hope this helps,
Marius

>
>
>
> --
> View this message in context: http://xwiki.475771.n2.nabble.com/Looking-for-help-with-groovy-tp7589782p7589803.html
> Sent from the XWiki- Dev mailing list archive at Nabble.com.
> _______________________________________________
> devs mailing list
> [hidden email]
> http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
I don't understand what you mean by "Wrap this request".  How would I do that?
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Marius Dumitru Florea
See http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequestWrapper.html
and http://stackoverflow.com/questions/17601279/use-servlet-filter-to-remove-a-form-parameter-from-posted-data
as an example.

Hope this helps,
Marius

On Wed, Mar 26, 2014 at 2:35 PM, DeHaynes <[hidden email]> wrote:

> I don't understand what you mean by "Wrap this request".  How would I do
> that?
>
>
>
> --
> View this message in context: http://xwiki.475771.n2.nabble.com/Looking-for-help-with-groovy-tp7589782p7589818.html
> Sent from the XWiki- Dev mailing list archive at Nabble.com.
> _______________________________________________
> devs mailing list
> [hidden email]
> http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Timothy Ray Hays
I apologize for my ignorance, but I am not a Java web developer.  I have
never heard of velocity or groovy until a month ago when I started looking
at XWiki.  I have a couple years of experience doing ASP.Net development.
So when I looked at HttpServletRequestWrapper, I have no idea what I am
looking at.

From what I read a servlet is a Java programming language class used on a
server.  Most of the time it is a web server.  

I do not understand how this RequestWrapper integrates with a request.
Therefore I do not know how I should use this class.  I looked at your
example link. From that I think I should

* Create a class that extends HttpServletRequestWrapper.  
* Create a public property for xredirect
* put this class in my groovy section of my xwiki page

I don't know
* How would my class get populated with the existing request

Marius, I appreciate your help, but I am lost.  :)

________________________________________
Tim Hays

-----Original Message-----
From: devs [mailto:[hidden email]] On Behalf Of Marius Dumitru
Florea
Sent: Wednesday, March 26, 2014 11:13 AM
To: XWiki Developers
Subject: Re: [xwiki-devs] Looking for help with groovy

See
http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequestW
rapper.html
and
http://stackoverflow.com/questions/17601279/use-servlet-filter-to-remove-a
-form-parameter-from-posted-data
as an example.

Hope this helps,
Marius

On Wed, Mar 26, 2014 at 2:35 PM, DeHaynes <[hidden email]> wrote:

> I don't understand what you mean by "Wrap this request".  How would I
> do that?
>
>
>
> --
> View this message in context:
> http://xwiki.475771.n2.nabble.com/Looking-for-help-with-groovy-tp75897
> 82p7589818.html Sent from the XWiki- Dev mailing list archive at
> Nabble.com.
> _______________________________________________
> devs mailing list
> [hidden email]
> http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
In reply to this post by Marius Dumitru Florea
I feel like I am so close, but it just is not working.  I have the following code but it is throwing an error.  I will attach a screenshot of the error.  (My company is blocking SSH all of a sudden. So I cannot copy the file.)  It is saying there is no such property.  I assume it means the "xredirect"?

{{groovy}}
import org.xwiki.observation.*
import org.xwiki.observation.event.*
import org.xwiki.bridge.event.*
import org.xwiki.context.*
import com.xpn.xwiki.web.*
import com.xpn.xwiki.*
import org.apache.velocity.VelocityContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class RequestWrapper extends HttpServletRequestWrapper
{
    private HashMap params = new HashMap();

    public RequestWrapper(HttpServletRequest request)
    {
        super(request);
    }

   public String getParameter(String name)
   {
      // if we added one, return that one
      if ( params.get( name ) != null )
      {
         return params.get( name );
      }
     
      // otherwise return what's in the original request
      HttpServletRequest req = (HttpServletRequest) super.getRequest();
     
      return req.getParameter( name );
   }

   public void addParameter( String name, String value )
   {
      params.put( name, value );
   }

}

class ProcessDocumentRenamer implements EventListener
{
    def xwiki
    def context
    def response
 
    ProcessDocumentRenamer(xwiki, context)
    {
        this.xwiki = xwiki
        this.context = context
    }

    String getName()
    {
        // The unique name of this event listener
        return "ProcessDocumentRenamer"
    }

    List<Event> getEvents()
    {
        // The list of events this listener listens to
        return Arrays.asList(new DocumentCreatedEvent(), new DocumentUpdatedEvent())
    }

    // Called by the Observation Manager when an event matches the list of events returned
    // by getEvents()
    void onEvent(Event event, Object source, Object data)
    {
        // Current context
        def crtContext = Utils.getComponent(Execution.class).getContext().getProperty('xwikicontext')
        def response =  Utils.getComponent(Execution.class).getContext().getProperty('response')

        // Defines the type of object that should be looked for
        def myObject = source.getObject("DocumentationTemplates.ProcessClass");

        // If the page has an object of the specified class, we get the value of the relevant property and assign it to our title variable
        if (myObject != null) {
          // Defines the variable that we will later use to update the title of the document
          def documentName = myObject.get("processName").value

          if (source.getName() != documentName) {
            // Build the new name for the document.
            def FullDocumentName = source.getSpaceName() + "." + documentName;

            // Set the document title to the new name.
            source.setTitle(documentName)

            // Force the storage to keep the same version number, so that this looks like a single save event
            source.setMetaDataDirty(false);
            source.setContentDirty(false);
 
            // Rename the document
            source.rename(FullDocumentName, crtContext);

            def RedirectRequest = new RequestWrapper(request);
            RedirectRequest.addParameter('xredirect',xwiki.getURL(FullDocumentName));
          }
        }        
    }
}

// Register against the Observation Manager
def observation = Utils.getComponent(ObservationManager.class)
observation.removeListener("ProcessDocumentRenamer")
def listener = new ProcessDocumentRenamer(xwiki, xcontext)
observation.addListener(listener)
{{/groovy}}

Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Marius Dumitru Florea
On Wed, Mar 26, 2014 at 11:00 PM, DeHaynes <[hidden email]> wrote:

> I feel like I am so close, but it just is not working.  I have the following
> code but it is throwing an error.  I will attach a screenshot of the error.
> (My company is blocking SSH all of a sudden. So I cannot copy the file.)  It
> is saying there is no such property.  I assume it means the "xredirect"?
>
> {{groovy}}
> import org.xwiki.observation.*
> import org.xwiki.observation.event.*
> import org.xwiki.bridge.event.*
> import org.xwiki.context.*
> import com.xpn.xwiki.web.*
> import com.xpn.xwiki.*
> import org.apache.velocity.VelocityContext;
>
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletRequestWrapper;
>

> public class RequestWrapper extends HttpServletRequestWrapper

public class RequestWrapper extends HttpServletRequestWrapper
implements XWikiRequest

(you need to implement XWikiRequest to be able to call
XWikiContext#setRequest(XWikiRequest) below)

> {
>     private HashMap params = new HashMap();
>
>     public RequestWrapper(HttpServletRequest request)
>     {
>         super(request);
>     }
>
>    public String getParameter(String name)
>    {
>       // if we added one, return that one
>       if ( params.get( name ) != null )
>       {
>          return params.get( name );
>       }
>
>       // otherwise return what's in the original request
>       HttpServletRequest req = (HttpServletRequest) super.getRequest();
>
>       return req.getParameter( name );
>    }
>
>    public void addParameter( String name, String value )
>    {
>       params.put( name, value );
>    }
>
> }
>
> class ProcessDocumentRenamer implements EventListener
> {
>     def xwiki
>     def context
>     def response
>
>     ProcessDocumentRenamer(xwiki, context)
>     {

>         this.xwiki = xwiki
>         this.context = context

You don't need this and it's not even recommended to keep a reference
to the xwiki and context object from the moment the event was created.
The event listener should use (as you did below) the context from when
the event is fired.

>     }
>
>     String getName()
>     {
>         // The unique name of this event listener
>         return "ProcessDocumentRenamer"
>     }
>
>     List<Event> getEvents()
>     {
>         // The list of events this listener listens to
>         return Arrays.asList(new DocumentCreatedEvent(), new
> DocumentUpdatedEvent())
>     }
>
>     // Called by the Observation Manager when an event matches the list of
> events returned
>     // by getEvents()
>     void onEvent(Event event, Object source, Object data)
>     {
>         // Current context
>         def crtContext =
> Utils.getComponent(Execution.class).getContext().getProperty('xwikicontext')
>         def response =
> Utils.getComponent(Execution.class).getContext().getProperty('response')
>
>         // Defines the type of object that should be looked for
>         def myObject =
> source.getObject("DocumentationTemplates.ProcessClass");
>
>         // If the page has an object of the specified class, we get the
> value of the relevant property and assign it to our title variable
>         if (myObject != null) {
>           // Defines the variable that we will later use to update the title
> of the document
>           def documentName = myObject.get("processName").value
>
>           if (source.getName() != documentName) {
>             // Build the new name for the document.

>             def FullDocumentName = source.getSpaceName() + "." +
> documentName;

It's recommended to use DocumentReference instead:

def newDocRef = new DocumentReference(documentName,
source.getDocumentReference().getLastSpaceReference())

>
>             // Set the document title to the new name.
>             source.setTitle(documentName)
>
>             // Force the storage to keep the same version number, so that
> this looks like a single save event
>             source.setMetaDataDirty(false);
>             source.setContentDirty(false);
>
>             // Rename the document
>             source.rename(FullDocumentName, crtContext);
>
>             def RedirectRequest = new RequestWrapper(request);

> RedirectRequest.addParameter('xredirect',xwiki.getURL(FullDocumentName));

RedirectRequest.addParameter('xredirect', source.getURL('view', crtContext));
crtContext.setRequest(RedirectRequest);

Hope this helps,
Marius

>           }
>         }
>     }
> }
>
> // Register against the Observation Manager
> def observation = Utils.getComponent(ObservationManager.class)
> observation.removeListener("ProcessDocumentRenamer")
> def listener = new ProcessDocumentRenamer(xwiki, xcontext)
> observation.addListener(listener)
> {{/groovy}}
>
> <http://xwiki.475771.n2.nabble.com/file/n7589834/Error.png>
>
>
>
> --
> View this message in context: http://xwiki.475771.n2.nabble.com/Looking-for-help-with-groovy-tp7589782p7589834.html
> Sent from the XWiki- Dev mailing list archive at Nabble.com.
> _______________________________________________
> devs mailing list
> [hidden email]
> http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
Thank you all VERY much.  I got it working.  However, you said


>>           def FullDocumentName = source.getSpaceName() + "." +
>>  documentName;
>
> It's recommended to use DocumentReference instead:
> def newDocRef = new DocumentReference(documentName,
> source.getDocumentReference().getLastSpaceReference())

I am not sure what you are telling me.  In this step, I am getting the space name for the current document and combining it with the name the user specified in the field.

I looked up "DocumentReference" in the Wiki API and it took me here.  http://extensions.xwiki.org/xwiki/bin/view/Extension/Model+Module

I don't see how to get the space name from a DocumentReference.
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
This code will take the text from a field on the form and set the form title to the text.  It will also rename the document to the specified text.  Finally it will redirect the XWiki to the newly named document.  This all happens when the user saves the document.

I have commented a large part of the code for myself and anyone else trying to understand.  

{{groovy}}
import org.xwiki.observation.*
import org.xwiki.observation.event.*
import org.xwiki.bridge.event.*
import org.xwiki.context.*
import com.xpn.xwiki.web.*
import com.xpn.xwiki.*
import org.apache.velocity.VelocityContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

// The main purpose of this class is to allow us to change/add the 'xredirect' parameter on the request.  Because we are renaming the document
//  in the ProcessDocumentRenamer, if we don't redirect the browser to the new document name, they will get a message saying the document they
//  just saved doesn't exist or has been deleted.
// This class wraps the HttpServletRequest class from the context.  The reason we do this is so we can access the contents of the request.  
//  There is a property('xredirect') that we want to change to point at our renamed document.
// This also implements XWikiRequest interface.  The reason we do this is because this interface is how we access the 'xredirect' parameter.
public class RequestWrapper extends HttpServletRequestWrapper implements XWikiRequest
{
    // Used to hold the parameters.
    private HashMap params = new HashMap();

    // The class constructor.  It takes the HttpServletRequest, object that it is going to wrap, as an input parameter.
    public RequestWrapper(HttpServletRequest request)
    {
        // I do not know what super does?  Do anybody else know?
        super(request);
    }

    // Gets parameters from the class.
    public String getParameter(String name)
    {
        // if we added one, return that one
        if ( params.get( name ) != null )
        {
            return params.get( name );
        }
     
        // otherwise return what's in the original request.
        HttpServletRequest req = (HttpServletRequest) super.getRequest();
     
        return req.getParameter( name );
    }

    // Method to add parameters to a class.  We will use this when we add 'xredirect'.
    public void addParameter( String name, String value )
    {
        params.put( name, value );
    }

    // This is needed to meet the XWikiRequest interface requirements.  Since the request is already an XWikiRequest, I just
    //  box it and pass the parameter through as the return value.
    public String get(String name)
    {
        return ((XWikiRequest)this).get(name);
    }

    // This is needed to meet the XWikiRequest interface requirements.  Since the request is already an XWikiRequest, I just
    //  box it and pass the parameter through as the return value.
    public javax.servlet.http.Cookie getCookie(String cookieName)
    {
        return ((XWikiRequest)this).getCookie(cookieName);
    }

    // This is needed to meet the XWikiRequest interface requirements.  Since the request is already an XWikiRequest, I just
    //  box it and pass it as the return value.
    public javax.servlet.http.HttpServletRequest getHttpServletRequest()
    {
        return ((javax.servlet.http.HttpServletRequest)this);
    }
}

// The main purpose of this class is to rename and re-title a document of type "DocumentationTemplates.ProcessClass" to the title
//  specified by the user in the "processName" field within the document.  This class is a listener that waits for the
//  "DocumentCreateEvent" or "DocumentUpdateEvents" for the "DocumentationTemplates.ProcessClass".  It then checks to see if the
//  current document name matches the "processName" field.  If it doesn't, it will rename and re-title the document to what is
//  specified in the "processName" field.  It will then use the "RequestWrapper" to direct the user's browser to the new document URL.
class ProcessDocumentRenamer implements EventListener
{
    // The "ProcessDocumentRenamer" constructor.  The "xwiki" and "context" input parameters are required, but we do not need them, so
    //  nothing is done with them.
    ProcessDocumentRenamer(xwiki, context)
    {
    }  

    // Required to implement the "EventListener" interface.  It provides the name of the listener to the system.
    String getName()
    {
        // The unique name of this event listener
        return "ProcessDocumentRenamer"
    }

    // Required to implement the "EventListener" interface.  It provides the events that the listener will respond to.
    List<Event> getEvents()
    {
        // The list of events this listener listens to
        return Arrays.asList(new DocumentCreatedEvent(), new DocumentUpdatedEvent())
    }

    // Called by the Observation Manager when an event matches the list of events returned by getEvents().
    void onEvent(Event event, Object source, Object data)
    {
        // Defines the type of object we should be looked for.
        def myObject = source.getObject("DocumentationTemplates.ProcessClass");

        // If the page has an object of the specified class, we get the object.
        if (myObject != null)
        {
            // Get the title that the user specified for the document and store it in the variable "NewDocumentName".  
            //  We will later use to update the title and name of the document.
            def NewDocumentName = myObject.get("processName").value

            // Check if the document name is different than the one the user specified.
            if (source.getName() != NewDocumentName)
            {
                // Build the new name for the document in the format of "SpaceName.PageName".
                def FullDocumentName = source.getSpaceName() + "." + NewDocumentName;

                // Set the document title to the new name.
                source.setTitle(NewDocumentName)

                // Force the storage to keep the same version number, so that this looks like a single save event
                source.setMetaDataDirty(false);
                source.setContentDirty(false);
 
                // Get the current context.  It is needed to rename the document.
                def crtContext = Utils.getComponent(Execution.class).getContext().getProperty('xwikicontext')

                // Rename the document
                source.rename(FullDocumentName, crtContext);

                // Create an instance of the RequestWrapper class and give it the request from the current context.
                def RedirectRequest = new RequestWrapper(crtContext.getRequest());

                // Get the URL for the document (which has already been renamed, so it points to the new location) and
                //  store it in the RedirectRequest.
                RedirectRequest.addParameter('xredirect', source.getURL('view', crtContext));

                // Store the modified request back in the context.
                crtContext.setRequest(RedirectRequest);
            }
        }        
    }
}

// Register against the Observation Manager
def observation = Utils.getComponent(ObservationManager.class)
observation.removeListener("ProcessDocumentRenamer")
def listener = new ProcessDocumentRenamer(xwiki, xcontext)
observation.addListener(listener)
{{/groovy}}


Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
With this approach is there a possibility of a collision if two people are editing a "DocumentationTemplates.ProcessClass" at the same time?
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Marius Dumitru Florea
In reply to this post by DeHaynes
Maybe you can publish this snippet on extensions.xwiki.org .

Thanks,
Marius

On Mar 27, 2014 8:56 PM, "DeHaynes" <[hidden email]> wrote:
>
> This code will take the text from a field on the form and set the form
title
> to the text.  It will also rename the document to the specified text.
> Finally it will redirect the XWiki to the newly named document.  This all
> happens when the user saves the document.
>
> I have commented a large part of the code for myself and anyone else
trying

> to understand.
>
> {{groovy}}
> import org.xwiki.observation.*
> import org.xwiki.observation.event.*
> import org.xwiki.bridge.event.*
> import org.xwiki.context.*
> import com.xpn.xwiki.web.*
> import com.xpn.xwiki.*
> import org.apache.velocity.VelocityContext;
>
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletRequestWrapper;
>
> // The main purpose of this class is to allow us to change/add the
> 'xredirect' parameter on the request.  Because we are renaming the
document
> //  in the ProcessDocumentRenamer, if we don't redirect the browser to the
> new document name, they will get a message saying the document they
> //  just saved doesn't exist or has been deleted.
> // This class wraps the HttpServletRequest class from the context.  The
> reason we do this is so we can access the contents of the request.
> //  There is a property('xredirect') that we want to change to point at
our

> renamed document.
> // This also implements XWikiRequest interface.  The reason we do this is
> because this interface is how we access the 'xredirect' parameter.
> public class RequestWrapper extends HttpServletRequestWrapper implements
> XWikiRequest
> {
>     // Used to hold the parameters.
>     private HashMap params = new HashMap();
>
>     // The class constructor.  It takes the HttpServletRequest, object
that

> it is going to wrap, as an input parameter.
>     public RequestWrapper(HttpServletRequest request)
>     {
>         // I do not know what super does?  Do anybody else know?
>         super(request);
>     }
>
>     // Gets parameters from the class.
>     public String getParameter(String name)
>     {
>         // if we added one, return that one
>         if ( params.get( name ) != null )
>         {
>             return params.get( name );
>         }
>
>         // otherwise return what's in the original request.
>         HttpServletRequest req = (HttpServletRequest) super.getRequest();
>
>         return req.getParameter( name );
>     }
>
>     // Method to add parameters to a class.  We will use this when we add
> 'xredirect'.
>     public void addParameter( String name, String value )
>     {
>         params.put( name, value );
>     }
>
>     // This is needed to meet the XWikiRequest interface requirements.
> Since the request is already an XWikiRequest, I just
>     //  box it and pass the parameter through as the return value.
>     public String get(String name)
>     {
>         return ((XWikiRequest)this).get(name);
>     }
>
>     // This is needed to meet the XWikiRequest interface requirements.
> Since the request is already an XWikiRequest, I just
>     //  box it and pass the parameter through as the return value.
>     public javax.servlet.http.Cookie getCookie(String cookieName)
>     {
>         return ((XWikiRequest)this).getCookie(cookieName);
>     }
>
>     // This is needed to meet the XWikiRequest interface requirements.
> Since the request is already an XWikiRequest, I just
>     //  box it and pass it as the return value.
>     public javax.servlet.http.HttpServletRequest getHttpServletRequest()
>     {
>         return ((javax.servlet.http.HttpServletRequest)this);
>     }
> }
>
> // The main purpose of this class is to rename and re-title a document of
> type "DocumentationTemplates.ProcessClass" to the title
> //  specified by the user in the "processName" field within the document.
> This class is a listener that waits for the
> //  "DocumentCreateEvent" or "DocumentUpdateEvents" for the
> "DocumentationTemplates.ProcessClass".  It then checks to see if the
> //  current document name matches the "processName" field.  If it doesn't,
> it will rename and re-title the document to what is
> //  specified in the "processName" field.  It will then use the
> "RequestWrapper" to direct the user's browser to the new document URL.
> class ProcessDocumentRenamer implements EventListener
> {
>     // The "ProcessDocumentRenamer" constructor.  The "xwiki" and
"context"
> input parameters are required, but we do not need them, so
>     //  nothing is done with them.
>     ProcessDocumentRenamer(xwiki, context)
>     {
>     }
>
>     // Required to implement the "EventListener" interface.  It provides
the
> name of the listener to the system.
>     String getName()
>     {
>         // The unique name of this event listener
>         return "ProcessDocumentRenamer"
>     }
>
>     // Required to implement the "EventListener" interface.  It provides
the

> events that the listener will respond to.
>     List<Event> getEvents()
>     {
>         // The list of events this listener listens to
>         return Arrays.asList(new DocumentCreatedEvent(), new
> DocumentUpdatedEvent())
>     }
>
>     // Called by the Observation Manager when an event matches the list of
> events returned by getEvents().
>     void onEvent(Event event, Object source, Object data)
>     {
>         // Defines the type of object we should be looked for.
>         def myObject =
> source.getObject("DocumentationTemplates.ProcessClass");
>
>         // If the page has an object of the specified class, we get the
> object.
>         if (myObject != null)
>         {
>             // Get the title that the user specified for the document and
> store it in the variable "NewDocumentName".
>             //  We will later use to update the title and name of the
> document.
>             def NewDocumentName = myObject.get("processName").value
>
>             // Check if the document name is different than the one the
user

> specified.
>             if (source.getName() != NewDocumentName)
>             {
>                 // Build the new name for the document in the format of
> "SpaceName.PageName".
>                 def FullDocumentName = source.getSpaceName() + "." +
> NewDocumentName;
>
>                 // Set the document title to the new name.
>                 source.setTitle(NewDocumentName)
>
>                 // Force the storage to keep the same version number, so
> that this looks like a single save event
>                 source.setMetaDataDirty(false);
>                 source.setContentDirty(false);
>
>                 // Get the current context.  It is needed to rename the
> document.
>                 def crtContext =
>
Utils.getComponent(Execution.class).getContext().getProperty('xwikicontext')

>
>                 // Rename the document
>                 source.rename(FullDocumentName, crtContext);
>
>                 // Create an instance of the RequestWrapper class and give
> it the request from the current context.
>                 def RedirectRequest = new
> RequestWrapper(crtContext.getRequest());
>
>                 // Get the URL for the document (which has already been
> renamed, so it points to the new location) and
>                 //  store it in the RedirectRequest.
>                 RedirectRequest.addParameter('xredirect',
> source.getURL('view', crtContext));
>
>                 // Store the modified request back in the context.
>                 crtContext.setRequest(RedirectRequest);
>             }
>         }
>     }
> }
>
> // Register against the Observation Manager
> def observation = Utils.getComponent(ObservationManager.class)
> observation.removeListener("ProcessDocumentRenamer")
> def listener = new ProcessDocumentRenamer(xwiki, xcontext)
> observation.addListener(listener)
> {{/groovy}}
>
>
>
>
>
>
> --
> View this message in context:
http://xwiki.475771.n2.nabble.com/Looking-for-help-with-groovy-tp7589782p7589851.html
> Sent from the XWiki- Dev mailing list archive at Nabble.com.
> _______________________________________________
> devs mailing list
> [hidden email]
> http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

Marius Dumitru Florea
In reply to this post by DeHaynes
On Mar 27, 2014 8:26 PM, "DeHaynes" <[hidden email]> wrote:

>
> Thank you all VERY much.  I got it working.  However, you said
>
>
> >>           def FullDocumentName = source.getSpaceName() + "." +
> >>  documentName;
> >
> > It's recommended to use DocumentReference instead:
> > def newDocRef = new DocumentReference(documentName,
> > source.getDocumentReference().getLastSpaceReference())
>
> I am not sure what you are telling me.  In this step, I am getting the
space
> name for the current document and combining it with the name the user
> specified in the field.
>
> I looked up "DocumentReference" in the Wiki API and it took me here.
> http://extensions.xwiki.org/xwiki/bin/view/Extension/Model+Module
>

> I don't see how to get the space name from a DocumentReference.

documentReference.getLastSpaceReference().getName()

"last space reference" because we'd like to support nested spaces in the
future.

Hope this helps,
Marius

>
>
>
> --
> View this message in context:
http://xwiki.475771.n2.nabble.com/Looking-for-help-with-groovy-tp7589782p7589850.html
> Sent from the XWiki- Dev mailing list archive at Nabble.com.
> _______________________________________________
> devs mailing list
> [hidden email]
> http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________
devs mailing list
[hidden email]
http://lists.xwiki.org/mailman/listinfo/devs
Reply | Threaded
Open this post in threaded view
|

Re: Looking for help with groovy

DeHaynes
I don't understand.  

All of the following pieces of data are being pulled from source variable, which is passed in by the XWiki system as a parameter in the onEvent method:
* The wiki document
* The value of the processName field in the wiki document.
* The wiki document's name.
* The document Title
* The documents Dirty flags.
* The URL for the document.

And what I think you are telling me is that the source is not a reliable place for getting the document space, because in the future sub-wikis will cause an issue.  Is that right?

If that is right, then wouldn't I need change where I get the data in the list above also?
12