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.object.ClientObjectManager;
007: import com.tc.object.SerializationUtil;
008: import com.tc.object.TCObject;
009: import com.tc.object.dna.api.DNA;
010: import com.tc.object.dna.api.DNACursor;
011: import com.tc.object.dna.api.DNAWriter;
012: import com.tc.object.dna.api.DNAEncoding;
013: import com.tc.object.dna.api.LogicalAction;
014: import com.tc.object.dna.api.PhysicalAction;
015: import com.tc.util.Assert;
016: import com.tc.util.FieldUtils;
017:
018: import java.io.IOException;
019: import java.lang.reflect.Field;
020: import java.util.LinkedHashMap;
021:
022: /**
023: * Apply a logical action to an object
024: */
025: public class LinkedHashMapApplicator extends PartialHashMapApplicator {
026: private static final String ACCESS_ORDER_FIELDNAME = "java.util.LinkedHashMap.accessOrder";
027: private static final Field ACCESS_ORDER_FIELD;
028:
029: static {
030: try {
031: ACCESS_ORDER_FIELD = LinkedHashMap.class
032: .getDeclaredField("accessOrder");
033: ACCESS_ORDER_FIELD.setAccessible(true);
034: } catch (Exception e) {
035: throw new RuntimeException(e);
036: }
037: }
038:
039: public LinkedHashMapApplicator(DNAEncoding encoding) {
040: super (encoding);
041: }
042:
043: public void hydrate(ClientObjectManager objectManager,
044: TCObject tcObject, DNA dna, Object pojo)
045: throws IOException, ClassNotFoundException {
046: DNACursor cursor = dna.getCursor();
047: while (cursor.next(encoding)) {
048: Object action = cursor.getAction();
049: if (action instanceof PhysicalAction) {
050: PhysicalAction physicalAction = (PhysicalAction) action;
051: Assert.assertEquals(ACCESS_ORDER_FIELDNAME,
052: physicalAction.getFieldName());
053: setAccessOrder(pojo, physicalAction.getObject());
054: } else {
055: LogicalAction logicalAction = (LogicalAction) action;
056: int method = logicalAction.getMethod();
057: Object[] params = logicalAction.getParameters();
058: apply(objectManager, pojo, method, params);
059: }
060: }
061: }
062:
063: private void setAccessOrder(Object target, Object value) {
064: try {
065: FieldUtils.tcSet(target, value, ACCESS_ORDER_FIELD);
066: } catch (Exception e) {
067: throw new RuntimeException(e);
068: }
069: }
070:
071: protected void apply(ClientObjectManager objectManager,
072: Object pojo, int method, Object[] params)
073: throws ClassNotFoundException {
074: switch (method) {
075: case SerializationUtil.GET:
076: ((LinkedHashMap) pojo).get(params[0]);
077: break;
078: default:
079: super .apply(objectManager, pojo, method, params);
080: }
081: }
082:
083: private boolean getAccessOrder(Object pojo) {
084: try {
085: return ACCESS_ORDER_FIELD.getBoolean(pojo);
086: } catch (Exception e) {
087: throw new RuntimeException(e);
088: }
089: }
090:
091: public void dehydrate(ClientObjectManager objectManager,
092: TCObject tcObject, DNAWriter writer, Object pojo) {
093: writer.addPhysicalAction(ACCESS_ORDER_FIELDNAME, new Boolean(
094: getAccessOrder(pojo)));
095: super .dehydrate(objectManager, tcObject, writer, pojo);
096: }
097:
098: public Object getNewInstance(ClientObjectManager objectManager,
099: DNA dna) throws IOException, ClassNotFoundException {
100: DNACursor cursor = dna.getCursor();
101: if (!cursor.next(encoding)) {
102: throw new AssertionError(
103: "Cursor is empty in LinkedHashMapApplicator.getNewInstance()");
104: }
105: PhysicalAction physicalAction = cursor.getPhysicalAction();
106:
107: return new LinkedHashMap(1, 0.75f, ((Boolean) physicalAction
108: .getObject()).booleanValue());
109: }
110: }
|