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.refactoring;
011:
012: import org.eclipse.core.resources.IProject;
013: import org.eclipse.core.resources.IResource;
014: import org.eclipse.core.resources.ResourcesPlugin;
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.core.runtime.IConfigurationElement;
017: import org.eclipse.core.runtime.IProgressMonitor;
018: import org.eclipse.core.runtime.OperationCanceledException;
019: import org.eclipse.core.runtime.SubProgressMonitor;
020: import org.eclipse.jdt.core.refactoring.descriptors.RenameResourceDescriptor;
021: import org.eclipse.ltk.core.refactoring.Change;
022: import org.eclipse.ltk.core.refactoring.CompositeChange;
023: import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
024: import org.eclipse.ltk.core.refactoring.RefactoringStatus;
025: import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
026: import org.eclipse.ltk.core.refactoring.participants.IParticipantDescriptorFilter;
027: import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
028: import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
029: import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
030: import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
031: import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
032: import org.eclipse.osgi.service.resolver.BundleDescription;
033: import org.eclipse.pde.core.plugin.IPluginModelBase;
034: import org.eclipse.pde.core.plugin.PluginRegistry;
035: import org.eclipse.pde.internal.ui.PDEUIMessages;
036: import org.osgi.framework.Constants;
037:
038: import com.ibm.icu.text.MessageFormat;
039:
040: public class RenamePluginProcessor extends RefactoringProcessor {
041:
042: RenamePluginInfo fInfo;
043:
044: public RenamePluginProcessor(RenamePluginInfo info) {
045: fInfo = info;
046: }
047:
048: public RefactoringStatus checkFinalConditions(IProgressMonitor pm,
049: CheckConditionsContext context) throws CoreException,
050: OperationCanceledException {
051: RefactoringStatus status = new RefactoringStatus();
052: IResource res = fInfo.getBase().getUnderlyingResource();
053: if (res == null)
054: status
055: .addFatalError(PDEUIMessages.RenamePluginProcessor_externalBundleError);
056: else if (!res.getProject()
057: .getFile("META-INF/MANIFEST.MF").exists()) //$NON-NLS-1$
058: status
059: .addFatalError(PDEUIMessages.RenamePluginProcessor_noManifestError);
060: if (fInfo.isRenameProject()) {
061: String newName = fInfo.getNewID();
062: IProject newProject = ResourcesPlugin.getWorkspace()
063: .getRoot().getProject(newName);
064: // if destination exists and it is not the same project we are currently trying to rename, show error message
065: if (newProject.exists()
066: && !(res.getProject().equals(newProject)))
067: status
068: .addFatalError(MessageFormat
069: .format(
070: PDEUIMessages.RenameProjectChange_destinationExists,
071: new String[] { newName }));
072: }
073: return status;
074: }
075:
076: public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
077: throws CoreException, OperationCanceledException {
078: return null;
079: }
080:
081: public Object[] getElements() {
082: return new Object[] { fInfo.getBase() };
083: }
084:
085: public String getIdentifier() {
086: return getClass().getName();
087: }
088:
089: public String getProcessorName() {
090: return PDEUIMessages.RenamePluginProcessor_processorName;
091: }
092:
093: public boolean isApplicable() throws CoreException {
094: return true;
095: }
096:
097: public RefactoringParticipant[] loadParticipants(
098: RefactoringStatus status,
099: SharableParticipants sharedParticipants)
100: throws CoreException {
101: if (fInfo.isRenameProject()) {
102: // filter out PDE's container rename refactor participant. We will already update the Manifest, so we don't need to run our participant
103: IParticipantDescriptorFilter filter = new IParticipantDescriptorFilter() {
104: static final String PDE_CONTAINER_RENAME_PARTICIPANT = "org.eclipse.pde.ui.manifestFolderRenameParticipant"; //$NON-NLS-1$
105:
106: public boolean select(IConfigurationElement element,
107: RefactoringStatus status) {
108: if (PDE_CONTAINER_RENAME_PARTICIPANT.equals(element
109: .getAttribute("id"))) //$NON-NLS-1$
110: return false;
111: return true;
112: }
113: };
114:
115: IProject project = fInfo.getBase().getUnderlyingResource()
116: .getProject();
117: return ParticipantManager.loadRenameParticipants(status,
118: this , project, new RenameArguments(
119: fInfo.getNewID(), true), filter,
120: getAffectedNatures(project), sharedParticipants);
121: }
122: return new RefactoringParticipant[0];
123: }
124:
125: private String[] getAffectedNatures(IProject project)
126: throws CoreException {
127: // NOTE: JDT searches each dependent project for additional natures
128: return project.getDescription().getNatureIds();
129: }
130:
131: public Change createChange(IProgressMonitor pm)
132: throws CoreException, OperationCanceledException {
133: CompositeChange change = new CompositeChange(
134: MessageFormat
135: .format(
136: PDEUIMessages.RenamePluginProcessor_changeTitle,
137: new String[] { fInfo.getCurrentID(),
138: fInfo.getNewID() }));
139: pm.beginTask("", getTotalWork()); //$NON-NLS-1$
140: // update manifest with new Id
141: CreateHeaderChangeOperation op = new CreateHeaderChangeOperation(
142: fInfo.getBase(), Constants.BUNDLE_SYMBOLICNAME, fInfo
143: .getCurrentID(), fInfo.getNewID());
144: op.run(new SubProgressMonitor(pm, 1));
145: change.add(op.getChange());
146:
147: if (fInfo.isRenameProject()) {
148: change
149: .add(createProjectChange(new SubProgressMonitor(pm,
150: 1)));
151: }
152: if (fInfo.isUpdateReferences())
153: change
154: .addAll(createReferenceChanges(new SubProgressMonitor(
155: pm, 2)));
156: return change;
157: }
158:
159: private int getTotalWork() {
160: int total = 1;
161: if (fInfo.isRenameProject())
162: total += 1;
163: if (fInfo.isUpdateReferences())
164: total += 2;
165: return total;
166: }
167:
168: protected Change createProjectChange(IProgressMonitor monitor) {
169: RenameResourceDescriptor descriptor = new RenameResourceDescriptor();
170: IProject project = fInfo.getBase().getUnderlyingResource()
171: .getProject();
172: String newName = fInfo.getNewID();
173: // if project's name is already the same as the destination, then we don't have to do anything to rename project
174: if (project.getName().equals(newName))
175: return null;
176: descriptor.setDescription(MessageFormat.format(
177: PDEUIMessages.RenamePluginProcessor_renameProjectDesc,
178: new String[] { project.getName(), newName }));
179: descriptor.setComment(""); //$NON-NLS-1$
180: descriptor.setFlags(RefactoringDescriptor.STRUCTURAL_CHANGE
181: | RefactoringDescriptor.MULTI_CHANGE
182: | RefactoringDescriptor.BREAKING_CHANGE);
183: descriptor.setResource(project);
184: descriptor.setNewName(fInfo.getNewID());
185: monitor.done();
186: return new RenameProjectChange(descriptor, project, fInfo
187: .getNewID(), null);
188: }
189:
190: protected Change[] createReferenceChanges(IProgressMonitor monitor)
191: throws CoreException {
192: IPluginModelBase currentBase = fInfo.getBase();
193: BundleDescription desc = currentBase.getBundleDescription();
194: if (desc == null) {
195: IPluginModelBase savedBase = PluginRegistry
196: .findModel(currentBase.getUnderlyingResource()
197: .getProject());
198: desc = (savedBase != null) ? savedBase
199: .getBundleDescription() : null;
200: }
201: if (desc != null) {
202: FindReferenceOperation op = new FindReferenceOperation(
203: desc, fInfo.getNewID());
204: op.run(monitor);
205: return op.getChanges();
206: }
207: return new Change[0];
208: }
209:
210: }
|