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.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.UUID; import org.apache.commons.beanutils.PropertyUtilsBean; import com.khubla.cbean.annotation.Entity; import com.khubla.cbean.annotation.Id; import com.khubla.cbean.annotation.Property; import com.khubla.cbean.annotation.Version; /** * A CBean type contains the metadata for a cBean annotated POJO. Metadata is cached by the class to avoid having to generate it more than once per type. * * @author tom */ public class CBeanType { /** * CBean types */ private static final HashMap<Class<?>, CBeanType> types = new HashMap<Class<?>, CBeanType>(); /** * static getter for CBeanTypes */ public static CBeanType getCBeanType(Class<?> clazz) throws CBeanException { CBeanType cBeanType = types.get(clazz); if (null == cBeanType) { cBeanType = new CBeanType(clazz); types.put(clazz, cBeanType); } return cBeanType; } /** * getter map */ private final HashMap<String, String> getterMap = new HashMap<String, String>(); /** * setter map */ private final HashMap<String, String> setterMap = new HashMap<String, String>(); /** * clazz */ private final Class<?> clazz; /** * id field name */ private final Field idField; /** * version field name */ private final Field versionField; /** * entity */ private final Entity entity; /** * persistable fields */ private final Field[] persistableFields; /** * Id annotation */ private final Id id; /** * lazy load fields */ private final Field[] lazyLoadFields; /** * ctor */ public CBeanType(Class<?> clazz) throws CBeanException { this.clazz = clazz; idField = findIdField(); versionField = findVersionField(); id = findId(); persistableFields = findPersistableFields(); lazyLoadFields = findLazyLoadFields(); if (null == idField) { throw new CBeanException("Unable to find Id field"); } if ((false == (idField.getType() == String.class)) && (false == (idField.getType() == UUID.class))) { throw new CBeanException("@Id field must be a String or UUID"); } entity = getEntity(); if (null == entity) { throw new CBeanException("Unable to find Entity field"); } if ((null != versionField) && (versionField.getType() != Integer.class)) { throw new CBeanException("@Version field must be an Integer"); } buildGetterSetterMap(); } /** * build the map of getters and setters to properties */ private void buildGetterSetterMap() { final PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean(); final PropertyDescriptor[] propertyDescriptors = propertyUtilsBean.getPropertyDescriptors(clazz); if (null != propertyDescriptors) { for (int i = 0; i < propertyDescriptors.length; i++) { final PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; if (null != propertyDescriptor.getReadMethod()) { getterMap.put(propertyDescriptor.getReadMethod().getName(), propertyDescriptor.getName()); } if (null != propertyDescriptor.getWriteMethod()) { setterMap.put(propertyDescriptor.getWriteMethod().getName(), propertyDescriptor.getName()); } } } } /** * find id field */ private Id findId() { final Field[] fields = clazz.getDeclaredFields(); if (null != fields) { for (int i = 0; i < fields.length; i++) { final Field field = fields[i]; final Id id = field.getAnnotation(Id.class); if (null != id) { return id; } } } return null; } /** * get the name of the Id field */ private Field findIdField() { final Field[] fields = clazz.getDeclaredFields(); if (null != fields) { for (int i = 0; i < fields.length; i++) { final Field field = fields[i]; final Id id = field.getAnnotation(Id.class); if (null != id) { return field; } } } return null; } private Field[] findLazyLoadFields() throws CBeanException { final List<Field> fieldList = new ArrayList<Field>(); for (int i = 0; i < persistableFields.length; i++) { final Field field = persistableFields[i]; final Property property = field.getAnnotation(Property.class); /* * check if it's a lazy load */ if (null != property) { if ((false == property.cascadeLoad()) && (true == CBean.isEntity(field.getType()))) { fieldList.add(field); } } } final Field[] ret = new Field[fieldList.size()]; fieldList.toArray(ret); return ret; } /** * find persistable fields */ private Field[] findPersistableFields() { final List<Field> fieldList = new ArrayList<Field>(); final Field[] fields = clazz.getDeclaredFields(); if (null != fields) { for (int i = 0; i < fields.length; i++) { final Field field = fields[i]; /* * find annotations */ final Property property = field.getAnnotation(Property.class); final Id id = field.getAnnotation(Id.class); final Version version = field.getAnnotation(Version.class); /* * persist? */ if ((null != id) || (null != version) || ((null != property) && (false == property.ignore()))) { fieldList.add(field); } } } final Field[] ret = new Field[fieldList.size()]; fieldList.toArray(ret); return ret; } /** * find version field */ private Field findVersionField() { final Field[] fields = clazz.getDeclaredFields(); if (null != fields) { for (int i = 0; i < fields.length; i++) { final Field field = fields[i]; final Version version = field.getAnnotation(Version.class); if (null != version) { return field; } } } return null; } public Class<?> getClazz() { return clazz; } /** * get the entity annotation */ public Entity getEntity() { return clazz.getAnnotation(Entity.class); } public Id getId() { return id; } /** * get the Id field */ public Field getIdField() { return idField; } public Field[] getLazyLoadFields() { return lazyLoadFields; } public Field[] getPersistableFields() { return persistableFields; } /** * get the property name from a getter method */ public String getterToProperty(Method method) { return getterMap.get(method.getName()); } public Field getVersionField() { return versionField; } /** * get the property name from a setter method */ public String setterToProperty(Method method) { return setterMap.get(method.getName()); } }