1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.xml.spring.boot.http.codec;
18
19 import java.util.AbstractCollection;
20 import java.util.HashSet;
21 import java.util.Objects;
22 import java.util.Set;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.bremersee.xml.JaxbContextBuilder;
26 import org.bremersee.xml.http.codec.ReactiveJaxbDecoder;
27 import org.bremersee.xml.http.codec.ReactiveJaxbEncoder;
28 import org.bremersee.xml.spring.boot.JaxbContextBuilderAutoConfiguration;
29 import org.bremersee.xml.spring.boot.http.JaxbReadWriteConfigurer;
30 import org.jspecify.annotations.NonNull;
31 import org.springframework.beans.factory.ObjectProvider;
32 import org.springframework.boot.autoconfigure.AutoConfiguration;
33 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
34 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
35 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
36 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
37 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
38 import org.springframework.boot.context.event.ApplicationReadyEvent;
39 import org.springframework.context.event.EventListener;
40 import org.springframework.http.codec.ServerCodecConfigurer;
41 import org.springframework.util.ClassUtils;
42 import org.springframework.web.reactive.config.WebFluxConfigurer;
43
44
45
46
47
48
49 @ConditionalOnWebApplication(type = Type.REACTIVE)
50 @ConditionalOnClass({WebFluxConfigurer.class, JaxbContextBuilder.class})
51 @ConditionalOnBean(JaxbContextBuilder.class)
52 @AutoConfigureAfter(JaxbContextBuilderAutoConfiguration.class)
53 @AutoConfiguration
54 public class Jaxb2HttpMessageCodecAutoConfiguration implements WebFluxConfigurer {
55
56 private static final Log log = LogFactory.getLog(Jaxb2HttpMessageCodecAutoConfiguration.class);
57
58 private final JaxbContextBuilder jaxbContextBuilder;
59
60 private final Set<Class<?>> ignoreReadingClasses;
61
62 private final Set<Class<?>> ignoreWritingClasses;
63
64
65
66
67
68
69
70 public Jaxb2HttpMessageCodecAutoConfiguration(
71 ObjectProvider<JaxbContextBuilder> jaxbContextBuilder,
72 ObjectProvider<JaxbReadWriteConfigurer> readWriteConfigurers) {
73 this.jaxbContextBuilder = jaxbContextBuilder.getIfAvailable();
74 this.ignoreReadingClasses = readWriteConfigurers
75 .stream()
76 .collect(
77 HashSet::new,
78 (a, b) -> a.addAll(b.getIgnoreReadingClasses()),
79 AbstractCollection::addAll);
80 this.ignoreWritingClasses = readWriteConfigurers
81 .stream()
82 .collect(
83 HashSet::new,
84 (a, b) -> a.addAll(b.getIgnoreWritingClasses()),
85 AbstractCollection::addAll);
86 }
87
88
89
90
91 @EventListener(ApplicationReadyEvent.class)
92 public void init() {
93 log.info(String.format("""
94
95 *********************************************************************************
96 * %s
97 *********************************************************************************
98 * jaxbContextBuilder = %s
99 * ignoreReadingClasses = %s
100 * ignoreWritingClasses = %s
101 *********************************************************************************""",
102 ClassUtils.getUserClass(getClass()).getSimpleName(),
103 jaxbContextBuilder, ignoreReadingClasses, ignoreWritingClasses));
104 }
105
106 @Override
107 public void configureHttpMessageCodecs(@NonNull ServerCodecConfigurer configurer) {
108 if (Objects.nonNull(jaxbContextBuilder)) {
109 log.info("Registering jaxb encoder and decoder.");
110 configurer
111 .customCodecs()
112 .registerWithDefaultConfig(new ReactiveJaxbEncoder(
113 jaxbContextBuilder, ignoreWritingClasses));
114 configurer
115 .customCodecs()
116 .registerWithDefaultConfig(new ReactiveJaxbDecoder(
117 jaxbContextBuilder, ignoreReadingClasses));
118 }
119 }
120
121 }