001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object.applicator;
006:
007: import com.tc.exception.TCNotSupportedMethodException;
008: import com.tc.object.ClientObjectManager;
009: import com.tc.object.TCObject;
010: import com.tc.object.TraversedReferences;
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.object.tx.optimistic.OptimisticTransactionManager;
017: import com.tc.util.Assert;
018:
019: import java.io.IOException;
020: import java.lang.reflect.AccessibleObject;
021: import java.lang.reflect.Constructor;
022: import java.lang.reflect.Field;
023: import java.lang.reflect.Method;
024: import java.util.Map;
025:
026: public class AccessibleObjectApplicator extends BaseApplicator {
027: private static final String DECLARING_CLASS_FIELD_NAME = "java.lang.reflect.AccessibleObject.declaringClass";
028: private static final String ACCESSIBLE_OBJECT_NAME_FILED_NAME = "java.lang.reflect.AccessibleObject.name";
029: private static final String OVERRIDE_FILED_NAME = "java.lang.reflect.AccessibleObject.override";
030: private static final String PARAMETER_TYPES = "java.lang.reflect.AccessibleObject.parameterTypes";
031: private static final String ACCESSIBLE_OBJECT_TYPE = "java.lang.reflect.AccessibleObject.type";
032: private static final String METHOD_CLASS_NAME = Method.class
033: .getName();
034: private static final String CONSTRUCTOR_CLASS_NAME = Constructor.class
035: .getName();
036: private static final String FIELD_CLASS_NAME = Field.class
037: .getName();
038:
039: public AccessibleObjectApplicator(DNAEncoding encoding) {
040: super (encoding);
041: }
042:
043: public TraversedReferences getPortableObjects(Object pojo,
044: TraversedReferences addTo) {
045: if (pojo instanceof Method) {
046: Method m = (Method) pojo;
047: addTo.addAnonymousReference(m.getDeclaringClass());
048: addTo.addAnonymousReference(m.getName());
049: addTo.addAnonymousReference(m.getParameterTypes());
050: } else if (pojo instanceof Constructor) {
051: Constructor c = (Constructor) pojo;
052: addTo.addAnonymousReference(c.getDeclaringClass());
053: addTo.addAnonymousReference(c.getName());
054: addTo.addAnonymousReference(c.getParameterTypes());
055: } else if (pojo instanceof Field) {
056: Field f = (Field) pojo;
057: addTo.addAnonymousReference(f.getDeclaringClass());
058: addTo.addAnonymousReference(f.getName());
059: }
060: return addTo;
061: }
062:
063: public void hydrate(ClientObjectManager objectManager,
064: TCObject tcObject, DNA dna, Object po) throws IOException,
065: IllegalArgumentException, ClassNotFoundException {
066: DNACursor cursor = dna.getCursor();
067: Assert.eval(cursor.getActionCount() <= 1);
068:
069: if (cursor.next(encoding)) {
070: PhysicalAction a = (PhysicalAction) cursor.getAction();
071: Boolean value = (Boolean) a.getObject();
072: ((AccessibleObject) po).setAccessible(value.booleanValue());
073: }
074: }
075:
076: public void dehydrate(ClientObjectManager objectManager,
077: TCObject tcObject, DNAWriter writer, Object pojo) {
078: Class declaringClass = null;
079: String name = null;
080: Class[] parameterTypes = null;
081: AccessibleObject ao = (AccessibleObject) pojo;
082: boolean override = ao.isAccessible();
083: if (ao instanceof Method) {
084: Method m = (Method) ao;
085: declaringClass = m.getDeclaringClass();
086: name = m.getName();
087: parameterTypes = m.getParameterTypes();
088: } else if (ao instanceof Constructor) {
089: Constructor c = (Constructor) ao;
090: declaringClass = c.getDeclaringClass();
091: name = c.getName();
092: parameterTypes = c.getParameterTypes();
093: } else if (ao instanceof Field) {
094: Field f = (Field) ao;
095: declaringClass = f.getDeclaringClass();
096: name = f.getName();
097: }
098: writer.addPhysicalAction(ACCESSIBLE_OBJECT_TYPE, ao.getClass()
099: .getName());
100: writer.addPhysicalAction(DECLARING_CLASS_FIELD_NAME,
101: declaringClass);
102: writer.addPhysicalAction(ACCESSIBLE_OBJECT_NAME_FILED_NAME,
103: name);
104: writer.addPhysicalAction(OVERRIDE_FILED_NAME, new Boolean(
105: override));
106: if (!(ao instanceof Field)) {
107: writer.addPhysicalAction(PARAMETER_TYPES, parameterTypes);
108: }
109: }
110:
111: public Object getNewInstance(ClientObjectManager objectManager,
112: DNA dna) throws IOException, ClassNotFoundException {
113: Class[] parameterTypes = null;
114:
115: DNACursor cursor = dna.getCursor();
116:
117: cursor.next(encoding);
118: PhysicalAction a = cursor.getPhysicalAction();
119: String objectType = (String) a.getObject();
120:
121: cursor.next(encoding);
122: a = cursor.getPhysicalAction();
123: Class declaringClass = (Class) a.getObject();
124:
125: cursor.next(encoding);
126: a = cursor.getPhysicalAction();
127: String name = (String) a.getObject();
128:
129: cursor.next(encoding);
130: a = cursor.getPhysicalAction();
131: Boolean override = (Boolean) a.getObject();
132:
133: if (!FIELD_CLASS_NAME.equals(objectType)) {
134: cursor.next(encoding);
135: a = cursor.getPhysicalAction();
136: Object[] values = (Object[]) a.getObject();
137: parameterTypes = new Class[values.length];
138: System.arraycopy(values, 0, parameterTypes, 0,
139: values.length);
140: }
141:
142: if (METHOD_CLASS_NAME.equals(objectType)) {
143: try {
144: Method m = declaringClass.getDeclaredMethod(name,
145: parameterTypes);
146: m.setAccessible(override.booleanValue());
147: return m;
148: } catch (NoSuchMethodException e) {
149: throw new AssertionError(e);
150: }
151: } else if (CONSTRUCTOR_CLASS_NAME.equals(objectType)) {
152: try {
153: Constructor c = declaringClass
154: .getDeclaredConstructor(parameterTypes);
155: c.setAccessible(override.booleanValue());
156: return c;
157: } catch (NoSuchMethodException e) {
158: throw new AssertionError(e);
159: }
160: } else if (FIELD_CLASS_NAME.equals(objectType)) {
161: try {
162: Field f = declaringClass.getDeclaredField(name);
163: f.setAccessible(override.booleanValue());
164: return f;
165: } catch (SecurityException e) {
166: throw new AssertionError(e);
167: } catch (NoSuchFieldException e) {
168: throw new AssertionError(e);
169: }
170: } else {
171: throw new AssertionError("Object type not known.");
172: }
173: }
174:
175: public Map connectedCopy(Object source, Object dest, Map visited,
176: ClientObjectManager objectManager,
177: OptimisticTransactionManager txManager) {
178: throw new TCNotSupportedMethodException();
179: }
180: }
|