blob: 0318521183aaa8eab02f7d8988f8b6f9733018b5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Benjamin Cabe <benjamin.cabe@anyware-tech.com> - bug 219513
*******************************************************************************/
package org.eclipse.pde.internal.ui.wizards.tools;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.*;
import org.eclipse.ltk.core.refactoring.*;
import org.eclipse.ltk.core.refactoring.participants.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.IBaseModel;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
import org.eclipse.pde.internal.core.ibundle.IBundle;
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.internal.ui.search.dependencies.*;
import org.eclipse.pde.internal.ui.util.ModelModification;
import org.eclipse.pde.internal.ui.util.PDEModelUtility;
public class OrganizeManifestsProcessor extends RefactoringProcessor implements IOrganizeManifestsSettings {
// if operation is executed without setting operations, these defaults will be used
protected boolean fAddMissing = true; // add all packages to export-package
protected boolean fMarkInternal = true; // mark export-package as internal
protected String fPackageFilter = VALUE_DEFAULT_FILTER;
protected boolean fRemoveUnresolved = true; // remove unresolved export-package
protected boolean fCalculateUses = false; // calculate the 'uses' directive for exported packages
protected boolean fModifyDep = true; // modify import-package / require-bundle
protected boolean fRemoveDependencies = true; // if true: remove, else mark optional
protected boolean fUnusedDependencies = false; // find/remove unused dependencies - long running op
protected boolean fRemoveLazy = true; // remove lazy/auto start if no activator
protected boolean fRemoveUselessFiles = false; // remove fragment/plugin.xml if no extension/extension point defined
protected boolean fPrefixIconNL = false; // prefix icon paths with $nl$
protected boolean fUnusedKeys = false; // remove unused <bundle-localization>.properties keys
protected boolean fAddDependencies = false;
ArrayList fProjectList;
private IProject fCurrentProject;
public OrganizeManifestsProcessor(ArrayList projects) {
fProjectList = projects;
}
public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException, OperationCanceledException {
RefactoringStatus status = new RefactoringStatus();
for (Iterator i = fProjectList.iterator(); i.hasNext();) {
if (!(i.next() instanceof IProject))
status.addFatalError(PDEUIMessages.OrganizeManifestsProcessor_invalidParam);
}
return status;
}
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
return null;
}
public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
CompositeChange change = new CompositeChange(""); //$NON-NLS-1$
change.markAsSynthetic();
pm.beginTask(PDEUIMessages.OrganizeManifestJob_taskName, fProjectList.size());
for (Iterator i = fProjectList.iterator(); i.hasNext() && !pm.isCanceled();) {
CompositeChange projectChange = cleanProject((IProject) i.next(), new SubProgressMonitor(pm, 1));
if (projectChange.getChildren().length > 0)
change.add(projectChange);
}
return change;
}
private CompositeChange cleanProject(IProject project, IProgressMonitor monitor) {
fCurrentProject = project;
CompositeChange change = new CompositeChange(NLS.bind(PDEUIMessages.OrganizeManifestsProcessor_rootMessage, new String[] {fCurrentProject.getName()}));
monitor.beginTask(NLS.bind(PDEUIMessages.OrganizeManifestsProcessor_rootMessage, new String[] {fCurrentProject.getName()}), getTotalTicksPerProject());
final Change[] result = {null, null};
final Exception[] ee = new Exception[1];
ModelModification modification = new ModelModification(fCurrentProject) {
protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
if (model instanceof IBundlePluginModelBase)
try {
runCleanup(monitor, (IBundlePluginModelBase) model, result);
} catch (InvocationTargetException e) {
ee[0] = e;
} catch (InterruptedException e) {
ee[0] = e;
}
}
};
Change[] changes = PDEModelUtility.changesForModelModication(modification, monitor);
for (int i = 0; i < changes.length; i++)
change.add(changes[i]);
if (result[0] != null)
change.add(result[0]);
if (result[1] != null)
change.add(result[1]);
if (ee[0] != null)
PDEPlugin.log(ee[0]);
return change;
}
private void runCleanup(IProgressMonitor monitor, IBundlePluginModelBase modelBase, Change[] result) throws InvocationTargetException, InterruptedException {
IBundle currentBundle = modelBase.getBundleModel().getBundle();
ISharedExtensionsModel sharedExtensionsModel = modelBase.getExtensionsModel();
IPluginModelBase currentExtensionsModel = null;
if (sharedExtensionsModel instanceof IPluginModelBase)
currentExtensionsModel = (IPluginModelBase) sharedExtensionsModel;
String projectName = fCurrentProject.getName();
if (fAddMissing || fRemoveUnresolved) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_export, projectName));
if (!monitor.isCanceled())
OrganizeManifest.organizeExportPackages(currentBundle, fCurrentProject, fAddMissing, fRemoveUnresolved);
if (fAddMissing)
monitor.worked(1);
if (fRemoveUnresolved)
monitor.worked(1);
}
if (fMarkInternal) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_filterInternal, projectName));
if (!monitor.isCanceled())
OrganizeManifest.markPackagesInternal(currentBundle, fPackageFilter);
monitor.worked(1);
}
if (fModifyDep) {
String message = fRemoveDependencies ? NLS.bind(PDEUIMessages.OrganizeManifestsOperation_removeUnresolved, projectName) : NLS.bind(PDEUIMessages.OrganizeManifestsOperation_markOptionalUnresolved, projectName);
monitor.subTask(message);
if (!monitor.isCanceled())
OrganizeManifest.organizeImportPackages(currentBundle, fRemoveDependencies);
monitor.worked(1);
if (!monitor.isCanceled())
OrganizeManifest.organizeRequireBundles(currentBundle, fRemoveDependencies);
monitor.worked(1);
}
if (fCalculateUses) {
// we don't set the subTask because it is done in the CalculateUsesOperation, for each package it scans
if (!monitor.isCanceled()) {
CalculateUsesOperation op = new CalculateUsesOperation(fCurrentProject, modelBase);
op.run(new SubProgressMonitor(monitor, 2));
}
}
if (fAddDependencies) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_additionalDeps, projectName));
if (!monitor.isCanceled()) {
AddNewDependenciesOperation op = new AddNewDependenciesOperation(fCurrentProject, modelBase);
op.run(new SubProgressMonitor(monitor, 4));
}
}
if (fUnusedDependencies) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_unusedDeps, projectName));
if (!monitor.isCanceled()) {
SubProgressMonitor submon = new SubProgressMonitor(monitor, 4);
GatherUnusedDependenciesOperation udo = new GatherUnusedDependenciesOperation(modelBase);
udo.run(submon);
GatherUnusedDependenciesOperation.removeDependencies(modelBase, udo.getList().toArray());
submon.done();
}
}
if (fRemoveLazy) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_lazyStart, fCurrentProject.getName()));
if (!monitor.isCanceled())
OrganizeManifest.removeUnneededLazyStart(currentBundle);
monitor.worked(1);
}
if (fRemoveUselessFiles) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_uselessPluginFile, fCurrentProject.getName()));
if (!monitor.isCanceled()) {
result[1] = OrganizeManifest.deleteUselessPluginFile(fCurrentProject, currentExtensionsModel);
}
monitor.worked(1);
}
if (fPrefixIconNL) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_nlIconPath, projectName));
if (!monitor.isCanceled())
OrganizeManifest.prefixIconPaths(currentExtensionsModel);
monitor.worked(1);
}
if (fUnusedKeys) {
monitor.subTask(NLS.bind(PDEUIMessages.OrganizeManifestsOperation_unusedKeys, projectName));
if (!monitor.isCanceled()) {
Change[] results = OrganizeManifest.removeUnusedKeys(fCurrentProject, currentBundle, currentExtensionsModel);
if (results.length > 0)
result[0] = results[0];
}
monitor.worked(1);
}
}
public Object[] getElements() {
return fProjectList.toArray();
}
public String getIdentifier() {
return getClass().getName();
}
public String getProcessorName() {
return PDEUIMessages.OrganizeManifestsWizardPage_title;
}
public boolean isApplicable() throws CoreException {
return true;
}
public RefactoringParticipant[] loadParticipants(RefactoringStatus status, SharableParticipants sharedParticipants) throws CoreException {
return new RefactoringParticipant[0];
}
private int getTotalTicksPerProject() {
int ticks = 0;
if (fAddMissing)
ticks += 1;
if (fMarkInternal)
ticks += 1;
if (fRemoveUnresolved)
ticks += 1;
if (fCalculateUses)
ticks += 4;
if (fModifyDep)
ticks += 2;
if (fUnusedDependencies)
ticks += 4;
if (fAddDependencies)
ticks += 4;
if (fRemoveLazy)
ticks += 1;
if (fRemoveUselessFiles)
ticks += 1;
if (fPrefixIconNL)
ticks += 1;
if (fUnusedKeys)
ticks += 1;
return ticks;
}
public void setAddMissing(boolean addMissing) {
fAddMissing = addMissing;
}
public void setMarkInternal(boolean markInternal) {
fMarkInternal = markInternal;
}
public void setPackageFilter(String packageFilter) {
fPackageFilter = packageFilter;
}
public void setRemoveUnresolved(boolean removeUnresolved) {
fRemoveUnresolved = removeUnresolved;
}
public void setCalculateUses(boolean calculateUses) {
fCalculateUses = calculateUses;
}
public void setModifyDep(boolean modifyDep) {
fModifyDep = modifyDep;
}
public void setRemoveDependencies(boolean removeDependencies) {
fRemoveDependencies = removeDependencies;
}
public void setUnusedDependencies(boolean unusedDependencies) {
fUnusedDependencies = unusedDependencies;
}
public void setRemoveLazy(boolean removeLazy) {
fRemoveLazy = removeLazy;
}
public void setRemoveUselessFiles(boolean removeUselessFiles) {
fRemoveUselessFiles = removeUselessFiles;
}
public void setPrefixIconNL(boolean prefixIconNL) {
fPrefixIconNL = prefixIconNL;
}
public void setUnusedKeys(boolean unusedKeys) {
fUnusedKeys = unusedKeys;
}
public void setAddDependencies(boolean addDependencies) {
fAddDependencies = addDependencies;
}
}