18
18
19
19
import java .lang .reflect .Method ;
20
20
import java .time .Duration ;
21
+ import java .time .temporal .ChronoUnit ;
21
22
import java .util .ArrayList ;
22
23
import java .util .Arrays ;
23
24
import java .util .Collection ;
24
25
import java .util .Collections ;
26
+ import java .util .HashMap ;
25
27
import java .util .IdentityHashMap ;
26
28
import java .util .LinkedHashSet ;
27
29
import java .util .List ;
30
32
import java .util .TimeZone ;
31
33
import java .util .concurrent .ConcurrentHashMap ;
32
34
import java .util .concurrent .ScheduledExecutorService ;
35
+ import java .util .regex .Matcher ;
36
+ import java .util .regex .Pattern ;
33
37
34
38
import org .apache .commons .logging .Log ;
35
39
import org .apache .commons .logging .LogFactory ;
@@ -115,6 +119,20 @@ public class ScheduledAnnotationBeanPostProcessor
115
119
*/
116
120
public static final String DEFAULT_TASK_SCHEDULER_BEAN_NAME = "taskScheduler" ;
117
121
122
+ private static Pattern DURATION_IN_TEXT_FORMAT = Pattern .compile ("^([\\ +\\ -]?\\ d+)([a-zA-Z]{1,2})$" );
123
+
124
+ private static final Map <String , ChronoUnit > UNITS ;
125
+
126
+ static {
127
+ Map <String , ChronoUnit > units = new HashMap <>();
128
+ units .put ("ns" , ChronoUnit .NANOS );
129
+ units .put ("ms" , ChronoUnit .MILLIS );
130
+ units .put ("s" , ChronoUnit .SECONDS );
131
+ units .put ("m" , ChronoUnit .MINUTES );
132
+ units .put ("h" , ChronoUnit .HOURS );
133
+ units .put ("d" , ChronoUnit .DAYS );
134
+ UNITS = Collections .unmodifiableMap (units );
135
+ }
118
136
119
137
protected final Log logger = LogFactory .getLog (getClass ());
120
138
@@ -394,13 +412,9 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
394
412
initialDelayString = this .embeddedValueResolver .resolveStringValue (initialDelayString );
395
413
}
396
414
if (StringUtils .hasLength (initialDelayString )) {
397
- try {
398
- initialDelay = parseDelayAsLong (initialDelayString );
399
- }
400
- catch (RuntimeException ex ) {
401
- throw new IllegalArgumentException (
402
- "Invalid initialDelayString value \" " + initialDelayString + "\" - cannot parse into long" );
403
- }
415
+ initialDelay = parseDelayAsLong (initialDelayString ,
416
+ "Invalid initialDelayString value \" " +
417
+ initialDelayString + "\" - cannot parse into long" );
404
418
}
405
419
}
406
420
@@ -448,13 +462,9 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
448
462
if (StringUtils .hasLength (fixedDelayString )) {
449
463
Assert .isTrue (!processedSchedule , errorMessage );
450
464
processedSchedule = true ;
451
- try {
452
- fixedDelay = parseDelayAsLong (fixedDelayString );
453
- }
454
- catch (RuntimeException ex ) {
455
- throw new IllegalArgumentException (
456
- "Invalid fixedDelayString value \" " + fixedDelayString + "\" - cannot parse into long" );
457
- }
465
+ fixedDelay = parseDelayAsLong (fixedDelayString ,
466
+ "Invalid fixedDelayString value \" " + fixedDelayString + "\" - cannot parse into long" );
467
+
458
468
tasks .add (this .registrar .scheduleFixedDelayTask (new FixedDelayTask (runnable , fixedDelay , initialDelay )));
459
469
}
460
470
}
@@ -474,13 +484,9 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
474
484
if (StringUtils .hasLength (fixedRateString )) {
475
485
Assert .isTrue (!processedSchedule , errorMessage );
476
486
processedSchedule = true ;
477
- try {
478
- fixedRate = parseDelayAsLong (fixedRateString );
479
- }
480
- catch (RuntimeException ex ) {
481
- throw new IllegalArgumentException (
482
- "Invalid fixedRateString value \" " + fixedRateString + "\" - cannot parse into long" );
483
- }
487
+ fixedRate = parseDelayAsLong (fixedRateString ,
488
+ "Invalid fixedRateString value \" " + fixedRateString + "\" - cannot parse into long" );
489
+
484
490
tasks .add (this .registrar .scheduleFixedRateTask (new FixedRateTask (runnable , fixedRate , initialDelay )));
485
491
}
486
492
}
@@ -515,11 +521,24 @@ protected Runnable createRunnable(Object target, Method method) {
515
521
return new ScheduledMethodRunnable (target , invocableMethod );
516
522
}
517
523
518
- private static long parseDelayAsLong (String value ) throws RuntimeException {
519
- if (value .length () > 1 && (isP (value .charAt (0 )) || isP (value .charAt (1 )))) {
520
- return Duration .parse (value ).toMillis ();
524
+ private static long parseDelayAsLong (String value , String exceptionMessage ) throws IllegalArgumentException {
525
+ try {
526
+ if (value .length () > 1 && (isP (value .charAt (0 )) || isP (value .charAt (1 )))) {
527
+ return Duration .parse (value ).toMillis ();
528
+ }
529
+ return Long .parseLong (value );
530
+
531
+ }
532
+ catch (RuntimeException ex ) {
533
+ Matcher matcher = DURATION_IN_TEXT_FORMAT .matcher (value );
534
+
535
+ Assert .isTrue (matcher .matches (), exceptionMessage );
536
+ long amount = Long .parseLong (matcher .group (1 ));
537
+ ChronoUnit unit = UNITS .get (matcher .group (2 ).toLowerCase ());
538
+ Assert .notNull (unit , exceptionMessage );
539
+
540
+ return Duration .of (amount , unit ).toMillis ();
521
541
}
522
- return Long .parseLong (value );
523
542
}
524
543
525
544
private static boolean isP (char ch ) {
0 commit comments