Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent Eclipse from supplying deprecated classes when importing?

I have a recurring problem using Eclipse. Consider the following example:

Organize imports with deprecated class

As you can see I've pressed Ctrl+Shift+O. I can choose from a deprecated and a non-deprecated annotation. My problem is that I am often supplied with dozens of classes and half of them are deprecated (a perfect example is the JUnit Assert classes).

My question is how can I make Eclipse ignore all deprecated classes when organizing imports?

like image 289
Adam Arold Avatar asked Apr 08 '14 12:04

Adam Arold


People also ask

Why import option is not working in Eclipse?

Try this: Go to Preferences » Java » Editor » Content Assist » Advanced. Make sure Other Java Proposals is ticked/checked. If that does not work simply close the project and reopen it.

How do I fix all imports in eclipse?

Press: CTRL + SHIFT + O and you should see below dialog boxes. Choose your desired import package and click next. It will prompt you for your next import and thats it. You are done.


1 Answers

Currently Eclipse does not provide such an option... Eclipse Documentation for Organise Imports (Kepler version).

However, with a fudge you can achieve the same result...

Eclipse allows you to provide a list of classes/packages to filter-out. To do this, navigate to Preferences > Type Filters.

Preferences for Type Filters

I've done this in my environment to ensure "java.awt.List" is not suggested when I really want "java.util.List".

What you want is to add all deprecated classes to this list.

This list is maintained in your eclipse workspace preferences...

File ... C:\Users\[YOUR_USER_NAME]\workspace\.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.ui.prefs
Property ... org.eclipse.jdt.ui.typefilter.enabled=java.awt.List;

All that is required is that you create a list of deprecated classes, and store it in this properties file.

Eclispe can help create this list... Perform a "Java Search" for "Deprecated". Search for Deprecated classes

Then group the results by type. enter image description here

And copy the results using "Copy Qualified Name"

The results will contain Generics, and this should be removed. For example, "javafx.scene.control.Cell<T>" should read "javafx.scene.control.Cell".

In addition to containing deprecated classes, the results will also contain any class that has the word "Deprecated". This could be a comment or a method annotation. This list will need to be filtered to retain only deprecated classes.

The script below processes this class list to remove generics, and filtering out classes that are not deprecated (ie, only has method deprecation). The class list is read from a file named "DeprecatedClassList.txt". When it cannot check the class annotation, it skips the class and prints it out (for manual checking).

import java.lang.annotation.Annotation;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ConfigurationGenerator {

    public static void main(String[] args) throws Exception {

        List<String> cleanedList = Files
                .readAllLines(Paths.get("DeprecatedClassList.txt")).stream()
                .map(ConfigurationGenerator::removeGenerics)
                .filter(ConfigurationGenerator::hasDeprecatedConstructor)
                .collect(Collectors.toList());

        String propertyName = "org.eclipse.jdt.ui.typefilter.enabled=";
        String propertyValue = String.join(";", cleanedList).concat(";");

        String configuration = propertyName + propertyValue;
        System.out.println("Configuration property...");
        System.out.println(configuration);
    }

    public static String removeGenerics(String className) {
        int openingBracket = className.indexOf("<");
        if (openingBracket == -1)
            return className;
        else
            return className.substring(0, openingBracket);
    }

    public static boolean hasDeprecatedConstructor(String className) {

        Class theClass = null;
        try {
            theClass = Class.forName(className);
        } catch (Throwable e) {
            // Ignore bad results
            System.out.println("Skipping: " + className);
            return false;
        }

        Annotation[] annotations = theClass.getAnnotations();
        Optional<Annotation> deprecatedConstructor = Stream
                .of(annotations)
                .filter(annotation -> annotation.toString().equals(
                        "@java.lang.Deprecated()")).findAny();

        return deprecatedConstructor.isPresent();
    }
}

There is one problem with this approach though. You may want to use a deprecated class when a non-deprecated version does not exist. You will not see the deprecated class if it has been purposefully hidden. To resolve that, just be sure you exclude them from the filter.

like image 183
gahrae Avatar answered Oct 14 '22 06:10

gahrae