Log Message
Optimized XML structure for java.awt.Font.
Modified Paths
- trunk/xstream/src/java/com/thoughtworks/xstream/XStream.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java
- trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java
- trunk/xstream-distribution/src/content/changes.html
- trunk/xstream-distribution/src/content/converters.html
Diff
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/XStream.java (2133 => 2134)
--- trunk/xstream/src/java/com/thoughtworks/xstream/XStream.java 2013-09-26 18:07:27 UTC (rev 2133)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/XStream.java 2013-09-26 19:13:29 UTC (rev 2134)
@@ -794,7 +794,7 @@
registerConverter(new JavaMethodConverter(classLoaderReference), PRIORITY_NORMAL);
registerConverter(new JavaFieldConverter(classLoaderReference), PRIORITY_NORMAL);
if (JVM.isAWTAvailable()) {
- registerConverter(new FontConverter(), PRIORITY_NORMAL);
+ registerConverter(new FontConverter(mapper), PRIORITY_NORMAL);
registerConverter(new ColorConverter(), PRIORITY_NORMAL);
registerConverter(new TextAttributeConverter(), PRIORITY_NORMAL);
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java (2133 => 2134)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java 2013-09-26 18:07:27 UTC (rev 2133)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java 2013-09-26 19:13:29 UTC (rev 2134)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2013 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -13,35 +13,105 @@
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.mapper.Mapper;
import javax.swing.plaf.FontUIResource;
import java.awt.Font;
+import java.awt.font.TextAttribute;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
public class FontConverter implements Converter {
+ private final SingleValueConverter textAttributeConverter;
+ private final Mapper mapper;
+
+ /**
+ * Constructs a FontConverter.
+ * @deprecated As of upcoming
+ */
+ public FontConverter() {
+ this(null);
+ }
+
+ /**
+ * Constructs a FontConverter.
+ * @param mapper
+ * @since upcoming
+ */
+ public FontConverter(Mapper mapper) {
+ this.mapper = mapper;
+ if (mapper == null) {
+ textAttributeConverter = null;
+ } else {
+ textAttributeConverter = new TextAttributeConverter();
+ }
+ }
+
public boolean canConvert(Class type) {
// String comparison is used here because Font.class loads the class which in turns instantiates AWT,
// which is nasty if you don't want it.
return type.getName().equals("java.awt.Font") || type.getName().equals("javax.swing.plaf.FontUIResource");
}
- public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
- Font font = (Font) source;
+ public void marshal(Object source, HierarchicalStreamWriter writer,
+ MarshallingContext context) {
+ Font font = (Font)source;
Map attributes = font.getAttributes();
- writer.startNode("attributes"); // <attributes>
- context.convertAnother(attributes);
- writer.endNode(); // </attributes>
+ if (mapper != null) {
+ String classAlias = mapper.aliasForSystemAttribute("class");
+ for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry = (Map.Entry)iter.next();
+ String name = textAttributeConverter.toString(entry.getKey());
+ Object value = entry.getValue();
+ Class type = value != null ? value.getClass() : Mapper.Null.class;
+ ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, type);
+ writer.addAttribute(classAlias, mapper.serializedClass(type));
+ if (value != null) {
+ context.convertAnother(value);
+ }
+ writer.endNode();
+ }
+ } else {
+ writer.startNode("attributes"); // <attributes>
+ context.convertAnother(attributes);
+ writer.endNode(); // </attributes>
+ }
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
- reader.moveDown(); // into <attributes>
- Map attributes = (Map) context.convertAnother(null, Map.class);
- reader.moveUp(); // out of </attributes>
+ final Map attributes;
+ if (reader.hasMoreChildren()) {
+ reader.moveDown();
+ if (!reader.getNodeName().equals("attributes")) {
+ String classAlias = mapper.aliasForSystemAttribute("class");
+ attributes = new HashMap();
+ do {
+ if (!attributes.isEmpty()) {
+ reader.moveDown();
+ }
+ Class type = mapper.realClass(reader.getAttribute(classAlias));
+ TextAttribute attribute = (TextAttribute)textAttributeConverter.fromString(reader.getNodeName());
+ Object value = type == Mapper.Null.class ? null : context.convertAnother(null, type);
+ attributes.put(attribute, value);
+ reader.moveUp();
+ } while(reader.hasMoreChildren());
+ } else {
+ // in <attributes>
+ attributes = (Map)context.convertAnother(null, Map.class);
+ reader.moveUp(); // out of </attributes>
+ }
+ } else {
+ attributes = Collections.EMPTY_MAP;
+ }
Font font = Font.getFont(attributes);
if (context.getRequiredType() == FontUIResource.class) {
return new FontUIResource(font);
Modified: trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java (2133 => 2134)
--- trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java 2013-09-26 18:07:27 UTC (rev 2133)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java 2013-09-26 19:13:29 UTC (rev 2134)
@@ -69,6 +69,70 @@
assertEquals(inAttributes, outAttributes);
}
+
+ public void testUnmarshalsCurrentFormat() {
+ // XML representation since 1.4.5
+ String xml= (""
+ + "<awt-font>\n"
+ + " <posture class='null'/>\n"
+ + " <weight class='float'>2.0</weight>\n"
+ + " <superscript class='null'/>\n"
+ + " <transform class='null'/>\n"
+ + " <size class='float'>20.0</size>\n"
+ + " <width class='null'/>\n"
+ + " <family class='string'>Arial</family>\n"
+ + " <tracking class='null'/>\n"
+ + "</awt-font>").replace('\'', '"');
+ Font out = (Font) xstream.fromXML(xml);
+
+ // assert
+ assertEquals(in, out);
+ }
+
+ public void testUnmarshalsOldFormat() {
+ // XML representation pre 1.4.5
+ String xml = ""
+ + "<awt-font>\n"
+ + " <attributes>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>posture</awt-text-attribute>\n"
+ + " <null/>\n"
+ + " </entry>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>weight</awt-text-attribute>\n"
+ + " <float>2.0</float>\n"
+ + " </entry>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>superscript</awt-text-attribute>\n"
+ + " <null/>\n"
+ + " </entry>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>transform</awt-text-attribute>\n"
+ + " <null/>\n"
+ + " </entry>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>size</awt-text-attribute>\n"
+ + " <float>20.0</float>\n"
+ + " </entry>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>width</awt-text-attribute>\n"
+ + " <null/>\n"
+ + " </entry>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>family</awt-text-attribute>\n"
+ + " <string>Arial</string>\n"
+ + " </entry>\n"
+ + " <entry>\n"
+ + " <awt-text-attribute>tracking</awt-text-attribute>\n"
+ + " <null/>\n"
+ + " </entry>\n"
+ + " </attributes>\n"
+ + "</awt-font>";
+ Font out = (Font) xstream.fromXML(xml);
+
+ // assert
+ assertEquals(in, out);
+ }
public void testCorrectlyInitializesFontToPreventJvmCrash() {
// If a font has not been constructed in the correct way, the JVM crashes horribly through some internal
@@ -79,6 +143,5 @@
Toolkit.getDefaultToolkit().getFontMetrics(out);
// if the JVM hasn't crashed yet, we're good.
-
}
}
Modified: trunk/xstream-distribution/src/content/changes.html (2133 => 2134)
--- trunk/xstream-distribution/src/content/changes.html 2013-09-26 18:07:27 UTC (rev 2133)
+++ trunk/xstream-distribution/src/content/changes.html 2013-09-26 19:13:29 UTC (rev 2134)
@@ -58,7 +58,8 @@
inner elements.</li>
<li>JIRA:XSTR-726: New annotation XStreamAliasType to support declarative definition of XStream.aliasType().</li>
<li>JIRA:XSTR-735: Support for JDOM2 with JDom2Driver, JDom2Reader and JDom2Writer.</li>
- <li>Fix: ToAttributedValueConverter silently appends fields without attribute support to the value.</li>
+ <li>Optimized XML structure for java.awt.Font.</li>
+ <li>Fix: ToAttributedValueConverter silently appends fields without attribute support to the value producing mixed-mode XML.</li>
<li>JIRA:XSTR-566 and JIRA:XSTR-249: Better compatibility with Google AppEngine and J2ME, setup no longer fails for unavailable converters.</li>
</ul>
@@ -96,26 +97,26 @@
<h2>API changes</h2>
<ul>
- <li>Added c.t.x.converter.extended.NamedCollectionConverter for free element names in collections.</li>
- <li>Added c.t.x.converter.extended.NamedMapConverter for free element names in maps.</li>
+ <li>Added c.t.x.convertesr.extended.NamedCollectionConverter for free element names in collections.</li>
+ <li>Added c.t.x.converters.extended.NamedMapConverter for free element names in maps.</li>
<li>Added c.t.x.io.xml.StandardStaxDriver to use the StAX implementation delivered with the Java 6 runtime.</li>
<li>Deprecated c.t.x.io.xml.SjsxpStaxDriver to select the internal StAX implementation of Oracle.</li>
<li>Added static methods getStaxInputFactory and getStaxOutputFactory to c.t.x.core.JVM as returning the
implementations of javax.xml.stream.XMLInputFactory (resp. javax.xml.stream.XMLOutputFactory) delivered with
the Java Runtime since Java 6.</li>
<li>Added c.t.x.core.ClassLoaderReference.</li>
- <li>Added constructors taking an additional type argument for c.t.x.converter.collections.CollectionConverter
- and c.t.x.converter.collections.MapConverter.</li>
+ <li>Added constructors taking an additional Class argument for c.t.x.converters.collections.CollectionConverter
+ and c.t.x.converters.collections.MapConverter.</li>
<li>Added constructors taking a ClassLoaderReference instead of a ClassLoader and deprecated the ones taking the ClassLoader:
<ul>
<li>c.t.x.XStream</li>
- <li>c.t.x.converter.extended.DynamicProxyConverter</li>
- <li>c.t.x.converter.extended.JavaClassConverter</li>
- <li>c.t.x.converter.extended.JavaFieldConverter</li>
- <li>c.t.x.converter.extended.JavaMethodConverter</li>
- <li>c.t.x.converter.reflection.CGLIBEnhancedConverter</li>
- <li>c.t.x.converter.reflection.ExternalizableConverter</li>
- <li>c.t.x.converter.reflection.SerializableConverter</li>
+ <li>c.t.x.converters.extended.DynamicProxyConverter</li>
+ <li>c.t.x.converters.extended.JavaClassConverter</li>
+ <li>c.t.x.converters.extended.JavaFieldConverter</li>
+ <li>c.t.x.converters.extended.JavaMethodConverter</li>
+ <li>c.t.x.converters.reflection.CGLIBEnhancedConverter</li>
+ <li>c.t.x.converters.reflection.ExternalizableConverter</li>
+ <li>c.t.x.converters.reflection.SerializableConverter</li>
<li>c.t.x.mapper.AnnotationMapper</li>
<li>c.t.x.mapper.DefaultMapper</li>
</ul>
@@ -132,6 +133,8 @@
String).</li>
<li>Deprecated constructor c.t.x.converters.extended.RegexPatternConverter(Converter)
in favor of c.t.x.converters.extended.RegexPatternConverter().</li>
+ <li>Deprecated default constructor of c.t.x.converters.extended.FontConverter in favor of
+ c.t.x.converters.extended.FontConverter(Mapper).</li>
<li>Deprecated constructor c.t.x.converters.extended.ThrowableConverter(Converter)
in favor of c.t.x.converters.extended.ThrowableConverter(ConverterLookup).</li>
<li>Deprecated class c.t.x.converters.reflection.SelfStreamingInstanceChecker and moved
Modified: trunk/xstream-distribution/src/content/converters.html (2133 => 2134)
--- trunk/xstream-distribution/src/content/converters.html 2013-09-26 18:07:27 UTC (rev 2133)
+++ trunk/xstream-distribution/src/content/converters.html 2013-09-26 19:13:29 UTC (rev 2134)
@@ -692,7 +692,16 @@
<td><a href=""
<td>java.awt.Font<br/>
javax.swing.plaf.FontUIResource</td>
- <td class="example"><font>Arial</font></td>
+ <td class="example">
+ <awt-font><br/>
+ <family class="string">Arial</family><br/>
+ <size class="float">20.0</size><br/>
+ <width class="null"/><br/>
+ <posture class="null"/><br/>
+ <weight class="float">2.0</weight><br/>
+ <superscript class="null"/><br/>
+ </awt-font>
+ </td>
<td>Only automatically registered if runtime has AWT support.<br/>
<b>Warning:</b> The AWT toolkit is definitely initialized when a Font is deserialized.</td>
<td>normal</td>
To unsubscribe from this list please visit:
