1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.config.registry;
35
36 import static info.magnolia.cms.util.ExceptionUtil.exceptionToWords;
37 import static info.magnolia.config.registry.DefinitionProvider.Problem.SeverityType.SEVERE;
38 import static java.util.stream.Collectors.toList;
39
40 import info.magnolia.config.registry.DefinitionProvider.Problem;
41 import info.magnolia.config.registry.decoration.DefinitionDecorator;
42 import info.magnolia.transformer.TransformationResult;
43
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.List;
48
49 import com.google.common.collect.ImmutableList;
50
51
52
53
54
55
56
57
58
59 public class DefinitionProviderBuilder<T> {
60 public static <T> DefinitionProviderBuilder<T> newBuilder() {
61 return new DefinitionProviderBuilder<>();
62 }
63
64 private DefinitionMetadata metadata;
65 private DefinitionRawView rawView;
66 private T definition;
67 private List<Problem> problems = new ArrayList<>();
68 private List<DefinitionDecorator<T>> decorators = Collections.emptyList();
69 private List<String> errorMessages = new ArrayList<>();
70 private long lastModified = -1;
71
72 private DefinitionProviderBuilder() {
73 }
74
75 public DefinitionProviderBuilder<T> metadata(DefinitionMetadata metadata) {
76 this.metadata = metadata;
77 return this;
78 }
79
80 public DefinitionProviderBuilder<T> metadata(DefinitionMetadataBuilder metadata) {
81 this.metadata = metadata.build();
82 return this;
83 }
84
85 public DefinitionProviderBuilder<T> rawView(DefinitionRawView rawView) {
86 this.rawView = rawView;
87 return this;
88 }
89
90 public DefinitionProviderBuilder<T> definition(T definition) {
91 this.definition = definition;
92 return this;
93 }
94
95 public DefinitionProviderBuilder<T> addProblem(Problem problem) {
96 this.problems.add(problem);
97 return this;
98 }
99
100 public DefinitionProviderBuilder<T> decorators(List<DefinitionDecorator<T>> decorators) {
101 this.decorators = decorators;
102 return this;
103 }
104
105
106
107
108 @Deprecated
109 public DefinitionProviderBuilder<T> addErrorMessage(String errorMessage) {
110 this.errorMessages.add(errorMessage);
111 return this;
112 }
113
114 public DefinitionProviderBuilder<T> withLastModifed(long lastModified) {
115 this.lastModified = lastModified;
116 return this;
117 }
118
119 public DefinitionProvider<T> buildFromTransformationResult(TransformationResult<T> transformationResult) {
120 try {
121 transformationResult.getProblems().forEach(transformationProblem -> addProblem(
122 Problem
123 .fromTransformationProblem(transformationProblem)
124 .withType(Problem.DefaultTypes.RESOLUTION)
125 .withTitle("Source data processing problem")
126 .withDetails(transformationProblem.getMessage())
127 .build()));
128
129 definition(transformationResult.get());
130 } catch (Exception e) {
131 final String errorMessage = exceptionToWords(e);
132 addProblem(
133 Problem
134 .severe()
135 .withDetails(errorMessage)
136 .withType(Problem.DefaultTypes.RESOLUTION)
137 .withTitle("Source data processing failed with un-expected exception")
138 .build());
139 }
140
141 return build();
142 }
143
144 public DefinitionProvider<T> build() {
145 return new DefinitionProviderImpl<>(
146 this.metadata,
147 this.rawView,
148 this.definition,
149 ImmutableList.<String>builder()
150 .addAll(this.errorMessages)
151 .addAll(this.problems.stream()
152 .map(problem -> problem.getTitle() + problem.getDetails())
153 .collect(toList()))
154 .build(),
155 this.problems,
156 this.lastModified > 0 ? lastModified : System.currentTimeMillis(),
157 decorators
158 );
159 }
160
161
162
163
164 static class DefinitionProviderImpl<T> implements DefinitionProvider<T> {
165 private final List<Problem> problems;
166 private final DefinitionMetadata metadata;
167 private final DefinitionRawView rawView;
168 private final T definition;
169 private final List<String> errorMessages;
170 private final boolean valid;
171 private final long lastModified;
172 private final List<DefinitionDecorator<T>> decorators;
173
174 protected DefinitionProviderImpl(DefinitionMetadata metadata, DefinitionRawView rawView, T definition, List<String> errorMessages) {
175 this(metadata, rawView, definition, errorMessages, Collections.emptyList(), System.currentTimeMillis(), Collections.emptyList());
176 }
177
178 protected DefinitionProviderImpl(DefinitionMetadata metadata, DefinitionRawView rawView, T definition, List<String> errorMessages, List<Problem> problems, long lastModified, List<DefinitionDecorator<T>> decorators) {
179 this.metadata = metadata;
180 this.rawView = rawView;
181 this.definition = definition;
182 this.errorMessages = errorMessages;
183 this.problems = problems;
184 this.lastModified = lastModified;
185 this.decorators = decorators;
186 this.valid = metadata != null &&
187 rawView != null &&
188 definition != null &&
189 !this.problems.stream()
190 .filter(p -> p.getSeverityType() == SEVERE)
191 .findFirst()
192 .isPresent();
193 }
194
195 @Override
196 public Collection<Problem> getProblems() {
197 return problems;
198 }
199
200 @Override
201 public List<DefinitionDecorator<T>> getDecorators() {
202 return decorators;
203 }
204
205 @Override
206 public DefinitionMetadata getMetadata() {
207 return metadata;
208 }
209
210 @Override
211 public DefinitionRawView getRaw() {
212 return rawView;
213 }
214
215 @Override
216 public T get() {
217 if (!valid) {
218 throw new Registry.InvalidDefinitionException(metadata.getReferenceId());
219 }
220 return definition;
221 }
222
223 @Override
224 public boolean isValid() {
225 return valid;
226 }
227
228 @Override
229 public List<String> getErrorMessages() {
230 return errorMessages;
231 }
232
233 @Override
234 public long getLastModified() {
235 return lastModified;
236 }
237 }
238 }