001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.object.applicator;
005:
006: import com.tc.exception.TCRuntimeException;
007: import com.tc.object.ClientObjectManager;
008: import com.tc.object.TCClass;
009: import com.tc.object.TCObject;
010: import com.tc.object.bytecode.JavaUtilConcurrentHashMapSegmentAdapter;
011: import com.tc.object.dna.api.DNA;
012: import com.tc.object.dna.api.DNACursor;
013: import com.tc.object.dna.api.DNAWriter;
014: import com.tc.object.dna.api.DNAEncoding;
015: import com.tc.object.dna.api.PhysicalAction;
016: import com.tc.util.Assert;
017:
018: import java.io.IOException;
019: import java.lang.reflect.Field;
020: import java.lang.reflect.InvocationTargetException;
021: import java.lang.reflect.Method;
022:
023: public class ConcurrentHashMapSegmentApplicator extends
024: PhysicalApplicator {
025: private static final String TABLE_LENGTH_FIELD_NAME = "java.util.concurrent.ConcurrentHashMap$Segment.capacity";
026: private static final String TABLE_FIELD_NAME = "table";
027:
028: private final TCClass clazz;
029:
030: public ConcurrentHashMapSegmentApplicator(TCClass clazz,
031: DNAEncoding encoding) {
032: super (clazz, encoding);
033: this .clazz = clazz;
034: }
035:
036: public void hydrate(ClientObjectManager objectManager,
037: TCObject tcObject, DNA dna, Object po) throws IOException,
038: ClassNotFoundException {
039: DNACursor cursor = dna.getCursor();
040: String fieldName;
041: Object fieldValue;
042:
043: Integer capacity = null;
044:
045: while (cursor.next(encoding)) {
046: PhysicalAction a = cursor.getPhysicalAction();
047: Assert.eval(a.isTruePhysical());
048: fieldName = a.getFieldName();
049: fieldValue = a.getObject();
050: if (TABLE_LENGTH_FIELD_NAME.equals(fieldName)) {
051: capacity = (Integer) fieldValue;
052: } else {
053: tcObject.setValue(fieldName, fieldValue);
054: }
055: }
056: initializeTable(capacity, po);
057: }
058:
059: private void initializeTable(Integer capacity, Object pojo) {
060: Assert.assertNotNull(capacity);
061: Class peerClass = clazz.getPeerClass();
062: try {
063: Method method = peerClass
064: .getDeclaredMethod(
065: JavaUtilConcurrentHashMapSegmentAdapter.INITIAL_TABLE_METHOD_NAME,
066: new Class[] { Integer.TYPE });
067: method.setAccessible(true);
068: method.invoke(pojo, new Object[] { capacity });
069: } catch (SecurityException e) {
070: throw new TCRuntimeException(e);
071: } catch (NoSuchMethodException e) {
072: throw new TCRuntimeException(e);
073: } catch (IllegalArgumentException e) {
074: throw new TCRuntimeException(e);
075: } catch (IllegalAccessException e) {
076: throw new TCRuntimeException(e);
077: } catch (InvocationTargetException e) {
078: throw new TCRuntimeException(e);
079: }
080: }
081:
082: private Field getTableField() {
083: Class peerClass = clazz.getPeerClass();
084: try {
085: Field field = peerClass.getDeclaredField(TABLE_FIELD_NAME);
086: field.setAccessible(true);
087: return field;
088: } catch (NoSuchFieldException e) {
089: throw new TCRuntimeException(e);
090: }
091: }
092:
093: public void dehydrate(ClientObjectManager objectManager,
094: TCObject tcObject, DNAWriter writer, Object pojo) {
095: super .dehydrate(objectManager, tcObject, writer, pojo);
096:
097: try {
098: Field field = getTableField();
099: Object[] tableArray = (Object[]) field.get(pojo);
100: int tableLength = tableArray.length;
101: writer.addPhysicalAction(TABLE_LENGTH_FIELD_NAME,
102: new Integer(tableLength));
103: } catch (SecurityException e) {
104: throw new TCRuntimeException(e);
105: } catch (IllegalArgumentException e) {
106: throw new TCRuntimeException(e);
107: } catch (IllegalAccessException e) {
108: throw new TCRuntimeException(e);
109: }
110:
111: }
112:
113: }
|