Title: [2048] trunk: Allow unknown XML elements to be ignored using new method XStream.ignoreUnknownFields (XSTR-691).

Diff

Modified: trunk/xstream/src/java/com/thoughtworks/xstream/XStream.java (2047 => 2048)


--- trunk/xstream/src/java/com/thoughtworks/xstream/XStream.java	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/XStream.java	2013-03-19 01:35:28 UTC (rev 2048)
@@ -50,6 +50,7 @@
 import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.Vector;
+import java.util.regex.Pattern;
 
 import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.converters.Converter;
@@ -325,6 +326,7 @@
     public static final int PRIORITY_VERY_LOW = -20;
 
     private static final String ANNOTATION_MAPPER_TYPE = "com.thoughtworks.xstream.mapper.AnnotationMapper";
+    private static final Pattern IGNORE_ALL = Pattern.compile(".*");
 
     /**
      * Constructs a default XStream. The instance will use the {@link XppDriver} as default and
@@ -1779,8 +1781,42 @@
         }
         fieldAliasingMapper.omitField(definedIn, fieldName);
     }
+    
+    /**
+     * Ignore all unknown fields.
+     * 
+     * @since upcoming
+     */
+    public void ignoreUnknownFields() {
+        ignoreUnknownFields(IGNORE_ALL);
+    }
 
     /**
+     * Add pattern for unknown field names to ignore.
+     * 
+     * @param pattern the name pattern as regular _expression_
+     * @since upcoming
+     */
+    public void ignoreUnknownFields(String pattern) {
+        ignoreUnknownFields(Pattern.compile(pattern));
+    }
+
+    /**
+     * Add pattern for unknown field names to ignore.
+     * 
+     * @param pattern the name pattern as regular _expression_
+     * @since upcoming
+     */
+    private void ignoreUnknownFields(Pattern pattern) {
+        if (fieldAliasingMapper == null) {
+            throw new com.thoughtworks.xstream.InitializationException("No "
+                + FieldAliasingMapper.class.getName()
+                + " available");
+        }
+        fieldAliasingMapper.addFieldsToIgnore(pattern);
+    }
+
+    /**
      * Process the annotations of the given types and configure the XStream.
      * 
      * @param types the types with XStream annotations

Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java (2047 => 2048)


--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java	2013-03-19 01:35:28 UTC (rev 2048)
@@ -440,16 +440,16 @@
                 return itemType;
             } else {
                 String originalNodeName = reader.getNodeName();
-                if (definedInCls == null) {
-                    for(definedInCls = result.getClass(); definedInCls != null; definedInCls = definedInCls.getSuperclass()) {
-                        if (!mapper.shouldSerializeMember(definedInCls, originalNodeName)) {
-                            return null;
-                        }
-                    }
-                }
                 try {
                     return mapper.realClass(originalNodeName);
                 } catch (CannotResolveClassException e) {
+                    if (definedInCls == null) {
+                        for(definedInCls = result.getClass(); definedInCls != null; definedInCls = definedInCls.getSuperclass()) {
+                            if (!mapper.shouldSerializeMember(definedInCls, originalNodeName)) {
+                                return null;
+                            }
+                        }
+                    }
                     throw new UnknownFieldException(result.getClass().getName(), fieldName);
                 }
             }

Modified: trunk/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java (2047 => 2048)


--- trunk/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java	2013-03-19 01:35:28 UTC (rev 2048)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -15,8 +15,11 @@
 
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 /**
  * Mapper that allows a field of a specific class to be replaced with a shorter alias, or omitted
@@ -29,6 +32,7 @@
     protected final Map fieldToAliasMap = new HashMap();
     protected final Map aliasToFieldMap = new HashMap();
     protected final Set fieldsToOmit = new HashSet();
+    protected final Set unknownFieldsToIgnore = new LinkedHashSet();
 
     public FieldAliasingMapper(Mapper wrapped) {
         super(wrapped);
@@ -38,6 +42,10 @@
         fieldToAliasMap.put(key(type, fieldName), alias);
         aliasToFieldMap.put(key(type, alias), fieldName);
     }
+    
+    public void addFieldsToIgnore(final Pattern pattern) {
+        unknownFieldsToIgnore.add(pattern);
+    }
 
     private Object key(Class type, String name) {
         return new FastField(type, name);
@@ -70,7 +78,17 @@
     }
 
     public boolean shouldSerializeMember(Class definedIn, String fieldName) {
-        return !fieldsToOmit.contains(key(definedIn, fieldName));
+        if (fieldsToOmit.contains(key(definedIn, fieldName))) {
+            return false;
+        } else if (definedIn == Object.class && !unknownFieldsToIgnore.isEmpty()) {
+            for(Iterator iter = unknownFieldsToIgnore.iterator(); iter.hasNext();) {
+                Pattern pattern = (Pattern)iter.next();
+                if (pattern.matcher(fieldName).matches()) {
+                    return false;
+                }
+            }
+        }
+        return true;
     }
 
     public void omitField(Class definedIn, String fieldName) {

Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitArrayTest.java (2047 => 2048)


--- trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitArrayTest.java	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitArrayTest.java	2013-03-19 01:35:28 UTC (rev 2048)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012 XStream Committers.
+ * Copyright (C) 2011, 2012, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -27,6 +27,7 @@
         xstream.alias("farm", Farm.class);
         xstream.alias("animal", Animal.class);
         xstream.alias("MEGA-farm", MegaFarm.class);
+        xstream.ignoreUnknownFields();
     }
 
     public static class Farm extends StandardObject {

Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitCollectionTest.java (2047 => 2048)


--- trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitCollectionTest.java	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitCollectionTest.java	2013-03-19 01:35:28 UTC (rev 2048)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -57,6 +57,7 @@
         xstream.alias("room", Room.class);
         xstream.alias("house", House.class);
         xstream.alias("person", Person.class);
+        xstream.ignoreUnknownFields();
     }
 
     public void testWithout() {

Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitMapTest.java (2047 => 2048)


--- trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitMapTest.java	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/ImplicitMapTest.java	2013-03-19 01:35:28 UTC (rev 2048)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012 XStream Committers.
+ * Copyright (C) 2011, 2012, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -63,6 +63,7 @@
         xstream.alias("software", Software.class);
         xstream.alias("hardware", Hardware.class);
         xstream.alias("product", Product.class);
+        xstream.ignoreUnknownFields();
     }
 
     public void testWithout() {

Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/OmitFieldsTest.java (2047 => 2048)


--- trunk/xstream/src/test/com/thoughtworks/acceptance/OmitFieldsTest.java	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/OmitFieldsTest.java	2013-03-19 01:35:28 UTC (rev 2048)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2010, 2012 XStream Committers.
+ * Copyright (C) 2006, 2007, 2010, 2012, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -13,6 +13,7 @@
 
 import com.thoughtworks.acceptance.objects.StandardObject;
 import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.mapper.Mapper;
 import com.thoughtworks.xstream.mapper.MapperWrapper;
 
@@ -308,12 +309,46 @@
         assertEquals("d", out.derived);
     }
 
+    public void testIgnoreUnknownFieldsMatchingPattern() {
+        String actualXml = ""
+            + "<thing>\n"
+            + "  <sometimesIgnore>foo</sometimesIgnore>\n" 
+            + "  <neverIgnore>c</neverIgnore>\n" 
+            + "  <foobar>f</foobar>\n" 
+            + "  <derived>d</derived>\n" 
+            + "</thing>";
+
+        xstream.alias("thing", DerivedThing.class);
+        xstream.omitField(Thing.class, "sometimesIgnore");
+        xstream.ignoreUnknownFields("foo.*");
+
+        DerivedThing out = (DerivedThing)xstream.fromXML(actualXml);
+        assertEquals(null, out.alwaysIgnore);
+        assertEquals(null, out.sometimesIgnore);
+        assertEquals("c", out.neverIgnore);
+        assertEquals("d", out.derived);
+        
+        try {
+            xstream.fromXML(actualXml.replace("foobar", "unknown"));
+            fail("Thrown " + ConversionException.class.getName() + " expected");
+        } catch (final ConversionException e) {
+            String message = e.getMessage();
+            assertTrue(message,
+                e.getMessage().substring(0, message.indexOf('\n')).endsWith(
+                    DerivedThing.class.getName() + ".unknown"));
+        }
+    }
+
     static class ThingAgain extends Thing {
         String sometimesIgnore;
 
         void setHidden(String s) {
             super.sometimesIgnore = s;
         }
+        
+        String getHidden() {
+            return super.sometimesIgnore;
+        }
     }
 
     // TODO: XSTR-457
@@ -337,9 +372,9 @@
         assertEquals(expectedXml, actualXml);
 
         ThingAgain out = (ThingAgain)xstream.fromXML(expectedXml);
+        assertNull(out.alwaysIgnore);
+        assertEquals("b", out.getHidden());
+        assertEquals("c", out.neverIgnore);
         assertNull(out.sometimesIgnore);
-        out.alwaysIgnore = "a";
-        out.sometimesIgnore = "d";
-        assertEquals(in, out);
     }
 }

Modified: trunk/xstream-distribution/src/content/changes.html (2047 => 2048)


--- trunk/xstream-distribution/src/content/changes.html	2013-03-16 08:49:03 UTC (rev 2047)
+++ trunk/xstream-distribution/src/content/changes.html	2013-03-19 01:35:28 UTC (rev 2048)
@@ -45,6 +45,7 @@
     <h2>Major changes</h2>
     
     <ul>
+    	<li>JIRA:XSTR-691: Allow unknown XML elements to be ignored using new method XStream.ignoreUnknownFields.</li>
     	<li>JIRA:XSTR-723: XStream will now detect a working enhanced mode dynamically instead using lists of known
     	vendors. This allows enhanced support for JamVM if it is bundled with OpenJDK. It will currently fail on a 
     	runtime based on GNU	Classpath (at least up to version 0.98).</li>

To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to