/*****************************************************************
* 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.upgrade.v7;
import org.apache.cayenne.configuration.ConfigurationNameMapper;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.configuration.DefaultConfigurationNameMapper;
import org.apache.cayenne.configuration.XMLDataMapLoader;
import org.apache.cayenne.configuration.server.JNDIDataSourceFactory;
import org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory;
import org.apache.cayenne.di.*;
import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
import org.apache.cayenne.project.FileProjectSaver;
import org.apache.cayenne.project.ProjectSaver;
import org.apache.cayenne.project.unit.Project2Case;
import org.apache.cayenne.project.upgrade.UpgradeHandler;
import org.apache.cayenne.project.upgrade.UpgradeMetaData;
import org.apache.cayenne.project.upgrade.UpgradeType;
import org.apache.cayenne.resource.Resource;
import org.apache.cayenne.resource.URLResource;
import org.apache.cayenne.test.resource.ResourceUtil;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
public class ProjectUpgrader_V7Test extends Project2Case {
@Test
public void testMetadata_3_0_0_1() {
String baseUrl = getClass().getPackage().getName().replace('.', '/');
URL url = getClass().getClassLoader().getResource(baseUrl + "/3_0_0_1a/cayenne.xml");
assertNotNull(url);
Module testModule = new Module() {
public void configure(Binder binder) {
binder.bind(ProjectSaver.class).to(FileProjectSaver.class);
binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
}
};
ProjectUpgrader_V7 upgrader = new ProjectUpgrader_V7();
Injector injector = DIBootstrap.createInjector(testModule);
injector.injectMembers(upgrader);
Resource source = new URLResource(url);
UpgradeHandler handler = upgrader.getUpgradeHandler(source);
assertNotNull(handler);
assertSame(source, handler.getProjectSource());
UpgradeMetaData md = handler.getUpgradeMetaData();
assertNotNull(md);
assertSame(UpgradeType.UPGRADE_NEEDED, md.getUpgradeType());
assertNull(md.getIntermediateUpgradeVersion());
assertEquals("3.0.0.1", md.getProjectVersion());
assertEquals("7", md.getSupportedVersion());
}
@Test
public void testMetadata_Type2_0() {
String baseUrl = getClass().getPackage().getName().replace('.', '/');
URL url = getClass().getClassLoader().getResource(baseUrl + "/2_0a/cayenne.xml");
assertNotNull(url);
Module testModule = new Module() {
public void configure(Binder binder) {
binder.bind(ProjectSaver.class).to(FileProjectSaver.class);
binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
}
};
ProjectUpgrader_V7 upgrader = new ProjectUpgrader_V7();
Injector injector = DIBootstrap.createInjector(testModule);
injector.injectMembers(upgrader);
Resource source = new URLResource(url);
UpgradeHandler handler = upgrader.getUpgradeHandler(source);
assertNotNull(handler);
assertSame(source, handler.getProjectSource());
UpgradeMetaData md = handler.getUpgradeMetaData();
assertNotNull(md);
assertSame(UpgradeType.INTERMEDIATE_UPGRADE_NEEDED, md.getUpgradeType());
assertEquals("3.0.0.1", md.getIntermediateUpgradeVersion());
assertEquals("2.0", md.getProjectVersion());
assertEquals("7", md.getSupportedVersion());
}
@Test
public void testMetadata_Type6() {
String baseUrl = getClass().getPackage().getName().replace('.', '/');
URL url = getClass().getClassLoader().getResource(baseUrl + "/6a/cayenne-PROJECT1.xml");
assertNotNull(url);
Module testModule = new Module() {
public void configure(Binder binder) {
binder.bind(ProjectSaver.class).to(FileProjectSaver.class);
binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
}
};
ProjectUpgrader_V7 upgrader = new ProjectUpgrader_V7();
Injector injector = DIBootstrap.createInjector(testModule);
injector.injectMembers(upgrader);
Resource source = new URLResource(url);
UpgradeHandler handler = upgrader.getUpgradeHandler(source);
assertNotNull(handler);
assertSame(source, handler.getProjectSource());
UpgradeMetaData md = handler.getUpgradeMetaData();
assertNotNull(md);
assertSame(UpgradeType.UPGRADE_NEEDED, md.getUpgradeType());
assertNull(md.getIntermediateUpgradeVersion());
assertEquals("6", md.getProjectVersion());
assertEquals("7", md.getSupportedVersion());
}
@Test
public void testMetadata_Type7() {
String baseUrl = getClass().getPackage().getName().replace('.', '/');
URL url = getClass().getClassLoader().getResource(baseUrl + "/7a/cayenne-PROJECT1.xml");
assertNotNull(url);
Module testModule = new Module() {
public void configure(Binder binder) {
binder.bind(ProjectSaver.class).to(FileProjectSaver.class);
binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
}
};
ProjectUpgrader_V7 upgrader = new ProjectUpgrader_V7();
Injector injector = DIBootstrap.createInjector(testModule);
injector.injectMembers(upgrader);
Resource source = new URLResource(url);
UpgradeHandler handler = upgrader.getUpgradeHandler(source);
assertNotNull(handler);
assertSame(source, handler.getProjectSource());
UpgradeMetaData md = handler.getUpgradeMetaData();
assertNotNull(md);
assertSame(UpgradeType.UPGRADE_NOT_NEEDED, md.getUpgradeType());
assertNull(md.getIntermediateUpgradeVersion());
assertEquals("7", md.getProjectVersion());
assertEquals("7", md.getSupportedVersion());
}
@Test
public void testPerformUpgradeFrom3() throws Exception {
File testFolder = setupTestDirectory("testPerformUpgrade_3_0_0_1");
String sourceUrl = getClass().getPackage().getName().replace('.', '/') + "/3_0_0_1a/";
List<String> sources = new ArrayList<String>();
sources.add("cayenne.xml");
sources.add("d1Map1.map.xml");
sources.add("d1Map2.map.xml");
sources.add("d1NodeDriver.driver.xml");
// upgrades are done in-place, so copy it first
List<File> targetsBefore = new ArrayList<File>();
for (String source : sources) {
URL url = getClass().getClassLoader().getResource(sourceUrl + source);
File target = new File(testFolder, source);
assertNotNull(source);
ResourceUtil.copyResourceToFile(url, target);
targetsBefore.add(target);
}
Module testModule = new Module() {
public void configure(Binder binder) {
binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class);
binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class);
binder.bind(ProjectSaver.class).to(FileProjectSaver.class);
binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);
}
};
ProjectUpgrader_V7 upgrader = new ProjectUpgrader_V7();
Injector injector = DIBootstrap.createInjector(testModule);
injector.injectMembers(upgrader);
Resource source = new URLResource(targetsBefore.get(0).toURI().toURL());
UpgradeHandler handler = upgrader.getUpgradeHandler(source);
Resource upgraded = handler.performUpgrade();
assertNotNull(upgraded);
assertNotSame(source, upgrader);
// check that all the new files are created...
String[] targetsAfterNames = new String[] { "cayenne-d1.xml", "cayenne-d2.xml", "d1Map1.map.xml",
"d1Map2.map.xml" };
File[] targetsAfter = new File[targetsAfterNames.length];
for (int i = 0; i < targetsAfter.length; i++) {
targetsAfter[i] = new File(testFolder, targetsAfterNames[i]);
assertTrue("File was not created: " + targetsAfter[i].getAbsolutePath(), targetsAfter[i].exists());
}
// DataMap files should remain the same; all others need to be deleted
for (File file : targetsBefore) {
if (file.getName().endsWith(".map.xml")) {
assertTrue("DataMap file disappeared: " + file.getAbsolutePath(), file.exists());
} else {
assertFalse("File expected to be deleted: " + file.getAbsolutePath(), file.exists());
}
}
// assert XML structure of the generated files
assertPerformUpgrade_3_0_0_1_cayenne_d1(targetsAfter[0]);
assertPerformUpgrade_3_0_0_1_cayenne_d2(targetsAfter[1]);
assertPerformUpgrade_3_0_0_1_d1Map1(targetsAfter[2]);
assertPerformUpgrade_3_0_0_1_d1Map2(targetsAfter[3]);
}
private void assertPerformUpgrade_3_0_0_1_cayenne_d1(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("", xpath.evaluate("/domain/@name", document));
assertEquals("9", xpath.evaluate("/domain/@project-version", document));
NodeList maps = (NodeList) xpath.evaluate("/domain/map", document, XPathConstants.NODESET);
assertNotNull(maps);
assertEquals(2, maps.getLength());
Node map1 = maps.item(0);
Node map2 = maps.item(1);
assertEquals("d1Map1", xpath.evaluate("@name", map1));
assertEquals("d1Map2", xpath.evaluate("@name", map2));
NodeList nodes = (NodeList) xpath.evaluate("/domain/node", document, XPathConstants.NODESET);
assertNotNull(nodes);
assertEquals(1, nodes.getLength());
Node node1 = nodes.item(0);
assertEquals("d1NodeDriver", xpath.evaluate("@name", node1));
assertEquals(XMLPoolingDataSourceFactory.class.getName(), xpath.evaluate("@factory", node1));
NodeList mapRefs = (NodeList) xpath.evaluate("map-ref", node1, XPathConstants.NODESET);
assertNotNull(mapRefs);
assertEquals(2, mapRefs.getLength());
assertEquals("d1Map1", xpath.evaluate("@name", mapRefs.item(0)));
assertEquals("d1Map2", xpath.evaluate("@name", mapRefs.item(1)));
NodeList dataSources = (NodeList) xpath.evaluate("data-source", node1, XPathConstants.NODESET);
assertNotNull(dataSources);
assertEquals(1, dataSources.getLength());
Node ds = dataSources.item(0);
assertEquals("org.hsqldb.jdbcDriver", xpath.evaluate("driver/@value", ds));
assertEquals("jdbc:hsqldb:mem:xdb", xpath.evaluate("url/@value", ds));
}
private void assertPerformUpgrade_3_0_0_1_cayenne_d2(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("", xpath.evaluate("/domain/@name", document));
assertEquals("9", xpath.evaluate("/domain/@project-version", document));
NodeList maps = (NodeList) xpath.evaluate("/domain/map", document, XPathConstants.NODESET);
assertNotNull(maps);
assertEquals(0, maps.getLength());
NodeList nodes = (NodeList) xpath.evaluate("/domain/node", document, XPathConstants.NODESET);
assertNotNull(nodes);
assertEquals(2, nodes.getLength());
Node node1 = nodes.item(0);
Node node2 = nodes.item(1);
assertEquals("d2NodeDBCP", xpath.evaluate("@name", node1));
assertEquals("dbcpx", xpath.evaluate("@parameters", node1));
assertEquals("org.apache.cayenne.configuration.server.DBCPDataSourceFactory", xpath.evaluate("@factory", node1));
NodeList dataSources1 = (NodeList) xpath.evaluate("data-source", node1, XPathConstants.NODESET);
assertNotNull(dataSources1);
assertEquals(0, dataSources1.getLength());
assertEquals("d2NodeJNDI", xpath.evaluate("@name", node2));
assertEquals("jndi/x", xpath.evaluate("@parameters", node2));
assertEquals(JNDIDataSourceFactory.class.getName(), xpath.evaluate("@factory", node2));
NodeList dataSources2 = (NodeList) xpath.evaluate("data-source", node2, XPathConstants.NODESET);
assertNotNull(dataSources2);
assertEquals(0, dataSources2.getLength());
}
private void assertPerformUpgrade_3_0_0_1_d1Map1(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("9", xpath.evaluate("/data-map/@project-version", document));
}
private void assertPerformUpgrade_3_0_0_1_d1Map2(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("9", xpath.evaluate("/data-map/@project-version", document));
}
@Test
public void testPerformUpgradeFrom6() throws Exception {
File testFolder = setupTestDirectory("testUpgrade6a");
String sourceUrl = getClass().getPackage().getName().replace('.', '/') + "/6a/";
Module testModule = new Module() {
public void configure(Binder binder) {
binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class);
binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class);
binder.bind(ProjectSaver.class).to(FileProjectSaver.class);
binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);
}
};
String[] resources = { "cayenne-PROJECT1.xml", "testProjectMap1_1.map.xml", "testProjectMap1_2.map.xml" };
List<File> files = new ArrayList<File>();
for (String name : resources) {
URL xmlUrl = getClass().getClassLoader().getResource(sourceUrl + name);
File target = new File(testFolder, name);
ResourceUtil.copyResourceToFile(xmlUrl, target);
files.add(target);
}
Injector injector = DIBootstrap.createInjector(testModule);
ProjectUpgrader_V7 upgrader = new ProjectUpgrader_V7();
injector.injectMembers(upgrader);
Resource source = new URLResource(files.get(0).toURI().toURL());
assertNotNull(source);
UpgradeHandler handler = upgrader.getUpgradeHandler(source);
assertNotNull(handler);
Resource upgraded = handler.performUpgrade();
assertNotNull(upgraded);
assertNotSame(source, upgraded);
assertPerformUpgrade6Cayenne(files.get(0));
assertPerformUpgrade6Map1(files.get(1));
assertPerformUpgradeMap2(files.get(2));
}
private void assertPerformUpgrade6Map1(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("9", xpath.evaluate("/data-map/@project-version", document));
NodeList maps = (NodeList) xpath.evaluate("/data-map/obj-entity/entity-listener", document,
XPathConstants.NODESET);
assertNotNull(maps);
assertEquals(0, maps.getLength());
}
private void assertPerformUpgrade6Cayenne(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("9", xpath.evaluate("/domain/@project-version", document));
}
private void assertPerformUpgradeMap2(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("9", xpath.evaluate("/data-map/@project-version", document));
}
@Test
public void testObjAttributeDelete() throws Exception {
File testFolder = setupTestDirectory("testObjAttribute");
String sourceUrl = getClass().getPackage().getName().replace('.', '/') + "/6a/delete_shadow_attributes/";
Module testModule = new Module() {
public void configure(Binder binder) {
binder.bind(ProjectSaver.class).to(FileProjectSaver.class);
binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class);
binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);
binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class);
}
};
ArrayList<String> source = new ArrayList<String>();
source.add("cayenne-TestProject.xml");
source.add("testProjectMap1.map.xml");
source.add("testProjectMap2.map.xml");
ArrayList<File> file = new ArrayList<File>();
for (String name : source) {
URL xmlUrl = getClass().getClassLoader().getResource(sourceUrl + name);
File target = new File(testFolder, name);
ResourceUtil.copyResourceToFile(xmlUrl, target);
file.add(target);
}
Injector injector = DIBootstrap.createInjector(testModule);
ProjectUpgrader_V7 upgrader = new ProjectUpgrader_V7();
injector.injectMembers(upgrader);
Resource resource = new URLResource(file.get(0).toURI().toURL());
assertNotNull(resource);
UpgradeHandler handler = upgrader.getUpgradeHandler(resource);
assertNotNull(handler);
Resource upgraded = handler.performUpgrade();
assertNotNull(upgraded);
assertNotSame(resource, upgraded);
assertPerformUpgrade6Cayenne(file.get(0));
assertObjAttributeMap1(file.get(1));
assertObjAttributeMap2(file.get(2));
}
private void assertObjAttributeMap1(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("9", xpath.evaluate("/data-map/@project-version", document));
String xpathValue = "/data-map/obj-entity[@name='GreatArtist']/obj-attribute";
XPathExpression expr = xpath.compile(xpathValue);
Node node = (Node) expr.evaluate(document, XPathConstants.NODE);
assertEquals("attribute2", xpath.evaluate("@name", node));
}
private void assertObjAttributeMap2(File file) throws Exception {
Document document = toDOMTree(file);
XPath xpath = XPathFactory.newInstance().newXPath();
assertEquals("9", xpath.evaluate("/data-map/@project-version", document));
String xpath_1 = "/data-map/obj-entity[@name='House']/obj-attribute/@name";
String xpath_2 = "/data-map/obj-entity[@name='Penthouse']/obj-attribute/@name";
XPathExpression expr = xpath.compile(xpath_1);
String houseAttr = (String) expr.evaluate(document, XPathConstants.STRING);
expr = xpath.compile(xpath_2);
String penthouseAttr = (String) expr.evaluate(document, XPathConstants.STRING);
assertEquals("attribute2", houseAttr);
assertEquals("attribute3", penthouseAttr);
}
}