1 package jp.sourceforge.ea2ddl.dao.allcommon.s2dao.internal.various;
\r
3 import java.lang.reflect.Field;
\r
4 import java.lang.reflect.Modifier;
\r
5 import java.util.Collection;
\r
6 import java.util.List;
\r
7 import java.util.Map;
\r
8 import java.util.Stack;
\r
10 import org.seasar.framework.beans.BeanDesc;
\r
11 import org.seasar.framework.beans.factory.BeanDescFactory;
\r
12 import org.seasar.extension.jdbc.ValueType;
\r
13 import org.seasar.extension.jdbc.types.ValueTypes;
\r
14 import org.seasar.dao.ValueTypeFactory;
\r
15 import org.seasar.dao.util.TypeUtil;
\r
17 import jp.sourceforge.ea2ddl.dao.allcommon.cbean.ConditionBeanContext;
\r
20 * @author DBFlute(AutoGenerator)
\r
22 public class InternalProcedureMetaDataFactory {
\r
24 // ===================================================================================
\r
27 protected ValueTypeFactory valueTypeFactory;
\r
28 protected InternalFieldProcedureAnnotationReader annotationReader = new InternalFieldProcedureAnnotationReader();
\r
30 // ===================================================================================
\r
33 public InternalProcedureMetaData createProcedureMetaData(final String procedureName, final Class<?> pmbType) {
\r
34 final InternalProcedureMetaData metaData = new InternalProcedureMetaData(procedureName);
\r
35 if (pmbType == null) {
\r
38 if (!isDtoType(pmbType)) {
\r
39 throw new IllegalStateException("The pmb type was Not DTO type: " + pmbType.getName());
\r
42 final BeanDesc pmbDesc = BeanDescFactory.getBeanDesc(pmbType);
\r
45 final Stack<Class<?>> stack = new Stack<Class<?>>();
\r
46 for (Class<?> clazz = pmbType; clazz != null && clazz != Object.class; clazz = clazz.getSuperclass()) {
\r
49 for ( ; !stack.isEmpty() ;) {
\r
50 final Class<?> clazz = stack.pop();
\r
51 registerParameterType(metaData, pmbDesc, clazz.getDeclaredFields());
\r
56 protected void registerParameterType(InternalProcedureMetaData metaData, BeanDesc pmbDesc, Field[] fields) {
\r
57 for (Field field : fields) {
\r
58 if (!isInstanceField(field)) {
\r
61 final InternalProcedureParameterType ppt = getProcedureParameterType(pmbDesc, field);
\r
65 metaData.addParameterType(ppt);
\r
68 protected InternalProcedureParameterType getProcedureParameterType(final BeanDesc dtoDesc, final Field field) {
\r
69 final String procedureParameter = annotationReader.getProcedureParameter(dtoDesc, field);
\r
70 if (procedureParameter == null) {
\r
73 final String type = extractParameterType(procedureParameter);
\r
74 field.setAccessible(true);
\r
75 final InternalProcedureParameterType ppt = new InternalProcedureParameterType(field);
\r
76 if (type.equalsIgnoreCase("in")) {
\r
77 ppt.setInType(true);
\r
78 } else if (type.equalsIgnoreCase("out")) {
\r
79 ppt.setOutType(true);
\r
80 } else if (type.equalsIgnoreCase("inout")) {
\r
81 ppt.setInType(true);
\r
82 ppt.setOutType(true);
\r
83 } else if (type.equalsIgnoreCase("return")) {
\r
84 ppt.setOutType(true);
\r
85 ppt.setReturnType(true);
\r
87 String msg = "The parameter type should be 'in' or 'out' or 'inout' or 'return':";
\r
88 msg = msg + " class=" + field.getDeclaringClass().getSimpleName();
\r
89 msg = msg + " field=" + field.getName();
\r
90 msg = msg + " parameterType=" + type;
\r
91 throw new IllegalStateException(msg);
\r
93 final Integer index = extractParameterIndex(procedureParameter, field);
\r
94 ppt.setParameterIndex(index);
\r
95 final ValueType valueType = getValueType(dtoDesc, field);
\r
96 ppt.setValueType(valueType);
\r
99 protected String extractParameterType(String procedureParameter) {
\r
100 if (procedureParameter.contains(",")) {
\r
101 return procedureParameter.substring(0, procedureParameter.indexOf(",")).trim();
\r
103 return procedureParameter.trim();
\r
105 protected Integer extractParameterIndex(String procedureParameter, Field field) {
\r
106 if (procedureParameter.contains(",")) {
\r
107 String tmp = procedureParameter.substring(procedureParameter.indexOf(",") + ",".length()).trim();
\r
109 return Integer.valueOf(tmp);
\r
110 } catch (NumberFormatException e) {
\r
111 String msg = "The parameter index should be number:";
\r
112 msg = msg + " class=" + field.getDeclaringClass().getSimpleName();
\r
113 msg = msg + " field=" + field.getName();
\r
114 msg = msg + " parameterIndex=" + tmp + " procedureParameter=" + procedureParameter;
\r
115 throw new IllegalStateException(msg, e);
\r
120 protected ValueType getValueType(final BeanDesc dtoDesc, final Field field) {
\r
121 final String name = annotationReader.getValueType(dtoDesc, field);
\r
122 if (name != null) {
\r
123 return valueTypeFactory.getValueTypeByName(name);
\r
125 final Class<?> type = field.getType();
\r
126 if (List.class.isAssignableFrom(type)) {// is for out parameter cursor.
\r
127 if (ConditionBeanContext.isOracle()) {
\r
128 return ValueTypes.ORACLE_RESULT_SET;
\r
129 } else if (ConditionBeanContext.isPostgreSql()) {
\r
130 return ValueTypes.POSTGRE_RESULT_SET;
\r
132 return ValueTypes.SERIALIZABLE_BYTE_ARRAY;
\r
135 return valueTypeFactory.getValueTypeByClass(type);
\r
137 protected boolean isInstanceField(final Field field) {
\r
138 final int mod = field.getModifiers();
\r
139 return !Modifier.isStatic(mod) && !Modifier.isFinal(mod);
\r
141 protected boolean isDtoType(final Class<?> clazz) {
\r
142 return !TypeUtil.isSimpleType(clazz) && !isContainerType(clazz);
\r
144 protected boolean isContainerType(final Class<?> clazz) {
\r
145 if (clazz == null) { throw new NullPointerException("clazz"); }
\r
146 return Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz) || clazz.isArray();
\r
148 public void setValueTypeFactory(final ValueTypeFactory valueTypeFactory) {
\r
149 this.valueTypeFactory = valueTypeFactory;
\r
152 protected static class InternalFieldProcedureAnnotationReader {
\r
153 protected String PROCEDURE_PARAMETER_SUFFIX;
\r
154 protected String VALUE_TYPE_SUFFIX;
\r
155 public InternalFieldProcedureAnnotationReader() {
\r
156 PROCEDURE_PARAMETER_SUFFIX = "_PROCEDURE_PARAMETER";
\r
157 VALUE_TYPE_SUFFIX = "_VALUE_TYPE";
\r
159 public String getProcedureParameter(BeanDesc dtoDesc, Field field) {
\r
160 String fieldName = removeInstanceVariablePrefix(field.getName());// *Point
\r
161 String annotationName = fieldName + PROCEDURE_PARAMETER_SUFFIX;
\r
162 if (dtoDesc.hasField(annotationName)) {
\r
163 Field f = dtoDesc.getField(annotationName);
\r
164 return (String) getValue(f, null);
\r
169 public String getValueType(BeanDesc dtoDesc, Field field) {
\r
170 String fieldName = removeInstanceVariablePrefix(field.getName());// *Point
\r
171 String annotationName = fieldName + VALUE_TYPE_SUFFIX;
\r
172 if (dtoDesc.hasField(annotationName)) {
\r
173 Field f = dtoDesc.getField(annotationName);
\r
174 return (String) getValue(f, null);
\r
179 protected String removeInstanceVariablePrefix(String fieldName) {
\r
180 return fieldName.startsWith("_") ? fieldName.substring("_".length()) : fieldName;
\r
182 protected Object getValue(Field field, Object target) {
\r
184 return field.get(target);
\r
185 } catch (IllegalAccessException e) {
\r
186 String msg = "The getting of the field threw the exception:";
\r
187 msg = msg + " class=" + field.getDeclaringClass().getSimpleName();
\r
188 msg = msg + " field=" + field.getName();
\r
189 throw new IllegalStateException(msg, e);
\r