This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push:
new 39bc9c1ff CAY-2952 Unstable project extension ordering
39bc9c1ff is described below
commit 39bc9c1ff198e00f9faff0645bcb9827bdaf116d
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sun May 24 17:32:53 2026 -0400
CAY-2952 Unstable project extension ordering
---
RELEASE-NOTES.txt | 1 +
.../org/apache/cayenne/gen/xml/CgenExtension.java | 5 ++++
.../cayenne/dbsync/xml/DbImportExtension.java | 4 +++
.../apache/cayenne/project/FileProjectSaver.java | 9 ++++---
.../project/extension/ProjectExtension.java | 8 ++++++
.../project/extension/info/InfoExtension.java | 5 ++++
.../extension/validation/ValidationExtension.java | 5 ++++
.../cayenne/project/FileProjectSaverTest.java | 29 ++++++++++++++++++++++
8 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index c94bd087c..879dbf7cd 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -78,6 +78,7 @@ CAY-2931 Modeler: default encoding detected as UTF8, should
be UTF-8
CAY-2934 Modeler: dropdown data trunction
CAY-2944 MergerTokenFactoryProvider does not resolve adapter subclasses
CAY-2951 Newly reverse-engineered entities are excluded from CGen
+CAY-2952 Unstable project extension ordering
----------------------------------
Release: 5.0-M1
diff --git
a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
index 374819942..b4cd865c6 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
@@ -51,4 +51,9 @@ public class CgenExtension implements ProjectExtension {
public ConfigurationNodeVisitor<String> createNamingDelegate() {
return new BaseNamingDelegate();
}
+
+ @Override
+ public int order() {
+ return 30;
+ }
}
diff --git
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/xml/DbImportExtension.java
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/xml/DbImportExtension.java
index 5732061c7..4b24ab66a 100644
---
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/xml/DbImportExtension.java
+++
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/xml/DbImportExtension.java
@@ -53,4 +53,8 @@ public class DbImportExtension implements ProjectExtension {
return new BaseNamingDelegate();
}
+ @Override
+ public int order() {
+ return 20;
+ }
}
diff --git
a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
index e81c8a88f..80dd2ee20 100644
---
a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
+++
b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
@@ -42,6 +42,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
/**
@@ -68,9 +69,11 @@ public class FileProjectSaver implements ProjectSaver {
// this is not configurable yet... probably doesn't have to be
fileEncoding = "UTF-8";
- this.extensions = extensions;
- Collection<SaverDelegate> delegates = new
ArrayList<>(extensions.size());
- for (ProjectExtension extension : extensions) {
+ List<ProjectExtension> sorted = new ArrayList<>(extensions);
+ sorted.sort(Comparator.comparingInt(ProjectExtension::order));
+ this.extensions = sorted;
+ Collection<SaverDelegate> delegates = new ArrayList<>(sorted.size());
+ for (ProjectExtension extension : sorted) {
delegates.add(extension.createSaverDelegate());
}
delegate = new CompoundSaverDelegate(delegates);
diff --git
a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
index 2c1253f98..425fdfcbe 100644
---
a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
+++
b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
@@ -50,4 +50,12 @@ public interface ProjectExtension {
ConfigurationNodeVisitor<String> createNamingDelegate();
+ /**
+ * Controls the relative position of this extension's XML elements within
a saved file.
+ * Extensions with lower values are written first. Each known extension
must return a unique value.
+ *
+ * @since 5.0
+ */
+ int order();
+
}
diff --git
a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
index 20aa6c92a..5d40a9215 100644
---
a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
+++
b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
@@ -56,4 +56,9 @@ public class InfoExtension implements ProjectExtension {
public ConfigurationNodeVisitor<String> createNamingDelegate() {
return new BaseNamingDelegate();
}
+
+ @Override
+ public int order() {
+ return 10;
+ }
}
diff --git
a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/validation/ValidationExtension.java
b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/validation/ValidationExtension.java
index ac816df91..b8af97fbf 100644
---
a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/validation/ValidationExtension.java
+++
b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/validation/ValidationExtension.java
@@ -48,4 +48,9 @@ public class ValidationExtension implements ProjectExtension {
public ConfigurationNodeVisitor<String> createNamingDelegate() {
return new BaseNamingDelegate();
}
+
+ @Override
+ public int order() {
+ return 40;
+ }
}
diff --git
a/cayenne-project/src/test/java/org/apache/cayenne/project/FileProjectSaverTest.java
b/cayenne-project/src/test/java/org/apache/cayenne/project/FileProjectSaverTest.java
index 37fb24a4b..e44555f56 100644
---
a/cayenne-project/src/test/java/org/apache/cayenne/project/FileProjectSaverTest.java
+++
b/cayenne-project/src/test/java/org/apache/cayenne/project/FileProjectSaverTest.java
@@ -19,6 +19,7 @@
package org.apache.cayenne.project;
import org.apache.cayenne.configuration.ConfigurationNameMapper;
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
import org.apache.cayenne.configuration.ConfigurationTree;
import org.apache.cayenne.configuration.DataChannelDescriptor;
import org.apache.cayenne.configuration.DataNodeDescriptor;
@@ -27,7 +28,10 @@ import org.apache.cayenne.di.DIBootstrap;
import org.apache.cayenne.di.Injector;
import org.apache.cayenne.di.Module;
import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.project.extension.BaseSaverDelegate;
+import org.apache.cayenne.project.extension.LoaderDelegate;
import org.apache.cayenne.project.extension.ProjectExtension;
+import org.apache.cayenne.project.extension.SaverDelegate;
import org.apache.cayenne.resource.URLResource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -43,6 +47,7 @@ import java.io.File;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -135,6 +140,30 @@ public class FileProjectSaverTest {
assertEquals("C", xpath.evaluate("@name", mapRefs.item(2)));
}
+ @Test
+ public void extensionsAreSortedByOrder() {
+ ProjectExtension ext10 = stubExtension(10);
+ ProjectExtension ext20 = stubExtension(20);
+ ProjectExtension ext30 = stubExtension(30);
+
+ // supply in reverse order — saver must still store them sorted
ascending
+ FileProjectSaver s1 = new FileProjectSaver(List.of(ext30, ext20,
ext10));
+ assertEquals(List.of(ext10, ext20, ext30), s1.extensions);
+
+ // supply in random order
+ FileProjectSaver s2 = new FileProjectSaver(List.of(ext20, ext10,
ext30));
+ assertEquals(List.of(ext10, ext20, ext30), s2.extensions);
+ }
+
+ private static ProjectExtension stubExtension(int order) {
+ return new ProjectExtension() {
+ @Override public LoaderDelegate createLoaderDelegate() { return
null; }
+ @Override public SaverDelegate createSaverDelegate() { return new
BaseSaverDelegate(); }
+ @Override public ConfigurationNodeVisitor<String>
createNamingDelegate() { return null; }
+ @Override public int order() { return order; }
+ };
+ }
+
/**
* Regression test for CAY-1780: relative fragments (e.g. ./../) in target
* file path must be resolved correctly.