private void serializeCollection( StringWriter writer, String nestedFieldName, MetaCollection field, UserData data) { int size, maxSize; String typeName = field.getTypeName(); if ((typeName.equals("c_string")) || (typeName.equals("c_wstring")) || (typeName.startsWith("C_STRING<")) || (typeName.startsWith("C_WSTRING<"))) { this.serializeString(writer, nestedFieldName, data); } else { // Not a String collection. maxSize = field.getMaxSize(); if (maxSize == 0) { this.serializeUnboundedSequence(writer, nestedFieldName, field, data); } else if (maxSize == -1) { /* recursive type */ this.serializeRecursiveType(writer, nestedFieldName, field, data); } else { /* This is an array or bounded sequence. */ if (typeName.startsWith("C_ARRAY")) { /* When dealing with an array, then the actual size * is the same as the maximum size. */ size = maxSize; } else { /* When dealing with a bounded sequence, then the actual * size can differ from the maximum size. */ size = getSequenceSize(nestedFieldName, field, data); /* Also, we need this size within the data. */ writer.write("<size>" + size + "</size>"); } /* Now, fill up the elements. */ for (int i = 0; i < size; i++) { writer.write("<element>"); this.serializeType( writer, getCollectionFieldName(nestedFieldName, i), field.getSubType(), data, false); writer.write("</element>"); } } } }
/** * Serializes an unbounded sequence. * * @param nestedFieldName The name of the field (including scope) * @param seqType The type of the sequence. * @param data The data to serialize. */ private void serializeUnboundedSequence( StringWriter writer, String nestedFieldName, MetaCollection seqType, UserData data) { String value; String typeName; StringTokenizer tokenizer; MetaField subType = seqType.getSubType(); String token; String seqTypeName; seqTypeName = seqType.getTypeName(); if (subType instanceof MetaPrimitive) { value = data.getFieldValue(nestedFieldName); if (value != null) { if (value.equals("NULL")) { writer.write("<NULL>"); } else if (value.equals("[]")) { writer.write("<size>0</size>"); } else { tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ","); int size = tokenizer.countTokens(); writer.write("<size>" + size + "</size>"); for (int i = 0; i < size; i++) { token = tokenizer.nextToken(); writer.write("<element>" + token + "</element>"); } } } else { // also check for the alternative notation value = data.getFieldValue(nestedFieldName + "[0]"); if (value != null) { List<String> values = new ArrayList<String>(); int index = 1; while (value != null) { values.add(value); value = data.getFieldValue(nestedFieldName + "[" + index + "]"); index++; } writer.write("<size>" + values.size() + "</size>"); Iterator<String> it = values.iterator(); while (it.hasNext()) { writer.write("<element>" + it.next() + "</element>"); } } else { writer.write("<NULL>"); } } } else if (subType instanceof MetaCollection) { typeName = subType.getTypeName(); if ((typeName.equals("c_string")) || (typeName.equals("c_wstring")) || (typeName.startsWith("C_STRING<")) || (typeName.startsWith("C_WSTRING<"))) { value = data.getFieldValue(nestedFieldName); if (value != null) { if (value.equals("NULL")) { writer.write("<NULL>"); } else if (value.equals("[]")) { if (!(seqTypeName.startsWith("C_ARRAY"))) { writer.write("<size>0</size>"); } } else { tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ","); int size = tokenizer.countTokens(); if (!(seqTypeName.startsWith("C_ARRAY"))) { writer.write("<size>" + size + "</size>"); } for (int i = 0; i < size; i++) { token = tokenizer.nextToken(); writer.write("<element>" + token + "</element>"); } } } else { writer.write("<NULL>"); } } } else if (subType instanceof MetaStruct) { int size = 0; StringWriter localWriter = new StringWriter(); // Verify if member "size" exists, if so, then serialize and // increment LinkedHashSet<String> fields = data.getFieldNames(); boolean found = true; while (found) { String entryFieldName = nestedFieldName + "[" + size + "]"; boolean fieldExists = false; Iterator<String> it = fields.iterator(); while (!fieldExists && it.hasNext()) { if (it.next().startsWith(entryFieldName)) { fieldExists = true; } } if (fieldExists) { localWriter.write("<element>"); serializeStruct(localWriter, entryFieldName, (MetaStruct) subType, data); localWriter.write("</element>"); size++; } else { found = false; } } if (size == 0) { writer.write("<NULL>"); } else { writer.write("<size>" + size + "</size>"); } writer.write(localWriter.toString()); } else if (subType instanceof MetaUnion) { int size = 0; StringWriter localWriter = new StringWriter(); // Verify if member "size" exists, if so, then serialize and // increment LinkedHashSet<String> fields = data.getFieldNames(); boolean found = true; while (found) { String entryFieldName = nestedFieldName + "[" + size + "]"; boolean fieldExists = false; Iterator<String> it = fields.iterator(); while (!fieldExists && it.hasNext()) { if (it.next().startsWith(entryFieldName)) { fieldExists = true; } } if (fieldExists) { localWriter.write("<element>"); this.serializeUnion(localWriter, entryFieldName, (MetaUnion) subType, data); localWriter.write("</element>"); size++; } else { found = false; } } if (size == 0) { writer.write("<NULL>"); } else { writer.write("<size>" + size + "</size>"); } writer.write(localWriter.toString()); } else { writer.write("<NULL>"); } return; }
/** * Acquires the number of elements of the supplied sequence. * * @param nestedFieldName The name of the field (including scope) * @param seqType The type of the sequence. * @param data The data that is being serialized. * @return The number of elements in the given sequence. */ private int getSequenceSize(String nestedFieldName, MetaCollection seqType, UserData data) { /* * This is very much based on how serializeUnboundedSequence get * the size of its unbounded sequence. * The same actions can be used on bounded sequences as well to * get their actual size (which can be less then their maximum * size). */ int size = 0; StringTokenizer tokenizer; String typeName; String value; String token; MetaField subType = seqType.getSubType(); if (subType instanceof MetaPrimitive) { value = data.getFieldValue(nestedFieldName); if (value != null) { if (!(value.equals("NULL") || value.equals("[]"))) { tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ","); size = tokenizer.countTokens(); } } else { // also check for the alternative notation value = data.getFieldValue(nestedFieldName + "[0]"); if (value != null) { List<String> values = new ArrayList<String>(); int index = 1; while (value != null) { values.add(value); value = data.getFieldValue(nestedFieldName + "[" + index + "]"); index++; } size = values.size(); } } } else if (subType instanceof MetaCollection) { typeName = subType.getTypeName(); if ((typeName.equals("c_string")) || (typeName.equals("c_wstring")) || (typeName.startsWith("C_STRING<")) || (typeName.startsWith("C_WSTRING<"))) { value = data.getFieldValue(nestedFieldName); if (value != null) { if (!(value.equals("NULL") || value.equals("[]"))) { tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ","); size = tokenizer.countTokens(); } } } } else if ((subType instanceof MetaStruct) || (subType instanceof MetaUnion)) { // Verify if member "size" exists, if so, then serialize and // increment LinkedHashSet<String> fields = data.getFieldNames(); boolean found = true; while (found) { String entryFieldName = nestedFieldName + "[" + size + "]"; boolean fieldExists = false; Iterator<String> it = fields.iterator(); while (!fieldExists && it.hasNext()) { if (it.next().startsWith(entryFieldName)) { fieldExists = true; } } if (fieldExists) { size++; } else { found = false; } } } return size; }
/** * Serializes the contents of the supplied collection. * * @param nestedFieldName The name of the collection field in the data. * @param colType The type of the collection. * @param data The data to serialize. * @return The serialized representation of the collection data. */ private String getSerializedStringCollection( String nestedFieldName, MetaCollection colType, UserData data) { String result = null; String size = null; String typeName = colType.getTypeName(); int index = nestedFieldName.indexOf('['); String temp = null; if ((typeName.equals("c_string")) || (typeName.equals("c_wstring")) || (typeName.startsWith("C_STRING<")) || (typeName.startsWith("C_WSTRING<"))) { String strData = data.getFieldValue(nestedFieldName); result = strData.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">"); } else if (colType.getSubType() instanceof MetaCollection) { result = ""; if (colType.getSubType().getTypeName().startsWith("C_SEQUENCE<")) { size = "<size>" + ((MetaCollection) colType.getSubType()).getMaxSize() + "</size>"; } if (index != -1) { temp = nestedFieldName.substring(0, index); for (int i = 0; i < colType.getMaxSize(); i++) { result += "<element>"; if (size != null) { result += size; } result += getSerializedStringCollection( temp + "[" + i + "]" + nestedFieldName.substring(index), (MetaCollection) colType.getSubType(), data); result += "</element>"; } } else { for (int i = 0; i < colType.getMaxSize(); i++) { result += "<element>"; if (size != null) { result += size; } result += getSerializedStringCollection( nestedFieldName + "[" + i + "]", (MetaCollection) colType.getSubType(), data); result += "</element>"; } } } else { result = ""; if (index != -1) { temp = nestedFieldName.substring(0, index); for (int i = 0; i < colType.getMaxSize(); i++) { result += "<element>"; result += data.getFieldValue(temp + "[" + i + "]" + nestedFieldName.substring(index)); result += "</element>"; } } else { for (int i = 0; i < colType.getMaxSize(); i++) { result += "<element>"; result += data.getFieldValue(nestedFieldName + "[" + i + "]"); result += "</element>"; } } } return result; }