4545import com .google .api .client .json .JsonObjectParser ;
4646import com .google .api .client .util .GenericData ;
4747import com .google .api .core .InternalApi ;
48+ import com .google .api .core .ObsoleteApi ;
4849import com .google .auth .CredentialTypeForMetrics ;
4950import com .google .auth .ServiceAccountSigner ;
5051import com .google .auth .http .HttpCredentialsAdapter ;
5960import java .io .IOException ;
6061import java .io .InputStream ;
6162import java .io .ObjectInputStream ;
62- import java .text . DateFormat ;
63- import java .text . ParseException ;
64- import java .text . SimpleDateFormat ;
63+ import java .time . DateTimeException ;
64+ import java .time . Instant ;
65+ import java .time . format . DateTimeFormatter ;
6566import java .util .ArrayList ;
6667import java .util .Calendar ;
6768import java .util .Collection ;
@@ -101,7 +102,6 @@ public class ImpersonatedCredentials extends GoogleCredentials
101102 implements ServiceAccountSigner , IdTokenProvider {
102103
103104 private static final long serialVersionUID = -2133257318957488431L ;
104- private static final String RFC3339 = "yyyy-MM-dd'T'HH:mm:ssX" ;
105105 private static final int TWELVE_HOURS_IN_SECONDS = 43200 ;
106106 private static final int DEFAULT_LIFETIME_IN_SECONDS = 3600 ;
107107 private GoogleCredentials sourceCredentials ;
@@ -510,12 +510,16 @@ public CredentialTypeForMetrics getMetricsCredentialType() {
510510 }
511511
512512 /**
513- * Clones the impersonated credentials with a new calendar.
513+ * This method is marked obsolete. There is no alternative to setting a custom calendar for the
514+ * Credential.
515+ *
516+ * <p>Clones the impersonated credentials with a new calendar.
514517 *
515518 * @param calendar the calendar that will be used by the new ImpersonatedCredentials instance when
516519 * parsing the received expiration time of the refreshed access token
517520 * @return the cloned impersonated credentials with the given custom calendar
518521 */
522+ @ ObsoleteApi ("This method is obsolete and will be removed in a future release." )
519523 public ImpersonatedCredentials createWithCustomCalendar (Calendar calendar ) {
520524 return toBuilder ()
521525 .setScopes (this .scopes )
@@ -660,14 +664,23 @@ public AccessToken refreshAccessToken() throws IOException {
660664 String expireTime =
661665 OAuth2Utils .validateString (responseData , "expireTime" , "Expected to find an expireTime" );
662666
663- DateFormat format = new SimpleDateFormat (RFC3339 );
664- format .setCalendar (calendar );
667+ Instant expirationInstant ;
665668 try {
666- Date date = format .parse (expireTime );
667- return new AccessToken (accessToken , date );
668- } catch (ParseException pe ) {
669- throw new IOException ("Error parsing expireTime: " + pe .getMessage ());
669+ if (calendar != null ) {
670+ // For backward compatibility, if a custom calendar is set, use its timezone
671+ // and convert it to an Instant
672+ expirationInstant =
673+ Instant .from (
674+ DateTimeFormatter .ISO_INSTANT
675+ .withZone (calendar .getTimeZone ().toZoneId ())
676+ .parse (expireTime ));
677+ } else {
678+ expirationInstant = Instant .parse (expireTime );
679+ }
680+ } catch (DateTimeException e ) {
681+ throw new IOException ("Unparseable date: \" " + expireTime + "\" " , e );
670682 }
683+ return new AccessToken (accessToken , Date .from (expirationInstant ));
671684 }
672685
673686 /**
@@ -883,7 +896,17 @@ public Builder setIamEndpointOverride(String iamEndpointOverride) {
883896 return this ;
884897 }
885898
899+ /**
900+ * This method is marked obsolete. There is no alternative to setting a custom calendar for the
901+ * Credential.
902+ *
903+ * <p>Sets the calendar to be used for parsing the expiration time.
904+ *
905+ * @param calendar the calendar to use
906+ * @return the builder
907+ */
886908 @ CanIgnoreReturnValue
909+ @ ObsoleteApi ("This method is obsolete and will be removed in a future release." )
887910 public Builder setCalendar (Calendar calendar ) {
888911 this .calendar = calendar ;
889912 return this ;
@@ -903,6 +926,15 @@ public Builder setReadTimeout(int readTimeout) {
903926 return this ;
904927 }
905928
929+ /**
930+ * This method is marked obsolete. There is no alternative to getting a custom calendar for the
931+ * Credential.
932+ *
933+ * <p>Returns the calendar to be used for parsing the expiration time.
934+ *
935+ * @return the calendar
936+ */
937+ @ ObsoleteApi ("This method is obsolete and will be removed in a future release." )
906938 public Calendar getCalendar () {
907939 return this .calendar ;
908940 }
0 commit comments