1
16 package org.modelmapper.internal;
17
18 import java.util.List;
19
20 import org.modelmapper.Condition;
21 import org.modelmapper.Provider;
22 import org.modelmapper.config.Configuration;
23 import org.modelmapper.convention.MatchingStrategies;
24 import org.modelmapper.convention.NameTokenizers;
25 import org.modelmapper.convention.NameTransformers;
26 import org.modelmapper.convention.NamingConventions;
27 import org.modelmapper.internal.converter.AssignableConverter;
28 import org.modelmapper.internal.converter.ConverterStore;
29 import org.modelmapper.internal.converter.MergingCollectionConverter;
30 import org.modelmapper.internal.converter.NonMergingCollectionConverter;
31 import org.modelmapper.internal.util.Assert;
32 import org.modelmapper.internal.valueaccess.ValueAccessStore;
33 import org.modelmapper.internal.valuemutate.ValueMutateStore;
34 import org.modelmapper.spi.ConditionalConverter;
35 import org.modelmapper.spi.MatchingStrategy;
36 import org.modelmapper.spi.NameTokenizer;
37 import org.modelmapper.spi.NameTransformer;
38 import org.modelmapper.spi.NamingConvention;
39 import org.modelmapper.spi.ValueReader;
40 import org.modelmapper.spi.ValueWriter;
41
42
47 public class InheritingConfiguration implements Configuration {
48 private final Configuration parent;
49 public final TypeMapStore typeMapStore;
50 public final ConverterStore converterStore;
51 public final ValueAccessStore valueAccessStore;
52 public final ValueMutateStore valueMutateStore;
53 private NameTokenizer destinationNameTokenizer;
54 private NameTransformer destinationNameTransformer;
55 private NamingConvention destinationNamingConvention;
56 private AccessLevel fieldAccessLevel;
57 private MatchingStrategy matchingStrategy;
58 private AccessLevel methodAccessLevel;
59 private Provider<?> provider;
60 private Condition<?, ?> propertyCondition;
61 private NameTokenizer sourceNameTokenizer;
62 private NameTransformer sourceNameTransformer;
63 private NamingConvention sourceNamingConvention;
64 private Boolean fieldMatchingEnabled;
65 private Boolean ambiguityIgnored;
66 private Boolean fullTypeMatchingRequired;
67 private Boolean implicitMatchingEnabled;
68 private Boolean preferNestedProperties;
69 private Boolean skipNullEnabled;
70 private Boolean collectionsMergeEnabled;
71 private Boolean useOSGiClassLoaderBridging;
72
73
76 public InheritingConfiguration() {
77 parent = null;
78 typeMapStore = new TypeMapStore(this);
79 converterStore = new ConverterStore();
80 valueAccessStore = new ValueAccessStore();
81 valueMutateStore = new ValueMutateStore();
82 sourceNameTokenizer = NameTokenizers.CAMEL_CASE;
83 destinationNameTokenizer = NameTokenizers.CAMEL_CASE;
84 sourceNamingConvention = NamingConventions.JAVABEANS_ACCESSOR;
85 destinationNamingConvention = NamingConventions.JAVABEANS_MUTATOR;
86 sourceNameTransformer = NameTransformers.JAVABEANS_ACCESSOR;
87 destinationNameTransformer = NameTransformers.JAVABEANS_MUTATOR;
88 matchingStrategy = MatchingStrategies.STANDARD;
89 fieldAccessLevel = AccessLevel.PUBLIC;
90 methodAccessLevel = AccessLevel.PUBLIC;
91 fieldMatchingEnabled = Boolean.FALSE;
92 ambiguityIgnored = Boolean.FALSE;
93 fullTypeMatchingRequired = Boolean.FALSE;
94 implicitMatchingEnabled = Boolean.TRUE;
95 preferNestedProperties = Boolean.TRUE;
96 skipNullEnabled = Boolean.FALSE;
97 useOSGiClassLoaderBridging = Boolean.FALSE;
98 collectionsMergeEnabled = Boolean.FALSE;
99 }
100
101
104 InheritingConfiguration(InheritingConfiguration source, boolean inherit) {
105
106 typeMapStore = source.typeMapStore;
107 converterStore = source.converterStore;
108 valueAccessStore = source.valueAccessStore;
109 valueMutateStore = source.valueMutateStore;
110
111 if (inherit) {
112 this.parent = source;
113 } else {
114 parent = null;
115 sourceNameTokenizer = source.sourceNameTokenizer;
116 destinationNameTokenizer = source.destinationNameTokenizer;
117 sourceNamingConvention = source.sourceNamingConvention;
118 destinationNamingConvention = source.destinationNamingConvention;
119 sourceNameTransformer = source.sourceNameTransformer;
120 destinationNameTransformer = source.destinationNameTransformer;
121 matchingStrategy = source.matchingStrategy;
122 fieldAccessLevel = source.fieldAccessLevel;
123 methodAccessLevel = source.methodAccessLevel;
124 fieldMatchingEnabled = source.fieldMatchingEnabled;
125 ambiguityIgnored = source.ambiguityIgnored;
126 provider = source.provider;
127 propertyCondition = source.propertyCondition;
128 fullTypeMatchingRequired = source.fullTypeMatchingRequired;
129 implicitMatchingEnabled = source.implicitMatchingEnabled;
130 preferNestedProperties = source.preferNestedProperties;
131 skipNullEnabled = source.skipNullEnabled;
132 collectionsMergeEnabled = source.collectionsMergeEnabled;
133 }
134 }
135
136 @Override
137 public <T> Configuration addValueReader(ValueReader<T> valueReader) {
138 getValueReaders().add(valueReader);
139 return this;
140 }
141
142 @Override
143 public <T> Configuration addValueWriter(ValueWriter<T> valueWriter) {
144 getValueWriters().add(valueWriter);
145 return this;
146 }
147
148 @Override
149 public Configuration copy() {
150 return new InheritingConfiguration(this, false);
151 }
152
153
156 @Override
157 @SuppressWarnings("all")
158 public boolean equals(Object obj) {
159 if (this == obj)
160 return true;
161 if (obj == null || getClass() != obj.getClass())
162 return false;
163
164 InheritingConfiguration other = (InheritingConfiguration) obj;
165 if (!getSourceNameTransformer().equals(other.getSourceNameTransformer()))
166 return false;
167 if (!getDestinationNameTransformer().equals(other.getDestinationNameTransformer()))
168 return false;
169 if (getFieldAccessLevel() != other.getFieldAccessLevel())
170 return false;
171 if (getMethodAccessLevel() != other.getMethodAccessLevel())
172 return false;
173 if (isFieldMatchingEnabled() != other.isFieldMatchingEnabled())
174 return false;
175 return true;
176 }
177
178 @Override
179 public List<ConditionalConverter<?, ?>> getConverters() {
180 return converterStore.getConverters();
181 }
182
183 @Override
184 public NameTokenizer getDestinationNameTokenizer() {
185 return destinationNameTokenizer == null
186 ? Assert.notNull(parent).getDestinationNameTokenizer()
187 : destinationNameTokenizer;
188 }
189
190 @Override
191 public NameTransformer getDestinationNameTransformer() {
192 return destinationNameTransformer == null
193 ? Assert.notNull(parent).getDestinationNameTransformer()
194 : destinationNameTransformer;
195 }
196
197 @Override
198 public NamingConvention getDestinationNamingConvention() {
199 return destinationNamingConvention == null
200 ? Assert.notNull(parent).getDestinationNamingConvention()
201 : destinationNamingConvention;
202 }
203
204 @Override
205 public AccessLevel getFieldAccessLevel() {
206 return fieldAccessLevel == null
207 ? Assert.notNull(parent).getFieldAccessLevel()
208 : fieldAccessLevel;
209 }
210
211 @Override
212 public MatchingStrategy getMatchingStrategy() {
213 return matchingStrategy == null
214 ? Assert.notNull(parent).getMatchingStrategy()
215 : matchingStrategy;
216 }
217
218 @Override
219 public AccessLevel getMethodAccessLevel() {
220 return methodAccessLevel == null
221 ? Assert.notNull(parent).getMethodAccessLevel()
222 : methodAccessLevel;
223 }
224
225 @Override
226 public Condition<?, ?> getPropertyCondition() {
227 if (parent != null)
228 return propertyCondition == null
229 ? parent.getPropertyCondition()
230 : propertyCondition;
231 return propertyCondition;
232 }
233
234 @Override
235 public Provider<?> getProvider() {
236 if (parent != null)
237 return provider == null
238 ? Assert.notNull(parent).getProvider()
239 : provider;
240 return provider;
241 }
242
243 @Override
244 public NameTokenizer getSourceNameTokenizer() {
245 return sourceNameTokenizer == null
246 ? Assert.notNull(parent).getSourceNameTokenizer()
247 : sourceNameTokenizer;
248 }
249
250 @Override
251 public NameTransformer getSourceNameTransformer() {
252 return sourceNameTransformer == null
253 ? Assert.notNull(parent).getSourceNameTransformer()
254 : sourceNameTransformer;
255 }
256
257 @Override
258 public NamingConvention getSourceNamingConvention() {
259 return sourceNamingConvention == null
260 ? Assert.notNull(parent).getSourceNamingConvention()
261 : sourceNamingConvention;
262 }
263
264 @Override
265 public List<ValueReader<?>> getValueReaders() {
266 return valueAccessStore.getValueReaders();
267 }
268
269 @Override
270 public List<ValueWriter<?>> getValueWriters() {
271 return valueMutateStore.getValueWriters();
272 }
273
274
278 @Override
279 public int hashCode() {
280 final int prime = 31;
281 int result = 1;
282 result = prime * result + getSourceNameTransformer().hashCode();
283 result = prime * result + getDestinationNameTransformer().hashCode();
284 result = prime * result + getFieldAccessLevel().hashCode();
285 result = prime * result + getMethodAccessLevel().hashCode();
286 result = prime * result + (isFieldMatchingEnabled() ? 1231 : 1237);
287 return result;
288 }
289
290 @Override
291 public boolean isAmbiguityIgnored() {
292 return ambiguityIgnored == null
293 ? Assert.notNull(parent).isAmbiguityIgnored()
294 : ambiguityIgnored;
295 }
296
297 @Override
298 public boolean isFieldMatchingEnabled() {
299 return fieldMatchingEnabled == null
300 ? Assert.notNull(parent).isFieldMatchingEnabled()
301 : fieldMatchingEnabled;
302 }
303
304 @Override
305 public boolean isFullTypeMatchingRequired() {
306 return fullTypeMatchingRequired == null
307 ? Assert.notNull(parent).isFullTypeMatchingRequired()
308 : fullTypeMatchingRequired;
309 }
310
311 @Override
312 public boolean isImplicitMappingEnabled() {
313 return implicitMatchingEnabled == null
314 ? Assert.notNull(parent).isImplicitMappingEnabled()
315 : implicitMatchingEnabled;
316 }
317
318 @Override
319 public boolean isPreferNestedProperties() {
320 return preferNestedProperties == null
321 ? Assert.notNull(parent).isPreferNestedProperties()
322 : preferNestedProperties;
323 }
324
325 @Override
326 public boolean isSkipNullEnabled() {
327 return skipNullEnabled == null
328 ? Assert.notNull(parent).isSkipNullEnabled()
329 : skipNullEnabled;
330 }
331
332 @Override
333 public boolean isUseOSGiClassLoaderBridging() {
334 return useOSGiClassLoaderBridging == null
335 ? Assert.notNull(parent).isUseOSGiClassLoaderBridging()
336 : useOSGiClassLoaderBridging;
337 }
338
339 @Override
340 public boolean isDeepCopyEnabled() {
341 return !converterStore.hasConverter(AssignableConverter.class);
342 }
343
344 @Override
345 public boolean isCollectionsMergeEnabled() {
346 return converterStore.hasConverter(MergingCollectionConverter.class);
347 }
348
349 @Override
350 public Configuration setAmbiguityIgnored(boolean ignore) {
351 this.ambiguityIgnored = ignore;
352 return this;
353 }
354
355 @Override
356 public Configuration setDestinationNameTokenizer(NameTokenizer nameTokenizer) {
357 destinationNameTokenizer = Assert.notNull(nameTokenizer);
358 return this;
359 }
360
361 @Override
362 public Configuration setDestinationNameTransformer(NameTransformer nameTransformer) {
363 destinationNameTransformer = Assert.notNull(nameTransformer);
364 return this;
365 }
366
367 @Override
368 public Configuration setDestinationNamingConvention(NamingConvention namingConvention) {
369 destinationNamingConvention = Assert.notNull(namingConvention);
370 return this;
371 }
372
373 @Override
374 public Configuration setFieldAccessLevel(AccessLevel accessLevel) {
375 fieldAccessLevel = Assert.notNull(accessLevel);
376 return this;
377 }
378
379 @Override
380 public Configuration setFieldMatchingEnabled(boolean enabled) {
381 fieldMatchingEnabled = enabled;
382 return this;
383 }
384
385 @Override
386 public Configuration setFullTypeMatchingRequired(boolean required) {
387 fullTypeMatchingRequired = required;
388 return this;
389 }
390
391 @Override
392 public Configuration setImplicitMappingEnabled(boolean enabled) {
393 implicitMatchingEnabled = enabled;
394 return this;
395 }
396
397 @Override
398 public Configuration setPreferNestedProperties(boolean enabled) {
399 preferNestedProperties = enabled;
400 return this;
401 }
402
403 @Override
404 public Configuration setSkipNullEnabled(boolean enabled) {
405 skipNullEnabled = enabled;
406 return this;
407 }
408
409 @Override
410 public Configuration setDeepCopyEnabled(boolean enabled) {
411 if (enabled && converterStore.hasConverter(AssignableConverter.class))
412 converterStore.removeConverter(AssignableConverter.class);
413 else if (!enabled && !converterStore.hasConverter(AssignableConverter.class))
414 converterStore.addConverter(new AssignableConverter());
415 return this;
416 }
417
418 @Override
419 public Configuration setCollectionsMergeEnabled(boolean enabled) {
420 if (enabled) {
421 converterStore.replaceConverter(NonMergingCollectionConverter.class, new MergingCollectionConverter());
422 } else {
423 converterStore.replaceConverter(MergingCollectionConverter.class, new NonMergingCollectionConverter());
424 }
425 return this;
426 }
427
428 @Override
429 public Configuration setMatchingStrategy(MatchingStrategy matchingStrategy) {
430 this.matchingStrategy = Assert.notNull(matchingStrategy);
431 return this;
432 }
433
434 @Override
435 public Configuration setMethodAccessLevel(AccessLevel accessLevel) {
436 methodAccessLevel = Assert.notNull(accessLevel);
437 return this;
438 }
439
440 @Override
441 public Configuration setPropertyCondition(Condition<?, ?> condition) {
442 propertyCondition = Assert.notNull(condition);
443 return this;
444 }
445
446 @Override
447 public Configuration setProvider(Provider<?> provider) {
448 this.provider = Assert.notNull(provider);
449 return this;
450 }
451
452 @Override
453 public Configuration setSourceNameTokenizer(NameTokenizer nameTokenizer) {
454 sourceNameTokenizer = Assert.notNull(nameTokenizer);
455 return this;
456 }
457
458 @Override
459 public Configuration setSourceNameTransformer(NameTransformer nameTransformer) {
460 sourceNameTransformer = Assert.notNull(nameTransformer);
461 return this;
462 }
463
464 @Override
465 public Configuration setSourceNamingConvention(NamingConvention namingConvention) {
466 sourceNamingConvention = Assert.notNull(namingConvention);
467 return this;
468 }
469
470 @Override
471 public Configuration setUseOSGiClassLoaderBridging(boolean useOSGiClassLoaderBridging) {
472 this.useOSGiClassLoaderBridging = useOSGiClassLoaderBridging;
473 return this;
474 }
475 }
476