/******************************************************************************* * Copyright (c) 2006, 2015 Zend Technologies 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: * Zend Technologies - initial API and implementation *******************************************************************************/ package org.eclipse.php.refactoring.core.rename; import java.text.MessageFormat; import java.util.List; import java.util.Map.Entry; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.TextFileChange; import org.eclipse.php.core.ast.nodes.*; import org.eclipse.php.internal.core.ast.locator.PHPElementConciliator; import org.eclipse.php.refactoring.core.PhpRefactoringCoreMessages; import org.eclipse.php.refactoring.core.rename.logic.RenameGlobalConstant; /** * Rename a constant processor * * @author Roy, 2007 */ public class RenameGlobalConstantProcessor extends AbstractRenameProcessor<IFile> implements ITextUpdating { private static final String RENAME_IS_PROCESSING = PhpRefactoringCoreMessages .getString("RenameDefinedProcessor.0"); //$NON-NLS-1$ private static final String CREATING_MODIFICATIONS_LABEL = PhpRefactoringCoreMessages .getString("RenameDefinedProcessor.1"); //$NON-NLS-1$ private static final String CONSTANT_IS_USED = PhpRefactoringCoreMessages .getString("RenameDefinedProcessor.2"); //$NON-NLS-1$ private static final String ID_RENAME_CONSTANT = "php.refactoring.ui.rename.constant"; //$NON-NLS-1$ protected static final String ATTRIBUTE_TEXTUAL_MATCHES = "textual"; //$NON-NLS-1$ public static final String RENAME_CONSTANT_PROCESSOR_NAME = PhpRefactoringCoreMessages .getString("RenameDefinedProcessor.3"); //$NON-NLS-1$ /** * The original identifier node we want to rename */ private final Scalar scalar; private final String scalarName; /** * holds wether or not we want to change also the inlined text */ private boolean isUpdateTextualMatches; public RenameGlobalConstantProcessor(IFile operatedFile, ASTNode locateNode) { super(operatedFile); //$NON-NLS-1$ this.scalar = getScalar(locateNode); final String stringValue = scalar.getStringValue(); final char charAt = stringValue.charAt(0); this.scalarName = charAt != '"' && charAt != '\'' ? stringValue : stringValue.substring(1, stringValue.length() - 1); } private Scalar getScalar(ASTNode locateNode) { if (locateNode.getType() != ASTNode.SCALAR) { if (locateNode instanceof Identifier && "define".equals(((Identifier) locateNode).getName())) { //$NON-NLS-1$ FunctionInvocation inv = (FunctionInvocation) locateNode .getParent().getParent(); List<Expression> parameters = inv.parameters(); if (parameters != null && parameters.size() > 0) { return (Scalar) parameters.get(0); } } else { return null; } } else { return (Scalar) locateNode; } return null; } /** * Derive the change */ public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { CompositeChange rootChange = new CompositeChange( PhpRefactoringCoreMessages .getString("RenameDefinedProcessor.4")); //$NON-NLS-1$ rootChange.markAsSynthetic(); try { pm.beginTask(RenameGlobalConstantProcessor.RENAME_IS_PROCESSING, participantFiles.size()); pm.setTaskName(RenameGlobalConstantProcessor.CREATING_MODIFICATIONS_LABEL); if (pm.isCanceled()) throw new OperationCanceledException(); // get target parameters final String newElementName = getNewElementName(); // go over the files and check for global variable usage for (Entry<IFile, Program> entry : participantFiles.entrySet()) { final IFile file = entry.getKey(); final Program program = entry.getValue(); final RenameGlobalConstant rename = new RenameGlobalConstant( file, scalarName, newElementName, getUpdateTextualMatches()); // aggregate the changes identifiers program.accept(rename); if (pm.isCanceled()) throw new OperationCanceledException(); pm.worked(1); if (rename.hasChanges()) { // create the change TextFileChange change = acquireChange(file, program); rename.updateChange(change); rootChange.add(change); } } return rootChange; } finally { pm.done(); } } public Object[] getElements() { return new Object[] { scalar }; } public String getIdentifier() { return ID_RENAME_CONSTANT; } public String getProcessorName() { return RENAME_CONSTANT_PROCESSOR_NAME; } public Object getNewElement() { return getNewElementName(); } public String getCurrentElementName() { return scalarName; } public boolean canEnableTextUpdating() { return true; } public String getCurrentElementQualifier() { return scalarName; } public boolean getUpdateTextualMatches() { return isUpdateTextualMatches; } public void setUpdateTextualMatches(boolean update) { isUpdateTextualMatches = update; } public RefactoringStatus getRefactoringStatus(IFile key, Program program) { if (PHPElementConciliator.constantAlreadyExists(program, getNewElementName())) { final String message = MessageFormat.format( RenameGlobalConstantProcessor.CONSTANT_IS_USED, new Object[] { key.getName() }); return RefactoringStatus.createWarningStatus(message); } return null; } }