You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/07/26 08:39:29 UTC
cayenne git commit: CAY-2339 Compatibility module support old
versions of projects at runtime
Repository: cayenne
Updated Branches:
refs/heads/master 11b916f85 -> 3f375f384
CAY-2339 Compatibility module
support old versions of projects at runtime
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/3f375f38
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/3f375f38
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/3f375f38
Branch: refs/heads/master
Commit: 3f375f38443ce06d15d7024d3408b59a509f7b77
Parents: 11b916f
Author: Nikita Timofeev <st...@gmail.com>
Authored: Tue Jul 25 18:51:46 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Tue Jul 25 18:51:46 2017 +0300
----------------------------------------------------------------------
cayenne-project-compatibility/pom.xml | 64 +++++++++
...ompatibilityDataChannelDescriptorLoader.java | 134 +++++++++++++++++++
.../xml/CompatibilityDataMapLoader.java | 89 ++++++++++++
.../CompatibilityUpgradeService.java | 62 +++++++++
.../compatibility/DefaultDocumentProvider.java | 44 ++++++
.../project/compatibility/DocumentProvider.java | 34 +++++
.../ProjectCompatibilityModule.java | 54 ++++++++
.../ProjectCompatibilityModuleProvider.java | 51 +++++++
...iguration.server.CayenneServerModuleProvider | 20 +++
...patibilityDataChannelDescriptorLoaderIT.java | 105 +++++++++++++++
.../CompatibilityUpgradeServiceIT.java | 90 +++++++++++++
.../ProjectCompatibilityModuleProviderTest.java | 35 +++++
.../compatibility/cayenne-project-v6.xml | 35 +++++
.../project/compatibility/test-map-v6.map.xml | 21 +++
.../project/upgrade/DefaultUpgradeService.java | 63 ++++-----
.../upgrade/DefaultUpgradeServiceTest.java | 10 +-
.../configuration/xml/XMLDataMapLoader.java | 2 +-
.../main/java/org/apache/cayenne/util/Util.java | 25 ++++
pom.xml | 1 +
19 files changed, 899 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/pom.xml b/cayenne-project-compatibility/pom.xml
new file mode 100644
index 0000000..78f2516
--- /dev/null
+++ b/cayenne-project-compatibility/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>cayenne-parent</artifactId>
+ <groupId>org.apache.cayenne</groupId>
+ <version>4.1.M1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>cayenne-project-compatibility</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cayenne</groupId>
+ <artifactId>cayenne-project</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cayenne</groupId>
+ <artifactId>cayenne-server</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoader.java b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoader.java
new file mode 100644
index 0000000..575f080
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoader.java
@@ -0,0 +1,134 @@
+/*****************************************************************
+ * 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.cayenne.configuration.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.net.URL;
+
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.cayenne.ConfigurationException;
+import org.apache.cayenne.configuration.ConfigurationTree;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.project.compatibility.CompatibilityUpgradeService;
+import org.apache.cayenne.project.compatibility.DocumentProvider;
+import org.apache.cayenne.project.upgrade.UpgradeMetaData;
+import org.apache.cayenne.project.upgrade.UpgradeService;
+import org.apache.cayenne.project.upgrade.UpgradeType;
+import org.apache.cayenne.resource.Resource;
+import org.apache.cayenne.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+
+/**
+ * @since 4.1
+ */
+public class CompatibilityDataChannelDescriptorLoader extends XMLDataChannelDescriptorLoader {
+
+ private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
+
+ @Inject
+ Provider<UpgradeService> upgradeServiceProvider;
+
+ @Inject
+ DocumentProvider documentProvider;
+
+ @Override
+ public ConfigurationTree<DataChannelDescriptor> load(Resource configurationResource) throws ConfigurationException {
+ if (configurationResource == null) {
+ throw new NullPointerException("Null configurationResource");
+ }
+
+ if(!(upgradeServiceProvider.get() instanceof CompatibilityUpgradeService)) {
+ throw new ConfigurationException("CompatibilityUpgradeService expected");
+ }
+
+ CompatibilityUpgradeService upgradeService = (CompatibilityUpgradeService)upgradeServiceProvider.get();
+
+ UpgradeMetaData metaData = upgradeService.getUpgradeType(configurationResource);
+ if(metaData.getUpgradeType() == UpgradeType.UPGRADE_NOT_NEEDED) {
+ return super.load(configurationResource);
+ }
+
+ if(metaData.getUpgradeType() == UpgradeType.DOWNGRADE_NEEDED) {
+ throw new ConfigurationException("Unable to load configuration from %s: " +
+ "It was created using a newer version of the Modeler", configurationResource.getURL());
+ }
+
+ if(metaData.getUpgradeType() == UpgradeType.INTERMEDIATE_UPGRADE_NEEDED) {
+ throw new ConfigurationException("Unable to load configuration from %s: " +
+ "Open the project in the older Modeler to do an intermediate upgrade.", configurationResource.getURL());
+ }
+
+ URL configurationURL = configurationResource.getURL();
+
+ upgradeService.upgradeProject(configurationResource);
+ Document projectDocument = documentProvider.getDocument(configurationURL);
+ if(projectDocument == null) {
+ throw new ConfigurationException("Unable to upgrade " + configurationURL);
+ }
+
+ logger.info("Loading XML configuration resource from " + configurationURL);
+
+ final DataChannelDescriptor descriptor = new DataChannelDescriptor();
+ descriptor.setConfigurationSource(configurationResource);
+ descriptor.setName(nameMapper.configurationNodeName(DataChannelDescriptor.class, configurationResource));
+
+ try {
+ DOMSource source = new DOMSource(projectDocument);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ TransformerFactory transFactory = TransformerFactory.newInstance();
+ transFactory.newTransformer().transform(source, new StreamResult(baos));
+ InputSource isource = new InputSource(source.getSystemId());
+ isource.setByteStream(new ByteArrayInputStream(baos.toByteArray()));
+
+ XMLReader parser = Util.createXmlReader();
+ LoaderContext loaderContext = new LoaderContext(parser, handlerFactory);
+ loaderContext.addDataMapListener(new DataMapLoaderListener() {
+ @Override
+ public void onDataMapLoaded(DataMap dataMap) {
+ descriptor.getDataMaps().add(dataMap);
+ }
+ });
+
+ DataChannelHandler rootHandler = new DataChannelHandler(this, descriptor, loaderContext);
+ parser.setContentHandler(rootHandler);
+ parser.setErrorHandler(rootHandler);
+ parser.parse(isource);
+ } catch (Exception e) {
+ throw new ConfigurationException("Error loading configuration from %s", e, configurationURL);
+ }
+
+ // Finally upgrade model, if needed
+ upgradeService.upgradeModel(configurationResource, descriptor);
+
+ return new ConfigurationTree<>(descriptor, null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataMapLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataMapLoader.java b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataMapLoader.java
new file mode 100644
index 0000000..77ce2cd
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/configuration/xml/CompatibilityDataMapLoader.java
@@ -0,0 +1,89 @@
+/*****************************************************************
+ * 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.cayenne.configuration.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.project.compatibility.DocumentProvider;
+import org.apache.cayenne.resource.Resource;
+import org.apache.cayenne.util.Util;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+/**
+ * @since 4.1
+ */
+public class CompatibilityDataMapLoader extends XMLDataMapLoader {
+
+ @Inject
+ DocumentProvider documentProvider;
+
+ @Override
+ public DataMap load(Resource configurationResource) throws CayenneRuntimeException {
+ Document document = documentProvider.getDocument(configurationResource.getURL());
+ if(document == null) {
+ return super.load(configurationResource);
+ }
+
+ try {
+ DOMSource source = new DOMSource(document);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ TransformerFactory transFactory = TransformerFactory.newInstance();
+ transFactory.newTransformer().transform(source, new StreamResult(baos));
+ InputSource isource = new InputSource(source.getSystemId());
+ isource.setByteStream(new ByteArrayInputStream(baos.toByteArray()));
+
+ XMLReader parser = Util.createXmlReader();
+ LoaderContext loaderContext = new LoaderContext(parser, handlerFactory);
+ loaderContext.addDataMapListener(new DataMapLoaderListener() {
+ @Override
+ public void onDataMapLoaded(DataMap dataMap) {
+ map = dataMap;
+ }
+ });
+ RootDataMapHandler rootHandler = new RootDataMapHandler(loaderContext);
+
+ parser.setContentHandler(rootHandler);
+ parser.setErrorHandler(rootHandler);
+ parser.parse(isource);
+ } catch (Exception e) {
+ throw new CayenneRuntimeException("Error loading configuration from %s", e, configurationResource.getURL());
+ }
+
+ if(map == null) {
+ throw new CayenneRuntimeException("Unable to load data map from %s", configurationResource.getURL());
+ }
+
+ if(map.getName() == null) {
+ // set name based on location if no name provided by map itself
+ map.setName(mapNameFromLocation(configurationResource.getURL().getFile()));
+ }
+ return map;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeService.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeService.java b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeService.java
new file mode 100644
index 0000000..3444d37
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeService.java
@@ -0,0 +1,62 @@
+/*****************************************************************
+ * 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.cayenne.project.compatibility;
+
+import java.util.List;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.project.upgrade.DefaultUpgradeService;
+import org.apache.cayenne.project.upgrade.UpgradeUnit;
+import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler;
+import org.apache.cayenne.resource.Resource;
+
+/**
+ * @since 4.1
+ */
+public class CompatibilityUpgradeService extends DefaultUpgradeService {
+
+ @Inject
+ DocumentProvider documentProvider;
+
+ public CompatibilityUpgradeService(@Inject List<UpgradeHandler> handlerList) {
+ super(handlerList);
+ }
+
+ @Override
+ public Resource upgradeProject(Resource resource) {
+ List<UpgradeHandler> handlerList = getHandlersForVersion(loadProjectVersion(resource));
+ List<UpgradeUnit> upgradeUnits = upgradeDOM(resource, handlerList);
+
+ for(UpgradeUnit unit : upgradeUnits) {
+ documentProvider.putDocument(unit.getResource().getURL(), unit.getDocument());
+ }
+
+ return resource;
+ }
+
+ public void upgradeModel(Resource resource, DataChannelDescriptor descriptor) {
+ List<UpgradeHandler> handlerList = getHandlersForVersion(loadProjectVersion(resource));
+ for(UpgradeHandler handler : handlerList) {
+ handler.processModel(descriptor);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DefaultDocumentProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DefaultDocumentProvider.java b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DefaultDocumentProvider.java
new file mode 100644
index 0000000..5682782
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DefaultDocumentProvider.java
@@ -0,0 +1,44 @@
+/*****************************************************************
+ * 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.cayenne.project.compatibility;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.w3c.dom.Document;
+
+/**
+ * @since 4.1
+ */
+public class DefaultDocumentProvider implements DocumentProvider {
+
+ Map<String, Document> documentMap = new HashMap<>();
+
+ @Override
+ public Document getDocument(URL url) {
+ return documentMap.get(url.toString());
+ }
+
+ @Override
+ public void putDocument(URL url, Document document) {
+ documentMap.put(url.toString(), document);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DocumentProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DocumentProvider.java b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DocumentProvider.java
new file mode 100644
index 0000000..9210a8c
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/DocumentProvider.java
@@ -0,0 +1,34 @@
+/*****************************************************************
+ * 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.cayenne.project.compatibility;
+
+import java.net.URL;
+
+import org.w3c.dom.Document;
+
+/**
+ * @since 4.1
+ */
+public interface DocumentProvider {
+
+ Document getDocument(URL url);
+
+ void putDocument(URL url, Document document);
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModule.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModule.java b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModule.java
new file mode 100644
index 0000000..5a93695
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModule.java
@@ -0,0 +1,54 @@
+/*****************************************************************
+ * 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.cayenne.project.compatibility;
+
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.DataMapLoader;
+import org.apache.cayenne.configuration.xml.CompatibilityDataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.xml.CompatibilityDataMapLoader;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.project.ProjectModule;
+import org.apache.cayenne.project.upgrade.UpgradeService;
+import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V10;
+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;
+
+/**
+ * @since 4.1
+ */
+public class ProjectCompatibilityModule implements Module {
+
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(DataChannelDescriptorLoader.class).to(CompatibilityDataChannelDescriptorLoader.class);
+ binder.bind(DataMapLoader.class).to(CompatibilityDataMapLoader.class);
+
+ binder.bind(UpgradeService.class).to(CompatibilityUpgradeService.class);
+ binder.bind(DocumentProvider.class).to(DefaultDocumentProvider.class);
+
+ ProjectModule.contributeUpgradeHandler(binder)
+ .add(UpgradeHandler_V7.class)
+ .add(UpgradeHandler_V8.class)
+ .add(UpgradeHandler_V9.class)
+ .add(UpgradeHandler_V10.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProvider.java b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProvider.java
new file mode 100644
index 0000000..ae1adc6
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProvider.java
@@ -0,0 +1,51 @@
+/*****************************************************************
+ * 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.cayenne.project.compatibility;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.1
+ */
+public class ProjectCompatibilityModuleProvider implements CayenneServerModuleProvider {
+
+ @Override
+ public Module module() {
+ return new ProjectCompatibilityModule();
+ }
+
+ @Override
+ public Class<? extends Module> moduleType() {
+ return ProjectCompatibilityModule.class;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<Class<? extends Module>> overrides() {
+ // compatibility module overrides XML loaders defind in ServerModule
+ Collection modules = Collections.singletonList(ServerModule.class);
+ return modules;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-project-compatibility/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..2d2e31a
--- /dev/null
+++ b/cayenne-project-compatibility/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+# 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.
+##################################################################
+
+org.apache.cayenne.project.compatibility.ProjectCompatibilityModuleProvider
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java
new file mode 100644
index 0000000..acc31d7c
--- /dev/null
+++ b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java
@@ -0,0 +1,105 @@
+/*****************************************************************
+ * 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.cayenne.configuration.xml;
+
+import java.net.URL;
+
+import org.apache.cayenne.configuration.ConfigurationNameMapper;
+import org.apache.cayenne.configuration.ConfigurationTree;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.DataMapLoader;
+import org.apache.cayenne.configuration.DefaultConfigurationNameMapper;
+import org.apache.cayenne.di.AdhocObjectFactory;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.ClassLoaderManager;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
+import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.project.ProjectSaver;
+import org.apache.cayenne.project.compatibility.CompatibilityUpgradeService;
+import org.apache.cayenne.project.compatibility.DefaultDocumentProvider;
+import org.apache.cayenne.project.compatibility.DocumentProvider;
+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_V7;
+import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V8;
+import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V9;
+import org.apache.cayenne.resource.Resource;
+import org.apache.cayenne.resource.URLResource;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+
+/**
+ * @since 4.1
+ */
+public class CompatibilityDataChannelDescriptorLoaderIT {
+
+ @Test
+ public void testLoad() throws Exception {
+ Injector injector = DIBootstrap.createInjector(new Module() {
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(UpgradeService.class).to(CompatibilityUpgradeService.class);
+ binder.bind(DocumentProvider.class).to(DefaultDocumentProvider.class);
+ binder.bind(DataChannelDescriptorLoader.class).to(CompatibilityDataChannelDescriptorLoader.class);
+ binder.bind(DataMapLoader.class).to(CompatibilityDataMapLoader.class);
+
+ binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
+ binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
+ binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class);
+ binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class);
+
+ binder.bindList(UpgradeHandler.class)
+ .add(UpgradeHandler_V7.class)
+ .add(UpgradeHandler_V8.class)
+ .add(UpgradeHandler_V9.class)
+ .add(UpgradeHandler_V10.class);
+
+ binder.bind(ProjectSaver.class).toInstance(mock(ProjectSaver.class));
+ }
+ });
+
+ DataChannelDescriptorLoader loader = injector.getInstance(DataChannelDescriptorLoader.class);
+ assertTrue(loader instanceof CompatibilityDataChannelDescriptorLoader);
+
+ URL resourceUrl = getClass().getResource("../../project/compatibility/cayenne-project-v6.xml");
+ Resource resource = new URLResource(resourceUrl);
+
+ ConfigurationTree<DataChannelDescriptor> configurationTree = loader.load(resource);
+ assertNotNull(configurationTree.getRootNode());
+ assertTrue(configurationTree.getLoadFailures().isEmpty());
+ assertEquals(1, configurationTree.getRootNode().getDataMaps().size());
+
+ DataMap dataMap = configurationTree.getRootNode().getDataMaps().iterator().next();
+ assertEquals(1, dataMap.getDbEntities().size());
+ assertEquals(1, dataMap.getObjEntities().size());
+ assertNotNull(dataMap.getObjEntity("Artist"));
+ assertNotNull(dataMap.getDbEntity("Artist"));
+ assertEquals(2, dataMap.getDbEntity("Artist").getAttributes().size());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeServiceIT.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeServiceIT.java b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeServiceIT.java
new file mode 100644
index 0000000..8bfbea4
--- /dev/null
+++ b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/CompatibilityUpgradeServiceIT.java
@@ -0,0 +1,90 @@
+/*****************************************************************
+ * 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.cayenne.project.compatibility;
+
+import java.net.URL;
+
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.project.ProjectSaver;
+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_V7;
+import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V8;
+import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V9;
+import org.apache.cayenne.resource.Resource;
+import org.apache.cayenne.resource.URLResource;
+import org.junit.Test;
+import org.w3c.dom.Document;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+
+/**
+ * @since 4.1
+ */
+public class CompatibilityUpgradeServiceIT {
+
+ @Test
+ public void testUpgradeDom() throws Exception {
+ Injector injector = DIBootstrap.createInjector(new Module() {
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(UpgradeService.class).to(CompatibilityUpgradeService.class);
+ binder.bind(DocumentProvider.class).to(DefaultDocumentProvider.class);
+ binder.bindList(UpgradeHandler.class)
+ .add(UpgradeHandler_V7.class)
+ .add(UpgradeHandler_V8.class)
+ .add(UpgradeHandler_V9.class)
+ .add(UpgradeHandler_V10.class);
+
+ binder.bind(ProjectSaver.class).toInstance(mock(ProjectSaver.class));
+ binder.bind(DataChannelDescriptorLoader.class).toInstance(mock(DataChannelDescriptorLoader.class));
+ }
+ });
+
+ CompatibilityUpgradeService upgradeService = (CompatibilityUpgradeService)injector
+ .getInstance(UpgradeService.class);
+
+ DocumentProvider documentProvider = injector.getInstance(DocumentProvider.class);
+
+ URL resourceUrl = getClass().getResource("cayenne-project-v6.xml");
+ Resource resource = new URLResource(resourceUrl);
+ upgradeService.upgradeProject(resource);
+
+ Document domainDocument = documentProvider.getDocument(resourceUrl);
+
+ assertNotNull(domainDocument);
+ assertEquals("10", domainDocument.getDocumentElement().getAttribute("project-version"));
+
+ URL dataMapUrl = getClass().getResource("test-map-v6.map.xml");
+ Document dataMapDocument = documentProvider.getDocument(dataMapUrl);
+ assertNotNull(dataMapDocument);
+ assertEquals("10", dataMapDocument.getDocumentElement().getAttribute("project-version"));
+ assertEquals(1, dataMapDocument.getElementsByTagName("obj-entity").getLength());
+ assertEquals(1, dataMapDocument.getElementsByTagName("db-entity").getLength());
+ assertEquals(2, dataMapDocument.getElementsByTagName("db-attribute").getLength());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProviderTest.java b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProviderTest.java
new file mode 100644
index 0000000..2cc5de3
--- /dev/null
+++ b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/project/compatibility/ProjectCompatibilityModuleProviderTest.java
@@ -0,0 +1,35 @@
+/*****************************************************************
+ * 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.cayenne.project.compatibility;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.unit.util.ModuleProviderChecker;
+import org.junit.Test;
+
+/**
+ * @since 4.1
+ */
+public class ProjectCompatibilityModuleProviderTest {
+
+ @Test
+ public void testServerAutoLoadable() {
+ ModuleProviderChecker.testProviderPresent(ProjectCompatibilityModuleProvider.class, CayenneServerModuleProvider.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/cayenne-project-v6.xml
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/cayenne-project-v6.xml b/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/cayenne-project-v6.xml
new file mode 100644
index 0000000..772c3bc
--- /dev/null
+++ b/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/cayenne-project-v6.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<domain project-version="6">
+
+ <property name="cayenne.DataDomain.usingExternalTransactions" value="true"/>
+
+ <map name="test-map-v6" />
+
+ <node name="testProjectNode1"
+ adapter="org.example.test.Adapter" factory="org.example.test.DataSourceFactory">
+ <data-source>
+ <connectionPool min="1" max="1" />
+ <login />
+ </data-source>
+ <map-ref name="test-map-v6" />
+ </node>
+</domain>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/test-map-v6.map.xml
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/test-map-v6.map.xml b/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/test-map-v6.map.xml
new file mode 100644
index 0000000..25167f4
--- /dev/null
+++ b/cayenne-project-compatibility/src/test/resources/org/apache/cayenne/project/compatibility/test-map-v6.map.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/3.0/modelMap"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/3.0/modelMap http://cayenne.apache.org/schema/3.0/modelMap.xsd"
+ project-version="6">
+<db-entity name="Artist">
+ <db-attribute name="attributeOne" type="CHAR" isPrimaryKey="true" isMandatory="true" length="10"/>
+ <db-attribute name="attributeTwo" type="DATE"/>
+ </db-entity>
+ <obj-entity name="Artist" dbEntityName="Artist">
+ <entity-listener class="EntityListener">
+ <post-add method-name="prePersistEntityListener"/>
+ <post-persist method-name="postPersistEntityListener"/>
+ <pre-update method-name="preUpdateEntityListener"/>
+ <post-update method-name="postUpdateEntityListener"/>
+ <pre-remove method-name="preRemoveEntityListener"/>
+ <post-remove method-name="postRemoveEntityListener"/>
+ <post-load method-name="postLoadEntityListener"/>
+ </entity-listener>
+ </obj-entity>
+</data-map>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java
index aafb3d2..4e492e0 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java
@@ -19,18 +19,15 @@
package org.apache.cayenne.project.upgrade;
-import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@@ -127,7 +124,7 @@ public class DefaultUpgradeService implements UpgradeService {
return metaData;
}
- List<UpgradeHandler> getHandlersForVersion(String version) {
+ protected List<UpgradeHandler> getHandlersForVersion(String version) {
boolean found = MIN_SUPPORTED_VERSION.equals(version);
List<UpgradeHandler> handlerList = new ArrayList<>();
@@ -150,41 +147,50 @@ public class DefaultUpgradeService implements UpgradeService {
public Resource upgradeProject(Resource resource) {
List<UpgradeHandler> handlerList = getHandlersForVersion(loadProjectVersion(resource));
- resource = upgradeDOM(resource, handlerList);
- upgradeModel(resource, handlerList);
+ List<UpgradeUnit> upgradeUnits = upgradeDOM(resource, handlerList);
+ saveDOM(upgradeUnits);
+
+ resource = upgradeUnits.get(0).getResource();
+
+ ConfigurationTree<DataChannelDescriptor> configurationTree = upgradeModel(resource, handlerList);
+ saveModel(configurationTree);
return resource;
}
- Resource upgradeDOM(Resource resource, List<UpgradeHandler> handlerList) {
+ protected List<UpgradeUnit> upgradeDOM(Resource resource, List<UpgradeHandler> handlerList) {
+ List<UpgradeUnit> allUnits = new ArrayList<>();
+
// Load DOM for all resources
- Document projectDocument = readDocument(resource);
+ Document projectDocument = Util.readDocument(resource.getURL());
UpgradeUnit projectUnit = new UpgradeUnit(resource, projectDocument);
+ allUnits.add(projectUnit);
List<Resource> dataMapResources = getAdditionalDatamapResources(projectUnit);
- List<UpgradeUnit> upgradeUnits = new ArrayList<>(dataMapResources.size());
+ List<UpgradeUnit> dataMapUnits = new ArrayList<>(dataMapResources.size());
for (Resource dataMapResource : dataMapResources) {
- upgradeUnits.add(new UpgradeUnit(dataMapResource, readDocument(dataMapResource)));
+ dataMapUnits.add(new UpgradeUnit(dataMapResource, Util.readDocument(dataMapResource.getURL())));
}
+ allUnits.addAll(dataMapUnits);
// Update DOM
for(UpgradeHandler handler : handlerList) {
handler.processProjectDom(projectUnit);
- for(UpgradeUnit dataMapUnit : upgradeUnits) {
+ for(UpgradeUnit dataMapUnit : dataMapUnits) {
handler.processDataMapDom(dataMapUnit);
}
}
- // Save modified DOM back to original files
- saveDocument(projectUnit);
- for(UpgradeUnit dataMapUnit : upgradeUnits) {
- saveDocument(dataMapUnit);
- }
+ return allUnits;
+ }
- return projectUnit.getResource();
+ protected void saveDOM(Collection<UpgradeUnit> upgradeUnits) {
+ for(UpgradeUnit unit : upgradeUnits) {
+ saveDocument(unit);
+ }
}
- void upgradeModel(Resource resource, List<UpgradeHandler> handlerList) {
+ protected ConfigurationTree<DataChannelDescriptor> upgradeModel(Resource resource, List<UpgradeHandler> handlerList) {
// Load Model back from the update XML
ConfigurationTree<DataChannelDescriptor> configurationTree = loader.load(resource);
@@ -193,6 +199,10 @@ public class DefaultUpgradeService implements UpgradeService {
handler.processModel(configurationTree.getRootNode());
}
+ return configurationTree;
+ }
+
+ protected void saveModel(ConfigurationTree<DataChannelDescriptor> configurationTree) {
// Save project once again via project saver, this will normalize XML to minimize final diff
Project project = new Project(configurationTree);
projectSaver.save(project);
@@ -228,21 +238,6 @@ public class DefaultUpgradeService implements UpgradeService {
}
}
- protected Document readDocument(Resource resource) {
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setNamespaceAware(false);
- try {
- DocumentBuilder domBuilder = documentBuilderFactory.newDocumentBuilder();
- try (InputStream inputStream = resource.getURL().openStream()) {
- return domBuilder.parse(inputStream);
- } catch (IOException | SAXException e) {
- throw new ConfigurationException("Error loading configuration from %s", e, resource);
- }
- } catch (ParserConfigurationException e) {
- throw new ConfigurationException(e);
- }
- }
-
/**
* A default method for quick extraction of the project version from an XML
* file.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java
----------------------------------------------------------------------
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 e3a0342..7391d2a 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
@@ -30,6 +30,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler;
import org.apache.cayenne.resource.Resource;
import org.apache.cayenne.resource.URLResource;
+import org.apache.cayenne.util.Util;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatchers;
@@ -114,26 +115,25 @@ public class DefaultUpgradeServiceTest {
upgradeService = mock(DefaultUpgradeService.class);
when(upgradeService.upgradeDOM(any(Resource.class), ArgumentMatchers.<UpgradeHandler>anyList()))
.thenCallRealMethod();
- when(upgradeService.readDocument(any(Resource.class)))
- .thenCallRealMethod();
when(upgradeService.getAdditionalDatamapResources(any(UpgradeUnit.class)))
.thenCallRealMethod();
upgradeService.upgradeDOM(resource, handlers);
// one for project and two for data maps
- verify(upgradeService, times(3)).saveDocument(any(UpgradeUnit.class));
+// verify(upgradeService, times(3)).saveDocument(any(UpgradeUnit.class));
for(UpgradeHandler handler : handlers) {
+ verify(handler).getVersion();
verify(handler).processProjectDom(any(UpgradeUnit.class));
// two data maps
verify(handler, times(2)).processDataMapDom(any(UpgradeUnit.class));
+ verifyNoMoreInteractions(handler);
}
}
@Test
public void readDocument() throws Exception {
- Document document = upgradeService
- .readDocument(new URLResource(getClass().getResource("../cayenne-PROJECT1.xml")));
+ Document document = Util.readDocument(getClass().getResource("../cayenne-PROJECT1.xml"));
assertEquals("10", document.getDocumentElement().getAttribute("project-version"));
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
index eb82d32..68b236d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
@@ -40,7 +40,7 @@ public class XMLDataMapLoader implements DataMapLoader {
@Inject
protected HandlerFactory handlerFactory;
- private DataMap map;
+ DataMap map;
public synchronized DataMap load(Resource configurationResource) throws CayenneRuntimeException {
try(InputStream in = configurationResource.getURL().openStream()) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java b/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
index 7dfd57e..ff477ff 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
@@ -20,6 +20,7 @@
package org.apache.cayenne.util;
import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.ConfigurationException;
import org.apache.cayenne.PersistenceState;
import org.apache.cayenne.Persistent;
import org.apache.cayenne.di.AdhocObjectFactory;
@@ -30,9 +31,12 @@ import org.apache.cayenne.reflect.AttributeProperty;
import org.apache.cayenne.reflect.PropertyVisitor;
import org.apache.cayenne.reflect.ToManyProperty;
import org.apache.cayenne.reflect.ToOneProperty;
+import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
@@ -42,6 +46,7 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
@@ -275,6 +280,26 @@ public class Util {
}
/**
+ * @since 4.1
+ * @param url to read
+ * @return org.w3c.dom.Document from the given URL
+ */
+ public static Document readDocument(URL url) {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(false);
+ try {
+ DocumentBuilder domBuilder = documentBuilderFactory.newDocumentBuilder();
+ try (InputStream inputStream = url.openStream()) {
+ return domBuilder.parse(inputStream);
+ } catch (IOException | SAXException e) {
+ throw new ConfigurationException("Error loading configuration from %s", e, url);
+ }
+ } catch (ParserConfigurationException e) {
+ throw new ConfigurationException(e);
+ }
+ }
+
+ /**
* Returns package name for the Java class as a path separated with forward
* slash ("/"). Method is used to lookup resources that are located in
* package subdirectories. For example, a String "a/b/c" will be returned
http://git-wip-us.apache.org/repos/asf/cayenne/blob/3f375f38/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 99e972b..92f39f0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,7 @@
<module>cayenne-joda</module>
<module>cayenne-lifecycle</module>
<module>cayenne-project</module>
+ <module>cayenne-project-compatibility</module>
<module>cayenne-server</module>
<module>eventbridges</module>
<module>itests</module>