Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Annotation - array of Objects or toString values

I need to write an Annotation to exclude certain values from a result set.

Background:

Distinct values are selected from fields and are listed in a ComboBox. Some of the legacy values are Deprecated and I don't want to show them, even if they are returned by JDBC's SELECT DISTINCT(). It's like a mini-framework where people can build select queries by clicking values from ComboBoxes.

I tried the following (the code does not compile - commented lines are the ways I tried to solve the problem):

public enum JobType {
    //...
    S,
    //...
}

public @interface Exclude {
    Object[] values(); // Invalid type
    Enum[] values(); // Invalid type again
    String[] values(); // Accepts but see the following lines
}

@Table(name = "jobs_view")
public class JobSelectionView extends View {
    //...
    @Exclude(values = {JobType.S.toString()}) // Not a constant expression
    @Exclude(values = {JobType.S.name()}) // Not a constant expression ?!?!?!
    @Exclude(values = {"S"}) // Works but... come on!
    @Enumerated(value = EnumType.STRING)
    @Column(name = "type")
    private JobType type;
    //...
}

I don't like using {"S"}, any suggestions?

like image 803
Adam Horvath Avatar asked Jul 06 '15 11:07

Adam Horvath


Video Answer


1 Answers

But if declare JobType[] values() then I won't be able to reuse the @Exclude for other types of Enum.

This is the best way to do what you want, though. Here's the thing:

The class Enum is, itself, meaningless.

It only gains meaning when subclassed. Let's say you want to add another filter, say Color (your own custom Color enum, not java.awt.Color). Obviously, the thing thing that your filtration class is doing is very different for filtering out JobType than it would be for filtering out Color!

Therefore, the best thing to do would be to have each different time of enum you're trying to filter in it's own argument, e.g.

public @interface Exclude {
    JobType[] jobs;
    Color[] colors;
    Foo[] foos;
    Quux[] quuxes;
}

This will accomplish two things:

  1. Make it easy for you to do different filtration behavior for each different filter type.
  2. Make the @Excludes annotation more legibile by sorting the different parameters into different groups.

The Javadoc for Enum.name() says:

Returns the name of this enum constant, exactly as declared in its enum declaration. Most programmers should use the toString() method in preference to this one, as the toString method may return a more user-friendly name. This method is designed primarily for use in specialized situations where correctness depends on getting the exact name, which will not vary from release to release.

I suggest you try to tell the people in your company to read up on the Open/Closed principle and explain why violating it would be particularly damaging in this case.

like image 125
durron597 Avatar answered Oct 11 '22 22:10

durron597