11/*
2- * Copyright 2002-2014 the original author or authors.
2+ * Copyright 2002-2015 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1818
1919import java .text .DateFormat ;
2020import java .text .SimpleDateFormat ;
21+ import java .util .Arrays ;
2122import java .util .HashMap ;
2223import java .util .LinkedHashMap ;
2324import java .util .LinkedList ;
2425import java .util .List ;
26+ import java .util .Locale ;
2527import java .util .Map ;
28+ import java .util .TimeZone ;
2629
2730import com .fasterxml .jackson .annotation .JsonInclude ;
2831import com .fasterxml .jackson .core .JsonGenerator ;
4649import org .springframework .context .ApplicationContext ;
4750import org .springframework .util .Assert ;
4851import org .springframework .util .ClassUtils ;
52+ import org .springframework .util .StringUtils ;
4953
5054/**
5155 * A builder used to create {@link ObjectMapper} instances with a fluent API.
@@ -75,6 +79,10 @@ public class Jackson2ObjectMapperBuilder {
7579
7680 private DateFormat dateFormat ;
7781
82+ private Locale locale ;
83+
84+ private TimeZone timeZone ;
85+
7886 private AnnotationIntrospector annotationIntrospector ;
7987
8088 private PropertyNamingStrategy propertyNamingStrategy ;
@@ -91,9 +99,11 @@ public class Jackson2ObjectMapperBuilder {
9199
92100 private List <Module > modules ;
93101
94- private Class <? extends Module >[] modulesToInstall ;
102+ private Class <? extends Module >[] moduleClasses ;
103+
104+ private boolean findModulesViaServiceLoader = false ;
95105
96- private boolean findModulesViaServiceLoader ;
106+ private boolean findWellKnownModules = true ;
97107
98108 private ClassLoader moduleClassLoader = getClass ().getClassLoader ();
99109
@@ -134,6 +144,48 @@ public Jackson2ObjectMapperBuilder simpleDateFormat(String format) {
134144 return this ;
135145 }
136146
147+ /**
148+ * Override the default {@link Locale} to use for formatting.
149+ * Default value used is {@link Locale#getDefault()}.
150+ * @since 4.1.5
151+ */
152+ public Jackson2ObjectMapperBuilder locale (Locale locale ) {
153+ this .locale = locale ;
154+ return this ;
155+ }
156+
157+ /**
158+ * Override the default {@link Locale} to use for formatting.
159+ * Default value used is {@link Locale#getDefault()}.
160+ * @param localeString the locale ID as a String representation
161+ * @since 4.1.5
162+ */
163+ public Jackson2ObjectMapperBuilder locale (String localeString ) {
164+ this .locale = StringUtils .parseLocaleString (localeString );
165+ return this ;
166+ }
167+
168+ /**
169+ * Override the default {@link TimeZone} to use for formatting.
170+ * Default value used is UTC (NOT local timezone).
171+ * @since 4.1.5
172+ */
173+ public Jackson2ObjectMapperBuilder timeZone (TimeZone timeZone ) {
174+ this .timeZone = timeZone ;
175+ return this ;
176+ }
177+
178+ /**
179+ * Override the default {@link TimeZone} to use for formatting.
180+ * Default value used is UTC (NOT local timezone).
181+ * @param timeZoneString the zone ID as a String representation
182+ * @since 4.1.5
183+ */
184+ public Jackson2ObjectMapperBuilder timeZone (String timeZoneString ) {
185+ this .timeZone = StringUtils .parseTimeZoneString (timeZoneString );
186+ return this ;
187+ }
188+
137189 /**
138190 * Set an {@link AnnotationIntrospector} for both serialization and deserialization.
139191 */
@@ -337,31 +389,68 @@ public Jackson2ObjectMapperBuilder featuresToDisable(Object... featuresToDisable
337389 return this ;
338390 }
339391
392+ /**
393+ * Specify one or more modules to be registered with the {@link ObjectMapper}.
394+ * <p>Note: If this is set, no finding of modules is going to happen - not by
395+ * Jackson, and not by Spring either (see {@link #findModulesViaServiceLoader}).
396+ * As a consequence, specifying an empty list here will suppress any kind of
397+ * module detection.
398+ * <p>Specify either this or {@link #modulesToInstall}, not both.
399+ * @since 4.1.5
400+ * @see #modules(List)
401+ * @see com.fasterxml.jackson.databind.Module
402+ */
403+ public Jackson2ObjectMapperBuilder modules (Module ... modules ) {
404+ return modules (Arrays .asList (modules ));
405+ }
406+
340407 /**
341408 * Set a complete list of modules to be registered with the {@link ObjectMapper}.
342409 * <p>Note: If this is set, no finding of modules is going to happen - not by
343410 * Jackson, and not by Spring either (see {@link #findModulesViaServiceLoader}).
344411 * As a consequence, specifying an empty list here will suppress any kind of
345412 * module detection.
346413 * <p>Specify either this or {@link #modulesToInstall}, not both.
414+ * @see #modules(Module...)
347415 * @see com.fasterxml.jackson.databind.Module
348416 */
349417 public Jackson2ObjectMapperBuilder modules (List <Module > modules ) {
350418 this .modules = new LinkedList <Module >(modules );
419+ this .findModulesViaServiceLoader = false ;
420+ this .findWellKnownModules = false ;
421+ return this ;
422+ }
423+
424+ /**
425+ * Specify one or more modules to be registered with the {@link ObjectMapper}.
426+ * <p>Modules specified here will be registered after
427+ * Spring's autodetection of JSR-310 and Joda-Time, or Jackson's
428+ * finding of modules (see {@link #findModulesViaServiceLoader}),
429+ * allowing to eventually override their configuration.
430+ * <p>Specify either this or {@link #modules}, not both.
431+ * @since 4.1.5
432+ * @see com.fasterxml.jackson.databind.Module
433+ */
434+ public Jackson2ObjectMapperBuilder modulesToInstall (Module ... modules ) {
435+ this .modules = Arrays .asList (modules );
436+ this .findWellKnownModules = true ;
351437 return this ;
352438 }
353439
354440 /**
355- * Specify one or more modules by class (or class name in XML),
356- * to be registered with the {@link ObjectMapper}.
357- * <p>Modules specified here will be registered in combination with
441+ * Specify one or more modules by class to be registered with
442+ * the {@link ObjectMapper}.
443+ * <p>Modules specified here will be registered after
358444 * Spring's autodetection of JSR-310 and Joda-Time, or Jackson's
359- * finding of modules (see {@link #findModulesViaServiceLoader}).
445+ * finding of modules (see {@link #findModulesViaServiceLoader}),
446+ * allowing to eventually override their configuration.
360447 * <p>Specify either this or {@link #modules}, not both.
448+ * @see #modulesToInstall(Module...)
361449 * @see com.fasterxml.jackson.databind.Module
362450 */
363451 public Jackson2ObjectMapperBuilder modulesToInstall (Class <? extends Module >... modules ) {
364- this .modulesToInstall = modules ;
452+ this .moduleClasses = modules ;
453+ this .findWellKnownModules = true ;
365454 return this ;
366455 }
367456
@@ -444,9 +533,35 @@ public <T extends ObjectMapper> T build() {
444533 public void configure (ObjectMapper objectMapper ) {
445534 Assert .notNull (objectMapper , "ObjectMapper must not be null" );
446535
536+ if (this .findModulesViaServiceLoader ) {
537+ // Jackson 2.2+
538+ objectMapper .registerModules (ObjectMapper .findModules (this .moduleClassLoader ));
539+ }
540+ else if (this .findWellKnownModules ) {
541+ registerWellKnownModulesIfAvailable (objectMapper );
542+ }
543+
544+ if (this .modules != null ) {
545+ for (Module module : this .modules ) {
546+ // Using Jackson 2.0+ registerModule method, not Jackson 2.2+ registerModules
547+ objectMapper .registerModule (module );
548+ }
549+ }
550+ if (this .moduleClasses != null ) {
551+ for (Class <? extends Module > module : this .moduleClasses ) {
552+ objectMapper .registerModule (BeanUtils .instantiate (module ));
553+ }
554+ }
555+
447556 if (this .dateFormat != null ) {
448557 objectMapper .setDateFormat (this .dateFormat );
449558 }
559+ if (this .locale != null ) {
560+ objectMapper .setLocale (this .locale );
561+ }
562+ if (this .timeZone != null ) {
563+ objectMapper .setTimeZone (this .timeZone );
564+ }
450565
451566 if (this .annotationIntrospector != null ) {
452567 objectMapper .setAnnotationIntrospector (this .annotationIntrospector );
@@ -468,29 +583,6 @@ public void configure(ObjectMapper objectMapper) {
468583 configureFeature (objectMapper , feature , this .features .get (feature ));
469584 }
470585
471- if (this .modules != null ) {
472- // Complete list of modules given
473- for (Module module : this .modules ) {
474- // Using Jackson 2.0+ registerModule method, not Jackson 2.2+ registerModules
475- objectMapper .registerModule (module );
476- }
477- }
478- else {
479- // Combination of modules by class names specified and class presence in the classpath
480- if (this .modulesToInstall != null ) {
481- for (Class <? extends Module > module : this .modulesToInstall ) {
482- objectMapper .registerModule (BeanUtils .instantiate (module ));
483- }
484- }
485- if (this .findModulesViaServiceLoader ) {
486- // Jackson 2.2+
487- objectMapper .registerModules (ObjectMapper .findModules (this .moduleClassLoader ));
488- }
489- else {
490- registerWellKnownModulesIfAvailable (objectMapper );
491- }
492- }
493-
494586 if (this .propertyNamingStrategy != null ) {
495587 objectMapper .setPropertyNamingStrategy (this .propertyNamingStrategy );
496588 }
0 commit comments