blob: 2b0e71a739a18dc223e960011ec75612a1091aeb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.internal.corext.refactoring;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptModel;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.ScriptModelUtil;
import org.eclipse.dltk.internal.corext.refactoring.reorg.ReorgPolicyFactory;
import org.eclipse.dltk.internal.corext.refactoring.reorg.ReorgUtils;
import org.eclipse.dltk.internal.ui.editor.ModelTextSelection;
import org.eclipse.jface.viewers.IStructuredSelection;
/**
* Helper class to detect whether a certain refactoring can be enabled on a
* selection.
* <p>
* This class has been introduced to decouple actions from the refactoring code,
* in order not to eagerly load refactoring classes during action
* initialization.
* </p>
*
*
*/
public final class RefactoringAvailabilityTester {
public static IType getDeclaringType(IModelElement element) {
if (element == null)
return null;
if (!(element instanceof IType))
element = element.getAncestor(IModelElement.TYPE);
return (IType) element;
}
public static IModelElement[] getScriptElements(final Object[] elements) {
List<IModelElement> result = new ArrayList<>();
for (int index = 0; index < elements.length; index++) {
if (elements[index] instanceof IModelElement)
result.add((IModelElement) elements[index]);
}
return result.toArray(new IModelElement[result.size()]);
}
public static IResource[] getResources(final Object[] elements) {
List<IResource> result = new ArrayList<>();
for (int index = 0; index < elements.length; index++) {
if (elements[index] instanceof IResource)
result.add((IResource) elements[index]);
}
return result.toArray(new IResource[result.size()]);
}
public static boolean isRenameElementAvailable(IModelElement element)
throws CoreException {
switch (element.getElementType()) {
case IModelElement.SCRIPT_PROJECT:
return isRenameAvailable((IScriptProject) element);
case IModelElement.PROJECT_FRAGMENT:
return isRenameAvailable((IProjectFragment) element);
case IModelElement.SOURCE_MODULE:
return isRenameAvailable((ISourceModule) element);
case IModelElement.TYPE:
return isRenameAvailable((IType) element);
case IModelElement.METHOD:
final IMethod method = (IMethod) element;
if (method.isConstructor()) {
return isRenameAvailable(method.getDeclaringType());
}
return isRenameAvailable(method);
case IModelElement.FIELD:
final IField field = (IField) element;
return isRenameFieldAvailable(field);
}
return false;
}
public static boolean isRenameAvailable(final ISourceModule unit) {
if (unit == null)
return false;
if (!unit.exists())
return false;
if (!ScriptModelUtil.isPrimary(unit))
return false;
if (unit.isReadOnly())
return false;
return true;
}
public static boolean isRenameAvailable(final IScriptProject project)
throws ModelException {
if (project == null)
return false;
if (!Checks.isAvailable(project))
return false;
if (!project.isConsistent())
return false;
return true;
}
public static boolean isRenameAvailable(final IMethod method)
throws CoreException {
if (method == null)
return false;
if (!Checks.isAvailable(method))
return false;
if (method.isConstructor())
return false;
return true;
}
public static boolean isRenameAvailable(final IScriptFolder fragment)
throws ModelException {
if (fragment == null)
return false;
if (!Checks.isAvailable(fragment))
return false;
if (fragment.isRootFolder())
return false;
return true;
}
public static boolean isRenameAvailable(final IProjectFragment root)
throws ModelException {
if (root == null)
return false;
if (!Checks.isAvailable(root))
return false;
if (root.isArchive())
return false;
if (root.isExternal())
return false;
if (!root.isConsistent())
return false;
if (root.getResource() instanceof IProject)
return false;
return true;
}
public static boolean isRenameAvailable(final IResource resource) {
if (resource == null)
return false;
if (!resource.exists())
return false;
if (!resource.isAccessible())
return false;
return true;
}
public static boolean isRenameAvailable(final IType type)
throws ModelException {
if (type == null)
return false;
if (!Checks.isAvailable(type))
return false;
return true;
}
public static boolean isRenameFieldAvailable(final IField field)
throws ModelException {
return Checks.isAvailable(field);
}
public static boolean isReplaceInvocationsAvailable(IMethod method)
throws ModelException {
if (method == null)
return false;
if (!method.exists())
return false;
if (method.isConstructor())
return false;
return true;
}
public static boolean isDeleteAvailable(final IModelElement element)
throws ModelException {
if (!element.exists())
return false;
if (element instanceof IScriptModel
|| element instanceof IScriptProject)
return false;
if (element.getParent() != null && element.getParent().isReadOnly())
return false;
if (element instanceof IProjectFragment) {
IProjectFragment root = (IProjectFragment) element;
if (root.isExternal() || Checks.isBuildpathDelete(root)) // TODO
// rename
// isClasspathDelete
return false;
}
if (element.getResource() == null
&& !RefactoringAvailabilityTester.isWorkingCopyElement(element))
return false;
// if (element instanceof IMember && ((IMember) element).isBinary())
// return false;
if (ReorgUtils.isDeletedFromEditor(element))
return false;
return true;
}
public static boolean isDeleteAvailable(final IResource resource) {
if (!resource.exists() || resource.isPhantom())
return false;
if (resource.getType() == IResource.ROOT
|| resource.getType() == IResource.PROJECT)
return false;
return true;
}
public static boolean isDeleteAvailable(
final IStructuredSelection selection) throws ModelException {
if (!selection.isEmpty())
return isDeleteAvailable(selection.toArray());
return false;
}
public static boolean isDeleteAvailable(final Object[] objects)
throws ModelException {
if (objects.length != 0) {
final IResource[] resources = RefactoringAvailabilityTester
.getResources(objects);
final IModelElement[] elements = RefactoringAvailabilityTester
.getScriptElements(objects);
if (objects.length != resources.length + elements.length)
return false;
for (int index = 0; index < resources.length; index++) {
if (!isDeleteAvailable(resources[index]))
return false;
}
for (int index = 0; index < elements.length; index++) {
if (!isDeleteAvailable(elements[index]))
return false;
}
return true;
}
return false;
}
public static boolean isWorkingCopyElement(final IModelElement element) {
if (element instanceof ISourceModule)
return ((ISourceModule) element).isWorkingCopy();
if (ReorgUtils.isInsideSourceModule(element))
return ReorgUtils.getSourceModule(element).isWorkingCopy();
return false;
}
private RefactoringAvailabilityTester() {
// Not for instantiation
}
public static boolean isMoveAvailable(final IResource[] resources,
final IModelElement[] elements) throws ModelException {
if (elements != null) {
for (int index = 0; index < elements.length; index++) {
IModelElement element = elements[index];
if ((element instanceof IType)) {
return false;
}
// if ((element instanceof IPackageDeclaration))
// return false;
if (element instanceof IField) {// && DLTKFlags.isEnum((IMember)
// element))
return false;
}
}
}
return ReorgPolicyFactory.createMovePolicy(resources, elements)
.canEnable();
}
public static boolean isMoveAvailable(final ModelTextSelection selection)
throws ModelException {
final IModelElement element = selection.resolveEnclosingElement();
if (element == null)
return false;
return isMoveAvailable(new IResource[0],
new IModelElement[] { element });
}
}