1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.xml;
18
19 import java.util.Collections;
20 import java.util.LinkedHashSet;
21 import java.util.Optional;
22 import java.util.Set;
23 import java.util.stream.Collector;
24 import java.util.stream.Collectors;
25 import lombok.AccessLevel;
26 import lombok.NoArgsConstructor;
27 import org.springframework.util.ClassUtils;
28 import org.springframework.util.StringUtils;
29
30
31
32
33
34
35 public interface JaxbContextDetails {
36
37
38
39
40
41
42 static Collector<JaxbContextData, ?, JaxbContextDetailsImpl> contextDataCollector() {
43 return Collector.of(JaxbContextDetailsImpl::new, JaxbContextDetailsImpl::add, (left, right) -> {
44 if (left.size() < right.size()) {
45 right.addAll(left);
46 return right;
47 } else {
48 left.addAll(right);
49 return left;
50 }
51 });
52 }
53
54
55
56
57
58
59 static JaxbContextDetails empty() {
60 return new JaxbContextDetailsImpl();
61 }
62
63
64
65
66
67
68 boolean isEmpty();
69
70
71
72
73
74
75
76 Class<?>[] getClasses(ClassLoader... classLoaders);
77
78
79
80
81
82
83 String getSchemaLocation();
84
85
86
87
88
89
90 default Set<String> getNameSpacesWithSchemaLocations() {
91 return Optional.of(schemaLocationToArray(getSchemaLocation()))
92 .map(parts -> {
93 Set<String> locations = new LinkedHashSet<>();
94 for (int i = 1; i < parts.length; i = i + 2) {
95 locations.add(parts[i - 1] + " " + parts[i]);
96 }
97 return locations;
98 })
99 .orElseGet(Collections::emptySet);
100 }
101
102
103
104
105
106
107 default Set<String> getNameSpaces() {
108 return Optional.of(schemaLocationToArray(getSchemaLocation()))
109 .map(parts -> {
110 Set<String> nameSpaces = new LinkedHashSet<>();
111 for (int i = 0; i < parts.length; i = i + 2) {
112 nameSpaces.add(parts[i]);
113 }
114 return nameSpaces;
115 })
116 .orElseGet(Collections::emptySet);
117 }
118
119
120
121
122
123
124
125
126
127 default Set<String> getSchemaLocations() {
128 return Optional.of(schemaLocationToArray(getSchemaLocation()))
129 .map(parts -> {
130 Set<String> locations = new LinkedHashSet<>();
131 for (int i = 1; i < parts.length; i = i + 2) {
132 locations.add(parts[i]);
133 }
134 return locations;
135 })
136 .orElse(Collections.emptySet());
137 }
138
139 private static String[] schemaLocationToArray(String schemaLocation) {
140 return Optional.ofNullable(schemaLocation)
141 .map(sl -> sl.replaceAll("^\\s*|\\s*$", ""))
142 .map(sl -> sl.replaceAll("[\\s]{2,}", " "))
143 .map(sl -> StringUtils.delimitedListToStringArray(sl, " "))
144 .orElseGet(() -> new String[0]);
145 }
146
147
148
149
150 @SuppressWarnings("SameNameButDifferent")
151 @NoArgsConstructor(access = AccessLevel.PRIVATE)
152 class JaxbContextDetailsImpl
153 extends LinkedHashSet<JaxbContextData>
154 implements JaxbContextDetails {
155
156 @Override
157 public String getSchemaLocation() {
158 return this.stream()
159 .flatMap(JaxbContextData::getNameSpacesWithSchemaLocations)
160 .distinct()
161 .sorted()
162 .map(SchemaLocation::toString)
163 .collect(Collectors.joining(" "));
164 }
165
166 @Override
167 public Class<?>[] getClasses(ClassLoader... classLoaders) {
168 return ClassUtils
169 .toClassArray(this
170 .stream()
171 .flatMap(data -> data.getJaxbClasses(classLoaders))
172 .collect(Collectors.toSet()));
173 }
174
175 }
176
177 }