1 5 package com.tc.objectserver.managedobject; 6 7 import org.apache.commons.lang.ArrayUtils; 8 9 import com.tc.object.LiteralValues; 10 import com.tc.object.ObjectID; 11 import com.tc.object.dna.api.DNA; 12 import com.tc.object.dna.api.DNACursor; 13 import com.tc.object.dna.api.DNAWriter; 14 import com.tc.object.dna.api.PhysicalAction; 15 import com.tc.objectserver.mgmt.ManagedObjectFacade; 16 import com.tc.objectserver.mgmt.PhysicalManagedObjectFacade; 17 import com.tc.text.PrettyPrintable; 18 import com.tc.text.PrettyPrinter; 19 import com.tc.util.Assert; 20 21 import java.io.IOException ; 22 import java.io.ObjectInput ; 23 import java.io.ObjectOutput ; 24 import java.lang.reflect.Array ; 25 import java.util.Arrays ; 26 import java.util.HashMap ; 27 import java.util.Map ; 28 import java.util.Set ; 29 30 public class ArrayManagedObjectState extends LogicalManagedObjectState implements PrettyPrintable { 31 private static final LiteralValues LITERAL_VALUES = new LiteralValues(); 32 33 private Object arrayData; 34 private int size = DNA.NULL_ARRAY_SIZE; 35 private boolean isPrimitive; 36 private int literalType; 37 38 ArrayManagedObjectState(long classID) { 39 super(classID); 40 } 41 42 protected ArrayManagedObjectState(ObjectInput in) throws IOException { 43 super(in); 44 } 45 46 public void apply(ObjectID objectID, DNACursor cursor, BackReferences includeIDs) throws IOException { 47 ManagedObjectChangeListener listener = getListener(); 48 49 while (cursor.next()) { 50 PhysicalAction a = cursor.getPhysicalAction(); 51 52 if (a.isArrayElement()) { 53 int index = a.getArrayIndex(); 54 Object value = a.getObject(); 55 informListener(objectID, listener, index, value, includeIDs); 56 setArrayElement(arrayData, index, value, literalType); 57 } else if (a.isEntireArray()) { 58 initArray(a.getObject()); 59 if (!isPrimitive) { 60 Object [] objArray = (Object []) arrayData; 61 for (int i = 0, n = size; i < n; i++) { 62 informListener(objectID, listener, i, objArray[i], includeIDs); 63 } 64 } 65 } else if (a.isSubArray()) { 66 int startPos = a.getArrayIndex(); 67 Object value = a.getObject(); 68 System.arraycopy(value, 0, arrayData, startPos, Array.getLength(value)); 69 } else { 70 throw Assert.failure("unknown action type"); 71 } 72 } 73 } 74 75 private void initArray(Object array) { 76 arrayData = array; 77 size = Array.getLength(arrayData); 78 Class clazz = arrayData.getClass().getComponentType(); 79 literalType = LITERAL_VALUES.valueForClassName(clazz.getName()); 80 isPrimitive = clazz.isPrimitive(); 81 } 82 83 private static void setArrayElement(Object array, int index, Object value, int type) { 84 switch (type) { 85 case LiteralValues.BOOLEAN: 86 ((boolean[]) array)[index] = ((Boolean ) value).booleanValue(); 87 break; 88 case LiteralValues.BYTE: 89 ((byte[]) array)[index] = ((Byte ) value).byteValue(); 90 break; 91 case LiteralValues.CHARACTER: 92 ((char[]) array)[index] = ((Character ) value).charValue(); 93 break; 94 case LiteralValues.DOUBLE: 95 ((double[]) array)[index] = ((Double ) value).doubleValue(); 96 break; 97 case LiteralValues.FLOAT: 98 ((float[]) array)[index] = ((Float ) value).floatValue(); 99 break; 100 case LiteralValues.INTEGER: 101 ((int[]) array)[index] = ((Integer ) value).intValue(); 102 break; 103 case LiteralValues.LONG: 104 ((long[]) array)[index] = ((Long ) value).longValue(); 105 break; 106 case LiteralValues.SHORT: 107 ((short[]) array)[index] = ((Short ) value).shortValue(); 108 break; 109 default: 110 ((Object []) array)[index] = value; 111 break; 112 } 113 } 114 115 private void informListener(ObjectID objectID, ManagedObjectChangeListener listener, int index, Object value, 116 BackReferences includeIDs) { 117 if (!isPrimitive) { 118 Object [] objectArray = (Object []) arrayData; 119 Object oldVal = objectArray[index]; 120 ObjectID oldValue = oldVal instanceof ObjectID ? (ObjectID) oldVal : ObjectID.NULL_ID; 121 ObjectID newValue = value instanceof ObjectID ? (ObjectID) value : ObjectID.NULL_ID; 122 listener.changed(objectID, oldValue, newValue); 123 includeIDs.addBackReference(newValue, objectID); 124 } 125 } 126 127 protected void addAllObjectReferencesTo(Set refs) { 128 if (!isPrimitive) { 129 addAllObjectReferencesFromIteratorTo(Arrays.asList((Object []) arrayData).iterator(), refs); 130 } 131 } 132 133 public void dehydrate(ObjectID objectID, DNAWriter writer) { 134 writer.addEntireArray(arrayData); 135 writer.setArrayLength(size); 136 } 137 138 public ManagedObjectFacade createFacade(ObjectID objectID, String className, int limit) { 139 if (limit < 0) { 140 limit = size; 141 } else { 142 limit = Math.min(limit, size); 143 } 144 145 Map dataCopy = new HashMap (limit); 146 147 for (int i = 0; i < limit; i++) { 148 dataCopy.put(String.valueOf(i), Array.get(arrayData, i)); 150 } 151 152 boolean isArray = true; 153 ObjectID parent = ObjectID.NULL_ID; 154 boolean isInner = false; 155 156 return new PhysicalManagedObjectFacade(objectID, parent, className, dataCopy, isInner, limit, isArray); 157 } 158 159 public PrettyPrinter prettyPrint(PrettyPrinter out) { 160 PrettyPrinter rv = out; 161 out = out.print(getClass().getName()).duplicateAndIndent().println(); 162 out.indent().print("size: " + size).println(); 163 out.indent().print("data: " + ArrayUtils.toString(arrayData)).println(); 164 return rv; 165 } 166 167 public byte getType() { 168 return ARRAY_TYPE; 169 } 170 171 protected void basicWriteTo(ObjectOutput out) throws IOException { 172 out.writeObject(arrayData); 173 } 174 175 static ArrayManagedObjectState readFrom(ObjectInput in) throws IOException , ClassNotFoundException { 176 ArrayManagedObjectState amos = new ArrayManagedObjectState(in); 177 amos.initArray(in.readObject()); 178 return amos; 179 } 180 181 protected boolean basicEquals(LogicalManagedObjectState other) { 182 ArrayManagedObjectState amo = (ArrayManagedObjectState) other; 183 return size == amo.size && isPrimitive == amo.isPrimitive && literalType == amo.literalType 184 && equals(arrayData, amo.arrayData, literalType); 185 } 186 187 private static boolean equals(Object a1, Object a2, int type) { 188 switch (type) { 189 case LiteralValues.BOOLEAN: 190 return Arrays.equals((boolean[]) a1, (boolean[]) a2); 191 case LiteralValues.BYTE: 192 return Arrays.equals((byte[]) a1, (byte[]) a2); 193 case LiteralValues.CHARACTER: 194 return Arrays.equals((char[]) a1, (char[]) a2); 195 case LiteralValues.DOUBLE: 196 return Arrays.equals((double[]) a1, (double[]) a2); 197 case LiteralValues.FLOAT: 198 return Arrays.equals((float[]) a1, (float[]) a2); 199 case LiteralValues.INTEGER: 200 return Arrays.equals((int[]) a1, (int[]) a2); 201 case LiteralValues.LONG: 202 return Arrays.equals((long[]) a1, (long[]) a2); 203 case LiteralValues.SHORT: 204 return Arrays.equals((short[]) a1, (short[]) a2); 205 default: 206 return Arrays.equals((Object []) a1, (Object []) a2); 207 } 208 } 209 210 } 211 | Popular Tags |