Java tutorial
/* * 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); } } }