Java tutorial
/** * Copyright 2012 Subho Ghosh (subho.ghosh at outlook dot com) * * 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. * * @filename EntityHelper.java * @created Sep 15, 2012 * @author subhagho * */ package com.sqewd.open.dal.core.persistence.db; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Stack; import org.apache.commons.beanutils.MethodUtils; import org.apache.commons.beanutils.PropertyUtils; import com.sqewd.open.dal.api.persistence.AbstractEntity; import com.sqewd.open.dal.api.persistence.EnumPrimitives; import com.sqewd.open.dal.api.persistence.EnumRefereceType; import com.sqewd.open.dal.api.persistence.ReflectionUtils; import com.sqewd.open.dal.api.persistence.StructAttributeReflect; import com.sqewd.open.dal.api.persistence.StructEntityReflect; import com.sqewd.open.dal.api.utils.KeyValuePair; /** * TODO: <comment> * * @author subhagho * */ public class EntityHelper { public static void setEntity(final StructEntityReflect enref, final HashMap<String, AbstractEntity> entities, final ResultSet rs) throws Exception { Class<?> type = Class.forName(enref.Class); Object obj = type.newInstance(); if (!(obj instanceof AbstractEntity)) throw new Exception("Unsupported Entity type [" + type.getCanonicalName() + "]"); AbstractEntity entity = (AbstractEntity) obj; AbstractJoinGraph gr = AbstractJoinGraph.lookup(type); for (StructAttributeReflect attr : enref.Attributes) { Stack<KeyValuePair<Class<?>>> path = new Stack<KeyValuePair<Class<?>>>(); Class<?> at = attr.Field.getType(); KeyValuePair<Class<?>> ak = new KeyValuePair<Class<?>>(); ak.setValue(entity.getClass()); ak.setKey(attr.Column); path.push(ak); if (attr.Reference == null || attr.Reference.Type != EnumRefereceType.One2Many) { setColumnValue(rs, attr, entity, gr, path); } else if (attr.Reference != null) { // Object ao = createListInstance(entity, attr); Class<?> rt = Class.forName(attr.Reference.Class); Object ro = rt.newInstance(); if (!(ro instanceof AbstractEntity)) throw new Exception( "Reference [" + attr.Column + "] is of invalid type. [" + at.getCanonicalName() + "] does not extend from [" + AbstractEntity.class.getCanonicalName() + "]"); AbstractEntity ae = (AbstractEntity) getColumnValue(rs, attr, entity, gr, path); addListValue(ae, entity, attr); } } String key = entity.getEntityKey(); if (!entities.containsKey(key)) { entities.put(entity.getEntityKey(), entity); } else { AbstractEntity target = entities.get(key); for (StructAttributeReflect attr : enref.Attributes) { if (attr.Reference.Type == EnumRefereceType.One2Many) { copyToList(entity, target, attr); } } } } public static <T extends AbstractEntity> void copyToList(final T source, final T dest, final StructAttributeReflect attr) throws Exception { Object so = PropertyUtils.getSimpleProperty(source, attr.Field.getName()); Object to = PropertyUtils.getSimpleProperty(dest, attr.Field.getName()); if (so == null) return; if (to == null) throw new Exception("Source List has not been intiialized for Field [" + attr.Column + "]"); if (!(so instanceof List<?>)) throw new Exception("Source element [" + attr.Column + "] is not a List"); if (!(to instanceof List<?>)) throw new Exception("Target element [" + attr.Column + "] is not a List"); MethodUtils.invokeMethod(to, "addAll", new Object[] { so }); } public static <T extends AbstractEntity> Object createListInstance(final AbstractEntity entity, final StructAttributeReflect attr) throws Exception { Object vo = PropertyUtils.getSimpleProperty(entity, attr.Field.getName()); if (vo == null) { vo = new ArrayList<T>(); PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), vo); } return vo; } public static <T extends AbstractEntity> void addListValue(final AbstractEntity entity, final AbstractEntity parent, final StructAttributeReflect attr) throws Exception { Object vo = createListInstance(parent, attr); MethodUtils.invokeMethod(vo, "add", new Object[] { entity }); } public static void setEntity(final AbstractEntity entity, final ResultSet rs, final AbstractJoinGraph gr, final Stack<KeyValuePair<Class<?>>> path) throws Exception { StructEntityReflect enref = ReflectionUtils.get().getEntityMetadata(entity.getClass()); for (StructAttributeReflect attr : enref.Attributes) { setColumnValue(rs, attr, entity, gr, path); } } @SuppressWarnings({ "unchecked", "rawtypes" }) public static void setColumnValue(final ResultSet rs, final StructAttributeReflect attr, final AbstractEntity entity, final AbstractJoinGraph gr, final Stack<KeyValuePair<Class<?>>> path) throws Exception { KeyValuePair<String> alias = gr.getAliasFor(path, attr.Column, 0); String tabprefix = alias.getKey(); if (EnumPrimitives.isPrimitiveType(attr.Field.getType())) { EnumPrimitives prim = EnumPrimitives.type(attr.Field.getType()); switch (prim) { case ECharacter: String sv = rs.getString(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), sv.charAt(0)); } break; case EShort: short shv = rs.getShort(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), shv); } break; case EInteger: int iv = rs.getInt(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), iv); } break; case ELong: long lv = rs.getLong(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), lv); } break; case EFloat: float fv = rs.getFloat(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), fv); } break; case EDouble: double dv = rs.getDouble(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), dv); } break; default: throw new Exception("Unsupported Data type [" + prim.name() + "]"); } } else if (attr.Convertor != null) { String value = rs.getString(tabprefix + "." + attr.Column); if (!rs.wasNull()) { attr.Convertor.load(entity, attr.Column, value); } } else if (attr.Field.getType().equals(String.class)) { String value = rs.getString(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), value); } } else if (attr.Field.getType().equals(Date.class)) { long value = rs.getLong(tabprefix + "." + attr.Column); if (!rs.wasNull()) { Date dt = new Date(value); PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), dt); } } else if (attr.Field.getType().isEnum()) { String value = rs.getString(tabprefix + "." + attr.Column); if (!rs.wasNull()) { Class ecls = attr.Field.getType(); Object evalue = Enum.valueOf(ecls, value); PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), evalue); } } else if (attr.Reference != null) { Class<?> rt = Class.forName(attr.Reference.Class); Object obj = rt.newInstance(); if (!(obj instanceof AbstractEntity)) throw new Exception("Unsupported Entity type [" + rt.getCanonicalName() + "]"); AbstractEntity rentity = (AbstractEntity) obj; if (path.size() > 0) { path.peek().setKey(attr.Column); } KeyValuePair<Class<?>> cls = new KeyValuePair<Class<?>>(); cls.setValue(rentity.getClass()); path.push(cls); setEntity(rentity, rs, gr, path); PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), rentity); path.pop(); } } @SuppressWarnings({ "rawtypes", "unchecked" }) public static Object getColumnValue(final ResultSet rs, final StructAttributeReflect attr, final AbstractEntity entity, final AbstractJoinGraph gr, final Stack<KeyValuePair<Class<?>>> path) throws Exception { Object value = null; KeyValuePair<String> alias = gr.getAliasFor(path, attr.Column, 0); String tabprefix = alias.getKey(); if (EnumPrimitives.isPrimitiveType(attr.Field.getType())) { EnumPrimitives prim = EnumPrimitives.type(attr.Field.getType()); switch (prim) { case ECharacter: String sv = rs.getString(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), sv.charAt(0)); } break; case EShort: short shv = rs.getShort(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), shv); } break; case EInteger: int iv = rs.getInt(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), iv); } break; case ELong: long lv = rs.getLong(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), lv); } break; case EFloat: float fv = rs.getFloat(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), fv); } break; case EDouble: double dv = rs.getDouble(tabprefix + "." + attr.Column); if (!rs.wasNull()) { PropertyUtils.setSimpleProperty(entity, attr.Field.getName(), dv); } break; default: throw new Exception("Unsupported Data type [" + prim.name() + "]"); } } else if (attr.Convertor != null) { // TODO : Not supported at this time. value = rs.getString(tabprefix + "." + attr.Column); } else if (attr.Field.getType().equals(String.class)) { value = rs.getString(tabprefix + "." + attr.Column); if (rs.wasNull()) { value = null; } } else if (attr.Field.getType().equals(Date.class)) { long lvalue = rs.getLong(tabprefix + "." + attr.Column); if (!rs.wasNull()) { Date dt = new Date(lvalue); value = dt; } } else if (attr.Field.getType().isEnum()) { String svalue = rs.getString(tabprefix + "." + attr.Column); if (!rs.wasNull()) { Class ecls = attr.Field.getType(); value = Enum.valueOf(ecls, svalue); } } else if (attr.Reference != null) { Class<?> rt = Class.forName(attr.Reference.Class); Object obj = rt.newInstance(); if (!(obj instanceof AbstractEntity)) throw new Exception("Unsupported Entity type [" + rt.getCanonicalName() + "]"); AbstractEntity rentity = (AbstractEntity) obj; if (path.size() > 0) { path.peek().setKey(attr.Column); } KeyValuePair<Class<?>> cls = new KeyValuePair<Class<?>>(); cls.setValue(rentity.getClass()); path.push(cls); setEntity(rentity, rs, gr, path); value = rentity; path.pop(); } return value; } }