package com.yammer.dropwizard.auth;

import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.util.concurrent.ExecutionException;

public class CachingAuthenticator<C, P> implements Authenticator<C, P> {
    private final Authenticator<C, P> underlying;
    private final LoadingCache<C, Optional<P>> cache;

    public CachingAuthenticator(Authenticator<C, P> authenticator,
                                CacheBuilder<Object, Object> builder) {
        this.underlying = authenticator;
        this.cache = builder.build(new CacheLoader<C, Optional<P>> () {
            @Override
            public Optional<P> load(C key) throws Exception {
                return underlying.authenticate(key);
            }
        });
    }

    @Override
    public Optional<P> authenticate(C credentials) throws AuthenticationException {
        try {
            return cache.get(credentials);
        } catch (ExecutionException e) {
            throw new AuthenticationException(e);
        }
    }
}

@@ -327,16 +327,273 @@
 C, P%3E %7B%0A
+    public static %3CC, P%3E Authenticator%3CC, P%3E wrap(Authenticator%3CC, P%3E authenticator,%0A                                                  CacheBuilder%3CObject, Object%3E builder) %7B%0A        return new CachingAuthenticator%3CC, P%3E(authenticator, builder);%0A    %7D%0A    %0A
     priv
@@ -634,16 +634,16 @@
 rlying;%0A
-
     priv
@@ -694,21 +694,22 @@
 ;%0A%0A    p
-ublic
+rivate
  Caching

Use static factory methods for CachingAuthenticator.