Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 88204 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.xml (+8 lines)
Lines 1760-1763 Link Here
1760
                id="org.eclipse.jdt.ui.text.correction.QuickFixProcessor">
1760
                id="org.eclipse.jdt.ui.text.correction.QuickFixProcessor">
1761
          </quickFixProcessor>
1761
          </quickFixProcessor>
1762
       </extension>
1762
       </extension>
1763
       <extension
1764
             point="org.eclipse.jdt.ui.classpathFixProcessors">
1765
          <classpathFixProcessor
1766
                class="org.eclipse.pde.internal.ui.correction.java.UnresolvedImportFixProcessor"
1767
                id="org.eclipse.pde.ui.unresolvedImportQuickFixProcessor"
1768
                name="Unresolved Import Quick Fix Processor">
1769
          </classpathFixProcessor>
1770
       </extension>
1763
</plugin>
1771
</plugin>
(-)src/org/eclipse/pde/internal/ui/correction/java/UnresolvedImportFixProcessor.java (+241 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.correction.java;
12
13
import java.util.HashSet;
14
import java.util.Iterator;
15
import java.util.Set;
16
17
import org.eclipse.core.resources.IProject;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.OperationCanceledException;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.jdt.core.IJavaProject;
23
import org.eclipse.jdt.ui.text.java.ClasspathFixProcessor;
24
import org.eclipse.ltk.core.refactoring.Change;
25
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
26
import org.eclipse.osgi.service.resolver.BundleDescription;
27
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
28
import org.eclipse.pde.core.IBaseModel;
29
import org.eclipse.pde.core.plugin.IPluginImport;
30
import org.eclipse.pde.internal.core.PDECore;
31
import org.eclipse.pde.internal.core.WorkspaceModelManager;
32
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
33
import org.eclipse.pde.internal.ui.util.ModelModification;
34
import org.eclipse.pde.internal.ui.util.PDEModelUtility;
35
import org.eclipse.swt.graphics.Image;
36
37
/**
38
 * Offers a classpath fix proposal if the broken import statement can be
39
 * fixed by adding a plugin dependency (required bundle or package import).
40
 * @since 3.4
41
 */
42
public class UnresolvedImportFixProcessor extends ClasspathFixProcessor {
43
44
	/* (non-Javadoc)
45
	 * @see org.eclipse.jdt.ui.text.java.ClasspathFixProcessor#getFixImportProposals(org.eclipse.jdt.core.IJavaProject, java.lang.String)
46
	 */
47
	public ClasspathFixProposal[] getFixImportProposals(IJavaProject project, String name) throws CoreException {
48
		// TODO Check if project is of a PDE nature (this might be handled already by extension point)
49
		if (project == null || !WorkspaceModelManager.isPluginProject(project.getProject())){
50
			return null;
51
		}
52
		
53
		int idx= name.lastIndexOf('.');
54
		String packageName= idx != -1 ? name.substring(0, idx) : null;
55
		String typeName= name.substring(idx + 1);
56
		if (typeName.length() == 1 && typeName.charAt(0) == '*') {
57
			typeName= null;
58
		}
59
		
60
		if (packageName != null){
61
			// Get the packages exported by all bundles, see if any can provide the required classes
62
			ExportPackageDescription[] knownPackages = PDECore.getDefault().getModelManager().getState().getState().getExportedPackages();
63
			Set validPackages = new HashSet();
64
			for (int i = 0; i < knownPackages.length; i++) {
65
				// TODO Is there a better way to compare, currently no checking of class name
66
				if (knownPackages[i].getName().equals(packageName)){
67
					validPackages.add(knownPackages[i]);
68
				}
69
			}
70
			
71
			// TODO Do we want to create a proposal for every valid package?  Consider using a wizard to choose?
72
			ClasspathFixProposal[] proposals = new ClasspathFixProposal[validPackages.size()];
73
			int counter = 0;
74
			Iterator validPackagesIter = validPackages.iterator();
75
			while (validPackagesIter.hasNext()) {
76
				ExportPackageDescription currentPackage = (ExportPackageDescription) validPackagesIter.next();
77
				proposals[counter] = new RequireBundleFixProposal(project,currentPackage);
78
			}
79
			if (proposals.length > 0){
80
				return proposals;
81
			}
82
		}
83
		
84
		// TODO Do we want to allow overridden processors to run? 
85
		return null;
86
	}
87
	
88
	/**
89
	 * Proposal to fix a broken import by adding a required bundle.
90
	 */
91
	class RequireBundleFixProposal extends ClasspathFixProposal{
92
		
93
		private IProject fProject;
94
		private BundleDescription fBundleDescription;
95
		
96
		/**
97
		 * Constructor
98
		 * @param project The project that needs the new required bundle
99
		 * @param packageDescription the package we want a dependency on
100
		 */
101
		public RequireBundleFixProposal(IJavaProject project, ExportPackageDescription packageDescription) {
102
			fProject = project.getProject();
103
			fBundleDescription = packageDescription.getExporter();
104
		}
105
106
		/* (non-Javadoc)
107
		 * @see org.eclipse.jdt.ui.text.java.ClasspathFixProcessor.ClasspathFixProposal#createChange(org.eclipse.core.runtime.IProgressMonitor)
108
		 */
109
		public Change createChange(IProgressMonitor monitor) throws CoreException {
110
			return new BundleRequirementChange(fProject,fBundleDescription);
111
		}
112
113
		/* (non-Javadoc)
114
		 * @see org.eclipse.jdt.ui.text.java.ClasspathFixProcessor.ClasspathFixProposal#getAdditionalProposalInfo()
115
		 */
116
		public String getAdditionalProposalInfo() {
117
			return "Adds a bundle to the required bundles for this project.";
118
		}
119
		
120
		/* (non-Javadoc)
121
		 * @see org.eclipse.jdt.ui.text.java.ClasspathFixProcessor.ClasspathFixProposal#getDisplayString()
122
		 */
123
		public String getDisplayString() {
124
			return "Add " + fBundleDescription.getName() + " to required bundles";
125
		}
126
127
		/* (non-Javadoc)
128
		 * @see org.eclipse.jdt.ui.text.java.ClasspathFixProcessor.ClasspathFixProposal#getImage()
129
		 */
130
		public Image getImage() {
131
			return null;
132
			// TODO Use image such as JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
133
		}
134
135
		/* (non-Javadoc)
136
		 * @see org.eclipse.jdt.ui.text.java.ClasspathFixProcessor.ClasspathFixProposal#getRelevance()
137
		 */
138
		public int getRelevance() {
139
			return 8;
140
		}
141
	}
142
	
143
	/**
144
	 * Change that actually adds the required bundle dependency.
145
	 */
146
	class BundleRequirementChange extends Change{	
147
	
148
		private IProject fBaseProject;
149
		private BundleDescription fBundle;
150
		
151
		/**
152
		 * Constructor
153
		 * @param project the project to add the dependency to
154
		 * @param bundleDescription the bundle to add as a dependency
155
		 */
156
		public BundleRequirementChange(IProject project, BundleDescription bundleDescription){
157
			fBaseProject = project;
158
			fBundle = bundleDescription;
159
		}
160
		
161
		/* (non-Javadoc)
162
		 * @see org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime.IProgressMonitor)
163
		 */
164
		public Change perform(IProgressMonitor pm) throws CoreException {
165
			// TODO if the IBaseModel is a org.eclipse.pde.internal.core.text.plugin.PluginModelBase, the IPluginImport should be a PluginImportNode that will make it work for 3.0 projects also
166
			ModelModification modelMod = new ModelModification(fBaseProject){
167
				protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
168
					if (model instanceof IBundlePluginModelBase) {
169
						addRequiredBundle(monitor, (IBundlePluginModelBase)model, fBundle);
170
					}
171
				}
172
			};
173
			PDEModelUtility.modifyModel(modelMod, pm);
174
			return null;
175
		}
176
	
177
		/* (non-Javadoc)
178
		 * @see org.eclipse.ltk.core.refactoring.Change#isValid(org.eclipse.core.runtime.IProgressMonitor)
179
		 */
180
		public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException,	OperationCanceledException {
181
			return RefactoringStatus.create(Status.OK_STATUS);
182
		}
183
	
184
		/* (non-Javadoc)
185
		 * @see org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org.eclipse.core.runtime.IProgressMonitor)
186
		 */
187
		public void initializeValidationData(IProgressMonitor pm) {
188
		}
189
	
190
		/* (non-Javadoc)
191
		 * @see org.eclipse.ltk.core.refactoring.Change#getName()
192
		 */
193
		public String getName() {
194
			return "Change to bundle requirements";
195
		}
196
	
197
		/* (non-Javadoc)
198
		 * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement()
199
		 */
200
		public Object getModifiedElement() {
201
			return fBaseProject;
202
		}
203
		
204
		/**
205
		 * Adds the given bundle to the list of required bundles
206
		 * @param monitor
207
		 * @param baseBundle
208
		 * @param addBundle
209
		 * @throws CoreException
210
		 */
211
		private void addRequiredBundle(IProgressMonitor monitor, IBundlePluginModelBase baseBundle, BundleDescription addBundle) throws CoreException {
212
			// TODO Does not check if the bundle already is in the manifest?
213
			IPluginImport pluginImport = baseBundle.createImport();
214
			pluginImport.setId(addBundle.getSymbolicName());
215
			baseBundle.getPluginBase().add(pluginImport);
216
		}
217
		
218
//		public static void organizeImportPackages(IBundle bundle, boolean removeImports) {
219
//			if (!(bundle instanceof Bundle))
220
//				return;
221
//			ImportPackageHeader header = (ImportPackageHeader)((Bundle)bundle).getManifestHeader(Constants.IMPORT_PACKAGE);
222
//			if (header == null)
223
//				return;
224
//			ImportPackageObject[] importedPackages = header.getPackages();
225
//			Set availablePackages = getAvailableExportedPackages();
226
//			// get Preference
227
//			for (int i = 0; i < importedPackages.length; i++) {
228
//				String pkgName = importedPackages[i].getName();
229
//				if (!availablePackages.contains(pkgName)){
230
//					if (removeImports)
231
//						header.removePackage(importedPackages[i]);
232
//					else {
233
//						importedPackages[i].setOptional(true);
234
//					}
235
//				}
236
//			}
237
//		}
238
		
239
	}
240
	
241
}

Return to bug 88204