Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top