RefactoringFAQ

Q1: I want to delegate from my refactoring to the refactoring provided by refactoring/java module. However I also want to perform additional Java refactorings that may not be covered by the standard Java refactorings.

A1: Delegation is something which is supported: in prepare method of your plugin you can do this:

public Problem prepare(RefactoringElementsBag refactoringElements) {
  RefactoringSession currentSession = refactoringElements.getSession();
  RenameRefactoring delegate = new RenameRefactoring(...);
  ...
  ...
  delegate.prepare(currentSession);
  refactoringElements.add(...yourElements);
  ...
}

Q2: RefactoringElementsBag.add(..), RefactoringElementsBag.registerTransaction(..), RefactoringElementsBag.addFileChange(..) ... How this stuff works? Where should I put my refactoring code?

A2: Refactoring API supports 3 kind of changes, which are performed in this order:

  1. Plain Changes
  2. Model-driven Changes
  3. File Changes

Plain Changes are the simple ones. You need to use just RefactoringElementsBag.add(refactoring, yourRefactoringElementImplementation).

class MyRefactoringElementImplementation extends SimpleRefactoringElementImpl {
  public void performChange() {
    //perform single change related to this element
    //e.g. update one reference in html file
  }

  public void undoChange() {
    //undo change performed by performChange
  }
}

Model-driven Changes are more complex changes. For instance Java Refactoring module uses Retouche Java model to perform refactoring of java files. Changes of this kind are expected to be driven by some internal, domain specific model. In this case you need to do 2 things. 1. Call RefactoringElementsBag.add(refactoring, yourRefactoringElementImplementation):

class MyRefactoringElementImplementation extends SimpleRefactoringElementImpl {
  public void performChange() {
    //implementation is empty!
  }

  public void undoChange() {
    //implementation is empty!
  }

  public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    enableThisChangeInModel(enabled);
  }
}

2. Call RefactoringElementBag.registerTransaction(YourTransaction)

File Changes are changes like file rename, file move etc. Implementation can be following: Call RefactoringElementsBag.addFileChange(refactoring, yourRefactoringElementImplementation):

class MyRefactoringElementImplementation extends SimpleRefactoringElementImpl {
  public void performChange() {
    //do change
  }

  public void undoChange() {
    //undo change
  }

Q3: It is not clear top me as to how the clients are supposed to plug into the Undo and Redo Refactoring actions?

A3: You don't need to do anything special. If you correctly implement refactoring changes, redo is done automatically.

Q4: I want to have refactoring submenu on my node. What should I do?

A4: Do this in mf-layer.xml

  <folder name="Loaders">
    <folder name="text">
        <folder name="your mime type">
              <file name="RefactoringAll.instance">
                  <attr name="instanceCreate" methodvalue="org.netbeans.modules.refactoring.api.ui.RefactoringActionsFactory.popupSubmenuAction"/>
              </file>
         </folder>
     </folder>
 </folder>

Q5: I want to have refactoring submenu in my editor. What should I do?

A5: Do this in mf-layer.xml

    <folder name="Editors">
        <folder name="text">
            <folder name="your mime type x-java">
                <folder name="Popup">
                    <file name="RefactoringAll.instance">
                         <attr name="instanceCreate" methodvalue="org.netbeans.modules.refactoring.api.ui.RefactoringActionsFactory.editorSubmenuAction"/>
                    </file>
                </folder>
            </folder>
        </folder>
    </folder>

Q5: I need to add a new action into refactoring menu, what should I do?

A5: Do this in mf-layer.xml

    <folder name="Menu">
        <folder name="Refactoring">
            <file name="MyAction.instance">
                <attr name="instanceClass" stringvalue="org.netbeans.modules.my.MyAction"/>
            </file>
        </folder>    
     </folder>   

Q6: I have my own implementation of Rename, how can I connect it to Refactor | Rename action?

A6: Just implement ActionsImplementationsProvider and register it into META-INF services:

public class MyProvider extends ActionsImplementationsProvider {

 public boolean canRename(Lookup lookup) {
   Node[] nodes = lookup.lookupAll(Node.class);
   if (..one node selected and the node belongs to java...)
      return true;
   else 
      return false;
 }

 public void doRename(Lookup selectedNodes) {
   Node[] nodes = lookup.lookupAll(Node.class);
   final FileObject fo = getFileFromNode(nodes[0]);
   return new Runnable() {
     public void run() {
       UI.openRefactoringUI(new RenameRefactoringUI(fo);
     }
   }    
 }
}
Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo