test_class.declarator: INITIAL_CURRENT_TIME_IN_MILLIS = 1000
test_class.modifier: private static final
test_class.original_string: private static final long INITIAL_CURRENT_TIME_IN_MILLIS = 1000;
test_class.type: long
test_class.var_name: INITIAL_CURRENT_TIME_IN_MILLIS
test_class.declarator: backgroundFetchFinishedLatch
test_class.modifier: private
test_class.original_string: private CountDownLatch backgroundFetchFinishedLatch;
test_class.type: CountDownLatch
test_class.var_name: backgroundFetchFinishedLatch
test_class.declarator: delayHttpResponseLatch
test_class.modifier: private
test_class.original_string: private CountDownLatch delayHttpResponseLatch;
test_class.type: CountDownLatch
test_class.var_name: delayHttpResponseLatch
test_class.declarator: executor
test_class.modifier: private
test_class.original_string: private ExecutorService executor;
test_class.type: ExecutorService
test_class.var_name: executor
test_class.declarator: httpResponseBuilder
test_class.modifier: private
test_class.original_string: private HttpResponseBuilder httpResponseBuilder;
test_class.type: HttpResponseBuilder
test_class.var_name: httpResponseBuilder
test_class.declarator: backgroundFetchStartedCount
test_class.modifier: private
test_class.original_string: private AtomicInteger backgroundFetchStartedCount;
test_class.type: AtomicInteger
test_class.var_name: backgroundFetchStartedCount
test_class.declarator: httpTransportGetCount
test_class.modifier: private
test_class.original_string: private AtomicInteger httpTransportGetCount;
test_class.type: AtomicInteger
test_class.var_name: httpTransportGetCount
test_class.declarator: executorIsAcceptingRunnables
test_class.modifier: private
test_class.original_string: private boolean executorIsAcceptingRunnables;
test_class.type: boolean
test_class.var_name: executorIsAcceptingRunnables
test_class.declarator: currentTimeInMillis
test_class.modifier: private
test_class.original_string: private long currentTimeInMillis;
test_class.type: long
test_class.var_name: currentTimeInMillis
test_class.file: java_src/src/test/java/com/google/crypto/tink/util/KeysDownloaderTest.java
test_class.identifier: KeysDownloaderTest
test_case.body: @Test
    public void shouldNotTriggerBackgroundRefreshBeforeHalfWayThroughExpiration() throws Exception {
      KeysDownloader instance = newInstanceForTests();
      httpResponseBuilder =
          new HttpResponseBuilder().setContent("keys1").setCacheControlWithMaxAgeInSeconds(3L);
      // Fetched and cached keys
      assertEquals("keys1", instance.download());
      // Keys changed
      httpResponseBuilder = new HttpResponseBuilder().setContent("keys2");
      // 1.5 seconds - 1ms later ...
      currentTimeInMillis += 1500L - 1;
  
      // Old keys are sill returned
      assertEquals("keys1", instance.download());
      // No background fetch should have been triggered
      assertEquals(0, backgroundFetchStartedCount.get());
    }
test_case.class_method_signature: KeysDownloaderTest.shouldNotTriggerBackgroundRefreshBeforeHalfWayThroughExpiration()
test_case.full_signature: @Test public void shouldNotTriggerBackgroundRefreshBeforeHalfWayThroughExpiration()
test_case.identifier: shouldNotTriggerBackgroundRefreshBeforeHalfWayThroughExpiration
test_case.invocations: newInstanceForTests setCacheControlWithMaxAgeInSeconds setContent assertEquals download setContent assertEquals download assertEquals get
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void shouldNotTriggerBackgroundRefreshBeforeHalfWayThroughExpiration()
focal_class.declarator: UTF_8 = Charset.forName("UTF-8")
focal_class.modifier: private static final
focal_class.original_string: private static final Charset UTF_8 = Charset.forName("UTF-8");
focal_class.type: Charset
focal_class.var_name: UTF_8
focal_class.declarator: DEFAULT_HTTP_TRANSPORT =
        new NetHttpTransport.Builder().build()
focal_class.modifier: private static final
focal_class.original_string: private static final NetHttpTransport DEFAULT_HTTP_TRANSPORT =
        new NetHttpTransport.Builder().build();
