Range.replace(Pattern pattern- IReplacingCallback handler-..) deprecated?

Hi,

I use the new Library Aspose Java Words 17.2.0 and the following method is as deprecated define! Why?

public int replace(Pattern pattern, IReplacingCallback handler, boolean isForward) throws Exception

I need to use the handler with the interface IReplacingCallback. How can I call the replace method with handler in the future?

Could you remove the deprecated annotation in the next release?

Thanks for your help.

Regards,
Mathieu

Hi Mathieu,

Thanks for your inquiry. We enhanced find and replace feature in Aspose.Words v16.7.0 so this needs to change the APIs. Please note that ReplaceAction, IReplacingCallback and ReplacingArgs are now moved to Aspose.Words.Replacing namespace. Please check public API and backward incompatible changes here:
Aspose.Words for Java 16.7.0 Release Notes

Please use the following code example to achieve your requirements. Hope this helps you.

Document document = new Document(MyDir + "in.docx");
FindReplaceOptions options = new FindReplaceOptions();
options.setDirection(FindReplaceDirection.FORWARD);
options.ReplacingCallback = new MyReplaceEvaluator();

Pattern regex = Pattern.compile("test");
document.getRange().replace(regex, "", options);
document.save(MyDir + "Out.docx");

---------------------------------------------

class MyReplaceEvaluator implements  IReplacingCallback
{
    public int replacing(ReplacingArgs e) throws Exception
    {
        //Your code...
        return ReplaceAction.REPLACE;
    }
}

Hi,Thanks for your help.If I used my old code. It’s work very fine.But if I used your new Interface FindReplaceOptions. The following error

come:context.document.getRange().replace(elem.regexReplace, "", findReplaceOption);java.lang.IllegalStateException: Cannot remove because there is no parent.
at com.aspose.words.Node.remove(Unknown Source)
at com.aspose.words.zzZYJ.zzYO(Unknown Source)
at com.aspose.words.zzZYJ.zzC(Unknown Source)
at com.aspose.words.zzZYJ.zzZF(Unknown Source)
at com.aspose.words.zzZYJ.zzZUU(Unknown Source)
at com.aspose.words.Range.zzZ(Unknown Source)
at com.aspose.words.Range.replace(Unknown Source

Your replace algorithm isn’t same? Could you please solve this issue?
If the node cannot be deleted the replace should continue running.
Unfortunately I can’t give you a sample.
.
Best gerads,
Mathieu

Hi Mathieu,

Thanks for your inquiry. To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document.
  • Please create a simple Java application (source code without compilation errors) that helps us to reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we’ll start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip them and Click ‘Reply’ button that will bring you to the ‘reply page’ and there at the bottom you can include any attachments with that post by clicking the ‘Add/Update’ button.

Hi,

Thank for your help. You will find in attachment the input Word document an the source code file.

The Problem came because I need to call the method splitRun.

Best regards,

Mathieu

Hi Mathieu,

Thanks for sharing the detail. Please use FindReplaceDirection.FORWARD instead of FindReplaceDirection.BACKWARD to avoid this exception. Please let us know if you have any more queries.

FindReplaceOptions findReplaceOption = new FindReplaceOptions(FindReplaceDirection.FORWARD, replace);
findReplaceOption.MatchCase = false;
findReplaceOption.FindWholeWordsOnly = false;

Hi,

Thanks for your Reply. We have already try with FindReplaceDirection.FORWARD and we got no more error.

But in our Project we need to use the FindReplaceDirection.BACKWARD command because we have a lot of replace and with the FORWARD the replace isn’t correct.

Could you please solve the issue so that the FindReplaceOptions run like the depracted method replace?

Thanks for your help.

Regards,
Mathieu

Hi Mathieu,

Thanks for your inquiry. We have tested the scenario and have managed to reproduce the same issue at our side. For the sake of correction, we have logged this problem in our issue tracking system as WORDSJAVA-1599. You will be notified via this forum thread once this issue is resolved.

We apologize for your inconvenience.

Hi Mathieu,

In your code, you are updating the nodes which are being replaced. This is the reason you are getting the exception. Please do not use ReplacingArgs.Replacement when you modify document during find and replace operation as you are doing in splitRun method. Please remove the Run nodes as shown below to get the desired output. Hope this helps you.

class ReplacingCallback implements IReplacingCallback {

    private DocumentBuilder docBuilder;

    public ReplacingCallback(DocumentBuilder d)
    {
        docBuilder = d;
    }

    public int replacing(ReplacingArgs e) throws Exception {

        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.getMatchNode();
        // The first (and may be the only) run can contain text before the match,
        // in this case it is necessary to split the run.
        if (e.getMatchOffset() > 0)
            currentNode = splitRun((Run) currentNode, e.getMatchOffset());

        ArrayList runs = new ArrayList();

        // Find all runs that contain parts of the match string.
        int remainingLength = e.getMatch().group().length();
        while ((remainingLength > 0) && (currentNode != null) && (currentNode.getText().length() <= remainingLength)) {
            runs.add(currentNode);
            remainingLength = remainingLength - currentNode.getText().length();
            // Select the next Run node.
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do {
                currentNode = currentNode.getNextSibling();
            } while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN));
        }

        // Split the last run that contains the match if there is any text left.
        if ((currentNode != null) && (remainingLength > 0)) {
            splitRun((Run) currentNode, remainingLength);
            runs.add(currentNode);
        }

        DocumentBuilder builder = new DocumentBuilder((Document)e.getMatchNode().getDocument());
        builder.moveTo((Run)runs.get(0));
	// Write your code here

        // Remove matched text
        for (Run run : (Iterable) runs)
            run.remove();

        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.SKIP;

    }
    public Run splitRun(Run run, int position) {
        try {
            Run afterRun = (Run) run.deepClone(true);
            String txt = run.getText();
            afterRun.setText(txt.substring(position));
            run.setText(txt.substring(0, position));
            run.getParentNode().insertAfter(afterRun, run);
            return afterRun;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return run;
    }
}