All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ninja.appengine.AppEngineCacheImpl Maven / Gradle / Ivy

There is a newer version: 1.9.88.1
Show newest version
package ninja.appengine;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import ninja.cache.Cache;

import org.slf4j.Logger;

import com.google.appengine.api.memcache.Expiration;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;
import com.google.inject.Singleton;

@Singleton
public class AppEngineCacheImpl implements Cache {

    private final MemcacheService memcacheService;
    private final Logger logger;

    @Inject
    public AppEngineCacheImpl(Logger logger) {
        this.memcacheService = MemcacheServiceFactory.getMemcacheService();
        
        this.logger = logger;
    }

    private void put(String key,
                     Object value,
                     int expiration,
                     MemcacheService.SetPolicy policy) {

        if (expiration == Integer.MAX_VALUE) {
            memcacheService.put(key, wrap(value), null, policy);
        } else {
            memcacheService.put(key, wrap(value),
                    Expiration.byDeltaSeconds(expiration), policy);
        }
    }

    public void add(String key, Object value, int expiration) {
        put(key, value, expiration,
                MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT);
    }

    public boolean safeAdd(String key, Object value, int expiration) {
        put(key, value, expiration,
                MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT);
        return true;
    }

    public void set(String key, Object value, int expiration) {
        put(key, value, expiration, MemcacheService.SetPolicy.SET_ALWAYS);
    }

    public boolean safeSet(String key, Object value, int expiration) {
        put(key, value, expiration, MemcacheService.SetPolicy.SET_ALWAYS);
        return true;
    }

    public void replace(String key, Object value, int expiration) {
        put(key, value, expiration,
                MemcacheService.SetPolicy.REPLACE_ONLY_IF_PRESENT);
    }

    public boolean safeReplace(String key, Object value, int expiration) {
        put(key, value, expiration,
                MemcacheService.SetPolicy.REPLACE_ONLY_IF_PRESENT);
        return true;
    }

    public Object get(String key) {
        return unwrap(memcacheService.get(key));
    }

    public Map get(String[] keys) {
        List list = Arrays.asList(keys);
        Map map = memcacheService.getAll(list);
        Map result = new HashMap();
        for (Object key : map.entrySet()) {
            result.put(key.toString(), unwrap(map.get(key)));
        }
        return map;
    }

    public long incr(String key, int by) {
        return memcacheService.increment(key, by);
    }

    public long decr(String key, int by) {
        return memcacheService.increment(key, -by);
    }

    public void clear() {
        memcacheService.clearAll();
    }

    public void delete(String key) {
        memcacheService.delete(key);
    }

    public boolean safeDelete(String key) {
        memcacheService.delete(key);
        return true;
    }

    public void stop() {
    }

    byte[] wrap(Object o) {
        if (o == null) {
            return null;
        }
        try {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bytes);
            oos.writeObject(o);
            return bytes.toByteArray();
        } catch (Exception e) {
            String ERROR_MESSAGE = "Cannot wrap a non-serializable value of type ";
            logger.error(ERROR_MESSAGE, e);
            throw new RuntimeException(ERROR_MESSAGE, e);
        }
    }

    Object unwrap(Object bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            return new ObjectInputStream(new ByteArrayInputStream(
                    (byte[]) bytes)) {

                @Override
                protected Class resolveClass(ObjectStreamClass desc)
                        throws IOException, ClassNotFoundException {
                    return Class.forName(desc.getName(), false, Thread
                            .currentThread().getContextClassLoader());
                }
            }.readObject();
        } catch (Exception e) {
            logger.error("Error while deserializing cached value", e);
            return null;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy