views:

1170

answers:

4

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.

+5  A: 

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.

VonC
thanks for the sentiment, but it seems you didn't actually vote for my answer
Rich Seller
+3  A: 

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

codedevour
Thanks for the point about the "rename subpackages" - it helped me sort out why the solution suggested by Andy and MatrixFrog didn't quite work for me (my bad)
digiarnie
+5  A: 
Rich Seller
Good catch, Rich. +1. May be your answer should be the official one.
VonC
What? I didn't actually do the upvote? Sorry. I really meant to. Well, better late than never... ;)
VonC
You're very kind. Just after I hit the rep limit for today naturally.
Rich Seller
VonC
right behind you and gaining at -40 votes/month!
Rich Seller
bingo! exactly what I wanted! Thanks for the information :D
digiarnie
+1  A: 

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
Rich Seller
And... +1. This time, it *should* count in your daily limit ;)
VonC
thanks very much, now just need 562 more
Rich Seller