focal_class.type: NetHttpTransport
focal_class.var_name: DEFAULT_HTTP_TRANSPORT
focal_class.declarator: DEFAULT_BACKGROUND_EXECUTOR = Executors.newCachedThreadPool()
focal_class.modifier: private static final
focal_class.original_string: private static final Executor DEFAULT_BACKGROUND_EXECUTOR = Executors.newCachedThreadPool();
focal_class.type: Executor
focal_class.var_name: DEFAULT_BACKGROUND_EXECUTOR
focal_class.declarator: MAX_AGE_PATTERN = Pattern.compile("\\s*max-age\\s*=\\s*(\\d+)\\s*")
focal_class.modifier: private static final
focal_class.original_string: private static final Pattern MAX_AGE_PATTERN = Pattern.compile("\\s*max-age\\s*=\\s*(\\d+)\\s*");
focal_class.type: Pattern
focal_class.var_name: MAX_AGE_PATTERN
focal_class.declarator: backgroundExecutor
focal_class.modifier: private final
focal_class.original_string: private final Executor backgroundExecutor;
focal_class.type: Executor
focal_class.var_name: backgroundExecutor
focal_class.declarator: httpTransport
focal_class.modifier: private final
focal_class.original_string: private final HttpTransport httpTransport;
focal_class.type: HttpTransport
focal_class.var_name: httpTransport
focal_class.declarator: fetchDataLock
focal_class.modifier: private final
focal_class.original_string: private final Object fetchDataLock;
focal_class.type: Object
focal_class.var_name: fetchDataLock
focal_class.declarator: instanceStateLock
focal_class.modifier: private final
focal_class.original_string: private final Object instanceStateLock;
focal_class.type: Object
focal_class.var_name: instanceStateLock
focal_class.declarator: url
focal_class.modifier: private final
focal_class.original_string: private final String url;
focal_class.type: String
focal_class.var_name: url
focal_class.declarator: pendingRefreshRunnable
focal_class.modifier: @GuardedBy("instanceStateLock")
    private
focal_class.original_string: @GuardedBy("instanceStateLock")
    private Runnable pendingRefreshRunnable;
focal_class.type: Runnable
focal_class.var_name: pendingRefreshRunnable
focal_class.declarator: cachedData
focal_class.modifier: @GuardedBy("instanceStateLock")
    private
focal_class.original_string: @GuardedBy("instanceStateLock")
    private String cachedData;
focal_class.type: String
focal_class.var_name: cachedData
focal_class.declarator: cachedTimeInMillis
focal_class.modifier: @GuardedBy("instanceStateLock")
    private
focal_class.original_string: @GuardedBy("instanceStateLock")
    private long cachedTimeInMillis;
focal_class.type: long
focal_class.var_name: cachedTimeInMillis
focal_class.declarator: cacheExpirationDurationInMillis
focal_class.modifier: @GuardedBy("instanceStateLock")
    private
focal_class.original_string: @GuardedBy("instanceStateLock")
    private long cacheExpirationDurationInMillis;
