2 Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 package com.mysql.clusterj.core.metadata;
20 import com.mysql.clusterj.core.spi.ValueHandler;
21 import com.mysql.clusterj.core.spi.DomainTypeHandler;
22 import com.mysql.clusterj.ClusterJUserException;
23 import com.mysql.clusterj.ColumnMetadata;
24 import com.mysql.clusterj.DynamicObjectDelegate;
26 import com.mysql.clusterj.core.CacheManager;
27 import com.mysql.clusterj.core.StateManager;
28 import com.mysql.clusterj.core.StoreManager;
30 import com.mysql.clusterj.core.util.I18NHelper;
31 import com.mysql.clusterj.core.util.Logger;
32 import com.mysql.clusterj.core.util.LoggerFactoryService;
34 import java.lang.reflect.InvocationHandler;
35 import java.lang.reflect.Method;
37 import java.math.BigDecimal;
38 import java.math.BigInteger;
42 import java.sql.Timestamp;
43 import java.util.BitSet;
44 import java.util.HashMap;
47 public class InvocationHandlerImpl<T> implements InvocationHandler,
48 StateManager, ValueHandler, DynamicObjectDelegate {
50 /** My message translator */
51 static final I18NHelper local = I18NHelper.getInstance(InvocationHandlerImpl.class);
54 static final Logger logger = LoggerFactoryService.getFactory().getInstance(InvocationHandlerImpl.class);
56 /** The properties of the instance. */
57 protected Object[] properties;
59 /** The number of fields */
60 protected int numberOfFields;
62 /** The types of the properties. */
63 protected Map<String, Class<?>> typemap = new HashMap<String, Class<?>>();
65 /** The DomainTypeHandlerImpl for this class. */
66 protected DomainTypeHandlerImpl<T> domainTypeHandler;
68 /** The modifiedFields bit for each field. */
69 BitSet modifiedFields;
71 /** Has this object been modified? */
72 boolean modified = false;
74 /** The proxy object this handler handles. */
77 /** The cache manager for object modification notifications. */
78 private CacheManager objectManager;
80 /** Has this object been found in the database? */
81 private Boolean found = null;
83 public InvocationHandlerImpl(DomainTypeHandlerImpl<T> domainTypeHandler) {
84 this.domainTypeHandler = domainTypeHandler;
85 numberOfFields = domainTypeHandler.getNumberOfFields();
86 properties = new Object[numberOfFields];
87 modifiedFields = new BitSet(numberOfFields);
88 domainTypeHandler.initializeNotPersistentFields(this);
91 public void setProxy(Object proxy) {
95 public Object getProxy() {
99 public void setCacheManager(CacheManager manager) {
100 objectManager = manager;
104 public Object invoke(Object proxy, Method method, Object[] args)
106 String methodName = method.getName();
107 if (logger.isDetailEnabled()) logger.detail("invoke with Method: " + method.getName());
109 String propertyHead = methodName.substring(3,4);
110 String propertyTail = methodName.substring(4);
111 String propertyName = propertyHead.toLowerCase() + propertyTail;
113 if (methodName.startsWith("get")) {
114 if (logger.isDetailEnabled()) logger.detail("Property name: " + propertyName);
115 // get the field number from the name
116 fieldNumber = domainTypeHandler.getFieldNumber(propertyName);
117 if (logger.isDetailEnabled()) logger.detail(methodName + ": Returning field number " + fieldNumber
118 + " value: " + properties[fieldNumber]);
119 return properties[fieldNumber];
120 } else if (methodName.startsWith("set")) {
121 if (logger.isDetailEnabled()) logger.detail("Property name: " + propertyName);
122 // get the field number from the name
123 fieldNumber = domainTypeHandler.getFieldNumber(propertyName);
124 // mark the field as modified
125 if (!modified && objectManager != null) {
127 objectManager.markModified(this);
128 if (logger.isDetailEnabled()) logger.detail("modifying " + this);
130 modifiedFields.set(fieldNumber);
131 properties[fieldNumber] = args[0];
132 } else if ("toString".equals(methodName)) {
133 return(domainTypeHandler.getDomainClass().getName()
134 + pkToString(domainTypeHandler));
135 } else if ("hashCode".equals(methodName)) {
136 return(this.hashCode());
138 throw new ClusterJUserException(
139 local.message("ERR_Method_Name", methodName));
144 public void markModified(int fieldNumber) {
145 modifiedFields.set(fieldNumber);
148 public String pkToString(DomainTypeHandler<?> domainTypeHandler) {
149 StringBuffer sb = new StringBuffer(" key: [");
150 int[] keys = domainTypeHandler.getKeyFieldNumbers();
151 String separator = "";
153 sb.append(separator);
154 sb.append(properties[i]);
158 return sb.toString();
161 /** Reset the modified flags
164 public void resetModified() {
166 modifiedFields.clear();
169 public boolean isNull(int fieldNumber) {
170 return properties[fieldNumber] == null;
173 public BigInteger bigIntegerValue(int fieldNumber) {
174 return (BigInteger) properties[fieldNumber];
177 public boolean booleanValue(int fieldNumber) {
178 return (Boolean) properties[fieldNumber];
181 public boolean[] booleansValue(int fieldNumber) {
182 return (boolean[]) properties[fieldNumber];
185 public byte[] bytesValue(int fieldNumber) {
186 return (byte[]) properties[fieldNumber];
189 public byte byteValue(int fieldNumber) {
190 return (Byte) properties[fieldNumber];
193 public Byte objectByteValue(int fieldNumber) {
194 return (Byte) properties[fieldNumber];
197 public java.util.Date javaUtilDateValue(int fieldNumber) {
198 return (java.util.Date) properties[fieldNumber];
201 public java.sql.Date javaSqlDateValue(int fieldNumber) {
202 return (java.sql.Date) properties[fieldNumber];
205 public java.sql.Time javaSqlTimeValue(int fieldNumber) {
206 return (java.sql.Time) properties[fieldNumber];
209 public java.sql.Timestamp javaSqlTimestampValue(int fieldNumber) {
210 return (java.sql.Timestamp) properties[fieldNumber];
213 public BigDecimal decimalValue(int fieldNumber) {
214 return (BigDecimal) properties[fieldNumber];
217 public double doubleValue(int fieldNumber) {
218 return (Double) properties[fieldNumber];
221 public float floatValue(int fieldNumber) {
222 return (Float) properties[fieldNumber];
225 public int intValue(int fieldNumber) {
226 if (logger.isDetailEnabled()) logger.detail("intValue: Returning field number " + fieldNumber
227 + " value: " + properties[fieldNumber]);
228 return (Integer) properties[fieldNumber];
231 public Integer objectIntValue(int fieldNumber) {
232 return (Integer) properties[fieldNumber];
235 public long longValue(int fieldNumber) {
236 return (Long) properties[fieldNumber];
239 public short shortValue(int fieldNumber) {
240 return (Short) properties[fieldNumber];
243 public String stringValue(int fieldNumber) {
244 if (logger.isDetailEnabled()) logger.detail("stringValue: Returning field number " + fieldNumber
245 + " value: " + properties[fieldNumber]);
246 return (String) properties[fieldNumber];
249 public void setValue(int fieldNumber, Object value) {
250 if (logger.isDetailEnabled()) logger.detail("setValue: Setting field number " + fieldNumber
251 + " to value " + value);
252 properties[fieldNumber] = value;
255 public void flush(StoreManager stm) {
256 // ignore flush until deferred updates are supported
259 public boolean isModified(int fieldNumber) {
260 return modifiedFields.get(fieldNumber);
263 public BigInteger getBigInteger(int fieldNumber) {
264 return bigIntegerValue(fieldNumber);
267 public boolean getBoolean(int fieldNumber) {
268 return booleanValue(fieldNumber);
271 public boolean[] getBooleans(int fieldNumber) {
272 return booleansValue(fieldNumber);
275 public Boolean getObjectBoolean(int fieldNumber) {
276 return booleanValue(fieldNumber);
279 public byte getByte(int fieldNumber) {
280 return byteValue(fieldNumber);
283 public byte[] getBytes(int fieldNumber) {
284 return bytesValue(fieldNumber);
287 public short getShort(int fieldNumber) {
288 return shortValue(fieldNumber);
291 public int getInt(int fieldNumber) {
292 return intValue(fieldNumber);
295 public long getLong(int fieldNumber) {
296 return longValue(fieldNumber);
299 public float getFloat(int fieldNumber) {
300 return floatValue(fieldNumber);
303 public double getDouble(int fieldNumber) {
304 return doubleValue(fieldNumber);
307 public Byte getObjectByte(int fieldNumber) {
308 return (Byte)properties[fieldNumber];
311 public Short getObjectShort(int fieldNumber) {
312 return (Short)properties[fieldNumber];
315 public Integer getObjectInt(int fieldNumber) {
316 return (Integer)properties[fieldNumber];
319 public Long getObjectLong(int fieldNumber) {
320 return (Long)properties[fieldNumber];
323 public Float getObjectFloat(int fieldNumber) {
324 return (Float)properties[fieldNumber];
327 public Double getObjectDouble(int fieldNumber) {
328 return (Double)properties[fieldNumber];
331 public BigDecimal getBigDecimal(int fieldNumber) {
332 return (BigDecimal)properties[fieldNumber];
335 public String getString(int fieldNumber) {
336 return (String)properties[fieldNumber];
339 public Date getJavaSqlDate(int fieldNumber) {
340 return (java.sql.Date)properties[fieldNumber];
343 public java.util.Date getJavaUtilDate(int fieldNumber) {
344 return (java.util.Date)properties[fieldNumber];
347 public Time getJavaSqlTime(int fieldNumber) {
348 return (java.sql.Time)properties[fieldNumber];
351 public Timestamp getJavaSqlTimestamp(int fieldNumber) {
352 return (java.sql.Timestamp)properties[fieldNumber];
355 public void setBigInteger(int fieldNumber, BigInteger value) {
356 properties[fieldNumber] = value;
359 public void setBoolean(int fieldNumber, boolean b) {
360 properties[fieldNumber] = b;
363 public void setBooleans(int fieldNumber, boolean[] b) {
364 properties[fieldNumber] = b;
367 public void setByte(int fieldNumber, byte value) {
368 properties[fieldNumber] = value;
371 public void setBytes(int fieldNumber, byte[] value) {
372 properties[fieldNumber] = value;
375 public void setShort(int fieldNumber, short value) {
376 properties[fieldNumber] = value;
379 public void setInt(int fieldNumber, int value) {
380 properties[fieldNumber] = value;
383 public void setLong(int fieldNumber, long value) {
384 properties[fieldNumber] = value;
387 public void setFloat(int fieldNumber, float value) {
388 properties[fieldNumber] = value;
391 public void setDouble(int fieldNumber, double value) {
392 properties[fieldNumber] = value;
395 public void setObjectBoolean(int fieldNumber, Boolean value) {
396 properties[fieldNumber] = value;
399 public void setObjectByte(int fieldNumber, Byte value) {
400 properties[fieldNumber] = value;
403 public void setObjectShort(int fieldNumber, Short value) {
404 properties[fieldNumber] = value;
407 public void setObjectInt(int fieldNumber, Integer value) {
408 properties[fieldNumber] = value;
411 public void setObjectLong(int fieldNumber, Long value) {
412 properties[fieldNumber] = value;
415 public void setObjectFloat(int fieldNumber, Float value) {
416 properties[fieldNumber] = value;
419 public void setObjectDouble(int fieldNumber, Double value) {
420 properties[fieldNumber] = value;
423 public void setBigDecimal(int fieldNumber, BigDecimal value) {
424 properties[fieldNumber] = value;
427 public void setString(int fieldNumber, String value) {
428 properties[fieldNumber] = value;
431 public void setObject(int fieldNumber, Object value) {
432 properties[fieldNumber] = value;
435 public void setJavaSqlDate(int fieldNumber, java.sql.Date value) {
436 properties[fieldNumber] = value;
439 public void setJavaUtilDate(int fieldNumber, java.util.Date value) {
440 properties[fieldNumber] = value;
443 public void setJavaSqlTime(int fieldNumber, java.sql.Time value) {
444 properties[fieldNumber] = value;
447 public void setJavaSqlTimestamp(int fieldNumber, java.sql.Timestamp value) {
448 properties[fieldNumber] = value;
451 public Object get(int columnNumber) {
452 return properties[columnNumber];
455 public void set(int columnNumber, Object value) {
456 modifiedFields.set(columnNumber);
457 properties[columnNumber] = value;
460 public ColumnMetadata[] columnMetadata() {
461 return domainTypeHandler.columnMetadata();
464 public void found(Boolean found) {
468 public Boolean found() {