com.gigaspaces.simpledao.dao.AbstractBaseDAO.java Source code

Java tutorial

Introduction

Here is the source code for com.gigaspaces.simpledao.dao.AbstractBaseDAO.java

Source

/*
 * Copyright 2010 Joseph B. Ottinger
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */

package com.gigaspaces.simpledao.dao;

import com.gigaspaces.simpledao.model.BaseEntity;
import com.google.common.collect.MapMaker;
import com.j_spaces.core.client.SQLQuery;
import net.jini.core.lease.Lease;
import org.openspaces.core.GigaSpace;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.ParameterizedType;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AbstractBaseDAO<T extends BaseEntity> implements DAO<T> {
    interface Actor<T extends BaseEntity> {
        T[] execute(SQLQuery<T> query, int count);
    }

    protected AtomicInteger reads = new AtomicInteger();
    protected AtomicInteger writes = new AtomicInteger();
    protected AtomicInteger takes = new AtomicInteger();
    protected Class<T> persistentClass;
    //protected Logger log = Logger.getLogger(this.getClass().getName());

    protected Map<String, Pair<Lock, SQLQuery<T>>> queries = new MapMaker().concurrencyLevel(32)
            .expiration(30, TimeUnit.SECONDS).makeMap();
    private Actor<T> readMultipleActor = new Actor<T>() {
        @Override
        public T[] execute(SQLQuery<T> sqlQuery, int count) {
            return getGigaspace().readMultiple(sqlQuery, count);
        }
    };
    private Actor<T> takeMultipleActor = new Actor<T>() {
        @Override
        public T[] execute(SQLQuery<T> sqlQuery, int count) {
            return getGigaspace().takeMultiple(sqlQuery, count);
        }
    };

    public GigaSpace getGigaspace() {
        return gigaspace;
    }

    public void setGigaspace(GigaSpace gigaspace) {
        this.gigaspace = gigaspace;
    }

    @Autowired
    protected GigaSpace gigaspace;

    /*protected T buildTemplate() {
    try {
        @SuppressWarnings({"UnnecessaryLocalVariable"})
        T instance = persistentClass.newInstance();
        return instance;
    } catch (InstantiationException e) {
        throw new Error(e);
    } catch (IllegalAccessException e) {
        throw new Error(e);
    }
    }
    */

    public AbstractBaseDAO() {
        //noinspection unchecked
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
    }

    protected boolean hasId(T entry) {
        return (entry.getId() != null);
    }

    @Override
    public T[] readMultiple(T template) {
        return readMultiple(template, Integer.MAX_VALUE);
    }

    @Override
    public T[] readMultiple(T template, int count) {
        reads.incrementAndGet();
        return getGigaspace().readMultiple(template, count);
    }

    @Override
    public T read(T template) {
        if (hasId(template)) {
            return readById(template.getId());
        }
        reads.incrementAndGet();
        return getGigaspace().read(template);
    }

    @Override
    public T readById(String id) {
        reads.incrementAndGet();
        return getGigaspace().readById(persistentClass, id);
    }

    @Override
    public T readByQuery(String query, Object... parameters) {
        T[] array = readMultipleByQuery(query, 1, parameters);
        if (array.length > 0) {
            return array[0];
        } else {
            return null;
        }
    }

    @Override
    public T[] readMultipleByQuery(String query, int count, Object... parameters) {
        return runQuery(query, count, parameters, readMultipleActor);
    }

    private T[] runQuery(String query, int count, Object[] parameters, Actor<T> actor) {
        if (query.trim().toLowerCase().startsWith("where")) {
            query = query.trim().substring(6);
        }
        if (!queries.containsKey(query)) {
            SQLQuery<T> queryObject = new SQLQuery<T>(persistentClass, query);
            queries.put(query, new Pair<Lock, SQLQuery<T>>(new ReentrantLock(), queryObject));
        }
        Pair<Lock, SQLQuery<T>> pair = queries.get(query);
        pair.getK().lock();
        try {
            pair.getV().setParameters(parameters);
            return actor.execute(pair.getV(), count);
        } finally {
            pair.getK().unlock();
        }
    }

    @Override
    public T[] takeMultiple(T template) {
        return takeMultiple(template, Integer.MAX_VALUE);
    }

    @Override
    public T[] takeMultiple(T template, int count) {
        takes.incrementAndGet();
        return getGigaspace().takeMultiple(template, count);
    }

    @Override
    public T take(T template) {
        takes.incrementAndGet();
        if (hasId(template)) {
            return getGigaspace().takeById(persistentClass, template.getId());
        }
        return gigaspace.take(template);
    }

    @Override
    public T takeById(String id) {
        return gigaspace.takeById(persistentClass, id);
    }

    @Override
    public T takeByQuery(String query, Object... parameters) {
        T[] array = takeMultipleByQuery(query, 1, parameters);
        if (array.length > 0) {
            return array[0];
        } else {
            return null;
        }
    }

    @Override
    public T[] takeMultipleByQuery(String query, int count, Object... parameters) {
        return runQuery(query, count, parameters, takeMultipleActor);
    }

    @Override
    public T poll(T template, long timeout) {
        takes.incrementAndGet();
        return gigaspace.take(template, timeout);
    }

    @Override
    public T peek(T template, long timeout) {
        reads.incrementAndGet();
        return gigaspace.read(template, timeout);
    }

    @Override
    public T push(T entry) {
        return push(entry, Lease.FOREVER);
    }

    @Override
    public T push(T entry, long timeout) {
        return write(entry, timeout);
    }

    @Override
    public T write(T entry) {
        return write(entry, Lease.FOREVER);
    }

    @Override
    public T write(T entry, long timeout) {
        writes.incrementAndGet();
        if (hasId(entry)) {
            gigaspace.takeById(persistentClass, entry.getId());
        } else {
            entry.setId(UUID.randomUUID().toString());
            entry.setCreateTime(System.currentTimeMillis());
        }
        entry.setUpdateTime(System.currentTimeMillis());
        gigaspace.write(entry, timeout);
        return entry;
    }

    @Override
    public T update(T entry) {
        return update(entry, Lease.FOREVER);
    }

    @Override
    public T update(T entry, long timeout) {
        if (hasId(entry)) {
            write(entry, timeout);
        } else {
            writes.incrementAndGet();
            take(entry);
            write(entry);
        }
        return entry;
    }

    @Override
    public int getReads() {
        return reads.intValue();
    }

    @Override
    public int getTakes() {
        return takes.intValue();
    }

    @Override
    public int getWrites() {
        return writes.intValue();
    }

    @Override
    public void reset() {
        reads.set(0);
        takes.set(0);
        writes.set(0);
    }
}