focal_class.type: long
focal_class.var_name: cacheExpirationDurationInMillis
focal_class.file: java_src/src/main/java/com/google/crypto/tink/util/KeysDownloader.java
focal_class.identifier: KeysDownloader
focal_class.class_method_signature: KeysDownloader.KeysDownloader(Executor backgroundExecutor, HttpTransport httpTransport, String url)
focal_class.full_signature: public  KeysDownloader(Executor backgroundExecutor, HttpTransport httpTransport, String url)
focal_class.identifier: KeysDownloader
focal_class.modifiers: public
focal_class.parameters: (Executor backgroundExecutor, HttpTransport httpTransport, String url)
focal_class.signature:  KeysDownloader(Executor backgroundExecutor, HttpTransport httpTransport, String url)
focal_class.class_method_signature: KeysDownloader.download()
focal_class.full_signature: public String download()
focal_class.identifier: download
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: String
focal_class.signature: String download()
focal_class.class_method_signature: KeysDownloader.getHttpTransport()
focal_class.full_signature: public HttpTransport getHttpTransport()
focal_class.identifier: getHttpTransport
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: HttpTransport
focal_class.signature: HttpTransport getHttpTransport()
focal_class.class_method_signature: KeysDownloader.getUrl()
focal_class.full_signature: public String getUrl()
focal_class.identifier: getUrl
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: String
focal_class.signature: String getUrl()
focal_class.class_method_signature: KeysDownloader.hasNonExpiredDataCached()
focal_class.full_signature: @GuardedBy("instanceStateLock") private boolean hasNonExpiredDataCached()
focal_class.identifier: hasNonExpiredDataCached
focal_class.modifiers: @GuardedBy("instanceStateLock") private
focal_class.parameters: ()
focal_class.return: boolean
focal_class.signature: boolean hasNonExpiredDataCached()
focal_class.class_method_signature: KeysDownloader.shouldProactivelyRefreshDataInBackground()
focal_class.full_signature: @GuardedBy("instanceStateLock") private boolean shouldProactivelyRefreshDataInBackground()
focal_class.identifier: shouldProactivelyRefreshDataInBackground
focal_class.modifiers: @GuardedBy("instanceStateLock") private
focal_class.parameters: ()
focal_class.return: boolean
focal_class.signature: boolean shouldProactivelyRefreshDataInBackground()
focal_class.class_method_signature: KeysDownloader.getCurrentTimeInMillis()
focal_class.full_signature:  long getCurrentTimeInMillis()
focal_class.identifier: getCurrentTimeInMillis
focal_class.parameters: ()
focal_class.return: long
focal_class.signature: long getCurrentTimeInMillis()
focal_class.class_method_signature: KeysDownloader.fetchAndCacheData()
focal_class.full_signature: @GuardedBy("fetchDataLock") private String fetchAndCacheData()
focal_class.identifier: fetchAndCacheData
focal_class.modifiers: @GuardedBy("fetchDataLock") private
focal_class.parameters: ()
focal_class.return: String
focal_class.signature: String fetchAndCacheData()
focal_class.class_method_signature: KeysDownloader.readerToString(Reader reader)
focal_class.full_signature: private static String readerToString(Reader reader)
focal_class.identifier: readerToString
focal_class.modifiers: private static
focal_class.parameters: (Reader reader)
focal_class.return: String
focal_class.signature: String readerToString(Reader reader)
focal_class.class_method_signature: KeysDownloader.getExpirationDurationInSeconds(HttpHeaders httpHeaders)
focal_class.full_signature:  long getExpirationDurationInSeconds(HttpHeaders httpHeaders)
focal_class.identifier: getExpirationDurationInSeconds
focal_class.parameters: (HttpHeaders httpHeaders)
focal_class.return: long
focal_class.signature: long getExpirationDurationInSeconds(HttpHeaders httpHeaders)
focal_class.class_method_signature: KeysDownloader.refreshInBackground()
focal_class.full_signature: public void refreshInBackground()
focal_class.identifier: refreshInBackground
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void refreshInBackground()
focal_class.class_method_signature: KeysDownloader.newRefreshRunnable()
focal_class.full_signature: private Runnable newRefreshRunnable()
focal_class.identifier: newRefreshRunnable
focal_class.modifiers: private
focal_class.parameters: ()
focal_class.return: Runnable
focal_class.signature: Runnable newRefreshRunnable()
focal_class.class_method_signature: KeysDownloader.validate(String url)
focal_class.full_signature: private static void validate(String url)
focal_class.identifier: validate
focal_class.modifiers: private static
focal_class.parameters: (String url)
focal_class.return: void
focal_class.signature: void validate(String url)
focal_method.body: public String download() throws IOException {
      synchronized (instanceStateLock) {
        // Checking and using the cache if required.
        if (hasNonExpiredDataCached()) {
          // Proactively triggering a refresh if we are close to the cache expiration.
          if (shouldProactivelyRefreshDataInBackground()) {
            refreshInBackground();
          }
          return cachedData;
        }
      }
  
      // Acquiring the fetch lock so we don't have multiple threads trying to fetch from the
      // server at the same time.
      synchronized (fetchDataLock) {
        // It is possible that some other thread performed the fetch already and we don't need
        // to fetch anymore, so double checking a fetch is still required.
        synchronized (instanceStateLock) {
          if (hasNonExpiredDataCached()) {
            return cachedData;
          }
        }
        // No other thread fetched, so it is up to this thread to fetch.
        return fetchAndCacheData();
      }
    }
focal_method.class_method_signature: KeysDownloader.download()
focal_method.full_signature: public String download()
focal_method.identifier: download
focal_method.invocations: hasNonExpiredDataCached shouldProactivelyRefreshDataInBackground refreshInBackground hasNonExpiredDataCached fetchAndCacheData
focal_method.modifiers: public
focal_method.parameters: ()
focal_method.return: String
focal_method.signature: String download()