blob: 913e60f1c7eb3793a88c19743176a2af428886d9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2011 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.nls;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IInitializer;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.ui.JavaPlugin;
/**
* @since 3.4
*/
public class NLSAccessorFieldRenameParticipant extends RenameParticipant {
private IField fField;
private String fNewName;
private TextFileChange fChange;
public NLSAccessorFieldRenameParticipant() {
}
@Override
public String getName() {
return NLSMessages.NLSAccessorFieldRenameParticipant_participantName;
}
@Override
public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException {
if (pm == null)
pm= new NullProgressMonitor();
pm.beginTask("", 100); //$NON-NLS-1$
try {
ICompilationUnit unit= fField.getCompilationUnit();
if (unit == null)
return null;
IType[] types= unit.getTypes();
if (types.length > 1)
return null;
if (!isPotentialNLSAccessor(unit))
return null;
IStorage resourceBundle= NLSHintHelper.getResourceBundle(unit);
if (!(resourceBundle instanceof IFile))
return null;
pm.worked(50);
IPath propertyFilePath= resourceBundle.getFullPath();
ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
try {
manager.connect(propertyFilePath, LocationKind.IFILE, new SubProgressMonitor(pm, 25));
IDocument document= manager.getTextFileBuffer(propertyFilePath, LocationKind.IFILE).getDocument();
PropertyFileDocumentModel model= new PropertyFileDocumentModel(document);
KeyValuePair oldPair= model.getKeyValuePair(fField.getElementName());
if (oldPair == null)
return null;
String value= oldPair.getValue();
KeyValuePair newPair= new KeyValuePair(fNewName, value);
ReplaceEdit edit= model.replace(oldPair, newPair);
if (edit == null)
return null;
fChange= new TextFileChange("", (IFile) resourceBundle); //$NON-NLS-1$
fChange.setEdit(edit);
String changeDescription= Messages.format(NLSMessages.NLSAccessorFieldRenameParticipant_changeDescription, new Object[] { fField.getElementName(), fNewName });
fChange.addTextEditChangeGroup(new TextEditChangeGroup(fChange, new TextEditGroup(changeDescription, edit)));
ResourceChangeChecker checker= context.getChecker(ResourceChangeChecker.class);
IResourceChangeDescriptionFactory deltaFactory= checker.getDeltaFactory();
deltaFactory.change((IFile) resourceBundle);
} finally {
manager.disconnect(propertyFilePath, LocationKind.IFILE, new SubProgressMonitor(pm, 25));
}
} catch (JavaModelException e) {
JavaPlugin.log(e);
return RefactoringStatus.createErrorStatus(NLSMessages.NLSAccessorFieldRenameParticipant_error_description);
} catch (CoreException e) {
JavaPlugin.log(e);
return RefactoringStatus.createErrorStatus(NLSMessages.NLSAccessorFieldRenameParticipant_error_description);
} finally {
pm.done();
}
return new RefactoringStatus();
}
@Override
public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
return fChange;
}
@Override
protected boolean initialize(Object element) {
fField= (IField) element;
return true;
}
@Override
public boolean initialize(RefactoringProcessor processor, Object element, RefactoringArguments arguments) {
fNewName= ((RenameArguments) arguments).getNewName();
return super.initialize(processor, element, arguments);
}
/*
* Be conservative, for every unit this returns true an AST will to be created!
*/
private static boolean isPotentialNLSAccessor(ICompilationUnit unit) throws JavaModelException {
IType type= unit.getTypes()[0];
if (!type.exists())
return false;
IField bundleNameField= getBundleNameField(type.getFields());
if (bundleNameField == null)
return false;
if (!importsOSGIUtil(unit))
return false;
for (IInitializer initializer : type.getInitializers()) {
if (Modifier.isStatic(initializer.getFlags()))
return true;
}
return false;
}
private static IField getBundleNameField(IField[] fields) {
for (IField field : fields) {
if ("BUNDLE_NAME".equals(field.getElementName())) { //$NON-NLS-1$
return field;
}
}
return null;
}
private static boolean importsOSGIUtil(ICompilationUnit unit) throws JavaModelException {
for (IImportDeclaration importDecl : unit.getImports()) {
if (importDecl.getElementName().startsWith("org.eclipse.osgi.util.")) { //$NON-NLS-1$
return true;
}
}
return false;
}
}