This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push:
new 64b32c0bb4 [MNG-7871] Fix location tracking (#1222)
64b32c0bb4 is described below
commit 64b32c0bb47c250e4d85236bac73cf6cd44507d1
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Sep 5 18:06:44 2023 +0200
[MNG-7871] Fix location tracking (#1222)
---
.../org/apache/maven/api/model/InputLocation.java | 4 +-
.../org/apache/maven/api/model/InputSource.java | 43 ++++++++
.../org/apache/maven/settings/SettingsUtilsV4.java | 37 +++++++
.../maven/model/building/DefaultModelBuilder.java | 16 ++-
.../apache/maven/model/inheritance/MergerTest.java | 111 +++++++++++++++++++++
src/mdo/merger.vm | 25 +++--
src/mdo/model.vm | 13 ++-
src/mdo/reader-stax.vm | 11 ++
src/mdo/writer-ex.vm | 8 +-
src/mdo/writer-stax.vm | 15 +--
10 files changed, 249 insertions(+), 34 deletions(-)
diff --git
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
index 3e9e9e377a..28bd415366 100644
---
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
+++
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
@@ -111,7 +111,7 @@ public class InputLocation implements Serializable,
InputLocationTracker {
locations.putAll(sourceDominant ? sourceLocations :
targetLocations);
}
- return new InputLocation(target.getLineNumber(),
target.getColumnNumber(), target.getSource(), locations);
+ return new InputLocation(-1, -1, InputSource.merge(source.getSource(),
target.getSource()), locations);
} // -- InputLocation merge( InputLocation, InputLocation, boolean )
/**
@@ -150,7 +150,7 @@ public class InputLocation implements Serializable,
InputLocationTracker {
}
}
- return new InputLocation(target.getLineNumber(),
target.getColumnNumber(), target.getSource(), locations);
+ return new InputLocation(-1, -1, InputSource.merge(source.getSource(),
target.getSource()), locations);
} // -- InputLocation merge( InputLocation, InputLocation,
java.util.Collection )
/**
diff --git
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java
index e192dcf8aa..d5dc895fb7 100644
---
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java
+++
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java
@@ -19,6 +19,11 @@
package org.apache.maven.api.model;
import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* Class InputSource.
@@ -27,10 +32,18 @@ public class InputSource implements Serializable {
private final String modelId;
private final String location;
+ private final List<InputSource> inputs;
public InputSource(String modelId, String location) {
this.modelId = modelId;
this.location = location;
+ this.inputs = null;
+ }
+
+ public InputSource(Collection<InputSource> inputs) {
+ this.modelId = null;
+ this.location = null;
+ this.inputs = ImmutableCollections.copy(inputs);
}
/**
@@ -51,8 +64,38 @@ public class InputSource implements Serializable {
return this.modelId;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ InputSource that = (InputSource) o;
+ return Objects.equals(modelId, that.modelId)
+ && Objects.equals(location, that.location)
+ && Objects.equals(inputs, that.inputs);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(modelId, location, inputs);
+ }
+
+ Stream<InputSource> sources() {
+ return inputs != null ? inputs.stream() : Stream.of(this);
+ }
+
@Override
public String toString() {
+ if (inputs != null) {
+ return
inputs.stream().map(InputSource::toString).collect(Collectors.joining(", ",
"merged[", "]"));
+ }
return getModelId() + " " + getLocation();
}
+
+ public static InputSource merge(InputSource src1, InputSource src2) {
+ return new InputSource(Stream.concat(src1.sources(),
src2.sources()).collect(Collectors.toSet()));
+ }
}
diff --git
a/maven-core/src/main/java/org/apache/maven/settings/SettingsUtilsV4.java
b/maven-core/src/main/java/org/apache/maven/settings/SettingsUtilsV4.java
index aa75da227d..f158094fc0 100644
--- a/maven-core/src/main/java/org/apache/maven/settings/SettingsUtilsV4.java
+++ b/maven-core/src/main/java/org/apache/maven/settings/SettingsUtilsV4.java
@@ -40,9 +40,11 @@ package org.apache.maven.settings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import org.apache.maven.api.model.ActivationFile;
+import org.apache.maven.api.model.InputLocation;
import org.apache.maven.api.settings.Activation;
import org.apache.maven.api.settings.ActivationOS;
import org.apache.maven.api.settings.ActivationProperty;
@@ -168,14 +170,18 @@ public final class SettingsUtilsV4 {
org.apache.maven.api.model.Activation.newBuilder();
activation.activeByDefault(settingsActivation.isActiveByDefault());
+ activation.location("activeByDefault",
toLocation(settingsActivation.getLocation("activeByDefault")));
activation.jdk(settingsActivation.getJdk());
+ activation.location("jdk",
toLocation(settingsActivation.getLocation("jdk")));
ActivationProperty settingsProp = settingsActivation.getProperty();
if (settingsProp != null) {
activation.property(org.apache.maven.api.model.ActivationProperty.newBuilder()
.name(settingsProp.getName())
.value(settingsProp.getValue())
+ .location("name",
toLocation(settingsProp.getLocation("name")))
+ .location("value",
toLocation(settingsProp.getLocation("value")))
.build());
}
@@ -186,6 +192,10 @@ public final class SettingsUtilsV4 {
.family(settingsOs.getFamily())
.name(settingsOs.getName())
.version(settingsOs.getVersion())
+ .location("arch",
toLocation(settingsOs.getLocation("arch")))
+ .location("family",
toLocation(settingsOs.getLocation("family")))
+ .location("name",
toLocation(settingsOs.getLocation("name")))
+ .location("version",
toLocation(settingsOs.getLocation("version")))
.build());
}
@@ -194,6 +204,8 @@ public final class SettingsUtilsV4 {
activation.file(ActivationFile.newBuilder()
.exists(settingsFile.getExists())
.missing(settingsFile.getMissing())
+ .location("exists",
toLocation(settingsFile.getLocation("exists")))
+ .location("missing",
toLocation(settingsFile.getLocation("missing")))
.build());
}
@@ -201,6 +213,7 @@ public final class SettingsUtilsV4 {
}
profile.properties(settingsProfile.getProperties());
+ profile.location("properties",
toLocation(settingsProfile.getLocation("properties")));
List<Repository> repos = settingsProfile.getRepositories();
if (repos != null) {
@@ -233,6 +246,11 @@ public final class SettingsUtilsV4 {
repo.name(settingsRepo.getName());
repo.url(settingsRepo.getUrl());
+ repo.location("id", toLocation(settingsRepo.getLocation("id")));
+ repo.location("layout",
toLocation(settingsRepo.getLocation("layout")));
+ repo.location("name", toLocation(settingsRepo.getLocation("name")));
+ repo.location("url", toLocation(settingsRepo.getLocation("url")));
+
if (settingsRepo.getSnapshots() != null) {
repo.snapshots(convertRepositoryPolicy(settingsRepo.getSnapshots()));
}
@@ -253,6 +271,9 @@ public final class SettingsUtilsV4 {
.enabled(Boolean.toString(settingsPolicy.isEnabled()))
.updatePolicy(settingsPolicy.getUpdatePolicy())
.checksumPolicy(settingsPolicy.getChecksumPolicy())
+ .location("enabled",
toLocation(settingsPolicy.getLocation("enabled")))
+ .location("updatePolicy",
toLocation(settingsPolicy.getLocation("updatePolicy")))
+ .location("checksumPolicy",
toLocation(settingsPolicy.getLocation("checksumPolicy")))
.build();
return policy;
}
@@ -297,4 +318,20 @@ public final class SettingsUtilsV4 {
}
return new org.apache.maven.settings.Settings(settings.getDelegate());
}
+
+ private static org.apache.maven.api.model.InputLocation toLocation(
+ org.apache.maven.api.settings.InputLocation location) {
+ if (location != null) {
+ org.apache.maven.api.settings.InputSource source =
location.getSource();
+ Map<Object, InputLocation> locs =
location.getLocations().entrySet().stream()
+ .collect(Collectors.toMap(Map.Entry::getKey, e ->
toLocation(e.getValue())));
+ return new org.apache.maven.api.model.InputLocation(
+ location.getLineNumber(),
+ location.getColumnNumber(),
+ source != null ? new
org.apache.maven.api.model.InputSource("", source.getLocation()) : null,
+ locs);
+ } else {
+ return null;
+ }
+ }
}
diff --git
a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
index fd5d2ffabb..985227f4fd 100644
---
a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
+++
b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -29,7 +29,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -1106,9 +1105,18 @@ public class DefaultModelBuilder implements ModelBuilder
{
try {
// must implement TransformContext, but should use request to
access properties/model cache
- Model transformedFileModel = modelProcessor.read(
- pomFile,
Collections.singletonMap(ModelReader.TRANSFORMER_CONTEXT, context));
-
+ Map<String, Object> options = new HashMap<>();
+ if (request.isLocationTracking()) {
+ org.apache.maven.api.model.InputLocation location =
+ rawModel.getDelegate().getLocation("");
+ if (location != null) {
+ options.put(
+ ModelProcessor.INPUT_SOURCE,
+ new
org.apache.maven.model.InputSource(location.getSource()));
+ }
+ }
+ options.put(ModelReader.TRANSFORMER_CONTEXT, context);
+ Model transformedFileModel = modelProcessor.read(pomFile,
options);
// rawModel with locationTrackers, required for proper
feedback during validations
// Apply enriched data
diff --git
a/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/MergerTest.java
b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/MergerTest.java
new file mode 100644
index 0000000000..b3d3f8562a
--- /dev/null
+++
b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/MergerTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.maven.model.inheritance;
+
+import java.io.InputStream;
+import java.io.StringReader;
+
+import org.apache.maven.api.model.InputLocation;
+import org.apache.maven.api.model.InputSource;
+import org.apache.maven.api.model.Model;
+import org.apache.maven.model.v4.MavenMerger;
+import org.apache.maven.model.v4.MavenStaxReader;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class MergerTest {
+
+ @Test
+ void testMergerPreserveLocations() throws Exception {
+ try (InputStream is =
getClass().getResourceAsStream("/poms/factory/complex.xml")) {
+
+ InputSource inputSource = new InputSource(null,
"classpath:/poms/factory/complex.xml");
+ Model model = new MavenStaxReader().read(is, true, inputSource);
+ InputLocation propertiesLocation = model.getLocation("properties");
+ assertNotNull(propertiesLocation);
+ assertEquals(13, propertiesLocation.getLineNumber());
+ assertEquals(5, propertiesLocation.getColumnNumber());
+ InputLocation filterPropLocation =
propertiesLocation.getLocation("my.filter.value");
+ assertNotNull(filterPropLocation);
+ assertEquals(14, filterPropLocation.getLineNumber());
+ assertEquals(31, filterPropLocation.getColumnNumber());
+
+ Model model2 = Model.newBuilder(model).build();
+ propertiesLocation = model2.getLocation("properties");
+ assertNotNull(propertiesLocation);
+ assertEquals(13, propertiesLocation.getLineNumber());
+ assertEquals(5, propertiesLocation.getColumnNumber());
+ filterPropLocation =
propertiesLocation.getLocation("my.filter.value");
+ assertNotNull(filterPropLocation);
+ assertEquals(14, filterPropLocation.getLineNumber());
+ assertEquals(31, filterPropLocation.getColumnNumber());
+ assertNotNull(model.getLocation("groupId"));
+
+ Model mergeInput = new MavenStaxReader()
+ .read(
+ new StringReader("<project>\n"
+ + " <properties>\n"
+ + " <my.prop>my-value</my.prop>\n"
+ + " </properties>\n"
+ + "</project>"),
+ true,
+ new InputSource(null, "merge-input"));
+ propertiesLocation = mergeInput.getLocation("properties");
+ assertNotNull(propertiesLocation);
+ assertEquals(2, propertiesLocation.getLineNumber());
+ assertEquals(3, propertiesLocation.getColumnNumber());
+ filterPropLocation = propertiesLocation.getLocation("my.prop");
+ assertNotNull(filterPropLocation);
+ assertEquals(3, filterPropLocation.getLineNumber());
+ assertEquals(22, filterPropLocation.getColumnNumber());
+
+ Model result = new MavenMerger().merge(model, mergeInput, true,
null);
+ propertiesLocation = result.getLocation("properties");
+ assertNotNull(propertiesLocation);
+ assertEquals(-1, propertiesLocation.getLineNumber());
+ assertEquals(-1, propertiesLocation.getColumnNumber());
+ filterPropLocation =
propertiesLocation.getLocation("my.filter.value");
+ assertNotNull(filterPropLocation);
+ assertEquals(14, filterPropLocation.getLineNumber());
+ assertEquals(31, filterPropLocation.getColumnNumber());
+ filterPropLocation = propertiesLocation.getLocation("my.prop");
+ assertNotNull(filterPropLocation);
+ assertEquals(3, filterPropLocation.getLineNumber());
+ assertEquals(22, filterPropLocation.getColumnNumber());
+ assertNotNull(result.getLocation("groupId"));
+
+ result = new
DefaultInheritanceAssembler.InheritanceModelMerger().merge(model, mergeInput,
true, null);
+ propertiesLocation = result.getLocation("properties");
+ assertNotNull(propertiesLocation);
+ assertEquals(-1, propertiesLocation.getLineNumber());
+ assertEquals(-1, propertiesLocation.getColumnNumber());
+ filterPropLocation =
propertiesLocation.getLocation("my.filter.value");
+ assertNotNull(filterPropLocation);
+ assertEquals(14, filterPropLocation.getLineNumber());
+ assertEquals(31, filterPropLocation.getColumnNumber());
+ filterPropLocation = propertiesLocation.getLocation("my.prop");
+ assertNotNull(filterPropLocation);
+ assertEquals(3, filterPropLocation.getLineNumber());
+ assertEquals(22, filterPropLocation.getColumnNumber());
+ assertNotNull(result.getLocation("groupId"));
+ }
+ }
+}
diff --git a/src/mdo/merger.vm b/src/mdo/merger.vm
index 37238787d7..ad71bf0b3a 100644
--- a/src/mdo/merger.vm
+++ b/src/mdo/merger.vm
@@ -102,7 +102,7 @@ public class ${className} {
protected void merge${class.name}(${class.name}.Builder builder,
${class.name} target, ${class.name} source, boolean sourceDominant, Map<Object,
Object> context) {
#if ( $class.superClass )
- merge${class.superClass}(builder, target ,source, sourceDominant,
context);
+ merge${class.superClass}(builder, target, source, sourceDominant,
context);
#end
#foreach ( $field in $class.getFields($version) )
merge${field.modelClass.name}_${Helper.capitalise($field.name)}(builder,
target, source, sourceDominant, context);
@@ -111,8 +111,7 @@ public class ${className} {
#foreach ( $field in $allFields )
#set ( $capField = ${Helper.capitalise($field.name)} )
- protected void merge${class.name}_${capField}(${class.name}.Builder
builder, ${class.name} target, ${class.name} source, boolean sourceDominant,
Map<Object, Object> context)
- {
+ protected void merge${class.name}_${capField}(${class.name}.Builder
builder, ${class.name} target, ${class.name} source, boolean sourceDominant,
Map<Object, Object> context) {
#if ( $field.type == "String" )
String src = source.get${capField}();
String tgt = target.get${capField}();
@@ -151,17 +150,14 @@ public class ${className} {
tgt = ${field.to}.newInstance(false);
}
${field.to} merged = merge${field.to}(tgt, src, sourceDominant,
context);
- if (merged == src) {
- builder.${field.name}(merged);
+ builder.${field.name}(merged);
#if ( $locationTracking )
+ if (target.get${capField}() == null) {
builder.location("${field.name}",
source.getLocation("${field.name}"));
- #end
} else if (merged != tgt) {
- builder.${field.name}(merged);
- #if ( $locationTracking )
- builder.location("${field.name}",
InputLocation.merge(target.getLocation("${field.name}"),
source.getLocation("${field.name}"), sourceDominant));
- #end
+ builder.location("${field.name}", new InputLocation(-1, -1));
}
+ #end
}
#elseif ( $field.to && $field.multiplicity == "*" )
if (deepMerge) {
@@ -176,10 +172,19 @@ public class ${className} {
XmlNode tgt = target.getConfiguration();
if (tgt == null) {
builder.configuration(src);
+ #if ( $locationTracking )
+ builder.location("${field.name}",
source.getLocation("configuration"));
+ #end
} else if (sourceDominant) {
builder.configuration(src.merge(tgt));
+ #if ( $locationTracking )
+ builder.location("${field.name}",
target.getLocation("configuration"));
+ #end
} else {
builder.configuration(tgt.merge(src));
+ #if ( $locationTracking )
+ builder.location("${field.name}", null);
+ #end
}
}
#elseif ($field.type == "boolean")
diff --git a/src/mdo/model.vm b/src/mdo/model.vm
index fa66957365..912545e580 100644
--- a/src/mdo/model.vm
+++ b/src/mdo/model.vm
@@ -446,14 +446,13 @@ public class ${class.name}
return base;
}
#if ( $locationTracking )
- Map<Object, InputLocation> locations = null;
- InputLocation location = null;
+ Map<Object, InputLocation> newlocs = this.locations != null ?
this.locations : Collections.emptyMap();
+ Map<Object, InputLocation> oldlocs = this.base != null &&
this.base.locations != null ? this.base.locations : Collections.emptyMap();
+ Map<Object, InputLocation> locations = new HashMap<>();
+ locations.put("", newlocs.containsKey("") ? newlocs.get("") :
oldlocs.get(""));
#foreach ( $field in $allFields )
- InputLocation ${field.name}Location = null;
+ locations.put("${field.name}",
newlocs.containsKey("${field.name}") ? newlocs.get("${field.name}") :
oldlocs.get("${field.name}"));
#end
- if (this.locations != null) {
- locations = this.locations;
- }
#end
return new ${class.name}(
#if ( $class == $root )
@@ -468,7 +467,7 @@ public class ${class.name}
#end
#end
#if ( $locationTracking )
- locations != null ? locations : (base != null ? base.locations
: null)
+ locations
#end
);
}
diff --git a/src/mdo/reader-stax.vm b/src/mdo/reader-stax.vm
index 054e6de247..6187de3ab7 100644
--- a/src/mdo/reader-stax.vm
+++ b/src/mdo/reader-stax.vm
@@ -586,7 +586,11 @@ public class ${className} {
${classLcapName}.${field.name}(getIntegerValue(interpolatedTrimmed(nextText(parser,
strict), "${fieldTagName}"), "${fieldTagName}", parser, strict,
${field.defaultValue}));
break;
#elseif ( $field.type == "DOM" )
+ #if ( $locationTracking )
+ ${classLcapName}.${field.name}(buildXmlNode(parser,
source));
+ #else
${classLcapName}.${field.name}(buildXmlNode(parser));
+ #end
break;
#elseif ( $field.type == "java.util.List" && $field.to == "String" &&
$field.multiplicity == "*" )
List<String> ${field.name} = new ArrayList<>();
@@ -850,9 +854,16 @@ public class ${className} {
return result.toString();
}
+#if ( $locationTracking )
+ private XmlNode buildXmlNode(XMLStreamReader parser, InputSource source)
throws XMLStreamException {
+ return XmlNodeBuilder.build(parser,
+ p -> new InputLocation(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), source));
+ }
+#else
private XmlNode buildXmlNode(XMLStreamReader parser) throws
XMLStreamException {
return XmlNodeBuilder.build(parser);
}
+#end
#foreach ( $class in $model.allClasses )
#foreach ( $field in $class.getFields($version) )
diff --git a/src/mdo/writer-ex.vm b/src/mdo/writer-ex.vm
index 11c930fa48..6192e2946a 100644
--- a/src/mdo/writer-ex.vm
+++ b/src/mdo/writer-ex.vm
@@ -252,7 +252,9 @@ public class ${className} {
#end
#end
serializer.endTag(NAMESPACE, tagName);
+ #if ( $field.to && $field.multiplicity == "1" )
writeLocationTracking(${classLcapName}, "", serializer);
+ #end
}
}
@@ -280,7 +282,6 @@ public class ${className} {
}
if (!flat) {
serializer.endTag(NAMESPACE, tagName);
- writeLocationTracking(locationTracker, tagName, serializer);
}
}
}
@@ -313,6 +314,11 @@ public class ${className} {
serializer.text(value);
}
serializer.endTag(NAMESPACE, dom.getName());
+#if ( $locationTracking )
+ if (dom.getInputLocation() instanceof InputLocation &&
dom.getChildren().isEmpty()) {
+ serializer.comment(toString((InputLocation)
dom.getInputLocation()));
+ }
+#end
}
}
diff --git a/src/mdo/writer-stax.vm b/src/mdo/writer-stax.vm
index 94d7c4766b..ecad9c87b2 100644
--- a/src/mdo/writer-stax.vm
+++ b/src/mdo/writer-stax.vm
@@ -178,7 +178,6 @@ public class ${className} {
serializer.writeCharacters(value);
}
serializer.writeEndElement();
-
} //-- void writeDomToSerializer(org.apache.maven.api.xml.XmlNode,
XMLStreamWriter)
@@ -268,9 +267,6 @@ public class ${className} {
#end
#end
serializer.writeEndElement();
- #if ( $locationTracking )
- writeLocationTracking(${classLcapName}, "", serializer);
- #end
}
}
@@ -311,9 +307,6 @@ public class ${className} {
}
if (!flat) {
serializer.writeEndElement();
-#if ( $locationTracking )
- writeLocationTracking(locationTracker, tagName, serializer);
-#end
}
}
}
@@ -338,9 +331,6 @@ public class ${className} {
#end
}
serializer.writeEndElement();
-#if ( $locationTracking )
- writeLocationTracking(locationTracker, tagName, serializer);
-#end
}
}
@@ -358,6 +348,11 @@ public class ${className} {
serializer.writeCharacters(value);
}
serializer.writeEndElement();
+#if ( $locationTracking )
+ if (dom.getInputLocation() instanceof InputLocation &&
dom.getChildren().isEmpty()) {
+ serializer.writeComment(toString((InputLocation)
dom.getInputLocation()));
+ }
+#end
}
}