add support for migration of imports/exports based on Move package refactoring (FELIX-1346)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@966638 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ExportPackageChange.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ExportPackageChange.java
index 96b8c2e..b32ae68 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ExportPackageChange.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ExportPackageChange.java
@@ -60,8 +60,13 @@
@Override
public Change perform(IProgressMonitor progress) throws CoreException
{
- sigil.getBundle().getBundleInfo().removeChild(oldExport);
- sigil.getBundle().getBundleInfo().addExport(newExport);
+ if (oldExport != null) {
+ sigil.getBundle().getBundleInfo().removeChild(oldExport);
+ }
+
+ if (newExport != null) {
+ sigil.getBundle().getBundleInfo().addExport(newExport);
+ }
sigil.save(progress);
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ImportPackageChange.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ImportPackageChange.java
index 289a2ac..53fbdce 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ImportPackageChange.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/ImportPackageChange.java
@@ -53,8 +53,13 @@
@Override
public Change perform(IProgressMonitor progress) throws CoreException
{
- sigil.getBundle().getBundleInfo().removeImport(oldImport);
- sigil.getBundle().getBundleInfo().addImport(newImport);
+ if (oldImport!=null) {
+ sigil.getBundle().getBundleInfo().removeImport(oldImport);
+ }
+
+ if (newImport != null) {
+ sigil.getBundle().getBundleInfo().addImport(newImport);
+ }
sigil.save(progress);
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/MovePackageParticipant.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/MovePackageParticipant.java
new file mode 100644
index 0000000..bb98253
--- /dev/null
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/MovePackageParticipant.java
@@ -0,0 +1,149 @@
+package org.apache.felix.sigil.ui.eclipse.refactor;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.apache.felix.sigil.eclipse.model.util.JavaHelper;
+import org.apache.felix.sigil.eclipse.model.util.ModelHelper;
+import org.apache.felix.sigil.model.ModelElementFactory;
+import org.apache.felix.sigil.model.osgi.IPackageExport;
+import org.apache.felix.sigil.model.osgi.IPackageImport;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.NullChange;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.MoveParticipant;
+
+public class MovePackageParticipant extends MoveParticipant
+{
+ private IPackageFragment packageFragment;
+ private List<Change> changes = new LinkedList<Change>();
+
+ @Override
+ public RefactoringStatus checkConditions(IProgressMonitor monitor,
+ CheckConditionsContext context) throws OperationCanceledException
+ {
+ if (getArguments().getUpdateReferences()) {
+ try
+ {
+ ISigilProjectModel sourceProject = SigilCore.create(packageFragment.getJavaProject().getProject());
+ IPackageFragmentRoot dest = (IPackageFragmentRoot) getArguments().getDestination();
+ ISigilProjectModel destProject = SigilCore.create(dest.getJavaProject().getProject());
+
+ RefactoringStatus status = new RefactoringStatus();
+ if ( !sourceProject.equals(destProject) ) {
+ final String packageName = packageFragment.getElementName();
+ IPackageExport oldExport = ModelHelper.findExport(sourceProject, packageName);
+
+ if (oldExport != null) {
+ IPackageExport newExport = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
+
+ newExport.setPackageName(oldExport.getPackageName());
+ newExport.setVersion(oldExport.getRawVersion());
+
+ changes.add(new ExportPackageChange(destProject,null, newExport));
+ changes.add(new ExportPackageChange(sourceProject, oldExport, null));
+
+ status.addWarning("Package " + packageName + " is exported from " + sourceProject.getSymbolicName() + ", this may effect client bundles that use require bundle");
+ }
+ else {
+ SubMonitor sub = SubMonitor.convert(monitor);
+
+ Set<String> users = JavaHelper.findLocalPackageUsers(sourceProject, packageName, sub.newChild(100));
+ Set<String> dependencies = JavaHelper.findLocalPackageDependencies(sourceProject, packageName, sub.newChild(100));
+
+ if (users.size() > 0 && dependencies.size() > 0) {
+ status.addWarning("Package " + packageName + " is coupled to " + users + " and " + dependencies + " this may cause a cyclical dependency");
+ }
+
+ if (users.size() > 0) { // attempt to move an API package
+ IPackageExport newExport = createNewExport(status, destProject, packageName);
+ createNewImport(status, sourceProject, newExport);
+ }
+
+ if (dependencies.size() > 0){ // moved an impl package
+ for (String dep : dependencies) {
+ IPackageExport newExport = createNewExport(status, sourceProject, dep);
+ createNewImport(status, destProject, newExport);
+ }
+ }
+ }
+ }
+ return status;
+ }
+ catch (CoreException e)
+ {
+ SigilCore.warn("Failed to create move refactor conditions", e);
+ throw new OperationCanceledException(e.getMessage());
+ }
+ }
+ else {
+ return new RefactoringStatus();
+ }
+ }
+
+ private void createNewImport(RefactoringStatus status,
+ ISigilProjectModel project, IPackageExport export)
+ {
+ IPackageImport newImport = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
+ newImport.setPackageName(export.getPackageName());
+ newImport.setVersions(ModelHelper.getDefaultRange(export.getVersion()));
+
+ status.addInfo("Creating new import in " + project.getSymbolicName());
+ changes.add( new ImportPackageChange(project, null, newImport));
+ }
+
+ private IPackageExport createNewExport(RefactoringStatus status,
+ ISigilProjectModel project, String packageName)
+ {
+ IPackageExport newExport = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
+ newExport.setPackageName(packageName);
+ // new export inherits project version by default
+ newExport.setVersion(project.getVersion());
+
+ status.addInfo("Creating new export " + packageName + " in " + project.getSymbolicName());
+ changes.add( new ExportPackageChange(project, null, newExport));
+ return newExport;
+ }
+
+ @Override
+ public Change createChange(IProgressMonitor monitor) throws CoreException,
+ OperationCanceledException
+ {
+ if (changes.isEmpty()) {
+ return new NullChange();
+ }
+ else
+ {
+ CompositeChange ret = new CompositeChange("Export-Package update");
+
+ ret.addAll(changes.toArray(new Change[changes.size()]));
+
+ return ret;
+ }
+ }
+
+ @Override
+ public String getName()
+ {
+ return "Sigil package move participant";
+ }
+
+ @Override
+ protected boolean initialize(Object element)
+ {
+ this.packageFragment = (IPackageFragment) element;
+ return true;
+ }
+
+}
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/RenamePackageParticipant.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/RenamePackageParticipant.java
index 43ff150..dbe39c7 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/RenamePackageParticipant.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/refactor/RenamePackageParticipant.java
@@ -6,6 +6,7 @@
import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.apache.felix.sigil.eclipse.model.util.ModelHelper;
import org.apache.felix.sigil.model.IModelElement;
import org.apache.felix.sigil.model.IModelWalker;
import org.apache.felix.sigil.model.ModelElementFactory;
@@ -37,57 +38,44 @@
{
RefactoringStatus status = new RefactoringStatus();
- try
- {
- ISigilProjectModel sigil = SigilCore.create(packageFragment.getJavaProject().getProject());
- final String packageName = packageFragment.getElementName();
-
- SigilCore.log("Rename checkConditions " + packageName);
-
- final IPackageExport[] found = new IPackageExport[1];
- sigil.visit(new IModelWalker()
- {
- public boolean visit(IModelElement element)
- {
- if (element instanceof IPackageExport) {
- IPackageExport pe = (IPackageExport) element;
- if (pe.getPackageName().equals(packageName)) {
- found[0] = pe;
+ if (getArguments().getUpdateReferences()) {
+ try
+ {
+ ISigilProjectModel sigil = SigilCore.create(packageFragment.getJavaProject().getProject());
+ final String packageName = packageFragment.getElementName();
+
+ SigilCore.log("Rename checkConditions " + packageName);
+
+ IPackageExport oldExport = ModelHelper.findExport(sigil, packageName);
+
+ if (oldExport != null) {
+ // record change to check if out of sync...
+ touch(context, sigil);
+
+ status = RefactoringStatus.createWarningStatus("Package " + packageName + " is exported. Renaming this package may effect bundles outside of this workspace");
+ SigilCore.log("Export Package " + packageName + " renamed to " + getArguments().getNewName());
+
+ IPackageExport newExport = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
+ newExport.setPackageName(getArguments().getNewName());
+ newExport.setVersion(oldExport.getVersion());
+
+ changes.add(new ExportPackageChange(sigil, oldExport, newExport));
+
+ for ( ISigilProjectModel other : SigilCore.getRoot().getProjects() ) {
+ if ( !sigil.equals(other) ) {
+ // record change to check if out of sync...
+ touch(context, other);
}
+ changes.add(createImportChange(status, other, oldExport, newExport));
}
- return found[0] == null;
- }
- });
-
- if (found[0] != null) {
- // record change to check if out of sync...
- touch(context, sigil);
-
- status = RefactoringStatus.createWarningStatus("Package " + packageName + " is exported. Renaming this package may effect bundles outside of this workspace");
- SigilCore.log("Export Package " + packageName + " renamed to " + getArguments().getNewName());
-
- IPackageExport oldExport = found[0];
- IPackageExport newExport = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
- newExport.setPackageName(getArguments().getNewName());
- newExport.setVersion(oldExport.getVersion());
-
- changes.add(new ExportPackageChange(sigil, oldExport, newExport));
-
- for ( ISigilProjectModel other : SigilCore.getRoot().getProjects() ) {
- if ( !sigil.equals(other) ) {
- // record change to check if out of sync...
- touch(context, other);
- }
- changes.add(createImportChange(status, other, oldExport, newExport));
}
}
- }
- catch (CoreException e)
- {
- SigilCore.warn("Failed to create export package refactor", e);
- throw new OperationCanceledException("Failed to create export package refactor");
- }
-
+ catch (CoreException e)
+ {
+ SigilCore.warn("Failed to create export package refactor", e);
+ throw new OperationCanceledException("Failed to create export package refactor");
+ }
+ }
return status;
}