jdk/src/share/classes/java/time/format/Parsed.java
changeset 19030 32f129cb6351
parent 17474 8c100beabcc0
child 20523 aee7c8a56c75
equal deleted inserted replaced
19029:30c64a024c86 19030:32f129cb6351
   141      */
   141      */
   142     private ResolverStyle resolverStyle;
   142     private ResolverStyle resolverStyle;
   143     /**
   143     /**
   144      * The resolved date.
   144      * The resolved date.
   145      */
   145      */
   146     private ChronoLocalDate<?> date;
   146     private ChronoLocalDate date;
   147     /**
   147     /**
   148      * The resolved time.
   148      * The resolved time.
   149      */
   149      */
   150     private LocalTime time;
   150     private LocalTime time;
   151     /**
   151     /**
   195         }
   195         }
   196         if (time != null && time.isSupported(field)) {
   196         if (time != null && time.isSupported(field)) {
   197             return time.getLong(field);
   197             return time.getLong(field);
   198         }
   198         }
   199         if (field instanceof ChronoField) {
   199         if (field instanceof ChronoField) {
   200             throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
   200             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
   201         }
   201         }
   202         return field.getFrom(this);
   202         return field.getFrom(this);
   203     }
   203     }
   204 
   204 
   205     @SuppressWarnings("unchecked")
   205     @SuppressWarnings("unchecked")
   253         resolveTimeFields();
   253         resolveTimeFields();
   254 
   254 
   255         // if any other fields, handle them
   255         // if any other fields, handle them
   256         // any lenient date resolution should return epoch-day
   256         // any lenient date resolution should return epoch-day
   257         if (fieldValues.size() > 0) {
   257         if (fieldValues.size() > 0) {
   258             boolean changed = false;
   258             int changedCount = 0;
   259             outer:
   259             outer:
   260             while (true) {
   260             while (changedCount < 50) {
   261                 for (Map.Entry<TemporalField, Long> entry : fieldValues.entrySet()) {
   261                 for (Map.Entry<TemporalField, Long> entry : fieldValues.entrySet()) {
   262                     TemporalField targetField = entry.getKey();
   262                     TemporalField targetField = entry.getKey();
   263                     Map<TemporalField, Long> changes = targetField.resolve(this, entry.getValue(), resolverStyle);
   263                     ChronoLocalDate resolvedDate = targetField.resolve(fieldValues, chrono, zone, resolverStyle);
   264                     if (changes != null) {
   264                     if (resolvedDate != null) {
   265                         changed = true;
   265                         updateCheckConflict(resolvedDate);
   266                         resolveFieldsMakeChanges(targetField, changes);
   266                         changedCount++;
   267                         fieldValues.remove(targetField);  // helps avoid infinite loops
   267                         continue outer;  // have to restart to avoid concurrent modification
       
   268                     } else if (fieldValues.containsKey(targetField) == false) {
       
   269                         changedCount++;
   268                         continue outer;  // have to restart to avoid concurrent modification
   270                         continue outer;  // have to restart to avoid concurrent modification
   269                     }
   271                     }
   270                 }
   272                 }
   271                 break;
   273                 break;
   272             }
   274             }
       
   275             if (changedCount == 50) {  // catch infinite loops
       
   276                 throw new DateTimeException("One of the parsed fields has an incorrectly implemented resolve method");
       
   277             }
   273             // if something changed then have to redo ChronoField resolve
   278             // if something changed then have to redo ChronoField resolve
   274             if (changed) {
   279             if (changedCount > 0) {
   275                 resolveDateFields();
   280                 resolveDateFields();
   276                 resolveTimeFields();
   281                 resolveTimeFields();
   277             }
       
   278         }
       
   279     }
       
   280 
       
   281     private void resolveFieldsMakeChanges(TemporalField targetField, Map<TemporalField, Long> changes) {
       
   282         for (Map.Entry<TemporalField, Long> change : changes.entrySet()) {
       
   283             TemporalField changeField = change.getKey();
       
   284             Long changeValue = change.getValue();
       
   285             Objects.requireNonNull(changeField, "changeField");
       
   286             if (changeValue != null) {
       
   287                 updateCheckConflict(targetField, changeField, changeValue);
       
   288             } else {
       
   289                 fieldValues.remove(changeField);
       
   290             }
   282             }
   291         }
   283         }
   292     }
   284     }
   293 
   285 
   294     private void updateCheckConflict(TemporalField targetField, TemporalField changeField, Long changeValue) {
   286     private void updateCheckConflict(TemporalField targetField, TemporalField changeField, Long changeValue) {
   303     //-----------------------------------------------------------------------
   295     //-----------------------------------------------------------------------
   304     private void resolveDateFields() {
   296     private void resolveDateFields() {
   305         updateCheckConflict(chrono.resolveDate(fieldValues, resolverStyle));
   297         updateCheckConflict(chrono.resolveDate(fieldValues, resolverStyle));
   306     }
   298     }
   307 
   299 
   308     private void updateCheckConflict(ChronoLocalDate<?> cld) {
   300     private void updateCheckConflict(ChronoLocalDate cld) {
   309         if (date != null) {
   301         if (date != null) {
   310             if (cld != null && date.equals(cld) == false) {
   302             if (cld != null && date.equals(cld) == false) {
   311                 throw new DateTimeException("Conflict found: Fields resolved to two different dates: " + date + " " + cld);
   303                 throw new DateTimeException("Conflict found: Fields resolved to two different dates: " + date + " " + cld);
   312             }
   304             }
   313         } else {
   305         } else {