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
commit 374ec4acc6d6c072176ae03e1236e2c8f069730b Author: Andrus Adamchik <[email protected]> AuthorDate: Fri May 8 16:59:27 2026 -0400 CAY-2937 Decomission "graph" support * wiring up v12 upgrade mechanism --- .../java/org/apache/cayenne/project/Project.java | 2 +- .../org/apache/cayenne/project/ProjectModule.java | 4 +- .../upgrade/handlers/UpgradeHandler_V12.java | 99 ++++++++++++++++ .../project/upgrade/DefaultUpgradeServiceTest.java | 12 +- .../upgrade/handlers/UpgradeHandler_V12Test.java | 128 +++++++++++++++++++++ .../upgrade/handlers/cayenne-project-v11.xml | 2 +- ...nne-project-v11.xml => cayenne-project-v13.xml} | 2 +- .../project/upgrade/v12/cayenne-project1.xml | 19 +++ .../cayenne/project/upgrade/v12/map1.map.xml | 42 +++++++ .../cayenne/project/upgrade/v12/project1.graph.xml | 7 ++ 10 files changed, 309 insertions(+), 8 deletions(-) diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/Project.java b/cayenne-project/src/main/java/org/apache/cayenne/project/Project.java index 4cd6c3242..20e840d88 100644 --- a/cayenne-project/src/main/java/org/apache/cayenne/project/Project.java +++ b/cayenne-project/src/main/java/org/apache/cayenne/project/Project.java @@ -42,7 +42,7 @@ public class Project { * * @since 4.1 */ - static public final int VERSION = 11; + static public final int VERSION = 12; protected boolean modified; diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/ProjectModule.java b/cayenne-project/src/main/java/org/apache/cayenne/project/ProjectModule.java index a594bd1ca..0b9ede4dc 100644 --- a/cayenne-project/src/main/java/org/apache/cayenne/project/ProjectModule.java +++ b/cayenne-project/src/main/java/org/apache/cayenne/project/ProjectModule.java @@ -29,6 +29,7 @@ import org.apache.cayenne.project.upgrade.UpgradeService; import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler; import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V10; import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V11; +import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V12; import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V7; import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V8; import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V9; @@ -85,6 +86,7 @@ public class ProjectModule implements Module { .addUpgradeHandler(UpgradeHandler_V8.class) .addUpgradeHandler(UpgradeHandler_V9.class) .addUpgradeHandler(UpgradeHandler_V10.class) - .addUpgradeHandler(UpgradeHandler_V11.class); + .addUpgradeHandler(UpgradeHandler_V11.class) + .addUpgradeHandler(UpgradeHandler_V12.class); } } diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V12.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V12.java new file mode 100644 index 000000000..78a46d88f --- /dev/null +++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V12.java @@ -0,0 +1,99 @@ +/***************************************************************** + * 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 + * + * https://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.cayenne.project.upgrade.handlers; + +import org.apache.cayenne.project.upgrade.UpgradeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import java.io.File; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +/** + * Upgrade handler for the project version "12" introduced by 5.0.M2 release. + * Changes: graph extension removal from Cayenne projects. + * + * @since 5.0 + */ +public class UpgradeHandler_V12 implements UpgradeHandler { + + private static final Logger logger = LoggerFactory.getLogger(UpgradeHandler_V12.class); + + static final String GRAPH_SUFFIX = ".graph.xml"; + + @Override + public String getVersion() { + return "12"; + } + + @Override + public void processProjectDom(UpgradeUnit upgradeUnit) { + updateDomainSchemaAndVersion(upgradeUnit); + removeGraphIncludes(upgradeUnit); + } + + @Override + public void processDataMapDom(UpgradeUnit upgradeUnit) { + updateDataMapSchemaAndVersion(upgradeUnit); + } + + private void removeGraphIncludes(UpgradeUnit upgradeUnit) { + XPath xpath = XPathFactory.newInstance().newXPath(); + NodeList nodes; + try { + nodes = (NodeList) xpath.evaluate("/domain/*[local-name()='include']", + upgradeUnit.getDocument(), XPathConstants.NODESET); + } catch (Exception e) { + return; + } + + List<Element> toRemove = new ArrayList<>(); + for (int j = 0; j < nodes.getLength(); j++) { + Element element = (Element) nodes.item(j); + String href = element.getAttribute("href"); + if (href != null && href.endsWith(GRAPH_SUFFIX)) { + deleteGraphFile(upgradeUnit, href); + toRemove.add(element); + } + } + for (Element element : toRemove) { + element.getParentNode().removeChild(element); + } + } + + private void deleteGraphFile(UpgradeUnit upgradeUnit, String href) { + try { + File projectFile = new File(upgradeUnit.getResource().getURL().toURI()); + File graphFile = new File(projectFile.getParentFile(), href); + if (!Files.deleteIfExists(graphFile.toPath())) { + logger.warn("Graph file not found, skipping deletion: {}", graphFile); + } + } catch (Exception e) { + logger.warn("Failed to delete graph file '{}': {}", href, e.getMessage()); + } + } +} diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java index a2ba5ca12..11eddc377 100644 --- a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java +++ b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java @@ -68,9 +68,12 @@ public class DefaultUpgradeServiceTest { assertEquals(UpgradeType.UPGRADE_NEEDED, metaData.getUpgradeType()); metaData = upgradeService.getUpgradeType(getResourceForVersion("11")); - assertEquals(UpgradeType.UPGRADE_NOT_NEEDED, metaData.getUpgradeType()); + assertEquals(UpgradeType.UPGRADE_NEEDED, metaData.getUpgradeType()); metaData = upgradeService.getUpgradeType(getResourceForVersion("12")); + assertEquals(UpgradeType.UPGRADE_NOT_NEEDED, metaData.getUpgradeType()); + + metaData = upgradeService.getUpgradeType(getResourceForVersion("13")); assertEquals(UpgradeType.DOWNGRADE_NEEDED, metaData.getUpgradeType()); } @@ -78,12 +81,13 @@ public class DefaultUpgradeServiceTest { public void getHandlersForVersion() throws Exception { List<UpgradeHandler> handlers = upgradeService.getHandlersForVersion("6"); - assertEquals(5, handlers.size()); + assertEquals(6, handlers.size()); handlers = upgradeService.getHandlersForVersion("9"); - assertEquals(2, handlers.size()); + assertEquals(3, handlers.size()); assertEquals("10", handlers.get(0).getVersion()); assertEquals("11", handlers.get(1).getVersion()); + assertEquals("12", handlers.get(2).getVersion()); } @Test @@ -148,7 +152,7 @@ public class DefaultUpgradeServiceTest { private void createHandlers() { handlers = new ArrayList<>(); - String[] versions = {"7", "8", "9", "10", "11"}; + String[] versions = {"7", "8", "9", "10", "11", "12"}; for(String version : versions) { handlers.add(createHandler(version)); } diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V12Test.java b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V12Test.java new file mode 100644 index 000000000..af7ba9b99 --- /dev/null +++ b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V12Test.java @@ -0,0 +1,128 @@ +/***************************************************************** + * 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 + * + * https://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.cayenne.project.upgrade.handlers; + +import org.apache.cayenne.configuration.DataChannelDescriptor; +import org.apache.cayenne.project.upgrade.UpgradeUnit; +import org.apache.cayenne.resource.URLResource; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * @since 5.0 + */ +public class UpgradeHandler_V12Test extends BaseUpgradeHandlerTest { + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + @Override + UpgradeHandler newHandler() { + return new UpgradeHandler_V12(); + } + + @Test + public void testProjectDomUpgrade() throws Exception { + File projectFile = copyResourceToTemp("../v12/cayenne-project1.xml", "cayenne-project.xml"); + File graphFile = copyResourceToTemp("../v12/project1.graph.xml", "project1.graph.xml"); + assertTrue("precondition: graph file exists", graphFile.exists()); + + Document document = processProjectDomFromFile(projectFile); + + Element root = document.getDocumentElement(); + assertEquals("12", root.getAttribute("project-version")); + assertEquals("http://cayenne.apache.org/schema/12/domain", root.getAttribute("xmlns")); + + XPath xpath = XPathFactory.newInstance().newXPath(); + NodeList includes = (NodeList) xpath.evaluate("/domain/*[local-name()='include']", + document, XPathConstants.NODESET); + assertEquals("xi:include must be removed", 0, includes.getLength()); + + assertFalse("graph file must be deleted", graphFile.exists()); + } + + @Test + public void testProjectDomUpgradeNoGraphFile() throws Exception { + File projectFile = copyResourceToTemp("../v12/cayenne-project1.xml", "cayenne-project.xml"); + + // graph file intentionally absent — upgrade must complete without exception + Document document = processProjectDomFromFile(projectFile); + + Element root = document.getDocumentElement(); + assertEquals("12", root.getAttribute("project-version")); + + XPath xpath = XPathFactory.newInstance().newXPath(); + NodeList includes = (NodeList) xpath.evaluate("/domain/*[local-name()='include']", + document, XPathConstants.NODESET); + assertEquals("xi:include must be removed", 0, includes.getLength()); + } + + @Test + public void testDataMapDomUpgrade() throws Exception { + Document document = processDataMapDom("../v12/map1.map.xml"); + + Element root = document.getDocumentElement(); + assertEquals("12", root.getAttribute("project-version")); + assertEquals("http://cayenne.apache.org/schema/12/modelMap", root.getAttribute("xmlns")); + } + + @Test + public void testModelUpgrade() { + DataChannelDescriptor descriptor = mock(DataChannelDescriptor.class); + handler.processModel(descriptor); + verifyNoInteractions(descriptor); + } + + private File copyResourceToTemp(String resourcePath, String targetName) throws Exception { + File target = new File(tempFolder.getRoot(), targetName); + try (InputStream in = getClass().getResourceAsStream(resourcePath)) { + Files.copy(in, target.toPath()); + } + return target; + } + + private Document processProjectDomFromFile(File file) throws Exception { + DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document doc; + try (InputStream in = Files.newInputStream(file.toPath())) { + doc = db.parse(in); + } + UpgradeUnit unit = new UpgradeUnit(new URLResource(file.toURI().toURL()), doc); + handler.processProjectDom(unit); + return doc; + } +} diff --git a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v11.xml b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v11.xml index 51f7c4cd1..28d421695 100644 --- a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v11.xml +++ b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v11.xml @@ -1,3 +1,3 @@ <?xml version="1.0" encoding="utf-8"?> <!-- Fake version to test DefaultUpgradeService --> -<domain project-version="11"/> \ No newline at end of file +<domain project-version="11"/> diff --git a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v11.xml b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v13.xml similarity index 74% copy from cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v11.xml copy to cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v13.xml index 51f7c4cd1..35dd50c5e 100644 --- a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v11.xml +++ b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/cayenne-project-v13.xml @@ -1,3 +1,3 @@ <?xml version="1.0" encoding="utf-8"?> <!-- Fake version to test DefaultUpgradeService --> -<domain project-version="11"/> \ No newline at end of file +<domain project-version="13"/> diff --git a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/cayenne-project1.xml b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/cayenne-project1.xml new file mode 100644 index 000000000..b305de836 --- /dev/null +++ b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/cayenne-project1.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<domain xmlns="http://cayenne.apache.org/schema/11/domain" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://cayenne.apache.org/schema/11/domain https://cayenne.apache.org/schema/11/domain.xsd" + project-version="11"> + <map name="map1"/> + <node name="node1" + adapter="org.example.test.Adapter" + factory="org.apache.cayenne.configuration.runtime.XMLPoolingDataSourceFactory"> + <map-ref name="map1"/> + <data-source> + <driver/> + <url/> + <connectionPool min="1" max="1"/> + <login/> + </data-source> + </node> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="project1.graph.xml"/> +</domain> diff --git a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/map1.map.xml b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/map1.map.xml new file mode 100644 index 000000000..c34c87c39 --- /dev/null +++ b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/map1.map.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<data-map xmlns="http://cayenne.apache.org/schema/11/modelMap" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://cayenne.apache.org/schema/11/modelMap https://cayenne.apache.org/schema/11/modelMap.xsd" + project-version="11"> + <property name="defaultPackage" value="org.apache.cayenne.x"/> + <db-entity name="db_entity"> + <db-attribute name="untitledAttr" type="INTEGER" isPrimaryKey="true" isMandatory="true"/> + </db-entity> + <db-entity name="db_entity1"> + <db-attribute name="untitledAttr" type="INTEGER" isPrimaryKey="true" isMandatory="true"/> + </db-entity> + <dbImport xmlns="http://cayenne.apache.org/schema/11/dbimport"> + <tableTypes> + <tableType>TABLE</tableType> + <tableType>VIEW</tableType> + </tableTypes> + <forceDataMapCatalog>false</forceDataMapCatalog> + <forceDataMapSchema>false</forceDataMapSchema> + <namingStrategy>org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator</namingStrategy> + <skipPrimaryKeyLoading>false</skipPrimaryKeyLoading> + <skipRelationshipsLoading>false</skipRelationshipsLoading> + <useJava7Types>false</useJava7Types> + </dbImport> + <cgen xmlns="http://cayenne.apache.org/schema/11/cgen"> + <name>Default</name> + <destDir>../../../../../../../java</destDir> + <mode>entity</mode> + <template>templates/v4_1/subclass.vm</template> + <superTemplate>templates/v4_1/superclass.vm</superTemplate> + <embeddableTemplate>templates/v4_1/embeddable-subclass.vm</embeddableTemplate> + <embeddableSuperTemplate>templates/v4_1/embeddable-superclass.vm</embeddableSuperTemplate> + <dataMapTemplate>templates/v4_1/datamap-subclass.vm</dataMapTemplate> + <dataMapSuperTemplate>templates/v4_1/datamap-superclass.vm</dataMapSuperTemplate> + <outputPattern>*.java</outputPattern> + <makePairs>true</makePairs> + <usePkgPath>true</usePkgPath> + <overwrite>false</overwrite> + <createPropertyNames>false</createPropertyNames> + <createPKProperties>true</createPKProperties> + </cgen> +</data-map> diff --git a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/project1.graph.xml b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/project1.graph.xml new file mode 100644 index 000000000..447447a36 --- /dev/null +++ b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/v12/project1.graph.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<graphs xmlns="http://cayenne.apache.org/schema/11/graph"> + <graph type="ER" scale="1.0"> + <entity name="db_entity" x="36.0" y="178.5" width="75.0" height="50.0"/> + <entity name="db_entity1" x="183.0" y="176.5" width="75.0" height="50.0"/> + </graph> +</graphs>
