Skip to content

Commit 76367a8

Browse files
committedNov 25, 2019
all tests working
1 parent 81e9237 commit 76367a8

File tree

13 files changed

+2709
-2543
lines changed

13 files changed

+2709
-2543
lines changed
 

‎annotation/src/main/java/com/tickaroo/tikxml/annotation/ElementNameMatcher.java

+1
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@
4949
* class (i.e. no abstract class, interface, etc.)
5050
*/
5151
boolean compileTimeChecks() default true;
52+
5253
}

‎annotationprocessortesting/src/main/java/com/tickaroo/tikxml/annotationprocessing/element/Server.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.tickaroo.tikxml.annotation.Attribute;
2222
import com.tickaroo.tikxml.annotation.Element;
2323
import com.tickaroo.tikxml.annotation.Xml;
24+
import java.util.Objects;
2425

2526
/**
2627
* @author Hannes Dorfmann
@@ -36,8 +37,8 @@ public class Server {
3637

3738
Server server = (Server) o;
3839

39-
if (name != null ? !name.equals(server.name) : server.name != null) return false;
40-
return config != null ? config.equals(server.config) : server.config == null;
40+
if (!Objects.equals(name, server.name)) return false;
41+
return Objects.equals(config, server.config);
4142
}
4243

4344
@Override public int hashCode() {

‎annotationprocessortesting/src/main/java/com/tickaroo/tikxml/annotationprocessing/element/polymorphism/Organisation.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.tickaroo.tikxml.annotation.PropertyElement;
2222
import com.tickaroo.tikxml.annotation.Xml;
23+
import java.util.Objects;
2324

2425
/**
2526
* @author Hannes Dorfmann
@@ -36,7 +37,7 @@ public class Organisation extends Writer {
3637

3738
Organisation that = (Organisation) o;
3839

39-
return address != null ? address.equals(that.address) : that.address == null;
40+
return Objects.equals(address, that.address);
4041
}
4142

4243
@Override public int hashCode() {

‎annotationprocessortesting/src/main/java/com/tickaroo/tikxml/annotationprocessing/elementlist/InlineListCatalogue.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.tickaroo.tikxml.annotation.Element;
2222
import com.tickaroo.tikxml.annotation.Xml;
2323
import java.util.List;
24+
import java.util.Objects;
2425

2526
/**
2627
* @author Hannes Dorfmann
@@ -37,7 +38,7 @@ public class InlineListCatalogue {
3738

3839
InlineListCatalogue that = (InlineListCatalogue) o;
3940

40-
return books != null ? books.equals(that.books) : that.books == null;
41+
return Objects.equals(books, that.books);
4142
}
4243

4344
@Override public int hashCode() {

‎autovalue/src/main/java/com/tickaroo/tikxml/autovalue/AutoValueScanner.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ fun toAnnotatedMethod(propertyName: String, element: ExecutableElement): Annotat
9797
if (annotationFound > 1) {
9898
// More than one annotation is not allowed
9999
throw ProcessingException(element, "Methods can ONLY be annotated with one of the "
100-
+ "following annotations @${Attribute::class.simpleName}, "
101-
+ "@${PropertyElement::class.simpleName}, @${Element::class.simpleName} or @${TextContent::class.simpleName} "
102-
+ "and not multiple of them! The field ${element.simpleName.toString()} in class "
100+
+ "following annotations @${Attribute::class.java.simpleName}, "
101+
+ "@${PropertyElement::class.java.simpleName}, @${Element::class.java.simpleName} or @${TextContent::class.java.simpleName} "
102+
+ "and not multiple of them! The field ${element.simpleName} in class "
103103
+ "${(element.enclosingElement as TypeElement).qualifiedName} is annotated with more than one of these annotations. You must annotate a field with exactly one of these annotations (not multiple)!")
104104
}
105105

‎processor/src/main/java/com/tickaroo/tikxml/processor/generator/CodeGeneratorHelper.kt

+477-454
Large diffs are not rendered by default.

‎processor/src/main/java/com/tickaroo/tikxml/processor/scanning/AnnotationScanner.kt

+396-352
Large diffs are not rendered by default.

‎processor/src/main/java/com/tickaroo/tikxml/processor/scanning/DefaultAnnotationDetector.kt

+64-48
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import com.tickaroo.tikxml.processor.field.TextContentField
4141
import com.tickaroo.tikxml.processor.utils.getSurroundingClassQualifiedName
4242
import com.tickaroo.tikxml.processor.utils.hasEmptyParameters
4343
import com.tickaroo.tikxml.processor.utils.hasMinimumPackageVisibilityModifiers
44+
import com.tickaroo.tikxml.processor.utils.hasSuperClass
4445
import com.tickaroo.tikxml.processor.utils.hasTikXmlAnnotation
4546
import com.tickaroo.tikxml.processor.utils.isAbstract
4647
import com.tickaroo.tikxml.processor.utils.isClass
@@ -51,7 +52,6 @@ import com.tickaroo.tikxml.processor.utils.isProtected
5152
import com.tickaroo.tikxml.processor.utils.isPublic
5253
import com.tickaroo.tikxml.processor.utils.isSamePackageAs
5354
import com.tickaroo.tikxml.processor.utils.isString
54-
import java.util.ArrayList
5555
import java.util.Locale
5656
import javax.lang.model.element.TypeElement
5757
import javax.lang.model.element.VariableElement
@@ -101,7 +101,7 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
101101
null
102102

103103
override fun isXmlField(element: VariableElement): NamedField? {
104-
var annotationFound = 0;
104+
var annotationFound = 0
105105

106106
// MAIN ANNOTATIONS
107107
val attributeAnnotation = element.getAnnotation(Attribute::class.java)
@@ -132,10 +132,10 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
132132

133133
if (annotationFound > 1) {
134134
// More than one annotation is not allowed
135-
throw ProcessingException(element, "Fields can ONLY be annotated with one of the "
136-
+ "following annotations @${Attribute::class.simpleName}, "
137-
+ "@${PropertyElement::class.simpleName}, @${Element::class.simpleName} or @${TextContent::class.simpleName} "
138-
+ "and not multiple of them! The field ${element.simpleName.toString()} in class "
135+
throw ProcessingException(element, "Fields can ONLY be annotated with ONE of the "
136+
+ "following annotations @${Attribute::class.java.simpleName}, "
137+
+ "@${PropertyElement::class.java.simpleName}, @${Element::class.java.simpleName} or @${TextContent::class.java.simpleName} "
138+
+ "and not multiple of them! The field ${element.simpleName} in class "
139139
+ "${(element.enclosingElement as TypeElement).qualifiedName} is annotated with more than one of these annotations. You must annotate a field with exactly one of these annotations (not multiple)!")
140140
}
141141

@@ -169,26 +169,32 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
169169
"The type of field '${element.simpleName}' in class ${element.enclosingElement} is not a class nor a interface. Only classes or interfaces can be annotated with @${Element::class.simpleName} annotation. If you try to annotate primitives than @${PropertyElement::class.simpleName}")
170170
}
171171

172-
if (isList(element)) {
173-
val genericListType = getGenericTypeFromList(element)
174-
val genericListTypeElement = typeUtils.asElement(genericListType) as TypeElement
175-
val genericTypeNames = genericTypes[genericListTypeElement.toString()]
176-
177-
if (genericTypeNames == null) {
178-
if (genericListTypeElement.isInterface()) {
172+
val checkTypeElement = fun(typeElement: TypeElement) {
173+
if (elementAnnotation.compileTimeChecks) {
174+
if (typeElement.isInterface()) {
179175
throw ProcessingException(element,
180-
"The generic list type of '$element' is an interface. Hence polymorphism must be resolved by annotating this interface with @${GenericAdapter::class.simpleName}.")
176+
"The type of field '${element.simpleName}' in class ${element.getSurroundingClassQualifiedName()} is an interface. Hence polymorphism must be resolved by annotating this interface with @${GenericAdapter::class.simpleName}!")
181177
}
182178

183-
if (genericListTypeElement.isAbstract()) {
179+
if (typeElement.isAbstract()) {
184180
throw ProcessingException(element,
185-
"The generic list type of '$element' is a abstract class. Hence polymorphism must be resolved by annotating this abstract class with @${GenericAdapter::class.simpleName}.")
186-
} else if (genericListTypeElement.isClass()) {
181+
"The type of field '${element.simpleName}' in class ${element.getSurroundingClassQualifiedName()} is an abstract class. Hence polymorphism must be resolved by annotating this abstract class with @${GenericAdapter::class.simpleName}!")
182+
} else if (typeElement.isClass()) {
187183
checkNameMatchers(nameMatchers, element)
188184
}
185+
}
186+
}
187+
188+
if (isList(element)) {
189+
val genericListType = getGenericTypeFromList(element)
190+
val genericListTypeElement = typeUtils.asElement(genericListType) as TypeElement
191+
val genericTypeNames = genericTypes[genericListTypeElement.toString()]
192+
193+
if (genericTypeNames == null) {
194+
checkTypeElement(genericListTypeElement)
189195

190196
val elementName = if (elementAnnotation.name.isEmpty()) {
191-
getXmlElementNameOrThrowException(element, genericListTypeElement, elementAnnotation.compileTimeChecks)
197+
getXmlElementNameOrThrowException(element, genericListTypeElement, elementAnnotation.compileTimeChecks, true)
192198
} else {
193199
elementAnnotation.name
194200
}
@@ -199,6 +205,8 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
199205
genericListType
200206
)
201207
} else {
208+
checkNameMatchers(nameMatchers, element)
209+
202210
return PolymorphicListElementField(
203211
element,
204212
"placeholderToSubstituteWithPolymorphicListElement",
@@ -211,30 +219,20 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
211219
val genericTypeNames = genericTypes[element.asType().toString()]
212220
val typeElement = (element.asType() as DeclaredType).asElement() as TypeElement
213221

214-
if (genericTypeNames == null && typeElement.superclass.toString() != "none") {
215-
if (elementAnnotation.compileTimeChecks) {
216-
if (typeUtils.asElement(element.asType()).isInterface()) {
217-
throw ProcessingException(element,
218-
"The type of field '${element.simpleName}' in class ${element.getSurroundingClassQualifiedName()} is an interface. Hence polymorphism must be resolved by annotating this interface with @${GenericAdapter::class.simpleName}!")
219-
}
220-
221-
if (typeUtils.asElement(element.asType()).isAbstract()) {
222-
throw ProcessingException(element,
223-
"The type of field '${element.simpleName}' in class ${element.getSurroundingClassQualifiedName()} is an abstract class. Hence polymorphism must be resolved by annotating this abstract class with @${GenericAdapter::class.simpleName}!")
224-
}
225-
226-
checkNameMatchers(nameMatchers, element)
227-
}
222+
return if (genericTypeNames == null) {
223+
checkTypeElement(typeElement)
228224

229225
val elementName = if (elementAnnotation.name.isEmpty()) {
230-
getXmlElementNameOrThrowException(element, typeElement, elementAnnotation.compileTimeChecks)
226+
getXmlElementNameOrThrowException(element, typeElement, elementAnnotation.compileTimeChecks, true)
231227
} else {
232228
elementAnnotation.name
233229
}
234230

235-
return ElementField(element, elementName)
231+
ElementField(element, elementName)
236232
} else {
237-
return PolymorphicElementField(element, "placeholderToSubstituteWithPolymorphicElement",
233+
checkNameMatchers(nameMatchers, element)
234+
235+
PolymorphicElementField(element, "placeholderToSubstituteWithPolymorphicElement",
238236
getPolymorphicTypes(element, nameMatchers, genericTypeNames))
239237
}
240238
}
@@ -271,22 +269,39 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
271269

272270
val checkDuplicateNameMatchers =
273271
fun(element: VariableElement, nameMatchers: Array<ElementNameMatcher>, matcher: ElementNameMatcher) {
274-
val filteredNameMatchers = nameMatchers.filter { nameMatcher ->
272+
val (matcherType, matcherName) = try {
273+
Pair(matcher.type, matcher.name)
274+
} catch (mte: MirroredTypeException) {
275+
Pair(mte.typeMirror, matcher.name.takeIf { it.isNotBlank() } ?: getXmlElementName(
276+
(mte.typeMirror as DeclaredType).asElement() as TypeElement))
277+
}
275278

276-
val nameMatcherType = try { nameMatcher.type } catch (mte: MirroredTypeException) { mte.typeMirror }
277-
val matcherType = try { matcher.type } catch (mte: MirroredTypeException) { mte.typeMirror }
279+
val conflictingNameMatcher = nameMatchers.firstOrNull { nameMatcher ->
280+
val (nameMatcherType, nameMatcherName) = try {
281+
Pair(nameMatcher.type, matcher.name)
282+
} catch (mte: MirroredTypeException) {
283+
Pair(mte.typeMirror, nameMatcher.name.takeIf { it.isNotBlank() } ?: getXmlElementName(
284+
(mte.typeMirror as DeclaredType).asElement() as TypeElement))
285+
}
278286

279-
nameMatcher.name == matcher.name && nameMatcherType == matcherType
287+
nameMatcherName == matcherName && nameMatcherType != matcherType
280288
}
281289

282-
if (filteredNameMatchers.size >= 2) {
290+
if (conflictingNameMatcher != null) {
291+
val conflictingNameMatcherType = try {
292+
conflictingNameMatcher.type
293+
} catch (mte: MirroredTypeException) {
294+
mte.typeMirror
295+
}
296+
283297
throw ProcessingException(element,
284-
"Conflict: A @${ElementNameMatcher::class.simpleName} with the name \"${matcher.name}\" is already mapped to the type ${filteredNameMatchers[0].type} to resolve polymorphism. Hence it cannot be mapped to ${matcher.type} as well.")
298+
"Conflict: A @${ElementNameMatcher::class.simpleName} with the name \"${matcher.name}\" is already mapped to the type $matcherType to resolve polymorphism. Hence it cannot be mapped to $conflictingNameMatcherType as well.")
285299
}
286300
}
287301

288302
val checkTargetClassXmlAnnotated = fun(element: VariableElement, typeElement: TypeElement) {
289-
if (typeElement.getAnnotation(Xml::class.java) == null) {
303+
if (typeElement.getAnnotation(Xml::class.java) == null && (typeUtils.asElement(
304+
element.asType()) as TypeElement).hasSuperClass()) {
290305
throw ProcessingException(element,
291306
"The class ${typeElement.qualifiedName} is not annotated with @${Xml::class.simpleName}, but is used in '$element' in class @${element.getSurroundingClassQualifiedName()} to resolve polymorphism. Please annotate @${element.getSurroundingClassQualifiedName()} with @${Xml::class.simpleName}")
292307
}
@@ -301,7 +316,7 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
301316
"Neither @${ElementNameMatcher::class.simpleName} nor @${GenericAdapter::class.simpleName} specified to resolve polymorphism!")
302317
}
303318

304-
val namingMap = mutableMapOf<String, PolymorphicTypeElementNameMatcher>()
319+
val namingMap = hashMapOf<String, PolymorphicTypeElementNameMatcher>()
305320

306321
// add generic types first
307322
genericTypes?.forEach { qualifiedName ->
@@ -340,12 +355,12 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
340355
namingMap.values.firstOrNull { elementNameMatcher -> elementNameMatcher.type == typeMirror }
341356
?.also { elementNameMatcher ->
342357
namingMap.remove(elementNameMatcher.xmlElementName)
343-
} // delete common generic type if already in list
358+
}
344359
namingMap[xmlElementName] = PolymorphicTypeElementNameMatcher(xmlElementName, typeElement.asType())
345360
}
346361
}
347362

348-
return ArrayList(namingMap.values)
363+
return namingMap.values.toList()
349364
}
350365

351366
/**
@@ -381,7 +396,7 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
381396
val variableType = if (isList(variableElement)) getGenericTypeFromList(variableElement) else variableElement.asType()
382397
if (!typeUtils.isAssignable(typeElement.asType(), variableType)) {
383398
throw ProcessingException(variableElement,
384-
"The type $typeElement must be a sub type of ${variableType}. Otherwise this type cannot be used in @${ElementNameMatcher::class.simpleName} to resolve polymorphism");
399+
"The type $typeElement must be a sub type of ${variableType}. Otherwise this type cannot be used in @${ElementNameMatcher::class.simpleName} to resolve polymorphism.")
385400
}
386401

387402
for (constructor in ElementFilter.constructorsIn(typeElement.enclosedElements)) {
@@ -441,14 +456,15 @@ open class DefaultAnnotationDetector(protected val elementUtils: Elements, prote
441456
* Get the xmlElement name which is either @Xml(name = "foo") property or the class name decapitalize (first letter in lower case)
442457
*/
443458
private fun getXmlElementNameOrThrowException(field: VariableElement, typeElement: TypeElement,
444-
compileTimeChecks: Boolean): String {
459+
compileTimeChecks: Boolean, allowJavaObject: Boolean): String {
445460

446461
val xmlAnnotation = typeElement.getAnnotation(Xml::class.java)
447462
val genericAdapterAnnotation = typeElement.getAnnotation(GenericAdapter::class.java)
448463
val annotationName =
449464
if (typeElement.isClass() && !typeElement.isAbstract()) "@${Xml::class.simpleName}" else "@${GenericAdapter::class.simpleName}"
465+
val checkAnnotation = (typeElement.isClass() && typeElement.hasSuperClass()) || !allowJavaObject
450466

451-
if (xmlAnnotation == null && genericAdapterAnnotation == null && compileTimeChecks) {
467+
if (xmlAnnotation == null && genericAdapterAnnotation == null && compileTimeChecks && checkAnnotation) {
452468
throw ProcessingException(field,
453469
"The type ${typeElement.qualifiedName} used for field '$field' in ${field.getSurroundingClassQualifiedName()} can't be used, because it is not annotated with $annotationName. Annotate ${typeElement.qualifiedName} with $annotationName!")
454470
} else {

‎processor/src/main/java/com/tickaroo/tikxml/processor/xml/XmlElement.kt

+92-88
Original file line numberDiff line numberDiff line change
@@ -29,124 +29,128 @@ import com.tickaroo.tikxml.processor.field.AttributeField
2929
*/
3030
interface XmlElement {
3131

32-
val element: javax.lang.model.element.Element
32+
val element: javax.lang.model.element.Element
3333

34-
/**
35-
* Immutable to the outside, however should be mutable for the inside
36-
*/
37-
val attributes: Map<String, AttributeField>
38-
val childElements: Map<String, XmlChildElement>
34+
/**
35+
* Immutable to the outside, however should be mutable for the inside
36+
*/
37+
val attributes: Map<String, AttributeField>
38+
val childElements: Map<String, XmlChildElement>
3939

40-
fun hasAttributes() = attributes.isNotEmpty()
40+
fun hasAttributes() = attributes.isNotEmpty()
4141

42-
fun hasChildElements() = childElements.isNotEmpty()
42+
fun hasChildElements() = childElements.isNotEmpty()
4343

44-
fun hasTextContent() = false
44+
fun hasTextContent() = false
4545

46-
/**
47-
* Can this [XmlElement] be merged with another [XmlElement] ?
48-
* For instance a [PlaceholderXmlElement] can be merged with [com.tickaroo.tikxml.processor.field.PropertyField]
49-
* because his xml child elements and xml attributes can be parse within the root elements TypeAdapter,
50-
* whereas [com.tickaroo.tikxml.processor.field.ElementField] will be parsed in his own TypeAdapter
51-
* and therefore the xml attributes and child elements are not parsed by the root elements TypeAdapter,
52-
* but rather by the TypeAdapter generated for the corresponding [com.tickaroo.tikxml.processor.field.ElementField].
53-
* Thus, [com.tickaroo.tikxml.processor.field.ElementField] is not mergeable.
54-
*/
55-
fun isXmlElementAccessableFromOutsideTypeAdapter(): Boolean
46+
/**
47+
* Can this [XmlElement] be merged with another [XmlElement] ?
48+
* For instance a [PlaceholderXmlElement] can be merged with [com.tickaroo.tikxml.processor.field.PropertyField]
49+
* because his xml child elements and xml attributes can be parse within the root elements TypeAdapter,
50+
* whereas [com.tickaroo.tikxml.processor.field.ElementField] will be parsed in his own TypeAdapter
51+
* and therefore the xml attributes and child elements are not parsed by the root elements TypeAdapter,
52+
* but rather by the TypeAdapter generated for the corresponding [com.tickaroo.tikxml.processor.field.ElementField].
53+
* Thus, [com.tickaroo.tikxml.processor.field.ElementField] is not mergeable.
54+
*/
55+
fun isXmlElementAccessableFromOutsideTypeAdapter(): Boolean
5656

57-
/**
58-
* Get the element at the given path
59-
*/
60-
fun getXmlElementForPath(path: List<String>): XmlElement {
57+
/**
58+
* Get the element at the given path
59+
*/
60+
fun getXmlElementForPath(path: List<String>): XmlElement {
6161

62-
var currentElement = this
62+
var currentElement = this
6363

64-
for (segment in path) {
65-
val childElement = currentElement.childElements[segment]
64+
for (segment in path) {
65+
val childElement = currentElement.childElements[segment]
6666

67-
if (childElement == null) {
67+
if (childElement == null) {
6868

69-
// Ugly hack! Can't think of a better alterniative right now
70-
val placeholderElement = PlaceholderXmlElement(segment, currentElement.element)
69+
// Ugly hack! Can't think of a better alterniative right now
70+
val placeholderElement = PlaceholderXmlElement(segment, currentElement.element)
7171

72-
(currentElement.childElements as MutableMap).put(segment, placeholderElement)
73-
currentElement = placeholderElement
74-
} else {
75-
currentElement = childElement
76-
}
77-
}
78-
79-
return currentElement
72+
(currentElement.childElements as MutableMap)[segment] = placeholderElement
73+
currentElement = placeholderElement
74+
} else {
75+
currentElement = childElement
76+
}
8077
}
8178

82-
/**
83-
* Add an Attribute to the given class
84-
*/
85-
fun addAttribute(attributeField: AttributeField, path: List<String>) {
79+
return currentElement
80+
}
8681

87-
val currentElement = getXmlElementForPath(path)
88-
if (!currentElement.isXmlElementAccessableFromOutsideTypeAdapter()) {
89-
throw ProcessingException(currentElement.element, "Element $currentElement can't have attributes that are accessed from outside of the TypeAdapter that is generated from @${Element::class.simpleName} annotated class! Therefore attribute $attributeField can't be added. Most likely the @${Path::class.simpleName} is in conflict with an @${Element::class.simpleName} annotation.")
90-
}
82+
/**
83+
* Add an Attribute to the given class
84+
*/
85+
fun addAttribute(attributeField: AttributeField, path: List<String>) {
9186

92-
val existingAttribute = currentElement.attributes[attributeField.name]
87+
val currentElement = getXmlElementForPath(path)
88+
if (!currentElement.isXmlElementAccessableFromOutsideTypeAdapter()) {
89+
throw ProcessingException(currentElement.element,
90+
"Element $currentElement can't have attributes that are accessed from outside of the TypeAdapter that is generated from @${Element::class.simpleName} annotated class! Therefore attribute $attributeField can't be added. Most likely the @${Path::class.simpleName} is in conflict with an @${Element::class.simpleName} annotation.")
91+
}
9392

94-
if (existingAttribute != null) {
95-
throw ProcessingException(attributeField.element, "Conflict: $attributeField has the same xml attribute name "
96-
+ "'${attributeField.name}' as the $existingAttribute. "
97-
+ "You can specify another name via annotations.")
98-
} else {
99-
(currentElement.attributes as MutableMap).put(attributeField.name, attributeField);
100-
}
93+
val existingAttribute = currentElement.attributes[attributeField.name]
10194

95+
if (existingAttribute != null) {
96+
throw ProcessingException(attributeField.element, "Conflict: $attributeField has the same xml attribute name "
97+
+ "'${attributeField.name}' as the $existingAttribute. "
98+
+ "You can specify another name via annotations.")
99+
} else {
100+
(currentElement.attributes as MutableMap)[attributeField.name] = attributeField
102101
}
103102

104-
/**
105-
* Adds a child element at the given path
106-
*/
107-
fun addChildElement(toInsert: XmlChildElement, path: List<String>) {
103+
}
108104

109-
val currentElement = getXmlElementForPath(path)
105+
/**
106+
* Adds a child element at the given path
107+
*/
108+
fun addChildElement(toInsert: XmlChildElement, path: List<String>) {
110109

111-
val existingElement = currentElement.childElements[toInsert.name]
112-
if (existingElement != null) {
110+
val currentElement = getXmlElementForPath(path)
113111

114-
if (toInsert.isXmlElementAccessableFromOutsideTypeAdapter() && existingElement.isXmlElementAccessableFromOutsideTypeAdapter() && existingElement is PlaceholderXmlElement) {
115-
mergeXmlElements(currentElement, existingElement, toInsert)
116-
} else {
117-
// Conflict
118-
val variableField = toInsert.element
119-
throw ProcessingException(variableField, "Conflict: $toInsert is in conflict with $existingElement. Maybe both have the same xml name '${toInsert.name}' (you can change that via annotations) or @${Path::class.simpleName} is causing this conflict.")
120-
}
112+
val existingElement = currentElement.childElements[toInsert.name]
113+
if (existingElement != null) {
121114

122-
} else {
123-
(currentElement.childElements as MutableMap).put(toInsert.name, toInsert)
124-
}
115+
if (toInsert.isXmlElementAccessableFromOutsideTypeAdapter() && existingElement.isXmlElementAccessableFromOutsideTypeAdapter() && existingElement is PlaceholderXmlElement) {
116+
mergeXmlElements(currentElement, existingElement, toInsert)
117+
} else {
118+
// Conflict
119+
val variableField = toInsert.element
120+
throw ProcessingException(variableField,
121+
"Conflict: $toInsert is in conflict with $existingElement. Maybe both have the same xml name '${toInsert.name}' (you can change that via annotations) or @${Path::class.simpleName} is causing this conflict.")
122+
}
125123

124+
} else {
125+
(currentElement.childElements as MutableMap)[toInsert.name] = toInsert
126126
}
127127

128-
private fun mergeXmlElements(parentElement: XmlElement, toMerge: XmlChildElement, into: XmlChildElement) {
128+
}
129129

130-
// merge attributes
131-
for ((name, attributeField) in toMerge.attributes) {
132-
if (into.attributes[name] != null) {
133-
// Should not be possible, because we can't build a path with two PlaceholderXmlElement. Hence, this should never be reached.
134-
throw ProcessingException(toMerge.element, "Conflict: $toMerge has the same xml attribute name '$name' as $into . You can specify another name via annotations.")
135-
}
130+
private fun mergeXmlElements(parentElement: XmlElement, toMerge: XmlChildElement, into: XmlChildElement) {
136131

137-
(into.attributes as MutableMap).put(name, attributeField)
138-
}
132+
// merge attributes
133+
for ((name, attributeField) in toMerge.attributes) {
134+
if (into.attributes[name] != null) {
135+
// Should not be possible, because we can't build a path with two PlaceholderXmlElement. Hence, this should never be reached.
136+
throw ProcessingException(toMerge.element,
137+
"Conflict: $toMerge has the same xml attribute name '$name' as $into . You can specify another name via annotations.")
138+
}
139139

140-
// merge child elements
141-
for ((name, element) in toMerge.childElements) {
142-
if (into.childElements[name] != null) {
143-
// Should not be possible, because we can't build a path with two placeholder PlaceholderXmlElement. Hence, this should never be reached.
144-
throw ProcessingException(toMerge.element, "Conflict: $toMerge is in conflict with $into. Maybe both have the same xml name '$name' (you can change that via annotations) or @${Path::class.simpleName} is causing this conflict.")
145-
}
140+
(into.attributes as MutableMap)[name] = attributeField
141+
}
146142

147-
(into.childElements as MutableMap).put(name, element)
148-
}
143+
// merge child elements
144+
for ((name, element) in toMerge.childElements) {
145+
if (into.childElements[name] != null) {
146+
// Should not be possible, because we can't build a path with two placeholder PlaceholderXmlElement. Hence, this should never be reached.
147+
throw ProcessingException(toMerge.element,
148+
"Conflict: $toMerge is in conflict with $into. Maybe both have the same xml name '$name' (you can change that via annotations) or @${Path::class.simpleName} is causing this conflict.")
149+
}
149150

150-
(parentElement.childElements as MutableMap).put(into.name, into)
151+
(into.childElements as MutableMap)[name] = element
151152
}
153+
154+
(parentElement.childElements as MutableMap)[into.name] = into
155+
}
152156
}

‎processor/src/test/java/com/tickaroo/tikxml/processor/scanning/AnnotationScannerForConstructorsTest.kt

+316-296
Large diffs are not rendered by default.

‎processor/src/test/java/com/tickaroo/tikxml/processor/scanning/AnnotationScannerTest.kt

+1,109-1,080
Large diffs are not rendered by default.

‎processor/src/test/java/com/tickaroo/tikxml/processor/scanning/DefaultAnnotationDetectorTest.kt

+102-79
Large diffs are not rendered by default.

‎processor/src/test/java/com/tickaroo/tikxml/processor/xml/XmlElementTest.kt

+142-139
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.