KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > dna > impl > DNAWriterImpl


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.object.dna.impl;
6
7 import com.tc.io.TCByteBufferOutputStream;
8 import com.tc.io.TCByteBufferOutputStream.Mark;
9 import com.tc.object.LiteralValues;
10 import com.tc.object.ObjectID;
11 import com.tc.object.dna.api.DNAWriter;
12 import com.tc.util.Conversion;
13
14 public class DNAWriterImpl implements DNAWriter {
15
16   private static final long NULL_ID = ObjectID.NULL_ID.toLong();
17   private static final LiteralValues literalValues = new LiteralValues();
18
19   private final TCByteBufferOutputStream output;
20   private final Mark headerMark;
21   private final Mark parentIdMark;
22   private final Mark arrayLengthMark;
23   private final ObjectStringSerializer serializer;
24   private final DNAEncoding encoding;
25   private final String JavaDoc className;
26   private final ObjectID id;
27   private int actionCount = 0;
28
29   public DNAWriterImpl(TCByteBufferOutputStream output, ObjectID id, String JavaDoc className,
30                        ObjectStringSerializer serializer, DNAEncoding encoding, String JavaDoc loaderDesc, boolean isDelta) {
31     this.output = output;
32     this.id = id;
33     this.className = className;
34     this.encoding = encoding;
35
36     this.headerMark = output.mark();
37     output.writeInt(-1); // reserve 4 bytes for total length of this DNA
38
output.writeInt(-1); // reserve 4 bytes for # of actions
39
output.writeBoolean(isDelta);
40     output.writeLong(id.toLong());
41     this.parentIdMark = output.mark();
42     output.writeLong(NULL_ID); // reserve 8 bytes for the parent object ID
43
this.serializer = serializer;
44     serializer.writeString(output, className);
45     serializer.writeString(output, loaderDesc);
46     this.arrayLengthMark = output.mark();
47     output.writeInt(-1); // reserve 4 bytes for array length
48
}
49
50   public void addLogicalAction(int method, Object JavaDoc[] parameters) {
51     actionCount++;
52     output.writeByte(DNAEncoding.LOGICAL_ACTION_TYPE);
53     output.writeInt(method);
54     output.writeByte(parameters.length);
55
56     for (int i = 0; i < parameters.length; i++) {
57       encoding.encode(parameters[i], output);
58     }
59   }
60
61   public void addSubArrayAction(int start, Object JavaDoc array, int length) {
62     actionCount++;
63     output.writeByte(DNAEncoding.SUB_ARRAY_ACTION_TYPE);
64     output.writeInt(start);
65     encoding.encodeArray(array, output, length);
66   }
67
68   public void addClassLoaderAction(String JavaDoc classLoaderFieldName, Object JavaDoc value) {
69     actionCount++;
70     output.writeByte(DNAEncoding.PHYSICAL_ACTION_TYPE);
71     serializer.writeFieldName(output, classLoaderFieldName);
72     encoding.encodeClassLoader(value, output);
73   }
74
75   /**
76    * XXX::This method is uses the value to decide if the field is actually a referencable fields (meaning it is a non
77    * literal type.) This implementation is slightly flawed as you can set an instance of Integer or String to Object.
78    * But since that can only happens in Physical applicator and it correctly calls the other interface, this is left
79    * intact for now.
80    */

81   public void addPhysicalAction(String JavaDoc fieldName, Object JavaDoc value) {
82     addPhysicalAction(fieldName, value, value instanceof ObjectID);
83   }
84
85   public void addPhysicalAction(String JavaDoc fieldName, Object JavaDoc value, boolean canBeReferenced) {
86     if (value == null) {
87       //
88
throw new AssertionError JavaDoc("null value for field " + fieldName + " in type " + className + " " + id);
89     }
90
91     actionCount++;
92     if (canBeReferenced && literalValues.isLiteralInstance(value)) {
93       // an Object reference is set to a literal instance
94
output.writeByte(DNAEncoding.PHYSICAL_ACTION_TYPE_REF_OBJECT);
95     } else {
96       output.writeByte(DNAEncoding.PHYSICAL_ACTION_TYPE);
97     }
98     serializer.writeFieldName(output, fieldName);
99     encoding.encode(value, output);
100   }
101
102   public void addArrayElementAction(int index, Object JavaDoc value) {
103     actionCount++;
104     output.writeByte(DNAEncoding.ARRAY_ELEMENT_ACTION_TYPE);
105     output.writeInt(index);
106     encoding.encode(value, output);
107   }
108
109   public void addEntireArray(Object JavaDoc value) {
110     actionCount++;
111     output.writeByte(DNAEncoding.ENTIRE_ARRAY_ACTION_TYPE);
112     encoding.encodeArray(value, output);
113   }
114
115   public void addLiteralValue(Object JavaDoc value) {
116     actionCount++;
117     output.writeByte(DNAEncoding.LITERAL_VALUE_ACTION_TYPE);
118     encoding.encode(value, output);
119   }
120
121   private void finalizeHeader() {
122     int totalLength = this.output.getBytesWritten() - this.headerMark.getPosition();
123     byte[] lengths = new byte[8];
124     Conversion.writeInt(totalLength, lengths, 0);
125     Conversion.writeInt(actionCount, lengths, 4);
126     this.headerMark.write(lengths);
127   }
128
129   public void finalizeDNA() {
130     finalizeHeader();
131   }
132
133   public void setParentObjectID(ObjectID id) {
134     this.parentIdMark.write(Conversion.long2Bytes(id.toLong()));
135   }
136
137   public void setArrayLength(int length) {
138     this.arrayLengthMark.write(Conversion.int2Bytes(length));
139   }
140 }
141
Popular Tags