Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.
This repository was archived by the owner on May 28, 2018. It is now read-only.

SingleValueExtractor makes it impossible to support java.util.Optional (or Guava Optional) #2884

@glassfishrobot

Description

@glassfishrobot

SingleValueExtractor makes it impossible to support java.util.Optional (or Guava Optional) through custom ParamConverter as it checks for null before forwarding the value to the ParamConverter (thus not delegating the null value handling to the custom ParamConverter).

Hence it is impossible to write a resource method like

**HelloResource.java**@GET
@Produces("text/plain")
public String hello(@QueryParam("name") final Optional<String> name) {
     return "Hello " + name.orElse("World") + "!";
}

While given a custom ParamConverterProvider like this one for example:

**OptionalParamConverterProvider.java**@Singleton
public class OptionalParamConverterProvider implements ParamConverterProvider {

    private final ServiceLocator locator;

    @Inject
    public OptionalParamConverterProvider(final ServiceLocator locator) {
        this.locator = locator;
    }

    @Override
    public <T> ParamConverter<T> getConverter(final Class<T> rawType, final Type genericType, final Annotation[] annotations) {

        final List<ClassTypePair> ctps = ReflectionHelper.getTypeArgumentAndClass(genericType);
        ClassTypePair ctp = (ctps.size() == 1) ? ctps.get(0) : null;
        if (ctp == null || ctp.rawClass() == String.class) {
            return new ParamConverter<T>() {
@Override
public T fromString(final String value) {
    return rawType.cast(Optional.ofNullable(value));
}

@Override
public String toString(final T value) throws IllegalArgumentException {
    return value.toString();
}
            };
        }

        final Set<ParamConverterProvider> converterProviders = Providers.getProviders(locator, ParamConverterProvider.class);
        for (ParamConverterProvider provider : converterProviders) {
            @SuppressWarnings("unchecked")
            ParamConverter<?> converter = provider.getConverter(ctp.rawClass(), ctp.type(), annotations);
            if (converter != null) {
return new ParamConverter<T>() {
    @Override
    public T fromString(final String value) {
        return rawType.cast(Optional.ofNullable(converter.fromString(value)));
    }

    @Override
    public String toString(final T value) throws IllegalArgumentException {
        return value.toString();
    }
};
            }
        }

        return null;
    }
}

Environment

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
OSX 10.9.4

Affected Versions

[2.11]

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions