Index: modules/beans/src/main/java/java/beans/XMLEncoder.java =================================================================== --- modules/beans/src/main/java/java/beans/XMLEncoder.java (revision 417276) +++ modules/beans/src/main/java/java/beans/XMLEncoder.java (working copy) @@ -24,6 +24,7 @@ import java.io.OutputStream; import java.util.Enumeration; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Iterator; import java.util.Vector; @@ -129,6 +130,7 @@ private void printObjectTag(int tabCount, Object object, ObjectNode node) { Class nodeType = null; + try { nodeType = node.getObjectType(); } catch (Exception e) { @@ -142,49 +144,20 @@ String tagName = getPrimitiveName(nodeType); Object arg = node.getObjectArguments()[0]; Tag tag = new Tag(tagName, arg.toString()); + printBytes(tabCount, tag.toString()); - } else if(isArray(nodeType)) { - Object[] args = node.getObjectArguments(); - - Tag tag = new Tag("array"); - - tag.addAttr("class", ((Class) args[0]).getName()); - tag.addAttr("length", ((Integer) args[1]).toString()); - - printBytes(tabCount, tag.toStringOnOpen()); - - Iterator e = node.statements(); - while(e.hasNext()) { - Statement s = (Statement) e.next(); - printVoidTag(++tabCount, s); - --tabCount; - } - - printBytes(tabCount, tag.toStringOnClose()); - } else { - Tag tag = new Tag("object"); - + } else { // if array or complex object + Tag tag = null; + Object[] arguments = node.getObjectArguments(); boolean objectPrinted = false; - //System.out.println("--->"); - //System.out.println("node.getInitializer().getMethodName() = " + node.getInitializer().getMethodName()); - //System.out.println("node.getReferencesNumber() = " + node.getReferencesNumber()); - //System.out.println("node.getReferencedExpressionsNumber() = " + node.getReferencedExpressionsNumber()); - boolean isReferenced = node.getReferencesNumber() > 0; - if(!isReferenced) { - Iterator referencedExpressions = node.referencedExpressions(); - while(referencedExpressions.hasNext()) { - Expression expr = - (Expression) referencedExpressions.next(); - - //System.out.println("expr.getMethodName() = " - // + expr.getMethodName()); - } + if (isArray(nodeType)) { + tag = new Tag("array"); + } else { + tag = new Tag("object"); } - //System.out.println("<---"); - // check if the object presents references if(isReferenced) { if(printed.contains(node)) { @@ -203,6 +176,7 @@ // check if it is necessary to assign // and display *id* attribute to the object String objectName = NameMaker.getInstanceName(type); + node.setId(objectName); tag.addAttr("id", objectName); } @@ -214,52 +188,90 @@ if(!objectPrinted) { try { - tag.addAttr("class", node.getObjectType().getName()); + if (isArray(nodeType)) { + tag.addAttr("class", ((Class) arguments[0]).getName()); + tag.addAttr("length", ((Integer) + arguments[1]).toString()); + } else { + tag.addAttr("class", node.getObjectType().getName()); + } } catch (Exception e) { getExceptionListener().exceptionThrown(e); } } - - printBytes(tabCount, tag.toStringOnOpen()); - - if(!objectPrinted) { + + // preprocessing is done, print it! + if (objectPrinted) { + // if object has been already printed then only print the + // reference + printBytes(tabCount, tag.toStringShortForm()); + } + else if (isArray(nodeType) && !node.statements().hasNext()) { + // if we have an empty array + printBytes(tabCount, tag.toStringShortForm()); + } + else if (arguments.length == 0 && + !node.statements().hasNext() && + !node.expressions().hasNext()) { + // if given tag has no children print the short form of the tag + printBytes(tabCount, tag.toStringShortForm()); + } + else { + // the tag has not been printed and contains children, + // let's print them + + printBytes(tabCount, tag.toStringOnOpen()); + printed.add(node); - Object[] arguments = node.getObjectArguments(); - for(int i = 0; i < arguments.length; ++i) { - if(arguments[i] != null) { - ObjectNode succNode = (ObjectNode) nodes.get( - arguments[i]); - printObjectTag(++tabCount, arguments[i], succNode); - } else { - printNullTag(++tabCount); + if (isArray(nodeType)) { // if array + Iterator it = node.statements(); + + while(it.hasNext()) { + Statement s = (Statement) it.next(); + + printVoidTag(++tabCount, s); + --tabCount; } + } else { // if object + Iterator i1; + Iterator i2; - --tabCount; - } - - Iterator i1 = node.expressions(); - while(i1.hasNext()) { - Expression e = (Expression) i1.next(); + for(int i = 0; i < arguments.length; ++i) { + if(arguments[i] != null) { + ObjectNode succNode = (ObjectNode) nodes.get( + arguments[i]); + + printObjectTag(++tabCount, arguments[i], succNode); + } else { + printNullTag(++tabCount); + } + + --tabCount; + } - printVoidTag(++tabCount, e); - --tabCount; - } - - Iterator i2 = node.statements(); - while(i2.hasNext()) { - Statement s = (Statement) i2.next(); + i1 = node.expressions(); + while(i1.hasNext()) { + Expression e = (Expression) i1.next(); + + printVoidTag(++tabCount, e); + --tabCount; + } - printVoidTag(++tabCount, s); - --tabCount; - } + i2 = node.statements(); + while(i2.hasNext()) { + Statement s = (Statement) i2.next(); + + printVoidTag(++tabCount, s); + --tabCount; + } + } // if object + printBytes(tabCount, tag.toStringOnClose()); } - - printBytes(tabCount, tag.toStringOnClose()); } // if node is of non-trivial type } - + private void printVoidTag(int tabCount, Expression expr) { Object exprValue = null; try { @@ -387,31 +399,73 @@ private void printBytes(int tabCount, String s) { try { String result = ""; - for(int i = 0; i < tabCount; ++i) result += '\t'; + + for(int i = 0; i < tabCount; ++i) { + result += '\t'; + } result = result + s + "\n"; out.write(result.getBytes("UTF-8")); } catch (IOException ioe) { ExceptionListener listener = getExceptionListener(); + if(listener != null) { listener.exceptionThrown(ioe); } } } + + /** + * Escapes '&', '<', '>', '\'', '"' chars. + * @param input input string to be escaped + * @return string with escaped characters + */ + static String escapeChars(String input) { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + + switch (c) { + case '&': + sb.append("&"); + break; + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '\'': + sb.append("'"); + break; + case '"': + sb.append("""); + break; + default: + sb.append(c); + break; + } + } + return sb.toString(); + } - class Tag { + /** + * This class is used by XMLEncoder to store XML tag information. + */ + static class Tag { String name; - HashMap attrs; + LinkedHashMap attrs; String characters; public Tag(String name) { this.name = name; - this.attrs = new HashMap(); + this.attrs = new LinkedHashMap(); this.characters = null; } public Tag(String name, String characters) { this.name = name; - this.attrs = new HashMap(); + this.attrs = new LinkedHashMap(); this.characters = characters; } @@ -423,58 +477,85 @@ attrs.put(attrName, attrValue); } - public String toStringOnOpen() { + public String toStringOnOpenUnfinished() { String result = "<" + name; Iterator i = attrs.keySet().iterator(); + while(i.hasNext()) { String attrName = (String) i.next(); String attrValue = (String) attrs.get(attrName); + result +=" " + attrName + "=\"" + attrValue + "\""; } - result += ">"; return result; } + + public String toStringOnOpen() { + return toStringOnOpenUnfinished() + ">"; + } + public String toStringShortForm() { + return toStringOnOpenUnfinished() + "/>"; + } + public String toStringOnClose() { return ""; } public String toStringOnCharacters() { - return characters; + return XMLEncoder.escapeChars(characters); } public String toString() { return toStringOnOpen() + toStringOnCharacters() + toStringOnClose(); } - } - -} -class NameMaker { - private static HashMap numOfExemplars = new HashMap(); - - public static void clear() { - numOfExemplars.clear(); - } - - public static String getInstanceName(Class type) { - String result = null; + + static class NameMaker { + private static HashMap numOfExemplars = new HashMap(); - String fullName = type.getName(); - String shortName = fullName.substring(fullName.lastIndexOf(".") + 1); + public static void clear() { + numOfExemplars.clear(); + } - Integer iNum = (Integer) numOfExemplars.get(shortName); + private static String getCompName(Class clz) { + if (clz.isArray()) { + return getCompName(clz.getComponentType()) + "Array"; + } else { + return clz.getName().substring( + clz.getName().lastIndexOf(".") + 1); + } + } - if(iNum == null) { - numOfExemplars.put(shortName, new Integer(0)); - result = shortName + "0"; - } else { - int newValue = iNum.intValue() + 1; - result = shortName + Integer.toString(newValue); - numOfExemplars.put(shortName, new Integer(newValue)); + public static String getInstanceName(Class type) { + String result = null; + + String fullName; + String shortName; + Integer iNum; + + if (type.isArray()) { + fullName = getCompName(type); + shortName = fullName; + } else { + fullName = type.getName(); + shortName = fullName.substring(fullName.lastIndexOf(".") + 1); + } + iNum = (Integer) numOfExemplars.get(shortName); + if(iNum == null) { + numOfExemplars.put(shortName, new Integer(0)); + result = shortName + "0"; + } else { + int newValue = iNum.intValue() + 1; + + result = shortName + Integer.toString(newValue); + numOfExemplars.put(shortName, new Integer(newValue)); + } + return result; } - return result; } } + + Index: modules/beans/src/main/java/org/apache/harmony/beans/ObjectNode.java =================================================================== --- modules/beans/src/main/java/org/apache/harmony/beans/ObjectNode.java (revision 417276) +++ modules/beans/src/main/java/org/apache/harmony/beans/ObjectNode.java (working copy) @@ -24,7 +24,7 @@ import java.beans.Statement; import java.util.Iterator; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Vector; /** @@ -38,7 +38,7 @@ private Object objectValue = null; private HashMap nodes; - private HashSet statements = new HashSet(); + private LinkedHashSet statements = new LinkedHashSet(); private Vector expressions = new Vector(); private Vector referencedExpressions = new Vector(); Index: modules/beans/src/test/resources/xml/bad_int.xml =================================================================== --- modules/beans/src/test/resources/xml/bad_int.xml (revision 417276) +++ modules/beans/src/test/resources/xml/bad_int.xml (working copy) @@ -1,19 +1,4 @@ - - - 3 Index: modules/beans/src/test/resources/xml/DependencyBean.xml =================================================================== --- modules/beans/src/test/resources/xml/DependencyBean.xml (revision 417276) +++ modules/beans/src/test/resources/xml/DependencyBean.xml (working copy) @@ -1,21 +1,6 @@ - - - - + 888 Index: modules/beans/src/test/resources/xml/int.xml =================================================================== --- modules/beans/src/test/resources/xml/int.xml (revision 417276) +++ modules/beans/src/test/resources/xml/int.xml (working copy) @@ -1,19 +1,4 @@ - - - 3 Index: modules/beans/src/test/resources/xml/IntArray.xml =================================================================== --- modules/beans/src/test/resources/xml/IntArray.xml (revision 417276) +++ modules/beans/src/test/resources/xml/IntArray.xml (working copy) @@ -1,19 +1,4 @@ - - - Index: modules/beans/src/test/resources/xml/MockBean4Codec_BornFriendChange.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4Codec_BornFriendChange.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4Codec_BornFriendChange.xml (working copy) @@ -1,21 +1,6 @@ - - - - + Index: modules/beans/src/test/resources/xml/MockBean4Codec_ManyChanges.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4Codec_ManyChanges.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4Codec_ManyChanges.xml (working copy) @@ -1,21 +1,6 @@ - - - - + 127 Index: modules/beans/src/test/resources/xml/MockBean4Codec_ManyChanges_2.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4Codec_ManyChanges_2.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4Codec_ManyChanges_2.xml (working copy) @@ -1,21 +1,6 @@ - - - - + java.lang.Exception Index: modules/beans/src/test/resources/xml/MockBean4Codec_NoChange.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4Codec_NoChange.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4Codec_NoChange.xml (working copy) @@ -1,19 +1,4 @@ - - - - + Index: modules/beans/src/test/resources/xml/MockBean4Owner_SetOwner.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4Owner_SetOwner.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4Owner_SetOwner.xml (working copy) @@ -1,22 +1,7 @@ - - - - + Index: modules/beans/src/test/resources/xml/MockBean4Owner_SetOwnerWithWriteStatement.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4Owner_SetOwnerWithWriteStatement.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4Owner_SetOwnerWithWriteStatement.xml (working copy) @@ -1,24 +1,9 @@ - - - - + Index: modules/beans/src/test/resources/xml/MockBean4StaticField.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4StaticField.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4StaticField.xml (working copy) @@ -1,19 +1,4 @@ - - - - + Index: modules/beans/src/test/resources/xml/MockBean4StaticField_Original.xml =================================================================== --- modules/beans/src/test/resources/xml/MockBean4StaticField_Original.xml (revision 417276) +++ modules/beans/src/test/resources/xml/MockBean4StaticField_Original.xml (working copy) @@ -1,21 +1,6 @@ - - - - + inst Index: modules/beans/src/test/resources/xml/null.xml =================================================================== --- modules/beans/src/test/resources/xml/null.xml (revision 417276) +++ modules/beans/src/test/resources/xml/null.xml (working copy) @@ -1,19 +1,4 @@ - - - Index: modules/beans/src/test/resources/xml/SampleBean_StringCodec.xml =================================================================== --- modules/beans/src/test/resources/xml/SampleBean_StringCodec.xml (revision 417276) +++ modules/beans/src/test/resources/xml/SampleBean_StringCodec.xml (working copy) @@ -1,26 +1,11 @@ - - - - + <Li Yang> & "liyang' - + a child