001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.wizards.tools;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.ArrayList;
014: import java.util.Iterator;
015:
016: import org.eclipse.core.resources.IProject;
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.core.runtime.IProgressMonitor;
019: import org.eclipse.core.runtime.OperationCanceledException;
020: import org.eclipse.core.runtime.SubProgressMonitor;
021: import org.eclipse.ltk.core.refactoring.Change;
022: import org.eclipse.ltk.core.refactoring.CompositeChange;
023: import org.eclipse.ltk.core.refactoring.RefactoringStatus;
024: import org.eclipse.ltk.core.refactoring.TextFileChange;
025: import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
026: import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
027: import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
028: import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
029: import org.eclipse.osgi.util.NLS;
030: import org.eclipse.pde.core.IBaseModel;
031: import org.eclipse.pde.core.plugin.IPluginModelBase;
032: import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
033: import org.eclipse.pde.internal.core.ibundle.IBundle;
034: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
035: import org.eclipse.pde.internal.ui.PDEPlugin;
036: import org.eclipse.pde.internal.ui.PDEUIMessages;
037: import org.eclipse.pde.internal.ui.search.dependencies.AddNewDependenciesOperation;
038: import org.eclipse.pde.internal.ui.search.dependencies.CalculateUsesOperation;
039: import org.eclipse.pde.internal.ui.search.dependencies.GatherUnusedDependenciesOperation;
040: import org.eclipse.pde.internal.ui.util.ModelModification;
041: import org.eclipse.pde.internal.ui.util.PDEModelUtility;
042:
043: public class OrganizeManifestsProcessor extends RefactoringProcessor
044: implements IOrganizeManifestsSettings {
045:
046: // if operation is executed without setting operations, these defaults will be used
047: protected boolean fAddMissing = true; // add all packages to export-package
048: protected boolean fMarkInternal = true; // mark export-package as internal
049: protected String fPackageFilter = VALUE_DEFAULT_FILTER;
050: protected boolean fRemoveUnresolved = true; // remove unresolved export-package
051: protected boolean fCalculateUses = false; // calculate the 'uses' directive for exported packages
052: protected boolean fModifyDep = true; // modify import-package / require-bundle
053: protected boolean fRemoveDependencies = true; // if true: remove, else mark optional
054: protected boolean fUnusedDependencies = false; // find/remove unused dependencies - long running op
055: protected boolean fRemoveLazy = true; // remove lazy/auto start if no activator
056: protected boolean fPrefixIconNL = false; // prefix icon paths with $nl$
057: protected boolean fUnusedKeys = false; // remove unused <bundle-localization>.properties keys
058: protected boolean fAddDependencies = false;
059:
060: ArrayList fProjectList;
061: private IProject fCurrentProject;
062:
063: public OrganizeManifestsProcessor(ArrayList projects) {
064: fProjectList = projects;
065: }
066:
067: public RefactoringStatus checkFinalConditions(IProgressMonitor pm,
068: CheckConditionsContext context) throws CoreException,
069: OperationCanceledException {
070: RefactoringStatus status = new RefactoringStatus();
071: for (Iterator i = fProjectList.iterator(); i.hasNext();) {
072: if (!(i.next() instanceof IProject))
073: status
074: .addFatalError(PDEUIMessages.OrganizeManifestsProcessor_invalidParam);
075: }
076: return status;
077: }
078:
079: public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
080: throws CoreException, OperationCanceledException {
081: return null;
082: }
083:
084: public Change createChange(IProgressMonitor pm)
085: throws CoreException, OperationCanceledException {
086: CompositeChange change = new CompositeChange(""); //$NON-NLS-1$
087: change.markAsSynthetic();
088: pm.beginTask(PDEUIMessages.OrganizeManifestJob_taskName,
089: fProjectList.size());
090: for (Iterator i = fProjectList.iterator(); i.hasNext()
091: && !pm.isCanceled();) {
092: CompositeChange projectChange = cleanProject((IProject) i
093: .next(), new SubProgressMonitor(pm, 1));
094: if (projectChange.getChildren().length > 0)
095: change.add(projectChange);
096: }
097: return change;
098: }
099:
100: private CompositeChange cleanProject(IProject project,
101: IProgressMonitor monitor) {
102: fCurrentProject = project;
103: CompositeChange change = new CompositeChange(NLS.bind(
104: PDEUIMessages.OrganizeManifestsProcessor_rootMessage,
105: new String[] { fCurrentProject.getName() }));
106: monitor.beginTask(NLS.bind(
107: PDEUIMessages.OrganizeManifestsProcessor_rootMessage,
108: new String[] { fCurrentProject.getName() }),
109: getTotalTicksPerProject());
110:
111: final TextFileChange[] result = { null };
112: final Exception[] ee = new Exception[1];
113: ModelModification modification = new ModelModification(
114: fCurrentProject) {
115: protected void modifyModel(IBaseModel model,
116: IProgressMonitor monitor) throws CoreException {
117: if (model instanceof IBundlePluginModelBase)
118: try {
119: runCleanup(monitor,
120: (IBundlePluginModelBase) model, result);
121: } catch (InvocationTargetException e) {
122: ee[0] = e;
123: } catch (InterruptedException e) {
124: ee[0] = e;
125: }
126: }
127: };
128: TextFileChange[] changes = PDEModelUtility
129: .changesForModelModication(modification, monitor);
130: for (int i = 0; i < changes.length; i++)
131: change.add(changes[i]);
132: if (result[0] != null)
133: change.add(result[0]);
134: if (ee[0] != null)
135: PDEPlugin.log(ee[0]);
136: return change;
137: }
138:
139: private void runCleanup(IProgressMonitor monitor,
140: IBundlePluginModelBase modelBase, TextFileChange[] result)
141: throws InvocationTargetException, InterruptedException {
142:
143: IBundle currentBundle = modelBase.getBundleModel().getBundle();
144: ISharedExtensionsModel sharedExtensionsModel = modelBase
145: .getExtensionsModel();
146: IPluginModelBase currentExtensionsModel = null;
147: if (sharedExtensionsModel instanceof IPluginModelBase)
148: currentExtensionsModel = (IPluginModelBase) sharedExtensionsModel;
149:
150: String projectName = fCurrentProject.getName();
151:
152: if (fAddMissing || fRemoveUnresolved) {
153: monitor.subTask(NLS.bind(
154: PDEUIMessages.OrganizeManifestsOperation_export,
155: projectName));
156: if (!monitor.isCanceled())
157: OrganizeManifest
158: .organizeExportPackages(currentBundle,
159: fCurrentProject, fAddMissing,
160: fRemoveUnresolved);
161: if (fAddMissing)
162: monitor.worked(1);
163: if (fRemoveUnresolved)
164: monitor.worked(1);
165: }
166:
167: if (fMarkInternal) {
168: monitor
169: .subTask(NLS
170: .bind(
171: PDEUIMessages.OrganizeManifestsOperation_filterInternal,
172: projectName));
173: if (!monitor.isCanceled())
174: OrganizeManifest.markPackagesInternal(currentBundle,
175: fPackageFilter);
176: monitor.worked(1);
177: }
178:
179: if (fModifyDep) {
180: String message = fRemoveDependencies ? NLS
181: .bind(
182: PDEUIMessages.OrganizeManifestsOperation_removeUnresolved,
183: projectName)
184: : NLS
185: .bind(
186: PDEUIMessages.OrganizeManifestsOperation_markOptionalUnresolved,
187: projectName);
188: monitor.subTask(message);
189: if (!monitor.isCanceled())
190: OrganizeManifest.organizeImportPackages(currentBundle,
191: fRemoveDependencies);
192: monitor.worked(1);
193:
194: if (!monitor.isCanceled())
195: OrganizeManifest.organizeRequireBundles(currentBundle,
196: fRemoveDependencies);
197: monitor.worked(1);
198: }
199:
200: if (fCalculateUses) {
201: // we don't set the subTask because it is done in the CalculateUsesOperation, for each package it scans
202: if (!monitor.isCanceled()) {
203: CalculateUsesOperation op = new CalculateUsesOperation(
204: fCurrentProject, modelBase);
205: op.run(new SubProgressMonitor(monitor, 2));
206: }
207: }
208:
209: if (fAddDependencies) {
210: monitor
211: .subTask(NLS
212: .bind(
213: PDEUIMessages.OrganizeManifestsOperation_additionalDeps,
214: projectName));
215: if (!monitor.isCanceled()) {
216: AddNewDependenciesOperation op = new AddNewDependenciesOperation(
217: fCurrentProject, modelBase);
218: op.run(new SubProgressMonitor(monitor, 4));
219: }
220: }
221:
222: if (fUnusedDependencies) {
223: monitor
224: .subTask(NLS
225: .bind(
226: PDEUIMessages.OrganizeManifestsOperation_unusedDeps,
227: projectName));
228: if (!monitor.isCanceled()) {
229: SubProgressMonitor submon = new SubProgressMonitor(
230: monitor, 4);
231: GatherUnusedDependenciesOperation udo = new GatherUnusedDependenciesOperation(
232: modelBase);
233: udo.run(submon);
234: GatherUnusedDependenciesOperation.removeDependencies(
235: modelBase, udo.getList().toArray());
236: submon.done();
237: }
238: }
239:
240: if (fRemoveLazy) {
241: monitor.subTask(NLS.bind(
242: PDEUIMessages.OrganizeManifestsOperation_lazyStart,
243: fCurrentProject.getName()));
244: if (!monitor.isCanceled())
245: OrganizeManifest.removeUnneededLazyStart(currentBundle);
246: monitor.worked(1);
247: }
248:
249: if (fPrefixIconNL) {
250: monitor
251: .subTask(NLS
252: .bind(
253: PDEUIMessages.OrganizeManifestsOperation_nlIconPath,
254: projectName));
255: if (!monitor.isCanceled())
256: OrganizeManifest
257: .prefixIconPaths(currentExtensionsModel);
258: monitor.worked(1);
259: }
260:
261: if (fUnusedKeys) {
262: monitor
263: .subTask(NLS
264: .bind(
265: PDEUIMessages.OrganizeManifestsOperation_unusedKeys,
266: projectName));
267: if (!monitor.isCanceled()) {
268: TextFileChange[] results = OrganizeManifest
269: .removeUnusedKeys(fCurrentProject,
270: currentBundle, currentExtensionsModel);
271: if (results.length > 0)
272: result[0] = results[0];
273: }
274: monitor.worked(1);
275: }
276: }
277:
278: public Object[] getElements() {
279: return fProjectList.toArray();
280: }
281:
282: public String getIdentifier() {
283: return getClass().getName();
284: }
285:
286: public String getProcessorName() {
287: return PDEUIMessages.OrganizeManifestsWizardPage_title;
288: }
289:
290: public boolean isApplicable() throws CoreException {
291: return true;
292: }
293:
294: public RefactoringParticipant[] loadParticipants(
295: RefactoringStatus status,
296: SharableParticipants sharedParticipants)
297: throws CoreException {
298: return new RefactoringParticipant[0];
299: }
300:
301: private int getTotalTicksPerProject() {
302: int ticks = 0;
303: if (fAddMissing)
304: ticks += 1;
305: if (fMarkInternal)
306: ticks += 1;
307: if (fRemoveUnresolved)
308: ticks += 1;
309: if (fCalculateUses)
310: ticks += 4;
311: if (fModifyDep)
312: ticks += 2;
313: if (fUnusedDependencies)
314: ticks += 4;
315: if (fAddDependencies)
316: ticks += 4;
317: if (fRemoveLazy)
318: ticks += 1;
319: if (fPrefixIconNL)
320: ticks += 1;
321: if (fUnusedKeys)
322: ticks += 1;
323: return ticks;
324: }
325:
326: public void setAddMissing(boolean addMissing) {
327: fAddMissing = addMissing;
328: }
329:
330: public void setMarkInternal(boolean markInternal) {
331: fMarkInternal = markInternal;
332: }
333:
334: public void setPackageFilter(String packageFilter) {
335: fPackageFilter = packageFilter;
336: }
337:
338: public void setRemoveUnresolved(boolean removeUnresolved) {
339: fRemoveUnresolved = removeUnresolved;
340: }
341:
342: public void setCalculateUses(boolean calculateUses) {
343: fCalculateUses = calculateUses;
344: }
345:
346: public void setModifyDep(boolean modifyDep) {
347: fModifyDep = modifyDep;
348: }
349:
350: public void setRemoveDependencies(boolean removeDependencies) {
351: fRemoveDependencies = removeDependencies;
352: }
353:
354: public void setUnusedDependencies(boolean unusedDependencies) {
355: fUnusedDependencies = unusedDependencies;
356: }
357:
358: public void setRemoveLazy(boolean removeLazy) {
359: fRemoveLazy = removeLazy;
360: }
361:
362: public void setPrefixIconNL(boolean prefixIconNL) {
363: fPrefixIconNL = prefixIconNL;
364: }
365:
366: public void setUnusedKeys(boolean unusedKeys) {
367: fUnusedKeys = unusedKeys;
368: }
369:
370: public void setAddDependencies(boolean addDependencies) {
371: fAddDependencies = addDependencies;
372: }
373: }
|