Renaming packages in Eclipse

48,544

Solution 1

By default empty parent packages are hidden in the package explorer, if you modify the Filters... in the Package Explorer to uncheck Empty Parent Packages (third from top in second screenshot) you'll be able to see the empty packages.

package explorer filters

filters view
(source: eclipse.org)

You can then rename the com package and check the Rename subpackages option to force all child packages to be renamed.

rename package
(source: eclipse.org)

Then when you're done reapply the filter to hide all those empty packages again.

Solution 2

It looks like the current JDT API (Java Development Tool, the part that includes package renamming) does only rename one package at a time (and not the sub-packages)

See:

When refactoring a package, that has subpackages, JDT creates child packages again, instead of just renaming the parent

we need an API on IPackageFragment to rename not only the fragment but also also all subpackages.
Effectively, the implementation would rename the folder of the package fragment and then update the package declarations in all contained CUs (including those in subpackages)

So it's "by design" at then moment (eclipse 3.5), but an enhancement is logged and will be taken into account for 3.6.

Note: that "lack of feature" has been noted since 2005!

I was testing the new hierarchical package rename and had two source folders with same package structure. To rename the packages in both I had to do the same operation twice.
It would be nice to get a hint and being asked whether the package rename should be applied to the other source folder(s) as well.

Solution 3

Create an File in your 'com' package. Rename it and check 'Rename subpackages'. Delete the file.

Solution 4

I've had a go at implementing a plugin to rename parent packages. It adds a "Rename parent package" item to the context menu of , or can be triggered by ctrl-7.

I've not implemented the code to enable/disable the menu item based on the active selection (there's some race condition that causes the wizard to stop cancelling). If the active selection is a package with a parent package, it will select that parent and launch the rename wizard. You'll still need to select "rename subpackages" manually.

Here's the plugin code:

package name.seller.rich.packagerenamer.actions;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
import org.eclipse.jdt.ui.actions.RenameAction;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;

public class RenameParentPackageHandler extends AbstractHandler {

    public RenameParentPackageHandler() {
    }

    public Object execute(ExecutionEvent event) throws ExecutionException {
        IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
        try {
            IStructuredSelection selection = SelectionConverter
                    .getStructuredSelection(activePart);

            IPackageFragment parentPackage = getParentPackage(selection);

            if (parentPackage != null && parentPackage.exists()) {

                RenameAction action = new RenameAction(HandlerUtil
                        .getActiveSite(event));

                StructuredSelection parentSelection = new StructuredSelection(
                        parentPackage);
                action.run(parentSelection);
            }
        } catch (JavaModelException e) {
            logException(e);
        }
        return null;
    }

    private IPackageFragment getParentPackage(IStructuredSelection selection) {
        IJavaElement[] elements = SelectionConverter.getElements(selection);

        if (elements != null && elements.length > 0) {
            if (elements[0] != null && elements[0] instanceof IPackageFragment) {
                IPackageFragment fragment = (IPackageFragment) elements[0];

                String packageName = fragment.getElementName();
                int lastDotIndex = packageName.lastIndexOf(".");

                if (lastDotIndex != -1) {
                    String parentPackageName = packageName.substring(0,
                            lastDotIndex);

                    IJavaElement parent = fragment.getParent();
                    if (parent != null
                            && parent instanceof IPackageFragmentRoot) {

                        return ((IPackageFragmentRoot) parent)
                                .getPackageFragment(parentPackageName);

                    }
                }
            }
        }
        return null;
    }

    protected void logException(Exception e) {
        JavaPlugin.log(e);
    }
}

Here's the plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin>
   <extension
     point="org.eclipse.ui.commands">
      <command
        name="Rename parent package"
        categoryId="name.seller.rich.packagerenamer.category"
        id="name.seller.rich.packagerenamer.renameParentPackage">
      </command>
   </extension>
   <extension
     point="org.eclipse.ui.handlers">
      <handler
        commandId="name.seller.rich.packagerenamer.renameParentPackage"
        class="name.seller.rich.packagerenamer.actions.RenameParentPackageHandler">
      </handler>
   </extension>
   <extension
     point="org.eclipse.ui.bindings">
      <key
        commandId="name.seller.rich.packagerenamer.renameParentPackage"
        contextId="org.eclipse.ui.contexts.window"
        sequence="M1+7"
        schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
      </key>
   </extension>
   <extension
     point="org.eclipse.ui.menus">
      <menuContribution
        locationURI="popup:org.eclipse.ui.popup.any?after=additions">
         <command
           commandId="name.seller.rich.packagerenamer.renameParentPackage"
           mnemonic="K">
         </command>
      </menuContribution>
   </extension>
</plugin>

And the manifest:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Classwizard
Bundle-SymbolicName: name.seller.rich.packagerenamer; singleton:=true
Bundle-Version: 1.0.0
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime,
 org.eclipse.jdt.core;bundle-version="3.5.0",
 org.eclipse.core.expressions;bundle-version="3.4.100",
 org.eclipse.jface.text;bundle-version="3.5.0",
 org.eclipse.jdt.ui;bundle-version="3.5.0",
 org.eclipse.ui.ide;bundle-version="3.5.0",
 org.eclipse.ui.editors;bundle-version="3.5.0",
 org.eclipse.core.resources;bundle-version="3.5.0"
Eclipse-AutoStart: true
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Share:
48,544
digiarnie
Author by

digiarnie

Updated on April 20, 2020

Comments

  • digiarnie
    digiarnie about 4 years

    In Eclipse's "Package Explorer", let's say I have a list of packages like this:

    • com.dog
    • com.cat
    • com.frog

    If I want to rename the "com" part of the package structure to be "animal", then I could select each package (above) and perform a refactor > rename.

    If I have many packages that start with "com", that process may take a while. Is there an easy way to rename the "com" package name without having to individually rename each package in the Package Explorer? or removing those packages from the build path before renaming?

    I tried going to the "Navigator" pane where it displays the folders in a tree structure but I am not given the rename capability.