Refactor DomElements

Hi all,

Just wondering if there's support for easily moving DomElements?

I am attempting to provide the ability to refactor DomElements from an existing Route DomElement into a newly created Route DomElement. For this I have registered a RefactoringSupportProvider which overrides the getExtractMethodHandler() method which returns my custom RefactoringActionHandler

For clarity this is what I am trying to achieve

Before - two beans selected for refactoring into a new route

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
            http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
        ">

    <camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
        <route>
            <from uri="direct:start" />

            <begin>
            <bean ref="myFirstBean" method="myMethod" />
            <bean ref="mySecondBean" method="myMethod" />
            <end>
        </route>
    </camelContext>
</blueprint>



After Refactor - a new route is created with a reference to the new route, and both bean DomElements are copied successfully

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
            http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
        ">

    <camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
        <route>
            <from uri="direct:start" />

            <caret><to uri="direct:foo" />
        </route>

        <route>             <from uri="direct:foo" />             <bean ref="myFirstBean" method="myMethod" />             <bean ref="mySecondBean" method="myMethod" />         </route>     </camelContext> </blueprint>


This is the code that I currently have for the RefactoringActionHandler

    @Override
    public void invoke(@NotNull Project project, Editor editor, PsiFile psiFile, DataContext dataContext) {
        final SelectionModel selectionModel = editor.getSelectionModel();
        if(!selectionModel.hasSelection()) return;

        final Blueprint blueprintRoot = getBlueprintRoot(project, editor, psiFile);
        if(blueprintRoot == null) return;

        final String newRouteUri = "direct:foo";

        // Find Selection start + end to copy into a new route
        PsiElement startElementSelection = psiFile.findElementAt(selectionModel.getSelectionStart());
        PsiElement endElementSelection = psiFile.findElementAt(selectionModel.getSelectionEnd());

        if(startElementSelection == null || endElementSelection == null) return;

        new WriteCommandAction.Simple(project) {
            @Override
            protected void run() throws Throwable {
                // Create a new route with the given route uri
                Route route = blueprintRoot.getCamelContext().addRoute();
                route.getFrom().getUri().setStringValue(newRouteUri);

                // TODO Copy Start + end selection elements into the new route
                // directly below the new route's`from` domElement

            }         }.execute();     }


Maybe attempting to use the DomElements API isn't the best solution for this? Would love to hear your thoughts :)

Cheers
Alan

4 comments
Comment actions Permalink

I've still had no luck with this unfortunately. I've checked out the usual suspects, such as the struts plugin which doesn't appear to offer any similiar functionality, and the maven plugin only creates new elements using the DomAPI - like shown in my example code

Would appreciate any direction with this! :)

Cheers

0
Comment actions Permalink

For anyone passing by; I've had to delve into the PsiElement code to get this working. I ended up removing most of the Dom related code - other than using it to easily find the correct Parent DomElements with getParentOfType, to make psiElem.addAfter easier to use.

The important thing seems to be creating new PsiElements, inserting them at the new location, and deleting the existing, rather than simply 'moving' them. I achieved this by finding the start/end offset range, to create an XmlString substring of the original document. Then with this string you can create a new temp PsiFile, as demonstrated during the first coding webinar

Hope this helps someone in the future too :)
Cheers

0
Comment actions Permalink

Dom Elements work for me for creation of elements.  Though I found that sometimes Dom fails to deduce attribute / tag names from the
methods / classes and needs little  prodding under tail end with annotation or two ;)

0
Comment actions Permalink

Folks, I'm wondering if anyone can give me a hand here, I'm having a similar problem. I need to find all selected XML tags (and probably comments too), and move them to another XML tag. So I got to the point where I have start and end XML tags, but I'm stuck now, I can't figure out how to get the range of everything between the two and refactor it. Any example would be greatly appreciated.

 

0

Please sign in to leave a comment.