001: /*
002: * Copyright 2006 Davide Deidda
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: /*
018: * PersistentField.java
019: *
020: * Created on 4 ottobre 2003, 15.13
021: */
022: package it.biobytes.ammentos;
023:
024: import java.sql.*;
025: import java.util.logging.*;
026:
027: import it.biobytes.ammentos.fieldtypes.*;
028: import java.math.BigDecimal;
029:
030: /**
031: * Represents an iformation field of a persistent object
032: * @author davide
033: */
034: public class Field implements Comparable {
035:
036: private String m_name;
037: private String m_description;
038: private FieldType m_dataType;
039: private boolean m_visible;
040: private boolean m_external; // Externally loaded
041: private boolean m_dynamic; // Valued at runtime, not persistent
042: private boolean m_automatic; // Automatically generated
043: private boolean m_useCache;
044: private AutomaticType m_automatic_type; // Type of automatic assignment
045: protected int position;
046: private Class m_mappedClass; // Mapped class
047: private java.lang.reflect.Field m_classField; // Class field
048: private String m_size; // Sql definition's size
049: private Logger m_logger = Logger.getLogger("ammentos");
050:
051: /** Creates a new instance of PersistentField */
052: public Field(String name, String description, FieldType type,
053: java.lang.reflect.Field classMember) {
054: m_name = name;
055: m_description = description;
056: m_dataType = type;
057: m_visible = true;
058: m_classField = classMember;
059: if (m_classField != null) {
060: // Ensures class field is accessible
061: m_classField.setAccessible(true);
062: m_mappedClass = m_classField.getType();
063: }
064: }
065:
066: /**
067: * Sets the field to be external (f.e. from a different table) or
068: * not. An external field of a persistent object will not be
069: * updatable into the DATABASE. By default a field is not external.
070: */
071: public void setExternal(boolean isExternallyManaged) {
072: m_external = isExternallyManaged;
073: }
074:
075: /**
076: * Indicates if this field is external.
077: * @see com.biobytes.sql.PersistentField.setExternallyManaged()
078: */
079: public boolean isExternal() {
080: return m_external;
081: }
082:
083: /**
084: * Sets the field to be automatic or not. An automatic field is a field which
085: * values are automatically generated from the FRAMEWORK (like a sequence in a
086: * DATABASE). Automatic field values are generated the first time a
087: * SqlPersistentObject is saved on the DATABASE and once created are not updatable.
088: * An automatic field can be used as primary key for a SqlPersistentObject because
089: * its value is guarantee to be unique.
090: * By default a field is not automatic.
091: *
092: * @param isAutomatic
093: */
094: public void setAutomatic(boolean isAutomatic) {
095: m_automatic = isAutomatic;
096: }
097:
098: /**
099: * Indicates if this field is automatic
100: *
101: * @return
102: */
103: public boolean isAutomatic() {
104: return m_automatic;
105: }
106:
107: public void setVisible(boolean visible) {
108: m_visible = visible;
109: }
110:
111: public boolean isVisible() {
112: return m_visible;
113: }
114:
115: public String getName() {
116: return m_name;
117: }
118:
119: public void setName(String name) {
120: m_name = name;
121: }
122:
123: public String getDescription() {
124: return m_description;
125: }
126:
127: public FieldType getType() {
128: return m_dataType;
129: }
130:
131: public int hashCode() {
132: return m_name.hashCode();
133: }
134:
135: public boolean equals(Object obj) {
136: boolean res = false;
137: if (obj != null) {
138: res = (hashCode() == obj.hashCode());
139: }
140: return res;
141: }
142:
143: public String formatValue(Object value) {
144: return m_dataType.formatValue(value);
145: }
146:
147: public Object parseValue(String str) throws PersistenceException {
148: return m_dataType.parseValue(str);
149: }
150:
151: public int compareTo(Object o) {
152: int res = 0;
153: try {
154: Field otherField = (Field) o;
155: res = (new Integer(position).compareTo(new Integer(
156: otherField.position)));
157: } catch (Exception e) {
158: }
159: return res;
160:
161: }
162:
163: public String toString() {
164: return m_description;
165: }
166:
167: /**
168: * Indicates if this field is calculated at runtime. A dynamic field is never
169: * loaded nor saved on the DATABASE.
170: * @return
171: */
172: public boolean isDynamic() {
173: return m_dynamic;
174: }
175:
176: /**
177: * Sets this field to be dynamically calculated or not.
178: * @param b
179: */
180: public void setDynamic(boolean b) {
181: m_dynamic = b;
182: }
183:
184: public Object loadValue(ResultSet rs) throws SQLException {
185: return m_dataType.loadValue(rs, this );
186: }
187:
188: public Object loadValue(String str) throws PersistenceException {
189: return m_dataType.parseValue(str);
190: }
191:
192: public void setParamValue(Object fieldValue,
193: PreparedStatement pstmt, int paramIndex)
194: throws SQLException {
195: // Managing null values
196: if (fieldValue == null) {
197: if (m_dataType == null) {
198: pstmt.setObject(paramIndex, null);
199: } else {
200: Class fieldType = this .m_dataType.getMappedClass();
201:
202: if (fieldType == String.class) {
203: pstmt.setString(paramIndex, null);
204: } else if (fieldType == Integer.class
205: || fieldType == Long.class
206: || fieldType == Double.class
207: || fieldType == BigDecimal.class
208: || fieldType == double.class
209: || fieldType == long.class
210: || fieldType == int.class
211: || fieldType == float.class) {
212: pstmt.setBigDecimal(paramIndex, null);
213: } else if (fieldType == Date.class) {
214: pstmt.setDate(paramIndex, null);
215: } else {
216: pstmt.setObject(paramIndex, null);
217: }
218: }
219:
220: } else {
221: m_dataType.setParamValue(fieldValue, pstmt, paramIndex);
222: }
223: }
224:
225: /**
226: * Generates an automatic value for this field in according with the field
227: * type.
228: *
229: * @return the generated value. <b>Cannot be null.</b>
230: * @throws SQLException If the field is not automatic or its type cannot be
231: * automatized.
232: */
233: public Object generateValue() throws PersistenceException {
234:
235: if (!m_automatic) {
236: throw new PersistenceException(
237: "Unable to generate automatic value for the field "
238: + m_name + " of type "
239: + m_dataType.getClass().getName());
240: }
241: return m_dataType.generateValue();
242: }
243:
244: public Object[] getPossibleValues() {
245: return m_dataType.getPossibleValues();
246: }
247:
248: public Class getMappedClass() {
249: Class res = (m_mappedClass != null) ? m_mappedClass : getType()
250: .getMappedClass();
251: // If the mapped class is Object the more specific class is obtained
252: if (res == Object.class) {
253: res = m_classField.getDeclaringClass();
254: m_mappedClass = res;
255: }
256: return res;
257: }
258:
259: /**
260: * Sets the value of this field for the object obj to the provided value
261: */
262: public void set(Object obj, Object value)
263: throws PersistenceException {
264: try {
265: m_classField.set(obj, value);
266: } catch (Exception e) {
267: m_logger.warning("Error assigning value " + value
268: + " to field " + getName());
269: m_logger.warning("AnnotatedEntity: " + e.getMessage());
270: //e.printStackTrace();
271: throw new PersistenceException(e);
272: }
273: }
274:
275: public Object get(Object obj) {
276: Object res = null;
277: try {
278: res = m_classField.get(obj);
279: } catch (Exception e) {
280: m_logger.warning("AnnotatedEntity: " + e.getMessage());
281: e.printStackTrace();
282: }
283: return res;
284: }
285:
286: public AutomaticType getAutomaticType() {
287: return m_automatic_type;
288: }
289:
290: public void setAutomaticType(AutomaticType automaticType) {
291: this .m_automatic_type = automaticType;
292: }
293:
294: public void setUseCache(boolean useCache) {
295: m_useCache = useCache;
296: }
297:
298: public boolean isUseCache() {
299: return m_useCache;
300: }
301:
302: public String getSize() {
303: return m_size;
304: }
305:
306: public void setSize(String size) {
307: m_size = size;
308: }
309: }
|