Problem converting macro from Velocity to Groovy: No signature of method is applicable for argument types

I have a working Velocity macro that copies a page from one location to another that I would like to convert to Groovy so that I can add some features that are easier to implement in Groovy. The problem is that I am getting an error when I run the Groovy version:

No signature of method: org.xwiki.refactoring.job.CopyRequest.setAutoRedirect() is applicable for argument types: (Boolean) values: [false]

I don’t have much experience with Groovy, so I feel like I must be missing something simple.

Here is the original, working Velocity script:

#if("$!request.src" != '' && "$request.dst" != '')
  #set ($_ = response.setContentType('text/plain'))
  #set ($srcRef = $services.model.resolveDocument($!request.src))
  #set ($dstRef = $services.model.resolveDocument($!request.dst))
  #set ($copyAsRequest = $services.refactoring.requestFactory.createCopyAsRequest($srcRef, $dstRef))
  #set ($_ = $copyAsRequest.setAutoRedirect(false))
  #set ($_ = $copyAsRequest.setUpdateLinks(false))
  #set ($success = false)
  #set ($copyAsJob = $services.refactoring.copyAs($copyAsRequest))
  #try
    $copyAsJob.join()
    #set ($copyAsJobStatus = $services.job.getJobStatus($copyAsJob.request.id))
    #set ($success = !$copyAsJobStatus.logTail.hasLogLevel('ERROR'))
  #end
  #if ($success)
    $response.writer.write('OK')
    $xcontext.setFinished(true)
  #else
    $response.writer.write('FAILED')
    $xcontext.setFinished(true)
  #end
#end

Here is the Groovy script that results in the error (kept as similar to the Velocity script as possible just to get it working):

if (request.src && request.dst) {
  response.setContentType('text/plain');
  def srcRef = services.model.resolveDocument(request.src);
  def dstRef = services.model.resolveDocument(request.dst);
  def copyAsRequest = services.refactoring.requestFactory.createCopyAsRequest(srcRef, dstRef);
  copyAsRequest.setAutoRedirect(false);
  copyAsRequest.setUpdateLinks(false);
  def success = false;
  def copyAsJob = services.refactoring.copyAs(copyAsRequest);
  try {
    copyAsJob.join();
    def copyAsJobStatus = services.job.getJobStatus(copyAsJob.request.id);
    success = copyAsJobStatus.logTail.hasLogLevel('ERROR');
  } catch(Exception ex) {
  }
  if (success) {
    response.getWriter().write('OK');
    xcontext.setFinished(true);
  } else {
    response.getWriter().write('ERROR');
    xcontext.setFinished(true);
  }
}

I have tried adding the following import lines (one at a time), but they didn’t help:

import org.xwiki.refactoring.job.CopyRequest
import org.xwiki.refactoring.job.*

If I remove these two method calls, the Groovy script will run and copy the page without error:

  copyAsRequest.setAutoRedirect(false);
  copyAsRequest.setUpdateLinks(false);

Am I missing an import or is there something else wrong with my code? Why would the Velocity script accept a boolean parameter for the setAutoRedirect method, but Groovy can’t find an implementation of the method with a boolean parameter?

I’ve tried a bunch of different permutations, but had no luck. For the sake of sanity, I looked up the source of my original velocity script, which came from the Refactoring Module documentation under the heading Copy page and keep links relative:

#set ($source = $services.model.resolveDocument('Path.To.Source.WebHome'))
#set ($destination = $services.model.resolveDocument('Path.To.New.WebHome'))
#set ($copyAsRequest = $services.refactoring.requestFactory.createCopyAsRequest($source, $destination)) 
#set ($discard = $copyAsRequest.setAutoRedirect(false))
$services.refactoring.copyAs($copyAsRequest).join()

So the official documentation shows the setAutoRedirect() method being called on a CopyRequest object that was returned from createCopyAsRequest().

To figure out why my Groovy implementation was generating an error about not finding a method signature with a boolean parameter, I started digging through the source code.

  1. org.xwiki.platform.refactoring.script.RequestFactory: createCopyAsRequest() returns a CopyRequest object

  2. org.xwiki.platform.refactoring.job.CopyRequest: CopyRequest has no setAutoRedirect() method, but extends AbstractCopyOrMoveRequest

  3. org.xwiki.platform.refactoring.job.AbstractCopyOrMoveRequest: AbstractCopyOrMoveRequest has no setAutoRedirect() method, but extends EntityRequest

  4. org.xwiki.platform.refactoring.job.EntityRequest: EntityRequest has no setAutoRedirect() method, but extends AbstractCheckRightsRequest

  5. org.xwiki.platform.job.api.AbstractCheckRightsRequest: AbstractCheckRightsRequest has no setAutoRedirect() method, but extends AbstractRequest

At this point, it’s obvious that there is no setAutoRedirect() method associated with CopyRequest either directly or inherited. So it appears that the example in the documentation is wrong.

By eliminating the lines:

copyAsRequest.setAutoRedirect(false);
copyAsRequest.setUpdateLinks(false);

the Groovy version appears to work correctly. As for my original Velocity version, I guess it just ignores the fact that there is no setAutoRedirect() method associated with CopyRequest?

Thx for noticing the typo. There shouldn’t be a call to setAutoRedirect on a Copy operation since that doesn’t make sense. Creating a redirect makes sense when you move a page or delete it.

Same for updating links, it only makes sense for move or delete operations.

I’ve fixed the typo (note that anyone is welcome to improve the doc on xwiki.org, it’s a wiki afrer all :slight_smile: You can even save as a Change Request if you want a review of your changes if you’re not sure!).

Thx!