001: /*
002: * JFox - The most lightweight Java EE Application Server!
003: * more details please visit http://www.huihoo.org/jfox or http://www.jfox.org.cn.
004: *
005: * JFox is licenced and re-distributable under GNU LGPL.
006: */
007: package org.jfox.entity;
008:
009: import java.lang.reflect.Field;
010: import java.util.ArrayList;
011: import java.util.Collection;
012: import java.util.HashMap;
013: import java.util.List;
014: import java.util.Map;
015: import javax.persistence.Column;
016: import javax.persistence.PersistenceException;
017:
018: import org.jfox.entity.annotation.MappingColumn;
019: import org.jfox.entity.annotation.ParameterMap;
020: import org.jfox.util.AnnotationUtils;
021: import org.jfox.util.ClassUtils;
022:
023: /**
024: * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
025: */
026: public class EntityFactory {
027: /**
028: * ä¿?å˜ä¸€ä¸ª Result Class çš„ column name=>column entry 的对应关系
029: * result class => {column name=> column entry}
030: */
031: protected static Map<Class<?>, Map<String, ColumnEntry>> resultClass2ColumnsMap = new HashMap<Class<?>, Map<String, ColumnEntry>>();
032:
033: static void introspectResultClass(Class<?> resultClass) {
034: if (ClassUtils.isPrimitiveClass(resultClass)) {
035: return;
036: } else if (MappedEntity.class.isAssignableFrom(resultClass)) {
037: return;
038: } else if (String.class.equals(resultClass)
039: || ClassUtils.isPrimitiveClass(resultClass)
040: || ClassUtils.isPrimitiveWrapperClass(resultClass)) {
041: return;
042: }
043:
044: if (resultClass.isInterface()) {
045: throw new PersistenceException(
046: "Not supported result class: "
047: + resultClass.getName()
048: + ", only support primitive class, MappedEntity, and @Entity Class.");
049: }
050:
051: if (resultClass2ColumnsMap.containsKey(resultClass)) {
052: return;
053: }
054: Map<String, ColumnEntry> columnMap = new HashMap<String, ColumnEntry>();
055: Field[] columnFields = AnnotationUtils.getAnnotatedFields(
056: resultClass, Column.class);
057: for (Field columnField : columnFields) {
058: columnField.setAccessible(true);
059: Column column = columnField.getAnnotation(Column.class);
060: ColumnEntry columnEntry = new ColumnEntry();
061: String columnName = column.name();
062: if (columnName.equals("")) {
063: columnName = columnField.getName().toUpperCase();
064: }
065: columnEntry.name = columnName;
066: columnEntry.field = columnField;
067: columnMap.put(column.name(), columnEntry);
068: }
069:
070: Field[] mappingColumnFields = AnnotationUtils
071: .getAnnotatedFields(resultClass, MappingColumn.class);
072: for (Field mappingColumnField : mappingColumnFields) {
073: MappingColumn mappingColumn = mappingColumnField
074: .getAnnotation(MappingColumn.class);
075: MappedColumnEntry mcEntry = new MappedColumnEntry();
076: mcEntry.name = mappingColumnField.getName().toUpperCase();
077: mcEntry.namedQuery = mappingColumn.namedQuery();
078: mcEntry.field = mappingColumnField;
079: mcEntry.params = mappingColumn.params();
080: columnMap.put(mcEntry.name, mcEntry);
081: }
082:
083: resultClass2ColumnsMap.put(resultClass, columnMap);
084: }
085:
086: public static <T> T newEntityObject(Class<T> resultClass) {
087: return newEntityObject(resultClass,
088: new HashMap<String, Object>(0));
089: }
090:
091: public static <T> T newEntityObject(Class<T> resultClass,
092: Map<String, Object> resultMap) {
093: if (resultClass.equals(MappedEntity.class)) {
094: return (T) MappedEntity.newMappedEntity(resultMap);
095: } else {
096: // 从 SQLTemplate ä¸èŽ·å¾— resultClass 的对应信æ?¯ï¼Œç„¶å?ŽField.set
097: try {
098: T entity = resultClass.newInstance();
099: for (Map.Entry<String, Object> entry : resultMap
100: .entrySet()) {
101: String columnName = entry.getKey();
102: ColumnEntry columnEntry = getColumnEntry(
103: resultClass, columnName);
104: if (columnEntry != null) {
105: columnEntry.field.set(entity, entry.getValue());
106: }
107: }
108: return entity;
109: } catch (Exception e) {
110: throw new PersistenceException(
111: "Create Entity for Class: "
112: + resultClass.getName() + " failed.", e);
113: }
114: }
115: }
116:
117: public static void appendMappedColumn(Object entity,
118: Map<String, Object> mappedColumnResultMap) {
119: // æ·»åŠ MapColumn到EntityObject
120: if (entity.getClass().equals(MappedEntity.class)) {
121: for (Map.Entry<String, Object> entry : mappedColumnResultMap
122: .entrySet()) {
123: ((MappedEntity) entity).setColumnValue(entry.getKey(),
124: entry.getValue());
125: }
126: } else {
127: try {
128: for (Map.Entry<String, Object> entry : mappedColumnResultMap
129: .entrySet()) {
130: String columnName = entry.getKey();
131: ColumnEntry columnEntry = getColumnEntry(entity
132: .getClass(), columnName);
133: if (columnEntry != null) {
134: columnEntry.field.setAccessible(true);
135: columnEntry.field.set(entity, entry.getValue());
136: }
137: }
138: } catch (Exception e) {
139: throw new PersistenceException(
140: "Append Entity MappedColumn for Class: "
141: + entity.getClass().getName()
142: + " failed.", e);
143: }
144: }
145: }
146:
147: public static Collection<MappedColumnEntry> getMappedColumnEntries(
148: Class<?> resultClass) {
149: List<MappedColumnEntry> mappedColumnEntries = new ArrayList<MappedColumnEntry>();
150: Map<String, ColumnEntry> entries = resultClass2ColumnsMap
151: .get(resultClass);
152: if (entries != null && !entries.isEmpty()) {
153: for (EntityFactory.ColumnEntry entry : resultClass2ColumnsMap
154: .get(resultClass).values()) {
155: if (entry instanceof EntityFactory.MappedColumnEntry) {
156: mappedColumnEntries
157: .add((EntityFactory.MappedColumnEntry) entry);
158: }
159: }
160: }
161: return mappedColumnEntries;
162: }
163:
164: public static ColumnEntry getColumnEntry(Class<?> resultClass,
165: String columnName) {
166: return resultClass2ColumnsMap.get(resultClass).get(columnName);
167: }
168:
169: // @Column
170: public static class ColumnEntry {
171: String name;
172: Field field;
173: }
174:
175: // @MappedColumn
176: public static class MappedColumnEntry extends ColumnEntry {
177: String namedQuery;
178: ParameterMap[] params;
179: }
180: }
|