public Map findWriters()

in johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java [726:831]


    public Map<String, Writer> findWriters(final Class<?> clazz) {
        final Map<String, Writer> writers = delegate.findWriters(clazz);

        final Comparator<String> keyComparator = fieldComparator(clazz);
        final Map<String, Writer> result = keyComparator == null ? new HashMap<>() : new TreeMap<>(keyComparator);
        for (final Map.Entry<String, Writer> entry : writers.entrySet()) {
            Writer initialWriter = entry.getValue();
            if (isTransient(initialWriter, visibility, clazz, false)) {
                validateAnnotationsOnTransientField(initialWriter);
                continue;
            }

            final Writer finalWriter;
            if (FieldAndMethodAccessMode.CompositeDecoratedType.class.isInstance(initialWriter)) { // unwrap to use the right reader
                final FieldAndMethodAccessMode.CompositeDecoratedType decoratedType = FieldAndMethodAccessMode.CompositeDecoratedType.class.cast(initialWriter);
                final DecoratedType type2 = decoratedType.getType2();
                if (MethodAccessMode.MethodWriter.class.isInstance(type2)) {
                    finalWriter = Writer.class.cast(type2);
                } else {
                    finalWriter = initialWriter;
                }
            } else {
                finalWriter = initialWriter;
            }

            // handle optionals since mapper is still only java 7
            final Type type;
            final BiConsumer<Object, Object> writer;
            final Type writerType = initialWriter.getType();
            if (isOptional(writerType)) {
                type = findOptionalType(writerType);
                writer = (i, val) -> finalWriter.write(i, Optional.ofNullable(val));
            } else if (OptionalInt.class == writerType) {
                type = Integer.class;
                writer = (i, value) -> finalWriter.write(i, value == null ?
                        OptionalInt.empty() : OptionalInt.of(Number.class.cast(value).intValue()));
            } else if (OptionalLong.class == writerType) {
                type = Long.class;
                writer = (i, value) -> finalWriter.write(i, value == null ?
                        OptionalLong.empty() : OptionalLong.of(Number.class.cast(value).longValue()));
            } else if (OptionalDouble.class == writerType) {
                type = Double.class;
                writer = (i, value) -> finalWriter.write(i, value == null ?
                        OptionalDouble.empty() : OptionalDouble.of(Number.class.cast(value).doubleValue()));
            } else if (isOptionalArray(initialWriter)) {
                final Type optionalUnwrappedType = findOptionalType(GenericArrayType.class.cast(writerType).getGenericComponentType());
                type = new GenericArrayTypeImpl(optionalUnwrappedType);
                writer = (i, value) -> {
                    if (value != null) {
                        finalWriter.write(i, Stream.of(Object[].class.cast(value))
                                .map(Optional::ofNullable)
                                .toArray(Optional[]::new));
                    }
                };
            } else {
                type = writerType;
                writer = finalWriter::write;
            }

            final ReaderConverters converters = new ReaderConverters(initialWriter);
            final JsonbProperty property = initialWriter.getAnnotation(JsonbProperty.class);
            final JsonbNillable propertyNillable = initialWriter.getAnnotation(JsonbNillable.class);
            final JsonbNillable classOrPackageNillable = initialWriter.getClassOrPackageAnnotation(JsonbNillable.class);
            final boolean isNillable = isNillable(property, propertyNillable, classOrPackageNillable);
            final String key = property == null || property.value().isEmpty() ? naming.translateName(entry.getKey()) : property.value();
            if (result.put(key, new Writer() {
                @Override
                public void write(final Object instance, final Object val) {
                    writer.accept(instance, val);
                }

                @Override
                public ObjectConverter.Reader<?> findObjectConverterReader() {
                    return converters.reader;
                }

                @Override
                public Type getType() {
                    return type;
                }

                @Override
                public <T extends Annotation> T getAnnotation(final Class<T> clazz) {
                    return initialWriter.getAnnotation(clazz);
                }

                @Override
                public <T extends Annotation> T getClassOrPackageAnnotation(final Class<T> clazz) {
                    return initialWriter.getClassOrPackageAnnotation(clazz);
                }

                @Override
                public Adapter<?, ?> findConverter() {
                    return converters.converter;
                }

                @Override
                public boolean isNillable(final boolean global) {
                    return isNillable;
                }
            }) != null) {
                throw new JsonbException("Ambiguous field " + key);
            }
        }
        return result;
    }