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 c0ac7a688a Revert "[MNG-8563] Provide a weak cache for objects from
the main model (#2087)"
c0ac7a688a is described below
commit c0ac7a688a4ec329301d900c51f9ba829542eee5
Author: Guillaume Nodet <[email protected]>
AuthorDate: Fri Feb 7 00:20:42 2025 +0100
Revert "[MNG-8563] Provide a weak cache for objects from the main model
(#2087)"
This reverts commit 16bd71adf60232e16f04d02de3170c3facc17d3c.
---
api/maven-api-model/pom.xml | 6 -
.../org/apache/maven/api/model/InputLocation.java | 130 +++--------
.../maven/api/model/InputLocationTracker.java | 43 +---
.../org/apache/maven/api/model/InputSource.java | 125 ++--------
.../apache/maven/api/model/CacheManagerTest.java | 67 ------
.../apache/maven/api/model/InputLocationTest.java | 65 ------
.../apache/maven/api/model/InputSourceTest.java | 63 -----
.../StringSearchModelInterpolator.java | 13 +-
.../java/org/apache/maven/model/InputLocation.java | 6 +-
.../java/org/apache/maven/model/InputSource.java | 2 +-
.../org/apache/maven/model/v4/Xpp3DomPerfTest.java | 2 +-
.../maven/settings/io/DefaultSettingsReader.java | 2 +-
.../toolchain/io/DefaultToolchainsReader.java | 2 +-
.../internal/impl/DefaultLifecycleRegistry.java | 2 +-
.../settings/PomConstructionWithSettingsTest.java | 2 +-
.../apache/maven/impl/DefaultModelXmlFactory.java | 2 +-
.../maven/impl/DefaultSettingsXmlFactory.java | 2 +-
.../maven/impl/DefaultToolchainsXmlFactory.java | 2 +-
.../org/apache/maven/impl/SettingsUtilsV4.java | 4 +-
.../model/DefaultDependencyManagementImporter.java | 4 +-
.../DefaultDependencyManagementImporterTest.java | 34 +--
src/mdo/common.vm | 1 -
src/mdo/java/CacheManager.java | 256 ---------------------
src/mdo/java/Cacheable.java | 45 ----
src/mdo/java/InputLocation.java | 28 ++-
src/mdo/java/InputSource.java | 6 +-
src/mdo/merger.vm | 2 +-
src/mdo/model.vm | 44 +---
src/mdo/reader-stax.vm | 12 +-
29 files changed, 110 insertions(+), 862 deletions(-)
diff --git a/api/maven-api-model/pom.xml b/api/maven-api-model/pom.xml
index b9a49ce44c..11023a08ab 100644
--- a/api/maven-api-model/pom.xml
+++ b/api/maven-api-model/pom.xml
@@ -40,12 +40,6 @@ under the License.
<groupId>org.apache.maven</groupId>
<artifactId>maven-api-xml</artifactId>
</dependency>
-
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
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 f4cb6a219f..e4e2acf237 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
@@ -20,117 +20,59 @@
import java.io.Serializable;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
/**
- * Tracks the source location of elements within Maven model files (such as
pom.xml).
- * This class stores information about where specific elements were defined,
including
- * line numbers, column numbers, and the source file information.
- *
- * <p>InputLocation instances are immutable and can be cached for performance
optimization.
- * They support tracking both direct locations and nested element locations
through a map
- * of field-specific locations.</p>
- *
- * <p>Usage example:</p>
- * <pre>
- * // Create a location for a source file
- * InputSource source = InputSource.source("com.example:myproject:1.0",
"pom.xml");
- * InputLocation location = InputLocation.location(10, 15, source);
- *
- * // Get line and column information
- * int line = location.getLineNumber(); // Returns 10
- * int column = location.getColumnNumber(); // Returns 15
- * </pre>
- *
- * <p>This class is particularly useful for:</p>
- * <ul>
- * <li>Error reporting with precise location information</li>
- * <li>Tracking the origin of merged model elements</li>
- * <li>Debugging model inheritance and interpolation</li>
- * </ul>
- *
- * @see InputSource
- * @see InputLocationTracker
+ * Class InputLocation.
*/
-public class InputLocation implements Serializable, InputLocationTracker,
Cacheable {
+public class InputLocation implements Serializable, InputLocationTracker {
private final int lineNumber;
private final int columnNumber;
private final InputSource source;
private final Map<Object, InputLocation> locations;
- private final int cacheHash;
+ private final InputLocation importedFrom;
- /**
- * Creates a new InputLocation with only source information.
- * Line and column numbers will be set to -1 to indicate they are not
specified.
- *
- * @param source the input source containing file and model identification
- * @return a cached instance of InputLocation
- */
- public static InputLocation location(InputSource source) {
- return CacheManager.getInstance().cached(new InputLocation(-1, -1,
source, 0));
- }
-
- /**
- * Creates a new InputLocation with line and column numbers but no source
information.
- * Useful for tracking positions in standalone files or when source
information is not needed.
- *
- * @param lineNumber the 1-based line number in the source file
- * @param columnNumber the 1-based column number in the source file
- * @return a cached instance of InputLocation
- */
- public static InputLocation location(int lineNumber, int columnNumber) {
- return CacheManager.getInstance().cached(new InputLocation(lineNumber,
columnNumber, null, null));
+ public InputLocation(InputSource source) {
+ this.lineNumber = -1;
+ this.columnNumber = -1;
+ this.source = source;
+ this.locations = Collections.singletonMap(0, this);
+ this.importedFrom = null;
}
- /**
- * Creates a new InputLocation with line, column, and source information.
- * This is the most common factory method for creating complete location
information.
- *
- * @param lineNumber the 1-based line number in the source file
- * @param columnNumber the 1-based column number in the source file
- * @param source the input source containing file and model identification
- * @return a cached instance of InputLocation
- */
- public static InputLocation location(int lineNumber, int columnNumber,
InputSource source) {
- return CacheManager.getInstance().cached(new InputLocation(lineNumber,
columnNumber, source, null));
+ public InputLocation(int lineNumber, int columnNumber) {
+ this(lineNumber, columnNumber, null, null);
}
- /**
- * Creates a new InputLocation with line, column, source, and
self-location information.
- * This factory method is useful when tracking locations of elements that
reference themselves.
- *
- * @param lineNumber the 1-based line number in the source file
- * @param columnNumber the 1-based column number in the source file
- * @param source the input source containing file and model identification
- * @param selfLocationKey the key to use for storing this location in its
own locations map
- * @return a cached instance of InputLocation
- */
- public static InputLocation location(int lineNumber, int columnNumber,
InputSource source, Object selfLocationKey) {
- return CacheManager.getInstance().cached(new InputLocation(lineNumber,
columnNumber, source, selfLocationKey));
+ public InputLocation(int lineNumber, int columnNumber, InputSource source)
{
+ this(lineNumber, columnNumber, source, null);
}
- InputLocation(int lineNumber, int columnNumber, InputSource source, Object
selfLocationKey) {
+ public InputLocation(int lineNumber, int columnNumber, InputSource source,
Object selfLocationKey) {
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
this.source = source;
- this.locations = selfLocationKey != null
- ? ImmutableCollections.singletonMap(selfLocationKey, this)
- : ImmutableCollections.emptyMap();
- this.cacheHash = CacheManager.getInstance().computeCacheHash(this);
+ this.locations =
+ selfLocationKey != null ?
Collections.singletonMap(selfLocationKey, this) : Collections.emptyMap();
+ this.importedFrom = null;
}
- InputLocation(int lineNumber, int columnNumber, InputSource source,
Map<Object, InputLocation> locations) {
+ public InputLocation(int lineNumber, int columnNumber, InputSource source,
Map<Object, InputLocation> locations) {
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
this.source = source;
this.locations = ImmutableCollections.copy(locations);
- this.cacheHash = CacheManager.getInstance().computeCacheHash(this);
+ this.importedFrom = null;
}
- @Override
- public int cacheIdentityHash() {
- return cacheHash;
+ public InputLocation(InputLocation original) {
+ this.lineNumber = original.lineNumber;
+ this.columnNumber = original.columnNumber;
+ this.source = original.source;
+ this.locations = original.locations;
+ this.importedFrom = original.importedFrom;
}
public int getLineNumber() {
@@ -161,24 +103,16 @@ public Map<Object, InputLocation> getLocations() {
* @since 4.0.0
*/
public InputLocation getImportedFrom() {
- return null;
+ return importedFrom;
}
/**
- * Merges two InputLocation instances, preserving location information
from both sources.
- * This is particularly useful when dealing with inherited or aggregated
model elements.
- *
- * <p>The merge strategy follows these rules:</p>
- * <ul>
- * <li>If either location is null, returns the non-null location</li>
- * <li>Locations are combined based on the sourceDominant parameter</li>
- * <li>Source information is merged using {@link InputSource#merge}</li>
- * </ul>
+ * Merges the {@code source} location into the {@code target} location.
*
- * @param target the target location to merge into
- * @param source the source location to merge from
- * @param sourceDominant if true, source locations take precedence over
target locations
- * @return a new merged InputLocation instance
+ * @param target the target location
+ * @param source the source location
+ * @param sourceDominant the boolean indicating of {@code source} is
dominant compared to {@code target}
+ * @return the merged location
*/
public static InputLocation merge(InputLocation target, InputLocation
source, boolean sourceDominant) {
if (source == null) {
diff --git
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocationTracker.java
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocationTracker.java
index df44d7bab4..8b2958a35c 100644
---
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocationTracker.java
+++
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocationTracker.java
@@ -18,52 +18,15 @@
*/
package org.apache.maven.api.model;
-import org.apache.maven.api.annotations.Nullable;
-
-/**
- * Provides a contract for tracking the source location of model elements.
- * This interface is implemented by classes that need to maintain information
- * about where their data was defined in source files.
- *
- * <p>The interface supports hierarchical location tracking, where elements can
- * have both their own location and locations for their child elements. It also
- * supports tracking locations of elements that have been imported from other
- * files.</p>
- *
- * <p>Usage example:</p>
- * <pre>
- * public class ModelElement implements InputLocationTracker {
- * private InputLocation location;
- * private Map<Object, InputLocation> locations;
- *
- * public InputLocation getLocation(Object field) {
- * return locations.get(field);
- * }
- *
- * public InputLocation getImportedFrom() {
- * return location.getImportedFrom();
- * }
- * }
- * </pre>
- */
public interface InputLocationTracker {
-
- /**
- * Retrieves the location information for a specific field within the
implementing class.
- *
- * @param field the identifier for the field whose location should be
retrieved
- * @return the InputLocation for the specified field, or null if not found
- */
InputLocation getLocation(Object field);
/**
- * Retrieves the original location information when the current element
was imported
- * from another source. This is particularly useful for tracking the
origin of
- * inherited or merged model elements.
+ * Gets the parent InputLocation where this InputLocation may have been
imported from.
+ * Can return {@code null}.
*
- * @return the InputLocation from which this element was imported, or null
if not imported
+ * @return InputLocation
* @since 4.0.0
*/
- @Nullable
InputLocation getImportedFrom();
}
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 acb78f1069..1d1998c6b4 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,112 +19,38 @@
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;
/**
- * Represents the source of input for Maven model elements, typically a POM
file.
- * This class maintains information about both the physical location (file
path or URL)
- * and the logical identity (groupId:artifactId:version) of the source.
- *
- * <p>InputSource instances can represent either:</p>
- * <ul>
- * <li>A single source file with its location and model ID</li>
- * <li>A merged set of multiple input sources (e.g., from parent POMs)</li>
- * </ul>
- *
- * <p>The class is immutable and supports caching for performance optimization.
- * It provides factory methods for creating instances and utilities for merging
- * multiple sources.</p>
- *
- * <p>Usage example:</p>
- * <pre>
- * // Create a simple source
- * InputSource source = InputSource.source(
- * "com.example:myproject:1.0",
- * "path/to/pom.xml"
- * );
- *
- * // Create a merged source
- * InputSource merged = InputSource.merge(parentSource, childSource);
- * </pre>
- *
- * @see InputLocation
+ * Class InputSource.
*/
-public class InputSource implements Serializable, Cacheable {
+public class InputSource implements Serializable {
private final String modelId;
private final String location;
private final List<InputSource> inputs;
private final InputLocation importedFrom;
- private final int hashCache;
-
- /**
- * Creates a new InputSource with model identification and location
information.
- * This is the most common factory method for creating a simple input
source.
- *
- * @param modelId the model identifier in the format
"groupId:artifactId:version"
- * @param location the file path or URL where the model is located
- * @return a cached instance of InputSource
- */
- public static InputSource source(String modelId, String location) {
- return CacheManager.getInstance().cached(new InputSource(modelId,
location, null, null));
- }
-
- /**
- * Creates a new InputSource with model identification, location, and
import information.
- * This factory method is useful when tracking sources that have been
imported from other files.
- *
- * @param modelId the model identifier in the format
"groupId:artifactId:version"
- * @param location the file path or URL where the model is located
- * @param importedFrom the location from which this source was imported
- * @return a cached instance of InputSource
- */
- public static InputSource source(String modelId, String location,
InputLocation importedFrom) {
- return CacheManager.getInstance().cached(new InputSource(modelId,
location, null, importedFrom));
- }
-
- /**
- * Creates a new InputSource representing a merged set of input sources.
- * This factory method is used when combining multiple sources, such as
when
- * dealing with parent POMs or aggregated models.
- *
- * @param inputs the list of input sources to merge
- * @return a cached instance of InputSource representing the merged sources
- */
- public static InputSource source(List<InputSource> inputs) {
- return CacheManager.getInstance().cached(new InputSource(null, null,
inputs, null));
- }
- /**
- * Creates a new InputSource with complete information including model ID,
location,
- * input sources, and import information. This is the most flexible
factory method
- * that allows specifying all possible source attributes.
- *
- * @param modelId the model identifier in the format
"groupId:artifactId:version"
- * @param location the file path or URL where the model is located
- * @param inputs the list of input sources to merge
- * @param importedFrom the location from which this source was imported
- * @return a cached instance of InputSource
- */
- public static InputSource source(
- String modelId, String location, List<InputSource> inputs,
InputLocation importedFrom) {
- return CacheManager.getInstance().cached(new InputSource(modelId,
location, inputs, importedFrom));
+ public InputSource(String modelId, String location) {
+ this(modelId, location, null);
}
- InputSource(String modelId, String location, List<InputSource> inputs,
InputLocation importedFrom) {
+ public InputSource(String modelId, String location, InputLocation
importedFrom) {
this.modelId = modelId;
this.location = location;
- this.inputs = inputs != null ? ImmutableCollections.copy(inputs) :
null;
+ this.inputs = null;
this.importedFrom = importedFrom;
- this.hashCache = CacheManager.getInstance().computeCacheHash(this);
}
- @Override
- public int cacheIdentityHash() {
- return hashCache;
+ public InputSource(Collection<InputSource> inputs) {
+ this.modelId = null;
+ this.location = null;
+ this.inputs = ImmutableCollections.copy(inputs);
+ this.importedFrom = null;
}
/**
@@ -187,32 +113,7 @@ public String toString() {
return getModelId() + " " + getLocation();
}
- /**
- * Merges two InputSource instances in a null-safe manner.
- *
- * @param src1 the first source
- * @param src2 the second source
- * @return merged InputSource, or one of the sources if the other is null
- */
public static InputSource merge(InputSource src1, InputSource src2) {
- // If either source is null, return the other source
- if (src1 == null) {
- return src2;
- }
- if (src2 == null) {
- return src1;
- }
-
- // Create streams from both sources
- Stream<InputSource> stream1 = src1.sources();
- Stream<InputSource> stream2 = src2.sources();
-
- // Merge the streams and create a new InputSource
- List<InputSource> mergedSources = Stream.concat(stream1, stream2)
- .filter(Objects::nonNull)
- .distinct()
- .collect(Collectors.toList());
-
- return new InputSource(null, null, mergedSources.isEmpty() ? null :
mergedSources, null);
+ return new InputSource(Stream.concat(src1.sources(),
src2.sources()).collect(Collectors.toSet()));
}
}
diff --git
a/api/maven-api-model/src/test/java/org/apache/maven/api/model/CacheManagerTest.java
b/api/maven-api-model/src/test/java/org/apache/maven/api/model/CacheManagerTest.java
deleted file mode 100644
index 0b07d0298b..0000000000
---
a/api/maven-api-model/src/test/java/org/apache/maven/api/model/CacheManagerTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.api.model;
-
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertSame;
-
-class CacheManagerTest {
-
- @Test
- void testSingletonInstance() {
- CacheManager cm1 = CacheManager.getInstance();
- CacheManager cm2 = CacheManager.getInstance();
-
- assertSame(cm1, cm2); // Should return same instance
- }
-
- @Test
- void testCachingOfInputLocation() {
- InputLocation loc1 = InputLocation.location(1, 1);
- InputLocation loc2 = InputLocation.location(1, 1);
-
- // Cached instances should be the same object
- assertSame(loc1, loc2);
- }
-
- @Test
- void testCachingOfInputSource() {
- InputSource src1 = InputSource.source("g:a:1.0", "pom.xml");
- InputSource src2 = InputSource.source("g:a:1.0", "pom.xml");
-
- // Cached instances should be the same object
- assertSame(src1, src2);
- }
-
- @Test
- void testCachingOfDependency() {
- Dependency dep1 = Dependency.newBuilder()
- .groupId(new String("myGroup"))
- .artifactId(new String("myArtifact"))
- .build();
- Dependency dep2 = Dependency.newBuilder()
- .groupId(new String("myGroup"))
- .artifactId(new String("myArtifact"))
- .build();
-
- // Cached instances should be the same object
- assertSame(dep1, dep2);
- }
-}
diff --git
a/api/maven-api-model/src/test/java/org/apache/maven/api/model/InputLocationTest.java
b/api/maven-api-model/src/test/java/org/apache/maven/api/model/InputLocationTest.java
deleted file mode 100644
index 0925151582..0000000000
---
a/api/maven-api-model/src/test/java/org/apache/maven/api/model/InputLocationTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.api.model;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class InputLocationTest {
-
- @Test
- void testBasicLocationCreation() {
- int line = 10;
- int column = 20;
- InputSource source = InputSource.source("group:artifact:1.0",
"pom.xml");
-
- InputLocation location = InputLocation.location(line, column, source);
-
- assertEquals(line, location.getLineNumber());
- assertEquals(column, location.getColumnNumber());
- assertEquals(source, location.getSource());
- }
-
- @Test
- void testLocationMergeWithoutSource() {
- InputLocation loc1 = InputLocation.location(1, 1);
- InputLocation loc2 = InputLocation.location(2, 2);
-
- InputLocation merged = InputLocation.merge(loc1, loc2, true);
-
- assertEquals(-1, merged.getLineNumber()); // Merged locations reset
line/column
- assertEquals(-1, merged.getColumnNumber());
- }
-
- @Test
- void testLocationMergeWithIndices() {
- InputLocation loc1 = InputLocation.location(1, 1);
- InputLocation loc2 = InputLocation.location(2, 2);
- List<Integer> indices = Arrays.asList(0, 1, ~0);
-
- InputLocation merged = InputLocation.merge(loc1, loc2, indices);
-
- assertNotNull(merged);
- assertEquals(-1, merged.getLineNumber());
- }
-}
diff --git
a/api/maven-api-model/src/test/java/org/apache/maven/api/model/InputSourceTest.java
b/api/maven-api-model/src/test/java/org/apache/maven/api/model/InputSourceTest.java
deleted file mode 100644
index 5eb5225b89..0000000000
---
a/api/maven-api-model/src/test/java/org/apache/maven/api/model/InputSourceTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.api.model;
-
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class InputSourceTest {
-
- @Test
- void testSourceCreation() {
- String modelId = "group:artifact:1.0";
- String location = "pom.xml";
-
- InputSource source = InputSource.source(modelId, location);
-
- assertEquals(modelId, source.getModelId());
- assertEquals(location, source.getLocation());
- assertNull(source.getImportedFrom());
- }
-
- @Test
- void testSourceMerge() {
- InputSource src1 = InputSource.source("g1:a1:1.0", "pom1.xml");
- InputSource src2 = InputSource.source("g2:a2:1.0", "pom2.xml");
-
- InputSource merged = InputSource.merge(src1, src2);
-
- assertNull(merged.getModelId()); // Merged sources reset modelId
- assertNull(merged.getLocation()); // and location
- assertTrue(merged.toString().contains("merged")); // Should indicate
merged state
- }
-
- @Test
- void testSourceEquality() {
- InputSource src1 = InputSource.source("g:a:1.0", "pom.xml");
- InputSource src2 = InputSource.source("g:a:1.0", "pom.xml");
- InputSource src3 = InputSource.source("g:a:2.0", "pom.xml");
-
- assertEquals(src1, src2);
- assertNotEquals(src1, src3);
- }
-}
diff --git
a/compat/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java
b/compat/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java
index 13350f235e..d63cbec5c1 100644
---
a/compat/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java
+++
b/compat/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java
@@ -28,7 +28,6 @@
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -98,7 +97,6 @@ private static final class InterpolateObjectAction implements
PrivilegedAction<M
private final boolean debugEnabled;
private final LinkedList<Object> interpolationTargets;
- private final IdentityHashMap<Object, Boolean> doneTargets = new
IdentityHashMap<>();
private final StringSearchModelInterpolator modelInterpolator;
private final Logger logger;
private final List<ValueSource> valueSources;
@@ -125,12 +123,11 @@ private static final class InterpolateObjectAction
implements PrivilegedAction<M
public ModelInterpolationException run() {
while (!interpolationTargets.isEmpty()) {
Object obj = interpolationTargets.removeFirst();
- if (doneTargets.put(obj, true) == null) {
- try {
- traverseObjectWithParents(obj.getClass(), obj);
- } catch (ModelInterpolationException e) {
- return e;
- }
+
+ try {
+ traverseObjectWithParents(obj.getClass(), obj);
+ } catch (ModelInterpolationException e) {
+ return e;
}
}
diff --git
a/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java
b/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java
index c10230f270..82bfc9162b 100644
--- a/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java
+++ b/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java
@@ -332,17 +332,17 @@ public void setLocations(java.util.Map<Object,
InputLocation> locations) {
public org.apache.maven.api.model.InputLocation toApiLocation() {
if (locations != null && locations.values().contains(this)) {
if (locations.size() == 1 && locations.values().iterator().next()
== this) {
- return org.apache.maven.api.model.InputLocation.location(
+ return new org.apache.maven.api.model.InputLocation(
lineNumber,
columnNumber,
source != null ? source.toApiSource() : null,
locations.keySet().iterator().next());
} else {
- return org.apache.maven.api.model.InputLocation.location(
+ return new org.apache.maven.api.model.InputLocation(
lineNumber, columnNumber, source != null ?
source.toApiSource() : null);
}
} else {
- return org.apache.maven.api.model.InputLocation.location(
+ return new org.apache.maven.api.model.InputLocation(
lineNumber,
columnNumber,
source != null ? source.toApiSource() : null,
diff --git
a/compat/maven-model/src/main/java/org/apache/maven/model/InputSource.java
b/compat/maven-model/src/main/java/org/apache/maven/model/InputSource.java
index b0a10fe073..1bd81e925e 100644
--- a/compat/maven-model/src/main/java/org/apache/maven/model/InputSource.java
+++ b/compat/maven-model/src/main/java/org/apache/maven/model/InputSource.java
@@ -152,6 +152,6 @@ public String toString() {
}
public org.apache.maven.api.model.InputSource toApiSource() {
- return org.apache.maven.api.model.InputSource.source(modelId,
location);
+ return new org.apache.maven.api.model.InputSource(modelId, location);
}
}
diff --git
a/compat/maven-model/src/test/java/org/apache/maven/model/v4/Xpp3DomPerfTest.java
b/compat/maven-model/src/test/java/org/apache/maven/model/v4/Xpp3DomPerfTest.java
index de375f8d87..090292cffa 100644
---
a/compat/maven-model/src/test/java/org/apache/maven/model/v4/Xpp3DomPerfTest.java
+++
b/compat/maven-model/src/test/java/org/apache/maven/model/v4/Xpp3DomPerfTest.java
@@ -73,7 +73,7 @@ public int readWithStax(AdditionState state) throws
IOException, XMLStreamExcept
try (InputStream is = Files.newInputStream(pom)) {
MavenStaxReader reader = new MavenStaxReader();
reader.setAddLocationInformation(false);
- reader.read(is, true, InputSource.source("id",
pom.toString()));
+ reader.read(is, true, new InputSource("id", pom.toString()));
i++;
} catch (XMLStreamException e) {
throw new RuntimeException("Error parsing: " + pom, e);
diff --git
a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java
b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java
index 979a68e8ae..f4ea4bdf4c 100644
---
a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java
+++
b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java
@@ -49,7 +49,7 @@ public Settings read(File input, Map<String, ?> options)
throws IOException {
Objects.requireNonNull(input, "input cannot be null");
try (InputStream in = Files.newInputStream(input.toPath())) {
- InputSource source = InputSource.source(input.toString());
+ InputSource source = new InputSource(input.toString());
return new Settings(new SettingsStaxReader().read(in,
isStrict(options), source));
} catch (XMLStreamException e) {
throw new SettingsParseException(
diff --git
a/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java
b/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java
index 7381ebb4f5..3e0665b57c 100644
---
a/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java
+++
b/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java
@@ -50,7 +50,7 @@ public PersistedToolchains read(File input, Map<String, ?>
options) throws IOExc
Objects.requireNonNull(input, "input cannot be null");
try (InputStream in = Files.newInputStream(input.toPath())) {
- InputSource source = InputSource.source(input.toString());
+ InputSource source = new InputSource(input.toString());
return new PersistedToolchains(new
MavenToolchainsStaxReader().read(in, isStrict(options), source));
} catch (XMLStreamException e) {
throw new ToolchainsParseException(
diff --git
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java
b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java
index ae6a974e30..859821ceac 100644
---
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java
+++
b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java
@@ -89,7 +89,7 @@ public class DefaultLifecycleRegistry implements
LifecycleRegistry {
+ ":default-lifecycle-bindings";
public static final InputLocation DEFAULT_LIFECYCLE_INPUT_LOCATION =
-
InputLocation.location(InputSource.source(DEFAULT_LIFECYCLE_MODELID, null));
+ new InputLocation(new InputSource(DEFAULT_LIFECYCLE_MODELID,
null));
private final List<LifecycleProvider> providers;
diff --git
a/impl/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java
b/impl/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java
index 8f36cffe9d..9aca25a9d3 100644
---
a/impl/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java
+++
b/impl/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java
@@ -128,7 +128,7 @@ private PomTestWrapper buildPom(String pomPath) throws
Exception {
private static Settings readSettingsFile(File settingsFile) throws
IOException, XMLStreamException {
try (InputStream is = Files.newInputStream(settingsFile.toPath())) {
SettingsStaxReader reader = new SettingsStaxReader();
- InputSource source = InputSource.source(settingsFile.toString());
+ InputSource source = new InputSource(settingsFile.toString());
return new Settings(reader.read(is, true, source));
}
}
diff --git
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java
index 3b9828eba1..8505beccf3 100644
---
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java
+++
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java
@@ -60,7 +60,7 @@ public Model read(@Nonnull XmlReaderRequest request) throws
XmlReaderException {
try {
InputSource source = null;
if (request.getModelId() != null || request.getLocation() != null)
{
- source = InputSource.source(
+ source = new InputSource(
request.getModelId(), path != null ?
path.toUri().toString() : null);
}
MavenStaxReader xml = new MavenStaxReader();
diff --git
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsXmlFactory.java
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsXmlFactory.java
index 2ce09ffe0c..fd1749cd0e 100644
---
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsXmlFactory.java
+++
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsXmlFactory.java
@@ -53,7 +53,7 @@ public Settings read(@Nonnull XmlReaderRequest request)
throws XmlReaderExceptio
try {
InputSource source = null;
if (request.getModelId() != null || request.getLocation() != null)
{
- source = InputSource.source(request.getLocation());
+ source = new InputSource(request.getLocation());
}
SettingsStaxReader xml = new SettingsStaxReader();
xml.setAddDefaultEntities(request.isAddDefaultEntities());
diff --git
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainsXmlFactory.java
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainsXmlFactory.java
index 847ea42261..d707ac824b 100644
---
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainsXmlFactory.java
+++
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainsXmlFactory.java
@@ -55,7 +55,7 @@ public PersistedToolchains read(@Nonnull XmlReaderRequest
request) throws XmlRea
try {
InputSource source = null;
if (request.getModelId() != null || request.getLocation() != null)
{
- source = InputSource.source(request.getLocation());
+ source = new InputSource(request.getLocation());
}
MavenToolchainsStaxReader xml = new MavenToolchainsStaxReader();
xml.setAddDefaultEntities(request.isAddDefaultEntities());
diff --git
a/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java
b/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java
index 9e8c841b10..a4f2ba618f 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java
@@ -321,10 +321,10 @@ private static org.apache.maven.api.model.InputLocation
toLocation(
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 org.apache.maven.api.model.InputLocation.location(
+ return new org.apache.maven.api.model.InputLocation(
location.getLineNumber(),
location.getColumnNumber(),
- source != null ?
org.apache.maven.api.model.InputSource.source("", source.getLocation()) : null,
+ source != null ? new
org.apache.maven.api.model.InputSource("", source.getLocation()) : null,
locs);
} else {
return null;
diff --git
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultDependencyManagementImporter.java
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultDependencyManagementImporter.java
index 45de07f83a..19ed567329 100644
---
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultDependencyManagementImporter.java
+++
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultDependencyManagementImporter.java
@@ -185,6 +185,8 @@ static Dependency updateWithImportedFrom(Dependency
dependency, DependencyManage
// We modify the input location that is used for the whole file.
// This is likely correct because the POM hierarchy applies to the
whole POM, not just one dependency.
- return Dependency.newBuilder(dependency,
true).importedFrom(bomLocation).build();
+ return Dependency.newBuilder(dependency, true)
+ .importedFrom(new InputLocation(bomLocation))
+ .build();
}
}
diff --git
a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultDependencyManagementImporterTest.java
b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultDependencyManagementImporterTest.java
index de95e8e8c4..1d5463e261 100644
---
a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultDependencyManagementImporterTest.java
+++
b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultDependencyManagementImporterTest.java
@@ -38,12 +38,12 @@ void
testUpdateWithImportedFrom_dependencyLocationAndBomLocationAreNull_dependen
@Test
void
testUpdateWithImportedFrom_dependencyManagementAndDependencyHaveSameSource_dependencyImportedFromSameSource()
{
- final InputSource source = InputSource.source("SINGLE_SOURCE", "");
+ final InputSource source = new InputSource("SINGLE_SOURCE", "");
final Dependency dependency = Dependency.newBuilder()
- .location("", InputLocation.location(1, 1, source))
+ .location("", new InputLocation(1, 1, source))
.build();
final DependencyManagement bom = DependencyManagement.newBuilder()
- .location("", InputLocation.location(1, 1, source))
+ .location("", new InputLocation(1, 1, source))
.build();
final Dependency result =
DefaultDependencyManagementImporter.updateWithImportedFrom(dependency, bom);
@@ -56,13 +56,13 @@ void
testUpdateWithImportedFrom_dependencyManagementAndDependencyHaveSameSource_
@Test
public void testUpdateWithImportedFrom_singleLevel_importedFromSet() {
// Arrange
- final InputSource dependencySource = InputSource.source("DEPENDENCY",
"DEPENDENCY");
- final InputSource bomSource = InputSource.source("BOM", "BOM");
+ final InputSource dependencySource = new InputSource("DEPENDENCY",
"DEPENDENCY");
+ final InputSource bomSource = new InputSource("BOM", "BOM");
final Dependency dependency = Dependency.newBuilder()
- .location("", InputLocation.location(1, 1, dependencySource))
+ .location("", new InputLocation(1, 1, dependencySource))
.build();
final DependencyManagement bom = DependencyManagement.newBuilder()
- .location("", InputLocation.location(2, 2, bomSource))
+ .location("", new InputLocation(2, 2, bomSource))
.build();
// Act
@@ -77,14 +77,14 @@ public void
testUpdateWithImportedFrom_singleLevel_importedFromSet() {
@Test
public void testUpdateWithImportedFrom_multiLevel_importedFromSetChanged()
{
// Arrange
- final InputSource bomSource = InputSource.source("BOM", "BOM");
+ final InputSource bomSource = new InputSource("BOM", "BOM");
final InputSource intermediateSource =
- InputSource.source("INTERMEDIATE", "INTERMEDIATE",
InputLocation.location(bomSource));
+ new InputSource("INTERMEDIATE", "INTERMEDIATE", new
InputLocation(bomSource));
final InputSource dependencySource =
- InputSource.source("DEPENDENCY", "DEPENDENCY",
InputLocation.location(intermediateSource));
- final InputLocation bomLocation = InputLocation.location(2, 2,
bomSource);
+ new InputSource("DEPENDENCY", "DEPENDENCY", new
InputLocation(intermediateSource));
+ final InputLocation bomLocation = new InputLocation(2, 2, bomSource);
final Dependency dependency = Dependency.newBuilder()
- .location("", InputLocation.location(1, 1, dependencySource))
+ .location("", new InputLocation(1, 1, dependencySource))
.importedFrom(bomLocation)
.build();
final DependencyManagement bom =
@@ -101,16 +101,16 @@ public void
testUpdateWithImportedFrom_multiLevel_importedFromSetChanged() {
@Test
public void
testUpdateWithImportedFrom_multiLevelAlreadyFoundInDifferentSource_importedFromSetMaintained()
{
// Arrange
- final InputSource bomSource = InputSource.source("BOM", "BOM");
+ final InputSource bomSource = new InputSource("BOM", "BOM");
final InputSource intermediateSource =
- InputSource.source("INTERMEDIATE", "INTERMEDIATE",
InputLocation.location(bomSource));
+ new InputSource("INTERMEDIATE", "INTERMEDIATE", new
InputLocation(bomSource));
final InputSource dependencySource =
- InputSource.source("DEPENDENCY", "DEPENDENCY",
InputLocation.location(intermediateSource));
+ new InputSource("DEPENDENCY", "DEPENDENCY", new
InputLocation(intermediateSource));
final Dependency dependency = Dependency.newBuilder()
- .location("", InputLocation.location(1, 1, dependencySource))
+ .location("", new InputLocation(1, 1, dependencySource))
.build();
final DependencyManagement differentSource =
DependencyManagement.newBuilder()
- .location("", InputLocation.location(2, 2,
InputSource.source("BOM2", "BOM2")))
+ .location("", new InputLocation(2, 2, new InputSource("BOM2",
"BOM2")))
.build();
// Act
diff --git a/src/mdo/common.vm b/src/mdo/common.vm
index f17bc474e0..b8ae209681 100644
--- a/src/mdo/common.vm
+++ b/src/mdo/common.vm
@@ -29,6 +29,5 @@
#end
#end
#set ( $locationTracking = true )
-#set ( $caching = true )
#end
#
\ No newline at end of file
diff --git a/src/mdo/java/CacheManager.java b/src/mdo/java/CacheManager.java
deleted file mode 100644
index 95fa7a2529..0000000000
--- a/src/mdo/java/CacheManager.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * 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 ${package};
-
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.maven.api.annotations.ThreadSafe;
-
-/**
- * Thread-safe cache manager for model objects.
- * Uses weak references to allow garbage collection of unused objects.
- */
-@ThreadSafe
-class CacheManager {
- private static final CacheManager INSTANCE = new CacheManager();
-
- // Cache of object instances
- private final ConcurrentHashMap<Class<?>, ConcurrentHashMap<Integer,
List<CacheReference>>> instanceCache =
- new ConcurrentHashMap<>();
-
- // Cache of reflected fields per class
- private final ConcurrentHashMap<Class<?>, Field[]> fieldCache = new
ConcurrentHashMap<>();
-
- // Reference queue
- private final ReferenceQueue<Cacheable> refQueue = new ReferenceQueue<>();
-
- private CacheManager() {
- // Start a background thread to process cleared references
- Thread cleanupThread = new Thread(() -> {
- while (!Thread.currentThread().isInterrupted()) {
- try {
- CacheReference ref = (CacheReference) refQueue.remove();
- ConcurrentHashMap<Integer, List<CacheReference>>
classCache = instanceCache.get(ref.clazz);
- if (classCache != null) {
- classCache.computeIfPresent(ref.hash, (k, list) -> {
- synchronized (list) {
- list.remove(ref);
- return list.isEmpty() ? null : list;
- }
- });
- if (classCache.isEmpty()) {
- instanceCache.remove(ref.clazz);
- }
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- break;
- }
- }
- }, "CacheManager-Cleanup");
- cleanupThread.setDaemon(true);
- cleanupThread.start();
- }
-
- public static CacheManager getInstance() {
- return INSTANCE;
- }
-
- /**
- * Gets all relevant fields for a class, using cached values when possible.
- * Includes all non-static, non-synthetic fields from the class and its
superclasses.
- */
- private Field[] getFields(Class<?> clazz) {
- return fieldCache.computeIfAbsent(clazz, k -> {
- List<Field> fields = new ArrayList<>();
- Class<?> currentClass = k;
-
- // Collect all fields from class hierarchy
- while (currentClass != null) {
- for (Field field : currentClass.getDeclaredFields()) {
- // Skip static and synthetic fields
- if ((field.getModifiers() & (Modifier.STATIC |
0x00001000)) == 0) {
- field.setAccessible(true); // Do this once during
caching
- fields.add(field);
- }
- }
- currentClass = currentClass.getSuperclass();
- }
-
- return fields.toArray(new Field[0]);
- });
- }
-
- /**
- * Computes a cache identity hash code by hashing all fields recursively.
- * Only processes objects that implement Cacheable.
- */
- public int computeCacheHash(Cacheable obj) {
- if (obj == null) {
- return 0;
- }
-
- try {
- int result = 1;
- for (Field field : getFields(obj.getClass())) {
- Object value = field.get(obj);
-
- int fieldHash;
- if (value instanceof List<?> list) {
- fieldHash = 1;
- for (Object element : list) {
- if (element instanceof Cacheable cacheable) {
- fieldHash = 31 * fieldHash +
computeCacheHash(cacheable);
- } else {
- fieldHash = 31 * fieldHash +
Objects.hashCode(element);
- }
- }
- } else if (value instanceof Cacheable cacheable) {
- fieldHash = computeCacheHash(cacheable);
- } else {
- fieldHash = Objects.hashCode(value);
- }
-
- result = 31 * result + fieldHash;
- }
- return result;
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Failed to compute hash", e);
- }
- }
-
- /**
- * Compares two cacheable objects for equality by comparing all their
fields recursively.
- */
- public boolean cacheEquals(Cacheable o1, Object o2) {
- if (o1 == o2) {
- return true;
- }
- if (o1 == null || o2 == null) {
- return false;
- }
- if (o1.getClass() != o2.getClass()) {
- return false;
- }
-
- try {
- for (Field field : getFields(o1.getClass())) {
- Object v1 = field.get(o1);
- Object v2 = field.get(o2);
-
- if (v1 == v2) {
- continue;
- }
- if (v1 == null || v2 == null) {
- return false;
- }
-
- if (v1 instanceof List<?> list1 && v2 instanceof List<?>
list2) {
- if (list1.size() != list2.size()) {
- return false;
- }
- for (int i = 0; i < list1.size(); i++) {
- Object e1 = list1.get(i);
- Object e2 = list2.get(i);
- if (e1 instanceof Cacheable cacheable1 && e2
instanceof Cacheable) {
- if (!cacheEquals(cacheable1, e2)) {
- return false;
- }
- } else if (!Objects.equals(e1, e2)) {
- return false;
- }
- }
- } else if (v1 instanceof Cacheable cacheable1 && v2 instanceof
Cacheable) {
- if (!cacheEquals(cacheable1, v2)) {
- return false;
- }
- } else if (!Objects.equals(v1, v2)) {
- return false;
- }
- }
- return true;
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Failed to compare objects", e);
- }
- }
-
- /**
- * Caches a Cacheable object, returning either the existing instance or
the new one.
- */
- @SuppressWarnings("unchecked")
- public <T extends Cacheable> T cached(T obj) {
- if (obj == null) {
- return null;
- }
-
- Class<?> clazz = obj.getClass();
- ConcurrentHashMap<Integer, List<CacheReference>> classCache =
- instanceCache.computeIfAbsent(clazz, k -> new
ConcurrentHashMap<>());
-
- int cacheHash = obj.cacheIdentityHash();
-
- List<CacheReference> refs = classCache.compute(cacheHash, (k, oldList)
-> {
- if (oldList == null) {
- oldList = new ArrayList<>();
- }
- List<CacheReference> newList = new ArrayList<>(oldList);
- newList.removeIf(ref -> ref == null || ref.get() == null);
- return newList;
- });
-
- synchronized (refs) {
- for (WeakReference<Cacheable> ref : refs) {
- Cacheable cached = ref.get();
- if (cached != null && obj.cacheEquals(cached)) {
- return (T) cached;
- }
- }
-
- refs.add(new CacheReference(obj, refQueue, clazz, cacheHash));
- return obj;
- }
- }
-
- /**
- * Clears all cached instances.
- * Does not clear the field cache as that remains valid.
- */
- public void clear() {
- instanceCache.clear();
- }
-
- // Custom WeakReference that keeps track of its key for removal
- private static class CacheReference extends WeakReference<Cacheable> {
- private final Class<?> clazz;
- private final int hash;
-
- CacheReference(Cacheable referent, ReferenceQueue<Cacheable> q,
Class<?> clazz, int hash) {
- super(referent, q);
- this.clazz = clazz;
- this.hash = hash;
- }
- }
-}
diff --git a/src/mdo/java/Cacheable.java b/src/mdo/java/Cacheable.java
deleted file mode 100644
index f572c89845..0000000000
--- a/src/mdo/java/Cacheable.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 ${package};
-
-/**
- * Interface for objects that can be cached in the CacheManager.
- * Implementing classes should ensure that cacheEquals() and
cacheIdentityHash()
- * use all relevant fields for determining cache identity.
- */
-public interface Cacheable {
- /**
- * Returns true if this object should be considered equal to another for
caching purposes.
- * This is separate from equals() to allow different equality semantics.
- *
- * @param other the object to compare with
- * @return true if the objects are equal for caching purposes
- */
- default boolean cacheEquals(Object other) {
- return CacheManager.getInstance().cacheEquals(this, other);
- }
-
- /**
- * Returns a hash code for cache identity purposes.
- * This is separate from hashCode() to allow different hashing semantics.
- *
- * @return the cache identity hash code
- */
- int cacheIdentityHash();
-}
diff --git a/src/mdo/java/InputLocation.java b/src/mdo/java/InputLocation.java
index 4468260a35..2685b813ba 100644
--- a/src/mdo/java/InputLocation.java
+++ b/src/mdo/java/InputLocation.java
@@ -33,32 +33,30 @@ public class InputLocation implements Serializable,
InputLocationTracker {
private final InputSource source;
private final Map<Object, InputLocation> locations;
- public static InputLocation location(InputSource source) {
- return new InputLocation(-1, -1, source, 0);
- }
-
- public static InputLocation location(int lineNumber, int columnNumber) {
- return new InputLocation(lineNumber, columnNumber, null, null);
+ public InputLocation(InputSource source) {
+ this.lineNumber = -1;
+ this.columnNumber = -1;
+ this.source = source;
+ this.locations = Collections.singletonMap(0, this);
}
- public static InputLocation location(int lineNumber, int columnNumber,
InputSource source) {
- return new InputLocation(lineNumber, columnNumber, source, null);
+ public InputLocation(int lineNumber, int columnNumber) {
+ this(lineNumber, columnNumber, null, null);
}
- public static InputLocation location(int lineNumber, int columnNumber,
InputSource source, Object selfLocationKey) {
- return new InputLocation(lineNumber, columnNumber, source,
selfLocationKey);
+ public InputLocation(int lineNumber, int columnNumber, InputSource source)
{
+ this(lineNumber, columnNumber, source, null);
}
- InputLocation(int lineNumber, int columnNumber, InputSource source, Object
selfLocationKey) {
+ public InputLocation(int lineNumber, int columnNumber, InputSource source,
Object selfLocationKey) {
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
this.source = source;
- this.locations = selfLocationKey != null
- ? ImmutableCollections.singletonMap(selfLocationKey, this)
- : ImmutableCollections.emptyMap();
+ this.locations =
+ selfLocationKey != null ?
Collections.singletonMap(selfLocationKey, this) : Collections.emptyMap();
}
- InputLocation(int lineNumber, int columnNumber, InputSource source,
Map<Object, InputLocation> locations) {
+ public InputLocation(int lineNumber, int columnNumber, InputSource source,
Map<Object, InputLocation> locations) {
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
this.source = source;
diff --git a/src/mdo/java/InputSource.java b/src/mdo/java/InputSource.java
index 0e8ca90056..aeb405f976 100644
--- a/src/mdo/java/InputSource.java
+++ b/src/mdo/java/InputSource.java
@@ -27,11 +27,7 @@ public class InputSource implements Serializable {
private final String location;
- public static InputSource source(String location) {
- return new InputSource(location);
- }
-
- InputSource(String location) {
+ public InputSource(String location) {
this.location = location;
}
diff --git a/src/mdo/merger.vm b/src/mdo/merger.vm
index dec3bb7a43..1ac8ad0315 100644
--- a/src/mdo/merger.vm
+++ b/src/mdo/merger.vm
@@ -155,7 +155,7 @@ public class ${className} {
if (target.get${capField}() == null) {
builder.location("${field.name}",
source.getLocation("${field.name}"));
} else if (merged != tgt) {
- builder.location("${field.name}", InputLocation.location(-1,
-1));
+ builder.location("${field.name}", new InputLocation(-1, -1));
}
#end
}
diff --git a/src/mdo/model.vm b/src/mdo/model.vm
index 74da7edc74..8e4c46243c 100644
--- a/src/mdo/model.vm
+++ b/src/mdo/model.vm
@@ -41,12 +41,6 @@
#end
#MODELLO-VELOCITY#SAVE-OUTPUT-TO
${package.replace('.','/')}/ImmutableCollections.java
#parse ( "java/ImmutableCollections.java" )
-#if ( $caching )
-#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/Cacheable.java
-#parse ( "java/Cacheable.java" )
-#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/CacheManager.java
-#parse ( "java/CacheManager.java" )
-#end
#if ( $class.name != "InputLocation" && $class.name != "InputSource" )
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java
#set ( $types = { } )
@@ -126,18 +120,10 @@ public class ${class.name}
#if ( $class.superClass )
extends ${class.superClass}
#end
- #if ( $caching )
- #if ( $locationTracking )
- implements Cacheable, Serializable, InputLocationTracker
- #else
- implements Cacheable, Serializable
- #end
- #else
- #if ( $locationTracking )
+ #if ( $locationTracking )
implements Serializable, InputLocationTracker
- #else
+ #else
implements Serializable
- #end
#end
{
#if ( $class == $root )
@@ -163,11 +149,6 @@ public class ${class.name}
final InputLocation importedFrom;
#end
- #if ( $caching )
- /** Pre-computed cache identity hash code */
- private final int cacheHash;
-
- #end
/**
* Constructor for this class, to be called from its subclasses and
{@link Builder}.
* @see Builder#build()
@@ -199,11 +180,6 @@ public class ${class.name}
#end
this.importedFrom = builder.importedFrom;
#end
- #if ( $caching )
-
- // Compute cache identity hash code once during construction
- this.cacheHash = computeCacheHash();
- #end
}
#if ( ! $eq.empty )
@@ -320,18 +296,6 @@ public class ${class.name}
}
#end
- #if ( $caching )
- @Override
- public int cacheIdentityHash() {
- return cacheHash;
- }
-
- /** Computes the cache identity hash code during construction */
- private int computeCacheHash() {
- return CacheManager.getInstance().computeCacheHash(this);
- }
- #end
-
/**
* Creates a new builder with this object as the basis.
*
@@ -565,11 +529,7 @@ public class ${class.name}
) {
return base;
}
- #if ( $caching )
- return CacheManager.getInstance().cached(new ${class.name}(this));
- #else
return new ${class.name}(this);
- #end
}
#if ( $locationTracking && ! $class.superClass )
diff --git a/src/mdo/reader-stax.vm b/src/mdo/reader-stax.vm
index 9bad8525af..96386d62f6 100644
--- a/src/mdo/reader-stax.vm
+++ b/src/mdo/reader-stax.vm
@@ -551,7 +551,7 @@ public class ${className} {
${classUcapName}.Builder ${classLcapName} =
${classUcapName}.newBuilder(true);
#if ( $locationTracking )
if (addLocationInformation) {
- ${classLcapName}.location("",
InputLocation.location(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
+ ${classLcapName}.location("", new
InputLocation(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
}
#end
for (int i = parser.getAttributeCount() - 1; i >= 0; i--) {
@@ -574,7 +574,7 @@ public class ${className} {
} else if ("$fieldTagName".equals(name)) {
#if ( $locationTracking )
if (addLocationInformation) {
- ${classLcapName}.location(name,
InputLocation.location(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
+ ${classLcapName}.location(name, new
InputLocation(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
}
#end
#if ( $field.type == "String" )
@@ -646,7 +646,7 @@ public class ${className} {
if
("${Helper.singular($fieldTagName)}".equals(parser.getLocalName())) {
#if ( $locationTracking )
if (addLocationInformation) {
-
locations.put(Integer.valueOf(locations.size()),
InputLocation.location(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
+
locations.put(Integer.valueOf(locations.size()), new
InputLocation(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
}
#end
${field.name}.add(interpolatedTrimmed(nextText(parser, strict),
"${fieldTagName}"));
@@ -666,7 +666,7 @@ public class ${className} {
String value = nextText(parser, strict).trim();
#if ( $locationTracking )
if (addLocationInformation) {
- locations.put(key,
InputLocation.location(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
+ locations.put(key, new
InputLocation(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc));
}
#end
${field.name}.put(key, value);
@@ -723,7 +723,7 @@ public class ${className} {
}
#if ( $locationTracking )
if (addLocationInformation) {
- ${classLcapName}.location(childName,
InputLocation.location(line, column, inputSrc, locations));
+ ${classLcapName}.location(childName, new InputLocation(line,
column, inputSrc, locations));
}
#end
}
@@ -926,7 +926,7 @@ public class ${className} {
private XmlNode buildXmlNode(XMLStreamReader parser, InputSource inputSrc)
throws XMLStreamException {
return XmlNodeStaxBuilder.build(parser,
addLocationInformation
- ? p ->
InputLocation.location(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc)
+ ? p -> new
InputLocation(parser.getLocation().getLineNumber(),
parser.getLocation().getColumnNumber(), inputSrc)
: null);
}
#else