| /******************************************************************************* |
| * 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; |
| } |
| } |