From 0b8a0291b32627e2464ee94bb19e193bd77b789d Mon Sep 17 00:00:00 2001 From: chenzero Date: Mon, 25 Sep 2017 16:46:03 +0800 Subject: [PATCH 1/2] try to fix duplicated fields in attribute and child element --- .../xstream/mapper/newtest1/Delete.java | 25 ++++++ .../xstream/mapper/newtest1/Id.java | 30 +++++++ .../xstream/mapper/newtest1/Insert.java | 25 ++++++ .../xstream/mapper/newtest1/Mapper.java | 82 +++++++++++++++++++ .../xstream/mapper/newtest1/Result.java | 35 ++++++++ .../xstream/mapper/newtest1/ResultMap.java | 77 +++++++++++++++++ .../xstream/mapper/newtest1/Select.java | 61 ++++++++++++++ .../xstream/mapper/newtest1/TestMapper.java | 27 ++++++ .../xstream/mapper/newtest1/Update.java | 32 ++++++++ .../xstream/mapper/newtest1/mapper1.xml | 36 ++++++++ 10 files changed, 430 insertions(+) create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Delete.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Insert.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Mapper.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Result.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/ResultMap.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Select.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/TestMapper.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Update.java create mode 100644 xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/mapper1.xml diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Delete.java b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Delete.java new file mode 100644 index 000000000..b583a48cf --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Delete.java @@ -0,0 +1,25 @@ +package com.thoughtworks.xstream.mapper.newtest1; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; + +@XStreamAlias("delete") +public class Delete { + @XStreamAlias("id") + @XStreamAsAttribute + public String id; + + @XStreamAlias("parameterType") + @XStreamAsAttribute + public String parameterType; + + + public String getParameterType() { + return parameterType; + } + + public void setParameterType(String parameterType) { + this.parameterType = parameterType; + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java new file mode 100644 index 000000000..cabcfa0bc --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java @@ -0,0 +1,30 @@ +package com.thoughtworks.xstream.mapper.newtest1; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; + +@XStreamAlias("id") +public class Id { + @XStreamAlias("column") + @XStreamAsAttribute + public String column; + + @XStreamAlias("property") + @XStreamAsAttribute + public String property; + + + public String getColumn() { + return column; + } + public void setColumn(String column) { + this.column = column; + } + public String getProperty() { + return property; + } + public void setProperty(String property) { + this.property = property; + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Insert.java b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Insert.java new file mode 100644 index 000000000..589c00612 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Insert.java @@ -0,0 +1,25 @@ +package com.thoughtworks.xstream.mapper.newtest1; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; + +@XStreamAlias("insert") +public class Insert { + @XStreamAlias("id") + @XStreamAsAttribute + public String id; + + @XStreamAlias("parameterType") + @XStreamAsAttribute + public String parameterType; + + + public String getParameterType() { + return parameterType; + } + + public void setParameterType(String parameterType) { + this.parameterType = parameterType; + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Mapper.java b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Mapper.java new file mode 100644 index 000000000..4f2787487 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Mapper.java @@ -0,0 +1,82 @@ +package com.thoughtworks.xstream.mapper.newtest1; + +import java.util.List; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamImplicit; + +@XStreamAlias("mapper") +public class Mapper { + + @XStreamImplicit(itemFieldName="resultMap") + public List resultMaps; + + @XStreamImplicit(itemFieldName="select") + public List getSelect() { + return select; + } + + public void setSelect(List + select S_ARTICLE.nextval from dual + + + + + select S_ARTICLE.nextval from dual + + + + update bus_article article + + update_time = #{article.updateTime, jdbcType=VARCHAR} + body =#{article.body, jdbcType=VARCHAR} + + where article_no=#{article.articleNo} + + + + + delete from BUS_ARTICLE article where article_no=#{article.articleNo} + + + + + From 375aab36de631423baec9084730fb050d5fcffdf Mon Sep 17 00:00:00 2001 From: chenzero Date: Tue, 26 Sep 2017 10:47:34 +0800 Subject: [PATCH 2/2] try to fix duplicated fields in attribute and child element --- .../com/thoughtworks/xstream/XStream.java | 20 +++++- .../AbstractReflectionConverter.java | 7 +- .../xstream/core/util/FastField.java | 68 ++++++++++++------- .../xstream/mapper/AnnotationMapper.java | 16 ++++- .../xstream/mapper/DefaultMapper.java | 5 ++ .../xstream/mapper/FieldAliasingMapper.java | 4 +- .../thoughtworks/xstream/mapper/Mapper.java | 8 +++ .../xstream/mapper/MapperWrapper.java | 5 ++ .../xstream/mapper/newtest1/Id.java | 4 ++ .../xstream/mapper/newtest1/ResultMap.java | 1 + .../xstream/mapper/newtest1/mapper1.xml | 9 ++- 11 files changed, 113 insertions(+), 34 deletions(-) diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java index 05c33154c..d80bd6b73 100644 --- a/xstream/src/java/com/thoughtworks/xstream/XStream.java +++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java @@ -1385,7 +1385,7 @@ public void aliasPackage(final String name, final String pkgName) { } packageAliasingMapper.addPackageAlias(name, pkgName); } - + /** * Create an alias for a field name. * @@ -1395,10 +1395,24 @@ public void aliasPackage(final String name, final String pkgName) { * @throws InitializationException if no {@link FieldAliasingMapper} is available */ public void aliasField(final String alias, final Class definedIn, final String fieldName) { + aliasField(alias, false, definedIn, fieldName); + } + + + /** + * Create an alias for a field name. + * + * @param alias the alias itself + * @param isAttr is attribute or not + * @param definedIn the type that declares the field + * @param fieldName the name of the field + * @throws InitializationException if no {@link FieldAliasingMapper} is available + */ + public void aliasField(final String alias, final boolean isAttr, final Class definedIn, final String fieldName) { if (fieldAliasingMapper == null) { throw new InitializationException("No " + FieldAliasingMapper.class.getName() + " available"); } - fieldAliasingMapper.addFieldAlias(alias, definedIn, fieldName); + fieldAliasingMapper.addFieldAlias(alias, isAttr, definedIn, fieldName); } /** @@ -1442,7 +1456,7 @@ public void aliasSystemAttribute(final String alias, final String systemAttribut * @since 1.2.2 */ public void aliasAttribute(final Class definedIn, final String attributeName, final String alias) { - aliasField(alias, definedIn, attributeName); + aliasField(alias, true, definedIn, attributeName); useAttributeFor(definedIn, attributeName); } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java index a472043fd..ad9f055d0 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java @@ -279,8 +279,10 @@ public Object unmarshal(final HierarchicalStreamReader reader, final Unmarshalli } public Object doUnmarshal(final Object result, final HierarchicalStreamReader reader, - final UnmarshallingContext context) { + final UnmarshallingContext context) { + final Class resultType = result.getClass(); + @SuppressWarnings("serial") final Set seenFields = new HashSet() { @Override @@ -297,7 +299,8 @@ public boolean add(final FastField e) { while (it.hasNext()) { final String attrAlias = it.next(); // TODO: realMember should return FastField - final String attrName = mapper.realMember(resultType, mapper.attributeForAlias(attrAlias)); + String attr1 = mapper.attributeForAlias(attrAlias); + final String attrName = mapper.realMember(resultType, attr1, true); final Field field = reflectionProvider.getFieldOrNull(resultType, attrName); if (field != null && shouldUnmarshalField(field)) { final Class classDefiningField = field.getDeclaringClass(); diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/FastField.java b/xstream/src/java/com/thoughtworks/xstream/core/util/FastField.java index 25810f10f..b2e46ae3f 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/util/FastField.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/FastField.java @@ -13,12 +13,20 @@ public final class FastField { private final String name; private final String declaringClass; + private final boolean isAttribute; public FastField(final String definedIn, final String name) { this.name = name; declaringClass = definedIn; + this.isAttribute = false; } + public FastField(final String definedIn, final String alias, boolean isAttribute) { + this.name = alias; + declaringClass = definedIn; + this.isAttribute = isAttribute; + } + public FastField(final Class definedIn, final String name) { this(definedIn == null ? null : definedIn.getName(), name); } @@ -31,33 +39,45 @@ public String getDeclaringClass() { return declaringClass; } - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (obj instanceof FastField) { - final FastField field = (FastField)obj; - if (declaringClass == null && field.declaringClass != null - || declaringClass != null && field.declaringClass == null) { - return false; - } - return name.equals(field.getName()) - && (declaringClass == null || declaringClass.equals(field.getDeclaringClass())); - } - return false; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + FastField other = (FastField) obj; + if (declaringClass == null) { + if (other.declaringClass != null) + return false; + } + else if (!declaringClass.equals(other.declaringClass)) + return false; + if (isAttribute != other.isAttribute) + return false; + if (name == null) { + if (other.name != null) + return false; + } + else if (!name.equals(other.name)) + return false; + return true; + } @Override - public int hashCode() { - return name.hashCode() ^ (declaringClass == null ? 0 : declaringClass.hashCode()); - } - + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((declaringClass == null) ? 0 : declaringClass.hashCode()); + result = prime * result + (isAttribute ? 1231 : 1237); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + @Override public String toString() { - return (declaringClass == null ? "" : declaringClass + ".") + name; + return (declaringClass == null ? "" : declaringClass + ".") + name + " " + isAttribute ; } + } \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java index 1eff98895..db2ba94ae 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java @@ -118,6 +118,14 @@ public String realMember(final Class type, final String serialized) { } return super.realMember(type, serialized); } + + public String realMember(final Class type, final String serialized, boolean attrOrNot) { + if (!locked) { + processAnnotation(type); + } + return super.realMember(type, serialized, attrOrNot); + } + @Override public String serializedClass(final Class type) { @@ -343,7 +351,13 @@ private void processFieldAliasAnnotation(final Field field) { if (fieldAliasingMapper == null) { throw new InitializationException("No " + FieldAliasingMapper.class.getName() + " available"); } - fieldAliasingMapper.addFieldAlias(aliasAnnotation.value(), field.getDeclaringClass(), field.getName()); + + boolean isAttr = false; + if(field.getAnnotation(XStreamAsAttribute.class)!=null) { + isAttr = true; + } + + fieldAliasingMapper.addFieldAlias(aliasAnnotation.value(), isAttr, field.getDeclaringClass(), field.getName()); } } diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java index f50a7268f..b92269001 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java @@ -159,6 +159,11 @@ public String realMember(final Class type, final String serialized) { return serialized; } + @Override + public String realMember(final Class type, final String serialized, boolean attributeOrNot) { + return serialized; + } + /** * @deprecated As of 1.3, use {@link #getConverterFromAttribute(Class, String, Class)} */ diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java index 110f16b68..baac84a6c 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java @@ -34,9 +34,9 @@ public FieldAliasingMapper(final Mapper wrapped) { elementIgnoringMapper = lookupMapperOfType(ElementIgnoringMapper.class); } - public void addFieldAlias(final String alias, final Class type, final String fieldName) { + public void addFieldAlias(final String alias, boolean isAttr, final Class type, final String fieldName) { fieldToAliasMap.put(key(type, fieldName), alias); - aliasToFieldMap.put(key(type, alias), fieldName); + aliasToFieldMap.put(new FastField(type.getName(), alias, isAttr), fieldName); } /** diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/Mapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/Mapper.java index 5a9df995b..6fc161efa 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/Mapper.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/Mapper.java @@ -36,10 +36,18 @@ class Null {} */ String serializedMember(Class type, String memberName); + /** * How a serialized member representation should be mapped back to a real member. */ String realMember(Class type, String serialized); + + /** + * How a serialized member representation should be mapped back to a real member. + * @param attributeOrNot: is attribute or child element + */ + String realMember(Class type, String serialized, boolean attributeOrNot); + /** * Whether this type is a simple immutable value (int, boolean, String, URL, etc). Immutable types will be diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/MapperWrapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/MapperWrapper.java index b83ff9913..55c188c68 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/MapperWrapper.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/MapperWrapper.java @@ -135,6 +135,11 @@ public String serializedMember(final Class type, final String memberName) { public String realMember(final Class type, final String serialized) { return realMemberMapper.realMember(type, serialized); } + + @Override + public String realMember(final Class type, final String serialized, boolean attrOrNot) { + return realMemberMapper.realMember(type, serialized, attrOrNot); + } @Override public boolean isImmutableValueType(final Class type) { diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java index cabcfa0bc..61486744a 100644 --- a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/Id.java @@ -13,6 +13,10 @@ public class Id { @XStreamAsAttribute public String property; + public String toString() { + return this.column + " " + this.property; + } + public String getColumn() { return column; diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/ResultMap.java b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/ResultMap.java index 489e08e8d..fc6ef9231 100644 --- a/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/ResultMap.java +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/newtest1/ResultMap.java @@ -32,6 +32,7 @@ public ResultMap() { public String toString() { String ret = id + " " + type + " \n"; + ret = ret + " " + id1 + "\n"; if(results!=null) { for(int i=0;i - - + + + + + + +