| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.intellij.util.xmlb; |
| |
| import com.intellij.openapi.util.JDOMUtil; |
| import com.intellij.openapi.util.Ref; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.util.xmlb.annotations.*; |
| import junit.framework.AssertionFailedError; |
| import junit.framework.TestCase; |
| import org.intellij.lang.annotations.Language; |
| import org.jdom.Element; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.*; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| /** |
| * @author mike |
| */ |
| public class XmlSerializerTest extends TestCase { |
| private static final String XML_PREFIX = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; |
| |
| public static class EmptyBean { |
| } |
| |
| public void testEmptyBeanSerialization() { |
| doSerializerTest("<EmptyBean />", new EmptyBean()); |
| } |
| |
| @Tag("Bean") |
| public static class EmptyBeanWithCustomName { |
| } |
| |
| public void testEmptyBeanSerializationWithCustomName() { |
| doSerializerTest("<Bean />", new EmptyBeanWithCustomName()); |
| } |
| |
| |
| public static class BeanWithPublicFields implements Comparable<BeanWithPublicFields> { |
| public int INT_V = 1; |
| public String STRING_V = "hello"; |
| |
| public BeanWithPublicFields(final int INT_V, final String STRING_V) { |
| this.INT_V = INT_V; |
| this.STRING_V = STRING_V; |
| } |
| |
| public BeanWithPublicFields() { |
| } |
| |
| @Override |
| public int compareTo(final BeanWithPublicFields o) { |
| return STRING_V.compareTo(o.STRING_V); |
| } |
| } |
| |
| public void testPublicFieldSerialization() { |
| BeanWithPublicFields bean = new BeanWithPublicFields(); |
| |
| doSerializerTest( |
| "<BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| "</BeanWithPublicFields>", bean); |
| |
| bean.INT_V = 2; |
| bean.STRING_V = "bye"; |
| |
| doSerializerTest( |
| "<BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| " <option name=\"STRING_V\" value=\"bye\" />\n" + |
| "</BeanWithPublicFields>", bean); |
| } |
| |
| |
| public static class BeanWithPublicFieldsDescendant extends BeanWithPublicFields { |
| public String NEW_S = "foo"; |
| } |
| |
| public void testPublicFieldSerializationWithInheritance() { |
| BeanWithPublicFieldsDescendant bean = new BeanWithPublicFieldsDescendant(); |
| |
| doSerializerTest( |
| "<BeanWithPublicFieldsDescendant>\n" + |
| " <option name=\"NEW_S\" value=\"foo\" />\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| "</BeanWithPublicFieldsDescendant>", |
| bean); |
| |
| bean.INT_V = 2; |
| bean.STRING_V = "bye"; |
| bean.NEW_S = "bar"; |
| |
| doSerializerTest( |
| "<BeanWithPublicFieldsDescendant>\n" + |
| " <option name=\"NEW_S\" value=\"bar\" />\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| " <option name=\"STRING_V\" value=\"bye\" />\n" + |
| "</BeanWithPublicFieldsDescendant>", |
| bean); |
| } |
| |
| public static class BeanWithSubBean { |
| public EmptyBeanWithCustomName BEAN1 = new EmptyBeanWithCustomName(); |
| public BeanWithPublicFields BEAN2 = new BeanWithPublicFields(); |
| } |
| |
| public void testSubBeanSerialization() { |
| BeanWithSubBean bean = new BeanWithSubBean(); |
| doSerializerTest( |
| "<BeanWithSubBean>\n" + |
| " <option name=\"BEAN1\">\n" + |
| " <Bean />\n" + |
| " </option>\n" + |
| " <option name=\"BEAN2\">\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " </option>\n" + |
| "</BeanWithSubBean>", |
| bean); |
| bean.BEAN2.INT_V = 2; |
| bean.BEAN2.STRING_V = "bye"; |
| |
| doSerializerTest( |
| "<BeanWithSubBean>\n" + |
| " <option name=\"BEAN1\">\n" + |
| " <Bean />\n" + |
| " </option>\n" + |
| " <option name=\"BEAN2\">\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| " <option name=\"STRING_V\" value=\"bye\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " </option>\n" + |
| "</BeanWithSubBean>", |
| bean); |
| } |
| |
| public void testNullFieldValue() { |
| BeanWithPublicFields bean1 = new BeanWithPublicFields(); |
| |
| doSerializerTest( |
| "<BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| "</BeanWithPublicFields>", |
| bean1); |
| |
| bean1.STRING_V = null; |
| |
| doSerializerTest( |
| "<BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" />\n" + |
| "</BeanWithPublicFields>", bean1); |
| |
| BeanWithSubBean bean2 = new BeanWithSubBean(); |
| bean2.BEAN1 = null; |
| bean2.BEAN2 = null; |
| |
| doSerializerTest( |
| "<BeanWithSubBean>\n" + |
| " <option name=\"BEAN1\" />\n" + |
| " <option name=\"BEAN2\" />\n" + |
| "</BeanWithSubBean>", bean2); |
| |
| } |
| |
| public static class BeanWithList { |
| public List<String> VALUES = new ArrayList<String>(Arrays.asList("a", "b", "c")); |
| } |
| |
| public void testListSerialization() { |
| BeanWithList bean = new BeanWithList(); |
| |
| doSerializerTest( |
| "<BeanWithList>\n" + |
| " <option name=\"VALUES\">\n" + |
| " <list>\n" + |
| " <option value=\"a\" />\n" + |
| " <option value=\"b\" />\n" + |
| " <option value=\"c\" />\n" + |
| " </list>\n" + |
| " </option>\n" + |
| "</BeanWithList>", |
| bean); |
| |
| bean.VALUES = new ArrayList<String>(Arrays.asList("1", "2", "3")); |
| |
| doSerializerTest( |
| "<BeanWithList>\n" + |
| " <option name=\"VALUES\">\n" + |
| " <list>\n" + |
| " <option value=\"1\" />\n" + |
| " <option value=\"2\" />\n" + |
| " <option value=\"3\" />\n" + |
| " </list>\n" + |
| " </option>\n" + |
| "</BeanWithList>", |
| bean); |
| } |
| |
| public static class BeanWithSet { |
| public Set<String> VALUES = new LinkedHashSet<String>(Arrays.asList("a", "b", "w")); |
| } |
| |
| public void testSetSerialization() { |
| BeanWithSet bean = new BeanWithSet(); |
| doSerializerTest( |
| "<BeanWithSet>\n" + |
| " <option name=\"VALUES\">\n" + |
| " <set>\n" + |
| " <option value=\"a\" />\n" + |
| " <option value=\"b\" />\n" + |
| " <option value=\"w\" />\n" + |
| " </set>\n" + |
| " </option>\n" + |
| "</BeanWithSet>", |
| bean); |
| bean.VALUES = new LinkedHashSet<String>(Arrays.asList("1", "2", "3")); |
| |
| doSerializerTest( |
| "<BeanWithSet>\n" + |
| " <option name=\"VALUES\">\n" + |
| " <set>\n" + |
| " <option value=\"1\" />\n" + |
| " <option value=\"2\" />\n" + |
| " <option value=\"3\" />\n" + |
| " </set>\n" + |
| " </option>\n" + |
| "</BeanWithSet>", |
| bean); |
| } |
| |
| public static class BeanWithMap { |
| public Map<String, String> VALUES = new HashMap<String, String>(); |
| |
| { |
| VALUES.put("a", "1"); |
| VALUES.put("b", "2"); |
| VALUES.put("c", "3"); |
| } |
| } |
| |
| public void testMapSerialization() { |
| BeanWithMap bean = new BeanWithMap(); |
| doSerializerTest( |
| "<BeanWithMap>\n" + |
| " <option name=\"VALUES\">\n" + |
| " <map>\n" + |
| " <entry key=\"a\" value=\"1\" />\n" + |
| " <entry key=\"b\" value=\"2\" />\n" + |
| " <entry key=\"c\" value=\"3\" />\n" + |
| " </map>\n" + |
| " </option>\n" + |
| "</BeanWithMap>", |
| bean); |
| bean.VALUES.clear(); |
| bean.VALUES.put("1", "a"); |
| bean.VALUES.put("2", "b"); |
| bean.VALUES.put("3", "c"); |
| |
| doSerializerTest( |
| "<BeanWithMap>\n" + |
| " <option name=\"VALUES\">\n" + |
| " <map>\n" + |
| " <entry key=\"1\" value=\"a\" />\n" + |
| " <entry key=\"2\" value=\"b\" />\n" + |
| " <entry key=\"3\" value=\"c\" />\n" + |
| " </map>\n" + " </option>\n" + |
| "</BeanWithMap>", |
| bean); |
| } |
| |
| |
| public static class BeanWithMapWithAnnotations { |
| @Property(surroundWithTag = false) |
| @MapAnnotation( |
| surroundWithTag = false, |
| entryTagName = "option", |
| keyAttributeName = "name", |
| valueAttributeName = "value" |
| ) |
| public Map<String, String> VALUES = new HashMap<String, String>(); |
| |
| { |
| VALUES.put("a", "1"); |
| VALUES.put("b", "2"); |
| VALUES.put("c", "3"); |
| } |
| } |
| |
| public void testMapSerializationWithAnnotations() { |
| BeanWithMapWithAnnotations bean = new BeanWithMapWithAnnotations(); |
| doSerializerTest( |
| "<BeanWithMapWithAnnotations>\n" + |
| " <option name=\"a\" value=\"1\" />\n" + |
| " <option name=\"b\" value=\"2\" />\n" + |
| " <option name=\"c\" value=\"3\" />\n" + |
| "</BeanWithMapWithAnnotations>", |
| bean); |
| bean.VALUES.clear(); |
| bean.VALUES.put("1", "a"); |
| bean.VALUES.put("2", "b"); |
| bean.VALUES.put("3", "c"); |
| |
| doSerializerTest( |
| "<BeanWithMapWithAnnotations>\n" + |
| " <option name=\"1\" value=\"a\" />\n" + |
| " <option name=\"2\" value=\"b\" />\n" + |
| " <option name=\"3\" value=\"c\" />\n" + |
| "</BeanWithMapWithAnnotations>", |
| bean); |
| } |
| |
| |
| public static class BeanWithMapWithBeanValue { |
| public Map<String, BeanWithProperty> VALUES = new HashMap<String, BeanWithProperty>(); |
| |
| } |
| public void testMapWithBeanValue() { |
| BeanWithMapWithBeanValue bean = new BeanWithMapWithBeanValue(); |
| |
| bean.VALUES.put("a", new BeanWithProperty("James")); |
| bean.VALUES.put("b", new BeanWithProperty("Bond")); |
| bean.VALUES.put("c", new BeanWithProperty("Bill")); |
| |
| doSerializerTest( |
| "<BeanWithMapWithBeanValue>\n" + |
| " <option name=\"VALUES\">\n" + |
| " <map>\n" + |
| " <entry key=\"a\">\n" + |
| " <value>\n" + |
| " <BeanWithProperty>\n" + |
| " <option name=\"name\" value=\"James\" />\n" + |
| " </BeanWithProperty>\n" + |
| " </value>\n" + |
| " </entry>\n" + |
| " <entry key=\"b\">\n" + |
| " <value>\n" + |
| " <BeanWithProperty>\n" + |
| " <option name=\"name\" value=\"Bond\" />\n" + |
| " </BeanWithProperty>\n" + |
| " </value>\n" + |
| " </entry>\n" + |
| " <entry key=\"c\">\n" + |
| " <value>\n" + |
| " <BeanWithProperty>\n" + |
| " <option name=\"name\" value=\"Bill\" />\n" + |
| " </BeanWithProperty>\n" + |
| " </value>\n" + |
| " </entry>\n" + |
| " </map>\n" + |
| " </option>\n" + |
| "</BeanWithMapWithBeanValue>", |
| bean); |
| } |
| |
| public static class BeanWithOption { |
| @OptionTag("path") |
| public String PATH; |
| } |
| |
| public void testOptionTag() { |
| BeanWithOption bean = new BeanWithOption(); |
| bean.PATH = "123"; |
| doSerializerTest("<BeanWithOption>\n" + |
| " <option name=\"path\" value=\"123\" />\n" + |
| "</BeanWithOption>", bean); |
| } |
| |
| public static class BeanWithCustomizedOption { |
| @OptionTag(tag = "setting", nameAttribute = "key", valueAttribute = "saved") |
| public String PATH; |
| } |
| |
| public void testCustomizedOptionTag() { |
| BeanWithCustomizedOption bean = new BeanWithCustomizedOption(); |
| bean.PATH = "123"; |
| doSerializerTest("<BeanWithCustomizedOption>\n" + |
| " <setting key=\"PATH\" saved=\"123\" />\n" + |
| "</BeanWithCustomizedOption>", bean); |
| } |
| |
| public static class BeanWithProperty { |
| private String name = "James"; |
| |
| public BeanWithProperty() { |
| } |
| |
| public BeanWithProperty(final String name) { |
| this.name = name; |
| } |
| |
| public String getName() { |
| return name; |
| } |
| |
| |
| public void setName(String name) { |
| this.name = name; |
| } |
| } |
| |
| public void testPropertySerialization() { |
| BeanWithProperty bean = new BeanWithProperty(); |
| |
| doSerializerTest( |
| "<BeanWithProperty>\n" + |
| " <option name=\"name\" value=\"James\" />\n" + |
| "</BeanWithProperty>", |
| bean); |
| |
| bean.setName("Bond"); |
| |
| doSerializerTest( |
| "<BeanWithProperty>\n" + |
| " <option name=\"name\" value=\"Bond\" />\n" + |
| "</BeanWithProperty>", bean); |
| } |
| |
| public static class BeanWithFieldWithTagAnnotation { |
| @Tag("name") |
| public String STRING_V = "hello"; |
| } |
| |
| public void testParallelDeserialization() throws InterruptedException { |
| final Element e = new Element("root").addContent(new Element("name").setText("x")); |
| XmlSerializer.deserialize(e, BeanWithArray.class);//to initialize XmlSerializerImpl.ourBindings |
| Thread[] threads = new Thread[5]; |
| final AtomicReference<AssertionFailedError> exc = new AtomicReference<AssertionFailedError>(); |
| for (int i = 0; i < threads.length; i++) { |
| threads[i] = new Thread("XmlSerializerTest#testParallelDeserialization-" + i) { |
| @Override |
| public void run() { |
| try { |
| for (int j = 0; j < 10; j++) { |
| BeanWithFieldWithTagAnnotation bean = XmlSerializer.deserialize(e, BeanWithFieldWithTagAnnotation.class); |
| assertNotNull(bean); |
| assertEquals("x", bean.STRING_V); |
| } |
| } |
| catch (AssertionFailedError e) { |
| exc.set(e); |
| } |
| } |
| }; |
| } |
| for (Thread thread : threads) { |
| thread.start(); |
| } |
| for (Thread thread : threads) { |
| thread.join(); |
| } |
| AssertionFailedError error = exc.get(); |
| if (error != null) { |
| throw error; |
| } |
| } |
| |
| public void testFieldWithTagAnnotation() { |
| BeanWithFieldWithTagAnnotation bean = new BeanWithFieldWithTagAnnotation(); |
| |
| doSerializerTest( |
| "<BeanWithFieldWithTagAnnotation>\n" + |
| " <name>hello</name>\n" + |
| "</BeanWithFieldWithTagAnnotation>", |
| bean); |
| |
| bean.STRING_V = "bye"; |
| |
| doSerializerTest( |
| "<BeanWithFieldWithTagAnnotation>\n" + |
| " <name>bye</name>\n" + |
| "</BeanWithFieldWithTagAnnotation>", bean); |
| } |
| |
| public void testEscapeCharsInTagText() { |
| BeanWithFieldWithTagAnnotation bean = new BeanWithFieldWithTagAnnotation(); |
| bean.STRING_V = "a\nb\"<"; |
| |
| doSerializerTest( |
| "<BeanWithFieldWithTagAnnotation>\n" + |
| " <name>a\nb"<</name>\n" + |
| "</BeanWithFieldWithTagAnnotation>", bean); |
| } |
| |
| public void testEscapeCharsInAttributeValue() { |
| final BeanWithPropertiesBoundToAttribute bean = new BeanWithPropertiesBoundToAttribute(); |
| bean.name = "a\nb\"<"; |
| doSerializerTest("<BeanWithPropertiesBoundToAttribute count=\"3\" name=\"a b"<\" />", bean); |
| } |
| |
| public void testShuffledDeserialize() { |
| BeanWithPublicFields bean = new BeanWithPublicFields(); |
| bean.INT_V = 987; |
| bean.STRING_V = "1234"; |
| |
| Element element = serialize(bean, null); |
| |
| Element node = (Element)element.getChildren().get(0); |
| element.removeContent(node); |
| element.addContent(node); |
| |
| bean = XmlSerializer.deserialize(element, bean.getClass()); |
| assert bean != null; |
| assertEquals(987, bean.INT_V); |
| assertEquals("1234", bean.STRING_V); |
| } |
| |
| public void testFilterSerializer() { |
| BeanWithPublicFields bean = new BeanWithPublicFields(); |
| assertSerializer(bean, |
| "<BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| "</BeanWithPublicFields>", |
| new SerializationFilter() { |
| @Override |
| public boolean accepts(Accessor accessor, Object bean) { |
| return accessor.getName().startsWith("I"); |
| } |
| }); |
| } |
| |
| public static class BeanWithArray { |
| public String[] ARRAY_V = new String[] {"a", "b"}; |
| } |
| public void testArray() { |
| final BeanWithArray bean = new BeanWithArray(); |
| doSerializerTest( |
| "<BeanWithArray>\n" + |
| " <option name=\"ARRAY_V\">\n" + |
| " <array>\n" + |
| " <option value=\"a\" />\n" + |
| " <option value=\"b\" />\n" + |
| " </array>\n" + |
| " </option>\n" + |
| "</BeanWithArray>", bean); |
| |
| bean.ARRAY_V = new String[] {"1", "2", "3"}; |
| doSerializerTest( |
| "<BeanWithArray>\n" + |
| " <option name=\"ARRAY_V\">\n" + |
| " <array>\n" + |
| " <option value=\"1\" />\n" + |
| " <option value=\"2\" />\n" + |
| " <option value=\"3\" />\n" + |
| " </array>\n" + " </option>\n" + |
| "</BeanWithArray>", bean); |
| } |
| |
| public static class BeanWithTransient { |
| @Transient |
| public int INT_V = 1; |
| |
| @Transient |
| public String getValue() { |
| return "foo"; |
| } |
| } |
| public void testTransient() { |
| final BeanWithTransient bean = new BeanWithTransient(); |
| doSerializerTest("<BeanWithTransient />", bean); |
| } |
| |
| public static class BeanWithArrayWithoutTagName { |
| @com.intellij.util.xmlb.annotations.AbstractCollection(surroundWithTag = false) |
| public String[] V = new String[]{"a"}; |
| } |
| public void testArrayAnnotationWithoutTagNAmeGivesError() { |
| final BeanWithArrayWithoutTagName bean = new BeanWithArrayWithoutTagName(); |
| |
| try { |
| doSerializerTest("<BeanWithArrayWithoutTagName><option name=\"V\"><option value=\"a\"/></option></BeanWithArrayWithoutTagName>", bean); |
| } |
| catch (XmlSerializationException e) { |
| return; |
| } |
| |
| fail("No Exception"); |
| } |
| |
| public static class BeanWithArrayWithElementTagName { |
| @com.intellij.util.xmlb.annotations.AbstractCollection(elementTag = "vvalue", elementValueAttribute = "v") |
| public String[] V = new String[]{"a", "b"}; |
| } |
| public void testArrayAnnotationWithElementTag() { |
| final BeanWithArrayWithElementTagName bean = new BeanWithArrayWithElementTagName(); |
| |
| doSerializerTest( |
| "<BeanWithArrayWithElementTagName>\n" + |
| " <option name=\"V\">\n" + |
| " <array>\n" + |
| " <vvalue v=\"a\" />\n" + |
| " <vvalue v=\"b\" />\n" + |
| " </array>\n" + |
| " </option>\n" + |
| "</BeanWithArrayWithElementTagName>", |
| bean); |
| |
| bean.V = new String[] {"1", "2", "3"}; |
| |
| doSerializerTest( |
| "<BeanWithArrayWithElementTagName>\n" + |
| " <option name=\"V\">\n" + |
| " <array>\n" + |
| " <vvalue v=\"1\" />\n" + |
| " <vvalue v=\"2\" />\n" + |
| " <vvalue v=\"3\" />\n" + |
| " </array>\n" + |
| " </option>\n" + |
| "</BeanWithArrayWithElementTagName>", bean); |
| } |
| |
| public static class BeanWithArrayWithoutTag { |
| @com.intellij.util.xmlb.annotations.AbstractCollection(elementTag = "vvalue", elementValueAttribute = "v", surroundWithTag = false) |
| public String[] V = new String[]{"a", "b"}; |
| public int INT_V = 1; |
| } |
| public void testArrayWithoutTag() { |
| final BeanWithArrayWithoutTag bean = new BeanWithArrayWithoutTag(); |
| |
| doSerializerTest( |
| "<BeanWithArrayWithoutTag>\n" + |
| " <option name=\"V\">\n" + |
| " <vvalue v=\"a\" />\n" + |
| " <vvalue v=\"b\" />\n" + |
| " </option>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| "</BeanWithArrayWithoutTag>", bean); |
| |
| bean.V = new String[] {"1", "2", "3"}; |
| |
| doSerializerTest( |
| "<BeanWithArrayWithoutTag>\n" + |
| " <option name=\"V\">\n" + |
| " <vvalue v=\"1\" />\n" + |
| " <vvalue v=\"2\" />\n" + |
| " <vvalue v=\"3\" />\n" + |
| " </option>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| "</BeanWithArrayWithoutTag>", bean); |
| } |
| |
| |
| public static class BeanWithPropertyWithoutTagOnPrimitiveValue { |
| @Property(surroundWithTag = false) |
| public int INT_V = 1; |
| } |
| public void testPropertyWithoutTagWithPrimitiveType() { |
| final BeanWithPropertyWithoutTagOnPrimitiveValue bean = new BeanWithPropertyWithoutTagOnPrimitiveValue(); |
| |
| try { |
| doSerializerTest("<BeanWithFieldWithTagAnnotation><name>hello</name></BeanWithFieldWithTagAnnotation>", bean); |
| } |
| catch (XmlSerializationException e) { |
| return; |
| } |
| |
| fail("No Exception"); |
| } |
| |
| public static class BeanWithPropertyWithoutTag { |
| @Property(surroundWithTag = false) |
| public BeanWithPublicFields BEAN1 = new BeanWithPublicFields(); |
| public int INT_V = 1; |
| } |
| public void testPropertyWithoutTag() { |
| final BeanWithPropertyWithoutTag bean = new BeanWithPropertyWithoutTag(); |
| |
| doSerializerTest( |
| "<BeanWithPropertyWithoutTag>\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| "</BeanWithPropertyWithoutTag>", |
| bean); |
| |
| bean.INT_V = 2; |
| bean.BEAN1.STRING_V = "junk"; |
| |
| doSerializerTest( |
| "<BeanWithPropertyWithoutTag>\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"junk\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| "</BeanWithPropertyWithoutTag>", bean); |
| } |
| |
| |
| public static class BeanWithArrayWithoutAllsTag { |
| @Property(surroundWithTag = false) |
| @com.intellij.util.xmlb.annotations.AbstractCollection(elementTag = "vvalue", elementValueAttribute = "v", surroundWithTag = false) |
| public String[] V = new String[]{"a", "b"}; |
| public int INT_V = 1; |
| } |
| public void testArrayWithoutAllTags() { |
| final BeanWithArrayWithoutAllsTag bean = new BeanWithArrayWithoutAllsTag(); |
| |
| doSerializerTest( |
| "<BeanWithArrayWithoutAllsTag>\n" + |
| " <vvalue v=\"a\" />\n" + |
| " <vvalue v=\"b\" />\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| "</BeanWithArrayWithoutAllsTag>", bean); |
| |
| bean.INT_V = 2; |
| bean.V = new String[] {"1", "2", "3"}; |
| |
| doSerializerTest( |
| "<BeanWithArrayWithoutAllsTag>\n" + |
| " <vvalue v=\"1\" />\n" + |
| " <vvalue v=\"2\" />\n" + |
| " <vvalue v=\"3\" />\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| "</BeanWithArrayWithoutAllsTag>", bean); |
| } |
| |
| public static class BeanWithArrayWithoutAllsTag2 { |
| @Property(surroundWithTag = false) |
| @com.intellij.util.xmlb.annotations.AbstractCollection(elementTag = "vvalue", elementValueAttribute = "", surroundWithTag = false) |
| public String[] V = new String[]{"a", "b"}; |
| public int INT_V = 1; |
| } |
| public void testArrayWithoutAllTags2() { |
| final BeanWithArrayWithoutAllsTag2 bean = new BeanWithArrayWithoutAllsTag2(); |
| |
| doSerializerTest( |
| "<BeanWithArrayWithoutAllsTag2>\n" + |
| " <vvalue>a</vvalue>\n" + |
| " <vvalue>b</vvalue>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| "</BeanWithArrayWithoutAllsTag2>", bean); |
| |
| bean.INT_V = 2; |
| bean.V = new String[] {"1", "2", "3"}; |
| |
| doSerializerTest( |
| "<BeanWithArrayWithoutAllsTag2>\n" + |
| " <vvalue>1</vvalue>\n" + |
| " <vvalue>2</vvalue>\n" + |
| " <vvalue>3</vvalue>\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| "</BeanWithArrayWithoutAllsTag2>", bean); |
| } |
| |
| public void testDeserializeFromFormattedXML() throws Exception { |
| String xml = "<BeanWithArrayWithoutAllsTag>\n" + " <option name=\"INT_V\" value=\"2\"/>\n" + " <vvalue v=\"1\"/>\n" + |
| " <vvalue v=\"2\"/>\n" + " <vvalue v=\"3\"/>\n" + "</BeanWithArrayWithoutAllsTag>"; |
| |
| final BeanWithArrayWithoutAllsTag bean = |
| XmlSerializer.deserialize(JDOMUtil.loadDocument(xml).getRootElement(), BeanWithArrayWithoutAllsTag.class); |
| |
| |
| assertEquals(2, bean.INT_V); |
| assertEquals("[1, 2, 3]", Arrays.asList(bean.V).toString()); |
| } |
| |
| |
| public static class BeanWithPolymorphicArray { |
| @com.intellij.util.xmlb.annotations.AbstractCollection(elementTypes = {BeanWithPublicFields.class, BeanWithPublicFieldsDescendant.class}) |
| public BeanWithPublicFields[] V = new BeanWithPublicFields[] {}; |
| } |
| |
| public void testPolymorphicArray() { |
| final BeanWithPolymorphicArray bean = new BeanWithPolymorphicArray(); |
| |
| doSerializerTest( |
| "<BeanWithPolymorphicArray>\n" + |
| " <option name=\"V\">\n" + |
| " <array />\n" + |
| " </option>\n" + |
| "</BeanWithPolymorphicArray>", bean); |
| |
| bean.V = new BeanWithPublicFields[] {new BeanWithPublicFields(), new BeanWithPublicFieldsDescendant(), new BeanWithPublicFields()}; |
| |
| doSerializerTest( |
| "<BeanWithPolymorphicArray>\n" + |
| " <option name=\"V\">\n" + |
| " <array>\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " <BeanWithPublicFieldsDescendant>\n" + |
| " <option name=\"NEW_S\" value=\"foo\" />\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| " </BeanWithPublicFieldsDescendant>\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " </array>\n" + |
| " </option>\n" + |
| "</BeanWithPolymorphicArray>", bean); |
| } |
| |
| |
| public static class BeanWithPropertiesBoundToAttribute { |
| @Attribute( "count") |
| public int COUNT = 3; |
| @Attribute("name") |
| public String name = "James"; |
| @Attribute("occupation") |
| public String occupation; |
| } |
| public void testBeanWithPrimitivePropertyBoundToAttribute() { |
| final BeanWithPropertiesBoundToAttribute bean = new BeanWithPropertiesBoundToAttribute(); |
| |
| doSerializerTest("<BeanWithPropertiesBoundToAttribute count=\"3\" name=\"James\" />", bean); |
| |
| bean.COUNT = 10; |
| bean.name = "Bond"; |
| |
| doSerializerTest("<BeanWithPropertiesBoundToAttribute count=\"10\" name=\"Bond\" />", bean); |
| } |
| |
| |
| public static class BeanWithPropertyFilter { |
| @Property( |
| filter = PropertyFilterTest.class |
| ) |
| public String STRING_V = "hello"; |
| } |
| public static class PropertyFilterTest implements SerializationFilter { |
| @Override |
| public boolean accepts(Accessor accessor, Object bean) { |
| return !accessor.read(bean).equals("skip"); |
| } |
| } |
| public void testPropertyFilter() { |
| BeanWithPropertyFilter bean = new BeanWithPropertyFilter(); |
| |
| doSerializerTest( |
| "<BeanWithPropertyFilter>\n" + |
| " <option name=\"STRING_V\" value=\"hello\" />\n" + |
| "</BeanWithPropertyFilter>", bean); |
| |
| bean.STRING_V = "bye"; |
| |
| doSerializerTest( |
| "<BeanWithPropertyFilter>\n" + |
| " <option name=\"STRING_V\" value=\"bye\" />\n" + |
| "</BeanWithPropertyFilter>", bean); |
| |
| bean.STRING_V = "skip"; |
| |
| assertSerializer(bean, "<BeanWithPropertyFilter />", null); |
| } |
| |
| public static class BeanWithJDOMElement { |
| public String STRING_V = "hello"; |
| @Tag("actions") |
| public org.jdom.Element actions; |
| } |
| |
| public void testSerializeJDOMElementField() { |
| BeanWithJDOMElement element = new BeanWithJDOMElement(); |
| element.STRING_V = "a"; |
| element.actions = new Element("x").addContent(new Element("a")).addContent(new Element("b")); |
| assertSerializer(element, "<BeanWithJDOMElement>\n" + |
| " <option name=\"STRING_V\" value=\"a\" />\n" + |
| " <actions>\n" + |
| " <a />\n" + |
| " <b />\n" + |
| " </actions>\n" + |
| "</BeanWithJDOMElement>", null); |
| |
| element.actions = null; |
| assertSerializer(element, "<BeanWithJDOMElement>\n" + |
| " <option name=\"STRING_V\" value=\"a\" />\n" + |
| "</BeanWithJDOMElement>", null); |
| } |
| |
| public void testDeserializeJDOMElementField() throws Exception { |
| |
| |
| final BeanWithJDOMElement bean = XmlSerializer.deserialize(JDOMUtil.loadDocument( |
| "<BeanWithJDOMElement><option name=\"STRING_V\" value=\"bye\"/><actions><action/><action/></actions></BeanWithJDOMElement>" |
| ).getRootElement(), BeanWithJDOMElement.class); |
| |
| |
| assertEquals("bye", bean.STRING_V); |
| assertNotNull(bean.actions); |
| assertEquals(2, bean.actions.getChildren("action").size()); |
| } |
| |
| public static class BeanWithJDOMElementArray { |
| public String STRING_V = "hello"; |
| @Tag("actions") |
| public org.jdom.Element[] actions; |
| } |
| |
| public void testJDOMElementArrayField() throws Exception { |
| String text = "<BeanWithJDOMElementArray>\n" + |
| " <option name=\"STRING_V\" value=\"bye\" />\n" + |
| " <actions>\n" + |
| " <action />\n" + |
| " <action />\n" + |
| " </actions>\n" + |
| " <actions>\n" + |
| " <action />\n" + |
| " </actions>\n" + |
| "</BeanWithJDOMElementArray>"; |
| final BeanWithJDOMElementArray bean = XmlSerializer.deserialize(JDOMUtil.loadDocument(text |
| ).getRootElement(), BeanWithJDOMElementArray.class); |
| |
| |
| assertEquals("bye", bean.STRING_V); |
| assertNotNull(bean.actions); |
| assertEquals(2, bean.actions.length); |
| assertEquals(2, bean.actions[0].getChildren().size()); |
| assertEquals(1, bean.actions[1].getChildren().size()); |
| |
| assertSerializer(bean, text, null); |
| |
| bean.actions = null; |
| String newText = "<BeanWithJDOMElementArray>\n" + |
| " <option name=\"STRING_V\" value=\"bye\" />\n" + |
| "</BeanWithJDOMElementArray>"; |
| doSerializerTest(newText, bean); |
| |
| bean.actions = new Element[0]; |
| doSerializerTest(newText, bean); |
| } |
| |
| public static class BeanWithTextAnnotation { |
| public int INT_V = 1; |
| @Text |
| public String STRING_V = "hello"; |
| |
| public BeanWithTextAnnotation(final int INT_V, final String STRING_V) { |
| this.INT_V = INT_V; |
| this.STRING_V = STRING_V; |
| } |
| |
| public BeanWithTextAnnotation() { |
| } |
| } |
| |
| public void testTextAnnotation() { |
| BeanWithTextAnnotation bean = new BeanWithTextAnnotation(); |
| |
| doSerializerTest( |
| "<BeanWithTextAnnotation>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " hello\n" + |
| "</BeanWithTextAnnotation>", bean); |
| |
| bean.INT_V = 2; |
| bean.STRING_V = "bye"; |
| |
| doSerializerTest( |
| "<BeanWithTextAnnotation>\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| " bye\n" + |
| "</BeanWithTextAnnotation>", bean); |
| } |
| |
| |
| public static enum TestEnum { |
| VALUE_1, |
| VALUE_2, |
| VALUE_3; |
| } |
| |
| public static class BeanWithEnum { |
| public TestEnum FLD = TestEnum.VALUE_1; |
| } |
| |
| public void testEnums() { |
| BeanWithEnum bean = new BeanWithEnum(); |
| |
| doSerializerTest( |
| "<BeanWithEnum>\n" + " <option name=\"FLD\" value=\"VALUE_1\" />\n" + "</BeanWithEnum>", bean); |
| |
| bean.FLD = TestEnum.VALUE_3; |
| |
| doSerializerTest( |
| "<BeanWithEnum>\n" + " <option name=\"FLD\" value=\"VALUE_3\" />\n" + "</BeanWithEnum>", bean); |
| } |
| |
| public static class BeanWithSetKeysInMap { |
| public Map<Collection<String>, String> myMap = new HashMap<Collection<String>, String>(); |
| } |
| |
| public void testSetKeysInMap() { |
| final BeanWithSetKeysInMap bean = new BeanWithSetKeysInMap(); |
| bean.myMap.put(new HashSet<String>(Arrays.asList("1", "2", "3")), "numbers"); |
| bean.myMap.put(new HashSet<String>(Arrays.asList("a", "b", "c")), "letters"); |
| |
| BeanWithSetKeysInMap bb = (BeanWithSetKeysInMap)doSerializerTest( |
| "<BeanWithSetKeysInMap>\n" + |
| " <option name=\"myMap\">\n" + |
| " <map>\n" + |
| " <entry value=\"letters\">\n" + |
| " <key>\n" + |
| " <set>\n" + |
| " <option value=\"a\" />\n" + |
| " <option value=\"b\" />\n" + |
| " <option value=\"c\" />\n" + |
| " </set>\n" + |
| " </key>\n" + |
| " </entry>\n" + |
| " <entry value=\"numbers\">\n" + |
| " <key>\n" + |
| " <set>\n" + |
| " <option value=\"1\" />\n" + |
| " <option value=\"2\" />\n" + |
| " <option value=\"3\" />\n" + |
| " </set>\n" + |
| " </key>\n" + |
| " </entry>\n" + |
| " </map>\n" + |
| " </option>\n" + |
| "</BeanWithSetKeysInMap>", |
| bean); |
| |
| for (Collection<String> collection : bb.myMap.keySet()) { |
| assertTrue(collection instanceof Set); |
| } |
| } |
| |
| public static class ConversionFromTextToAttributeBean { |
| @Property(surroundWithTag = false) |
| public ConditionBean myConditionBean = new ConditionBean(); |
| } |
| @Tag("condition") |
| public static class ConditionBean { |
| @Attribute("expression") |
| public String myNewCondition; |
| @Text |
| public String myOldCondition; |
| } |
| |
| public void testConversionFromTextToAttribute() { |
| ConversionFromTextToAttributeBean bean = new ConversionFromTextToAttributeBean(); |
| bean.myConditionBean.myOldCondition = "2+2"; |
| doSerializerTest("<ConversionFromTextToAttributeBean>\n" + |
| " <condition>2+2</condition>\n" + |
| "</ConversionFromTextToAttributeBean>", bean); |
| |
| bean = new ConversionFromTextToAttributeBean(); |
| bean.myConditionBean.myNewCondition = "2+2"; |
| doSerializerTest("<ConversionFromTextToAttributeBean>\n" + |
| " <condition expression=\"2+2\" />\n" + |
| "</ConversionFromTextToAttributeBean>", bean); |
| } |
| |
| public void testDeserializeInto() throws Exception { |
| BeanWithPublicFields bean = new BeanWithPublicFields(); |
| bean.STRING_V = "zzz"; |
| |
| String xml = "<BeanWithPublicFields><option name=\"INT_V\" value=\"999\"/></BeanWithPublicFields>"; |
| XmlSerializer.deserializeInto(bean, JDOMUtil.loadDocument(xml).getRootElement()); |
| |
| assertEquals(999, bean.INT_V); |
| assertEquals("zzz", bean.STRING_V); |
| } |
| |
| public static class BeanWithMapWithoutSurround { |
| @Tag("map") |
| @MapAnnotation(surroundWithTag = false, entryTagName = "pair", surroundKeyWithTag = false, surroundValueWithTag = false) |
| public Map<BeanWithPublicFields, BeanWithTextAnnotation> MAP = new HashMap<BeanWithPublicFields, BeanWithTextAnnotation>(); |
| } |
| |
| public void testMapWithNotSurroundingKeyAndValue() { |
| BeanWithMapWithoutSurround bean = new BeanWithMapWithoutSurround(); |
| |
| bean.MAP.put(new BeanWithPublicFields(1, "a"), new BeanWithTextAnnotation(2, "b")); |
| bean.MAP.put(new BeanWithPublicFields(3, "c"), new BeanWithTextAnnotation(4, "d")); |
| bean.MAP.put(new BeanWithPublicFields(5, "e"), new BeanWithTextAnnotation(6, "f")); |
| |
| doSerializerTest( |
| "<BeanWithMapWithoutSurround>\n" + |
| " <map>\n" + |
| " <pair>\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"1\" />\n" + |
| " <option name=\"STRING_V\" value=\"a\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " <BeanWithTextAnnotation>\n" + |
| " <option name=\"INT_V\" value=\"2\" />\n" + |
| " b\n" + |
| " </BeanWithTextAnnotation>\n" + |
| " </pair>\n" + " <pair>\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"3\" />\n" + |
| " <option name=\"STRING_V\" value=\"c\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " <BeanWithTextAnnotation>\n" + |
| " <option name=\"INT_V\" value=\"4\" />\n" + |
| " d\n" + |
| " </BeanWithTextAnnotation>\n" + |
| " </pair>\n" + |
| " <pair>\n" + |
| " <BeanWithPublicFields>\n" + |
| " <option name=\"INT_V\" value=\"5\" />\n" + |
| " <option name=\"STRING_V\" value=\"e\" />\n" + |
| " </BeanWithPublicFields>\n" + |
| " <BeanWithTextAnnotation>\n" + |
| " <option name=\"INT_V\" value=\"6\" />\n" + |
| " f\n" + |
| " </BeanWithTextAnnotation>\n" + |
| " </pair>\n" + |
| " </map>\n" + |
| "</BeanWithMapWithoutSurround>", |
| bean); |
| } |
| |
| public static class BeanWithMapAtTopLevel { |
| @Property(surroundWithTag = false) |
| @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false) |
| public Map<String, String> map = new HashMap<String, String>(); |
| |
| public String option; |
| } |
| |
| public void testMapAtTopLevel() { |
| BeanWithMapAtTopLevel bean = new BeanWithMapAtTopLevel(); |
| bean.map.put("a", "b"); |
| bean.option = "xxx"; |
| doSerializerTest("<BeanWithMapAtTopLevel>\n" + |
| " <entry key=\"a\" value=\"b\" />\n" + |
| " <option name=\"option\" value=\"xxx\" />\n" + |
| "</BeanWithMapAtTopLevel>", bean); |
| } |
| |
| private static class BeanWithConverter { |
| private static class MyConverter extends Converter<Ref<String>> { |
| @Nullable |
| @Override |
| public Ref<String> fromString(@NotNull String value) { |
| return Ref.create(value); |
| } |
| |
| @NotNull |
| @Override |
| public String toString(@NotNull Ref<String> o) { |
| return StringUtil.notNullize(o.get()); |
| } |
| } |
| |
| @Attribute(converter = MyConverter.class) |
| public Ref<String> foo; |
| |
| @OptionTag(converter = MyConverter.class) |
| public Ref<String> bar; |
| } |
| |
| public void testConverter() { |
| BeanWithConverter bean = new BeanWithConverter(); |
| doSerializerTest("<BeanWithConverter>\n" + |
| " <option name=\"bar\" />\n" + |
| "</BeanWithConverter>", bean); |
| |
| bean.foo = Ref.create("testValue"); |
| doSerializerTest("<BeanWithConverter foo=\"testValue\">\n" + |
| " <option name=\"bar\" />\n" + |
| "</BeanWithConverter>", bean); |
| |
| bean.foo = Ref.create(); |
| bean.bar = Ref.create("testValue2"); |
| doSerializerTest("<BeanWithConverter foo=\"\">\n" + |
| " <option name=\"bar\" value=\"testValue2\" />\n" + |
| "</BeanWithConverter>", bean); |
| } |
| |
| private static class BeanWithDefaultAttributeName { |
| @Attribute |
| public String getFoo() { |
| return "foo"; |
| } |
| |
| public void setFoo(@SuppressWarnings("UnusedParameters") String value) { |
| } |
| } |
| |
| public void testDefaultAttributeName() { |
| BeanWithDefaultAttributeName bean = new BeanWithDefaultAttributeName(); |
| doSerializerTest("<BeanWithDefaultAttributeName foo=\"foo\" />", bean); |
| } |
| |
| //--------------------------------------------------------------------------------------------------- |
| private static Element assertSerializer(Object bean, String expected, SerializationFilter filter) { |
| return assertSerializer(bean, expected, "Serialization failure", filter); |
| } |
| |
| private static Object doSerializerTest(@Language("XML") String expectedText, Object bean) { |
| try { |
| Element element = assertSerializer(bean, expectedText, null); |
| |
| //test deserializer |
| |
| Object o = XmlSerializer.deserialize(element, bean.getClass()); |
| assertSerializer(o, expectedText, "Deserialization failure", null); |
| return o; |
| } |
| catch (XmlSerializationException e) { |
| throw e; |
| } |
| catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private static Element assertSerializer(Object bean, String expectedText, String message, SerializationFilter filter) throws XmlSerializationException { |
| Element element = serialize(bean, filter); |
| |
| |
| String actualString = JDOMUtil.writeElement(element, "\n").trim(); |
| |
| if (!expectedText.startsWith(XML_PREFIX)) { |
| if (actualString.startsWith(XML_PREFIX)) actualString = actualString.substring(XML_PREFIX.length()).trim(); |
| } |
| |
| assertEquals(message, expectedText, actualString); |
| |
| return element; |
| } |
| |
| public static class BeanWithMapWithSetValue { |
| @MapAnnotation(entryTagName = "entry-tag", keyAttributeName = "key-attr", surroundWithTag = false) |
| public Map<String, Set<String>> myValues = new HashMap<String, Set<String>>(); |
| } |
| |
| public void testBeanWithMapWithSetValue() { |
| BeanWithMapWithSetValue bean = new BeanWithMapWithSetValue(); |
| |
| bean.myValues.put("a", ContainerUtil.newHashSet("first1", "second1")); |
| bean.myValues.put("b", ContainerUtil.newHashSet("first2", "second2")); |
| |
| doSerializerTest( |
| "<BeanWithMapWithSetValue>\n" + |
| " <option name=\"myValues\">\n" + |
| " <entry-tag key-attr=\"a\">\n" + |
| " <value>\n" + |
| " <set>\n" + |
| " <option value=\"first1\" />\n" + |
| " <option value=\"second1\" />\n" + |
| " </set>\n" + |
| " </value>\n" + |
| " </entry-tag>\n" + |
| " <entry-tag key-attr=\"b\">\n" + |
| " <value>\n" + |
| " <set>\n" + |
| " <option value=\"first2\" />\n" + |
| " <option value=\"second2\" />\n" + |
| " </set>\n" + |
| " </value>\n" + |
| " </entry-tag>\n" + |
| " </option>\n" + |
| "</BeanWithMapWithSetValue>", |
| bean); |
| } |
| |
| private static Element serialize(Object bean, SerializationFilter filter) { |
| return XmlSerializer.serialize(bean, filter); |
| } |
| } |