PropertyEditorManager - How Do I Register An Alternate Editor For Enums?

173 Views Asked by At

To be clear, this is specifically a Java 8 question.

I have a class which I use to bind between Map<String, String>, value selection functions, etc, to a model and I use the following code to find the required editor for the given PropertyDescriptor's type.

final PropertyEditor editor = PropertyEditorManager.findEditor(descriptor.getPropertyType());

In the class in question, I have a static block of code that registers additional property editors for other types, like so:

static {
    PropertyEditorManager.registerEditor(Timestamp.class, TimestampEditor.class);
    PropertyEditorManager.registerEditor(Date.class, DateEditor.class);
    PropertyEditorManager.registerEditor(LocalDate.class, LocalDateEditor.class);
    PropertyEditorManager.registerEditor(LocalTime.class, LocalTimeEditor.class);
    PropertyEditorManager.registerEditor(LocalDateTime.class, LocalDateTimeEditor.class);
    PropertyEditorManager.registerEditor(BigInteger.class, BigIntegerEditor.class);
    PropertyEditorManager.registerEditor(BigDecimal.class, BigDecimalEditor.class);
    PropertyEditorManager.registerEditor(File.class, FileEditor.class);
    PropertyEditorManager.registerEditor(Path.class, PathEditor.class);
    PropertyEditorManager.registerEditor(URL.class, UrlEditor.class);
    PropertyEditorManager.registerEditor(Class.class, ClassEditor.class);
}

This works great for me, as I can bind to the above types, based on a String value with ease.

I'm looking to implement an enum editor that not only takes the enum constant text values, but also the index as a String and still bind.

Unfortunately, the EnumEditor that Java itself provides only allows for the enum constant text values and doesn't allow for an index, nor does it allow subclassing, so I have tried this class:

package com.csa.model.bean.editor;

import com.csa.math.NumberUtil;
import com.sun.beans.editors.EnumEditor;

import java.awt.Component;
import java.beans.PropertyEditorSupport;

public class IndexedEnumEditor extends PropertyEditorSupport {
    private final EnumEditor enumEditor;

    public IndexedEnumEditor(final Class<? extends Enum<?>> clazz) {
        super();
        this.enumEditor = new EnumEditor(clazz);
    }

    @Override
    public Object getValue() {
        return this.enumEditor.getValue();
    }

    @Override
    public String getAsText() {
        return this.enumEditor.getAsText();
    }

    @Override
    public String getJavaInitializationString() {
        return this.enumEditor.getJavaInitializationString();
    }

    @Override
    public String[] getTags() {
        return this.enumEditor.getTags();
    }

    @Override
    public Component getCustomEditor() {
        return this.enumEditor.getCustomEditor();
    }

    @Override
    public void setAsText(final String text) throws IllegalArgumentException {
        final String textToUse;
        if (NumberUtil.isInteger(text)) {
            final int index = NumberUtil.getInt(text, -1);
            final String[] tags = this.getTags();
            NumberUtil.requireBetween(index, 0, tags.length - 1);
            textToUse = tags[index];
        } else {
            textToUse = text;
        }

        this.enumEditor.setAsText(textToUse);
    }

    @Override
    public void setValue(final Object value) {
        this.enumEditor.setValue(value);
    }
}

In my static block of code, I tried adding this new property editor by doing this:

PropertyEditorManager.registerEditor(Enum.class, IndexedEnumEditor.class);

However, this does not override the existing EnumEditor with my new one. When the call to findEditor is made, I still get the Java EnumEditor implementation rather than my own.

Anyone know how I can override the Java implementation successfully?

I can't register the enum classes directly BTW, as this code lies in a core library and I would much rather that the editor is registered without knowing about all the Enum classes that it needs to deal with, in a "hard-coded" sense. I would prefer to do it similar to the way I'm trying to do it, if that's at all possible.

Any ideas anyone? If you need any further clarification or code, let me know and I will provide it accordingly. The key problem for me here though is that trying to register my custom property editor isn't working. Adding editors for classes not already handled works, but not this one that is already registered.

0

There are 0 best solutions below