com.khubla.cbean.CBean.java Source code

Java tutorial

Introduction

Here is the source code for com.khubla.cbean.CBean.java

Source

/*
 * cBean Copyright 2016, Tom Everett <tom@khubla.com>
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.khubla.cbean;

import java.util.UUID;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.khubla.cbean.annotation.Entity;
import com.khubla.cbean.kvservice.KVService;
import com.khubla.cbean.serializer.Serializer;
import com.khubla.cbean.serializer.impl.DefaultSerializer;

/**
 * CBean
 *
 * @author tom
 */
public class CBean<T> {
    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(CBean.class);

    /**
     * check if a class is an entity
     */
    public static boolean isEntity(Class<?> clazz) throws CBeanException {
        try {
            final Entity entity = clazz.getAnnotation(Entity.class);
            if (null != entity) {
                return true;
            }
            return false;
        } catch (final Exception e) {
            throw new CBeanException(e);
        }
    }

    /**
     * CBeanConfiguration
     */
    private final KVService kvService;
    /**
     * persister
     */
    private final Serializer serializer;
    /**
     * type
     */
    private final CBeanType cBeanType;
    /**
     * root key
     */
    private final CBeanKey rootKey;

    /**
     * ctor
     */
    public CBean(KVService kvService, Class<?> clazz, CBeanKey schemaRoot) throws CBeanException {
        serializer = new DefaultSerializer(clazz);
        cBeanType = CBeanType.getCBeanType(clazz);
        this.kvService = kvService;
        this.rootKey = this.buildRootKey(schemaRoot);
    }

    /**
     * build the root key
     */
    private CBeanKey buildRootKey(CBeanKey schemaRoot) throws CBeanException {
        /*
         * empty key
         */
        CBeanKey ret = new CBeanKey(CBeanKey.SLASH);
        /*
         * add schema
         */
        if (null != schemaRoot) {
            if (true == schemaRoot.isAbsolute()) {
                throw new CBeanException("Schema root cannot be absolute");
            }
            if (false == schemaRoot.isDirectory()) {
                throw new CBeanException("Schema root must be a directory");
            }
            ret = ret.append(schemaRoot);
        }
        /*
         * add type root
         */
        final String path = this.getcBeanType().getEntity().path();
        if ((null != path) && (path.length() > 0)) {
            final CBeanKey pathKey = new CBeanKey(path);
            if (false == pathKey.isDirectory()) {
                throw new CBeanException("Entity path must be a directory");
            }
            ret = ret.append(pathKey);
        }
        /*
         * now add the type
         */
        ret = ret.append(new CBeanKey(cBeanType.getClazz().getCanonicalName() + CBeanKey.SLASH));
        /*
         * done
         */
        return ret;
    }

    public void delete(CBeanKey key) throws CBeanException {
        try {
            final long now = System.currentTimeMillis();
            /*
             * first use the serializer, in case there are contained objects to delete
             */
            final Object o = load(key);
            serializer.delete(o);
            /*
             * all contained objects have been deleted, if appropriate. delete this object.
             */
            final CBeanKey k = getCBeanKeyByKey(key);
            if (null != k) {
                kvService.delete(k);
                logger.info("Deleted object '" + k.getKey() + "' in '"
                        + Long.toString(System.currentTimeMillis() - now) + "' ms");
            }
        } catch (final Exception e) {
            throw new CBeanException(e);
        }
    }

    /**
     * get CBeanKey for T
     */
    private CBeanKey getCBeanKeyByInstance(T t) throws CBeanException {
        try {
            final CBeanKey key = getKey(t);
            if (key != null) {
                return getCBeanKeyByKey(key);
            }
            return null;
        } catch (final Exception e) {
            throw new CBeanException(e);
        }
    }

    /**
     * get CBeanKey for key
     */
    private CBeanKey getCBeanKeyByKey(CBeanKey key) throws CBeanException {
        return rootKey.append(key);
    }

    public CBeanType getcBeanType() {
        return cBeanType;
    }

    /**
     * get the id value
     */
    public String getId(T t) throws CBeanException {
        try {
            return BeanUtils.getProperty(t, cBeanType.getIdField().getName());
        } catch (final Exception e) {
            throw new CBeanException(e);
        }
    }

    /**
     * get Key for T
     */
    private CBeanKey getKey(T t) throws CBeanException {
        try {
            if (cBeanType.getIdField().getType() == UUID.class) {
                final UUID keyUUID = (UUID) PropertyUtils.getProperty(t, cBeanType.getIdField().getName());
                if (null == keyUUID) {
                    final UUID uuid = UUID.randomUUID();
                    BeanUtils.setProperty(t, cBeanType.getIdField().getName(), uuid);
                    return new CBeanKey(uuid.toString());
                } else {
                    return new CBeanKey(keyUUID);
                }
            } else if (cBeanType.getIdField().getType() == String.class) {
                final String keyString = BeanUtils.getProperty(t, cBeanType.getIdField().getName());
                if (null == keyString) {
                    final String uuid = UUID.randomUUID().toString();
                    BeanUtils.setProperty(t, cBeanType.getIdField().getName(), uuid);
                    return new CBeanKey(uuid.toString());
                } else {
                    return new CBeanKey(keyString);
                }
            } else {
                return null;
            }
        } catch (final Exception e) {
            throw new CBeanException(e);
        }
    }

    public CBeanKey getRootKey() {
        return rootKey;
    }

    public String[] list() throws CBeanException {
        try {
            final long now = System.currentTimeMillis();
            final String[] ret = kvService.list(rootKey);
            logger.info("Listed '" + Integer.toString(ret == null ? 0 : ret.length) + "' keys in '"
                    + Long.toString(System.currentTimeMillis() - now) + "' ms");
            return ret;
        } catch (final Exception e) {
            throw new CBeanException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public T load(CBeanKey key) throws CBeanException {
        try {
            final long now = System.currentTimeMillis();
            final CBeanKey k = getCBeanKeyByKey(key);
            if (null != k) {
                final byte[] bytes = kvService.load(k);
                if (null != bytes) {
                    final String json = new String(bytes);
                    logger.info("Loaded object '" + k.getKey() + "' in '"
                            + Long.toString(System.currentTimeMillis() - now) + "' ms");
                    return (T) serializer.deserialize(json);
                }
            }
            logger.info("Unable to load object '" + k.getKey() + "'");
            return null;
        } catch (final Exception e) {
            throw new CBeanException(e);
        }
    }

    public void save(T t) throws CBeanException {
        try {
            final long now = System.currentTimeMillis();
            final CBeanKey k = getCBeanKeyByInstance(t);
            if (null != k) {
                final String json = serializer.serialize(t);
                kvService.save(k, json.getBytes());
                logger.info("Saved object '" + k.getKey() + "' in '"
                        + Long.toString(System.currentTimeMillis() - now) + "' ms");
            }
        } catch (final Exception e) {
            logger.info("Unable to save object '" + t.toString() + "'");
            throw new CBeanException(e);
        }
    }
}