| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Mike Norman - May 2008, created DBWS test package |
| package dbws.testing.keymappings; |
| |
| //javase imports |
| import java.io.ByteArrayInputStream; |
| import java.io.Reader; |
| import java.io.StringReader; |
| import java.util.ArrayList; |
| import java.util.Vector; |
| import org.w3c.dom.Document; |
| import org.xml.sax.InputSource; |
| |
| //JUnit4 imports |
| import org.junit.AfterClass; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| //EclipseLink imports |
| import org.eclipse.persistence.dbws.DBWSModel; |
| import org.eclipse.persistence.dbws.DBWSModelProject; |
| import org.eclipse.persistence.dynamic.DynamicEntity; |
| import org.eclipse.persistence.internal.databaseaccess.Platform; |
| import org.eclipse.persistence.internal.helper.ConversionManager; |
| import org.eclipse.persistence.internal.sessions.factories.EclipseLinkObjectPersistenceRuntimeXMLProject; |
| import org.eclipse.persistence.internal.xr.XRDynamicClassLoader; |
| import org.eclipse.persistence.internal.xr.Invocation; |
| import org.eclipse.persistence.internal.xr.Operation; |
| import org.eclipse.persistence.internal.xr.ProjectHelper; |
| import org.eclipse.persistence.internal.xr.XRDynamicEntity_CollectionWrapper; |
| import org.eclipse.persistence.internal.xr.XRServiceAdapter; |
| import org.eclipse.persistence.internal.xr.XRServiceFactory; |
| import org.eclipse.persistence.internal.xr.XRServiceModel; |
| import org.eclipse.persistence.oxm.XMLContext; |
| import org.eclipse.persistence.oxm.XMLMarshaller; |
| import org.eclipse.persistence.oxm.XMLUnmarshaller; |
| import org.eclipse.persistence.platform.database.MySQLPlatform; |
| import org.eclipse.persistence.platform.xml.XMLComparer; |
| import org.eclipse.persistence.platform.xml.XMLParser; |
| import org.eclipse.persistence.platform.xml.XMLPlatform; |
| import org.eclipse.persistence.platform.xml.XMLPlatformFactory; |
| import org.eclipse.persistence.sessions.DatabaseLogin; |
| import org.eclipse.persistence.sessions.DatasourceLogin; |
| import org.eclipse.persistence.sessions.Project; |
| |
| import dbws.testing.AllTests; |
| |
| // testing imports |
| import static dbws.testing.DBWSTestHelper.CONSTANT_PROJECT_BUILD_VERSION; |
| import static dbws.testing.DBWSTestHelper.DATABASE_DRIVER_KEY; |
| import static dbws.testing.DBWSTestHelper.DATABASE_PASSWORD_KEY; |
| import static dbws.testing.DBWSTestHelper.DATABASE_URL_KEY; |
| import static dbws.testing.DBWSTestHelper.DATABASE_USERNAME_KEY; |
| import static dbws.testing.DBWSTestHelper.DATABASE_DDL_CREATE_KEY; |
| import static dbws.testing.DBWSTestHelper.DATABASE_DDL_DROP_KEY; |
| import static dbws.testing.DBWSTestHelper.DATABASE_DDL_DEBUG_KEY; |
| import static dbws.testing.DBWSTestHelper.DEFAULT_DATABASE_DDL_CREATE; |
| import static dbws.testing.DBWSTestHelper.DEFAULT_DATABASE_DDL_DROP; |
| import static dbws.testing.DBWSTestHelper.DEFAULT_DATABASE_DDL_DEBUG; |
| |
| public class KeyMappingsTestSuite { |
| |
| static final String CREATE_DDL = |
| "CREATE TABLE IF NOT EXISTS XR_KEYMAP_ADDRESS (" + |
| " ADDRESS_ID NUMERIC(15) NOT NULL," + |
| " STREET VARCHAR(80)," + |
| " CITY VARCHAR(80)," + |
| " PROVINCE VARCHAR(80)," + |
| " PRIMARY KEY (ADDRESS_ID)" + |
| ")|" + |
| "INSERT INTO XR_KEYMAP_ADDRESS (ADDRESS_ID, STREET, CITY, PROVINCE) VALUES (1, '20 Pinetrail Cres.', 'Nepean', 'Ont')|" + |
| "INSERT INTO XR_KEYMAP_ADDRESS (ADDRESS_ID, STREET, CITY, PROVINCE) VALUES (2, 'Davis Side Rd.', 'Carleton Place', 'Ont')|" + |
| "CREATE TABLE IF NOT EXISTS XR_KEYMAP_EMPLOYEE (" + |
| " EMP_ID NUMERIC(15) NOT NULL," + |
| " F_NAME VARCHAR(40)," + |
| " L_NAME VARCHAR(40)," + |
| " ADDR_ID NUMERIC(15)," + |
| " PRIMARY KEY (EMP_ID)," + |
| " CONSTRAINT XR_KEYMAP_EMPLOYEE_ADDRESS FOREIGN KEY (ADDR_ID) REFERENCES XR_KEYMAP_ADDRESS (ADDRESS_ID)" + |
| ")|" + |
| "INSERT INTO XR_KEYMAP_EMPLOYEE (EMP_ID, F_NAME, L_NAME, ADDR_ID) VALUES (1, 'Mike', 'Norman', 1)|" + |
| "INSERT INTO XR_KEYMAP_EMPLOYEE (EMP_ID, F_NAME, L_NAME, ADDR_ID) VALUES (2, 'Rick', 'Barkhouse', 2)|" + |
| "CREATE TABLE IF NOT EXISTS XR_KEYMAP_PHONE (" + |
| " PHONE_ID NUMERIC(15) NOT NULL," + |
| " OWNER_ID NUMERIC(15) NOT NULL," + |
| " AREA_CODE VARCHAR(3)," + |
| " P_NUMBER VARCHAR(7)," + |
| " TYPE VARCHAR(15) NOT NULL," + |
| " PRIMARY KEY (PHONE_ID)," + |
| " CONSTRAINT XR_KEYMAP_PHONE_EMPLOYEE FOREIGN KEY (OWNER_ID) REFERENCES XR_KEYMAP_EMPLOYEE (EMP_ID)" + |
| ")|" + |
| "INSERT INTO XR_KEYMAP_PHONE (PHONE_ID, OWNER_ID, AREA_CODE, P_NUMBER, TYPE) VALUES (1, 1, '613', '2281808', 'Home')|" + |
| "INSERT INTO XR_KEYMAP_PHONE (PHONE_ID, OWNER_ID, AREA_CODE, P_NUMBER, TYPE) VALUES (2, 1, '613', '2884638', 'Work')|" + |
| "INSERT INTO XR_KEYMAP_PHONE (PHONE_ID, OWNER_ID, AREA_CODE, P_NUMBER, TYPE) VALUES (3, 2, '613', '2832684', 'Home')|" + |
| "INSERT INTO XR_KEYMAP_PHONE (PHONE_ID, OWNER_ID, AREA_CODE, P_NUMBER, TYPE) VALUES (4, 2, '613', '2884613', 'Work')|" ; |
| |
| static final String DROP_DDL = |
| "DROP TABLE XR_KEYMAP_PHONE|" + |
| "DROP TABLE XR_KEYMAP_EMPLOYEE|" + |
| "DROP TABLE XR_KEYMAP_ADDRESS|" ; |
| |
| static final String KEYMAPPINGS_SCHEMA = |
| "<?xml version='1.0' encoding='UTF-8'?>" + |
| "<xsd:schema targetNamespace=\"urn:keymappings\" xmlns=\"urn:keymappings\" elementFormDefault=\"qualified\"\n" + |
| "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" + |
| ">\n" + |
| "<xsd:complexType name=\"phone\">\n" + |
| "<xsd:sequence>\n" + |
| "<xsd:element name=\"area-code\" type=\"xsd:string\" />\n" + |
| "<xsd:element name=\"phone-number\" type=\"xsd:string\" />\n" + |
| "<xsd:element name=\"type\" type=\"xsd:string\" />\n" + |
| "</xsd:sequence>\n" + |
| "<xsd:attribute name=\"phone-id\" type=\"xsd:int\" use=\"required\" />\n" + |
| "<xsd:attribute name=\"owner-ref-id\" type=\"xsd:int\" use=\"required\" />\n" + |
| "</xsd:complexType>\n" + |
| "<xsd:complexType name=\"address\">\n" + |
| "<xsd:sequence>\n" + |
| "<xsd:element name=\"street\" type=\"xsd:string\" />\n" + |
| "<xsd:element name=\"city\" type=\"xsd:string\" />\n" + |
| "<xsd:element name=\"province\" type=\"xsd:string\" />\n" + |
| "</xsd:sequence>\n" + |
| "<xsd:attribute name=\"address-id\" type=\"xsd:int\" use=\"required\" />\n" + |
| "</xsd:complexType>\n" + |
| "<xsd:complexType name=\"employee\">\n" + |
| "<xsd:sequence>\n" + |
| "<xsd:element name=\"first-name\" type=\"xsd:string\" />\n" + |
| "<xsd:element name=\"last-name\" type=\"xsd:string\" />\n" + |
| "<xsd:element name=\"address\" type=\"address\" minOccurs=\"0\" />\n" + |
| "<xsd:element name=\"phones\">\n" + |
| "<xsd:complexType>\n" + |
| "<xsd:sequence>\n" + |
| "<xsd:element maxOccurs=\"unbounded\" name=\"phone-ref\">\n" + |
| "<xsd:complexType>\n" + |
| "<xsd:attribute name=\"phone-id\" type=\"xsd:int\" use=\"required\" />\n" + |
| "</xsd:complexType>\n" + |
| "</xsd:element>\n" + |
| "</xsd:sequence>\n" + |
| "</xsd:complexType>\n" + |
| "</xsd:element>\n" + |
| "</xsd:sequence>\n" + |
| "<xsd:attribute name=\"employee-id\" type=\"xsd:int\" use=\"required\" />\n" + |
| "<xsd:attribute name=\"address-ref-id\" type=\"xsd:int\" use=\"required\" />\n" + |
| "</xsd:complexType>\n" + |
| "</xsd:schema>"; |
| static final String KEYMAPPINGS_DBWS = |
| "<?xml version='1.0' encoding='UTF-8'?>\n" + |
| "<dbws\n" + |
| "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" + |
| "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + |
| "xmlns:ns1=\"urn:keymappings\"\n" + |
| ">\n" + |
| "<name>keymappings</name>\n" + |
| "<query>\n" + |
| "<name>getAllEmployees</name>\n" + |
| "<result isCollection=\"true\">\n" + |
| "<type>ns1:employee</type>\n" + |
| "</result>\n" + |
| "<sql><![CDATA[select * from XR_KEYMAP_EMPLOYEE]]></sql>\n" + |
| "</query>\n" + |
| "</dbws>\n"; |
| static final String KEYMAPPINGS_OR_PROJECT = |
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + |
| "<object-persistence version=\"" + CONSTANT_PROJECT_BUILD_VERSION + "\"\n" + |
| " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + |
| " xmlns=\"http://www.eclipse.org/eclipselink/xsds/persistence\"\n" + |
| " >\n" + |
| "<name>keymappings</name>\n" + |
| "<class-mapping-descriptors>\n" + |
| "<class-mapping-descriptor xsi:type=\"relational-class-mapping-descriptor\">\n" + |
| "<class>dbws.testing.keymappings.Address</class>\n" + |
| "<alias>address</alias>\n" + |
| "<primary-key>\n" + |
| "<field table=\"XR_KEYMAP_ADDRESS\" name=\"ADDRESS_ID\" xsi:type=\"column\"/>\n" + |
| "</primary-key>\n" + |
| "<events xsi:type=\"event-policy\"/>\n" + |
| "<querying xsi:type=\"query-policy\"/>\n" + |
| "<attribute-mappings>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>addressId</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_ADDRESS\" name=\"ADDRESS_ID\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>street</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_ADDRESS\" name=\"STREET\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>city</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_ADDRESS\" name=\"CITY\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>province</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_ADDRESS\" name=\"PROVINCE\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "</attribute-mappings>\n" + |
| "<descriptor-type>independent</descriptor-type>\n" + |
| "<instantiation/>\n" + |
| "<copying xsi:type=\"instantiation-copy-policy\"/>\n" + |
| "<change-policy xsi:type=\"deferred-detection-change-policy\"/>\n" + |
| "<tables>\n" + |
| "<table name=\"XR_KEYMAP_ADDRESS\"/>\n" + |
| "</tables>\n" + |
| "</class-mapping-descriptor>\n" + |
| "<class-mapping-descriptor xsi:type=\"relational-class-mapping-descriptor\">\n" + |
| "<class>dbws.testing.keymappings.Employee</class>\n" + |
| "<alias>employee</alias>\n" + |
| "<primary-key>\n" + |
| "<field table=\"XR_KEYMAP_EMPLOYEE\" name=\"EMP_ID\" xsi:type=\"column\"/>\n" + |
| "</primary-key>\n" + |
| "<events xsi:type=\"event-policy\"/>\n" + |
| "<querying xsi:type=\"query-policy\">\n" + |
| "</querying>\n" + |
| "<attribute-mappings>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>employeeId</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_EMPLOYEE\" name=\"EMP_ID\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>firstName</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_EMPLOYEE\" name=\"F_NAME\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>lastName</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_EMPLOYEE\" name=\"L_NAME\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"one-to-one-mapping\">\n" + |
| "<attribute-name>address</attribute-name>\n" + |
| "<reference-class>dbws.testing.keymappings.Address</reference-class>\n" + |
| "<foreign-key>\n" + |
| "<field-reference>\n" + |
| "<source-field table=\"XR_KEYMAP_EMPLOYEE\" name=\"ADDR_ID\" xsi:type=\"column\"/>\n" + |
| "<target-field table=\"XR_KEYMAP_ADDRESS\" name=\"ADDRESS_ID\" xsi:type=\"column\"/>\n" + |
| "</field-reference>\n" + |
| "</foreign-key>\n" + |
| "<foreign-key-fields>\n" + |
| "<field table=\"XR_KEYMAP_EMPLOYEE\" name=\"ADDR_ID\" xsi:type=\"column\"/>\n" + |
| "</foreign-key-fields>\n" + |
| "<selection-query xsi:type=\"read-object-query\"/>\n" + |
| "<join-fetch>inner-join</join-fetch>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"one-to-many-mapping\">\n" + |
| "<attribute-name>phones</attribute-name>\n" + |
| "<reference-class>dbws.testing.keymappings.Phone</reference-class>\n" + |
| "<target-foreign-key>\n" + |
| "<field-reference>\n" + |
| "<source-field table=\"XR_KEYMAP_PHONE\" name=\"OWNER_ID\" xsi:type=\"column\"/>\n" + |
| "<target-field table=\"XR_KEYMAP_EMPLOYEE\" name=\"EMP_ID\" xsi:type=\"column\"/>\n" + |
| "</field-reference>\n" + |
| "</target-foreign-key>\n" + |
| "<container xsi:type=\"list-container-policy\">\n" + |
| "<collection-type>org.eclipse.persistence.indirection.IndirectList</collection-type>\n" + |
| "</container>\n" + |
| "<indirection xsi:type=\"transparent-collection-indirection-policy\"/>\n" + |
| "<selection-query xsi:type=\"read-all-query\">\n" + |
| "<container xsi:type=\"list-container-policy\">\n" + |
| "<collection-type>org.eclipse.persistence.indirection.IndirectList</collection-type>\n" + |
| "</container>\n" + |
| "</selection-query>\n" + |
| "</attribute-mapping>\n" + |
| "</attribute-mappings>\n" + |
| "<descriptor-type>independent</descriptor-type>\n" + |
| "<instantiation/>\n" + |
| "<copying xsi:type=\"instantiation-copy-policy\"/>\n" + |
| "<change-policy xsi:type=\"deferred-detection-change-policy\"/>\n" + |
| "<tables>\n" + |
| "<table name=\"XR_KEYMAP_EMPLOYEE\"/>\n" + |
| "</tables>\n" + |
| "</class-mapping-descriptor>\n" + |
| "<class-mapping-descriptor xsi:type=\"relational-class-mapping-descriptor\">\n" + |
| "<class>dbws.testing.keymappings.Phone</class>\n" + |
| "<alias>phone</alias>\n" + |
| "<primary-key>\n" + |
| "<field table=\"XR_KEYMAP_PHONE\" name=\"PHONE_ID\" xsi:type=\"column\"/>\n" + |
| "</primary-key>\n" + |
| "<events xsi:type=\"event-policy\"/>\n" + |
| "<querying xsi:type=\"query-policy\"/>\n" + |
| "<attribute-mappings>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>phoneId</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_PHONE\" name=\"PHONE_ID\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>areaCode</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_PHONE\" name=\"AREA_CODE\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>phonenumber</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_PHONE\" name=\"P_NUMBER\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"direct-mapping\">\n" + |
| "<attribute-name>type</attribute-name>\n" + |
| "<field table=\"XR_KEYMAP_PHONE\" name=\"TYPE\" xsi:type=\"column\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"one-to-one-mapping\">\n" + |
| "<attribute-name>owner</attribute-name>\n" + |
| "<reference-class>dbws.testing.keymappings.Employee</reference-class>\n" + |
| "<private-owned>false</private-owned>\n" + |
| "<foreign-key>\n" + |
| "<field-reference>\n" + |
| "<source-field table=\"XR_KEYMAP_PHONE\" name=\"OWNER_ID\" xsi:type=\"column\"/>\n" + |
| "<target-field table=\"XR_KEYMAP_EMPLOYEE\" name=\"EMP_ID\" xsi:type=\"column\"/>\n" + |
| "</field-reference>\n" + |
| "</foreign-key>\n" + |
| "<foreign-key-fields>\n" + |
| "<field table=\"XR_KEYMAP_PHONE\" name=\"OWNER_ID\" xsi:type=\"column\"/>\n" + |
| "</foreign-key-fields>\n" + |
| "<batch-reading>true</batch-reading>\n" + |
| "<selection-query xsi:type=\"read-object-query\"/>\n" + |
| "</attribute-mapping>\n" + |
| "</attribute-mappings>\n" + |
| "<descriptor-type>independent</descriptor-type>\n" + |
| "<instantiation/>\n" + |
| "<copying xsi:type=\"instantiation-copy-policy\"/>\n" + |
| "<change-policy xsi:type=\"deferred-detection-change-policy\"/>\n" + |
| "<tables>\n" + |
| "<table name=\"XR_KEYMAP_PHONE\"/>\n" + |
| "</tables>\n" + |
| "</class-mapping-descriptor>\n" + |
| "<class-mapping-descriptor xsi:type=\"class-mapping-descriptor\">" + |
| "<class>org.eclipse.persistence.internal.xr.XRDynamicEntity_CollectionWrapper</class>" + |
| "<alias>XRDynamicEntity_CollectionWrapper</alias>" + |
| "<events xsi:type=\"event-policy\"/>" + |
| "<querying xsi:type=\"query-policy\"/>" + |
| "<attribute-mappings>" + |
| "<attribute-mapping xsi:type=\"aggregate-collection-mapping\">" + |
| "<attribute-name>items</attribute-name>" + |
| "<private-owned>true</private-owned>" + |
| "<cascade-persist>true</cascade-persist>" + |
| "<cascade-merge>true</cascade-merge>" + |
| "<cascade-refresh>true</cascade-refresh>" + |
| "<cascade-remove>true</cascade-remove>" + |
| "<container xsi:type=\"list-container-policy\">" + |
| "<collection-type>java.util.ArrayList</collection-type>" + |
| "</container>" + |
| "<selection-query xsi:type=\"read-all-query\">" + |
| "<container xsi:type=\"list-container-policy\">" + |
| "<collection-type>java.util.ArrayList</collection-type>" + |
| "</container>" + |
| "</selection-query>" + |
| "</attribute-mapping>" + |
| "</attribute-mappings>" + |
| "<descriptor-type>aggregate</descriptor-type>" + |
| "<caching>" + |
| "<cache-size>-1</cache-size>" + |
| "</caching>" + |
| "<remote-caching>" + |
| "<cache-size>-1</cache-size>" + |
| "</remote-caching>" + |
| "<instantiation/>" + |
| "<copying xsi:type=\"instantiation-copy-policy\"/>" + |
| "</class-mapping-descriptor>" + |
| "</class-mapping-descriptors>\n" + |
| "<login xsi:type=\"database-login\">\n" + |
| "<bind-all-parameters>true</bind-all-parameters>\n" + |
| "</login>\n" + |
| "</object-persistence>"; |
| static final String KEYMAPPINGS_OX_PROJECT = |
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + |
| "<object-persistence version=\"" + CONSTANT_PROJECT_BUILD_VERSION + "\"\n" + |
| "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + |
| "xmlns=\"http://www.eclipse.org/eclipselink/xsds/persistence\"\n" + |
| ">\n" + |
| "<name>keymappings</name>\n" + |
| "<class-mapping-descriptors>\n" + |
| "<class-mapping-descriptor xsi:type=\"xml-class-mapping-descriptor\">\n" + |
| "<class>dbws.testing.keymappings.Phone</class>\n" + |
| "<alias>phone</alias>\n" + |
| "<primary-key>\n" + |
| "<field name=\"@phone-id\" xsi:type=\"node\"/>\n" + |
| "</primary-key>\n" + |
| "<events xsi:type=\"event-policy\"/>\n" + |
| "<querying xsi:type=\"query-policy\"/>\n" + |
| "<attribute-mappings>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>phoneId</attribute-name>\n" + |
| "<field name=\"@phone-id\" xsi:type=\"node\">\n" + |
| "</field>\n" + |
| "<converter xsi:type=\"type-conversion-converter\">\n" + |
| "<object-class>java.lang.Integer</object-class>\n" + |
| "<data-class>java.lang.String</data-class>\n" + |
| "</converter>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>areaCode</attribute-name>\n" + |
| "<field name=\"area-code/text()\" xsi:type=\"node\">\n" + |
| "<schema-type>{http://www.w3.org/2001/XMLSchema}string</schema-type>\n" + |
| "</field>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>phonenumber</attribute-name>\n" + |
| "<field name=\"phone-number/text()\" xsi:type=\"node\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>type</attribute-name>\n" + |
| "<field name=\"type/text()\" xsi:type=\"node\"/>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-object-reference-mapping\">\n" + |
| "<attribute-name>owner</attribute-name>\n" + |
| "<reference-class>dbws.testing.keymappings.Employee</reference-class>\n" + |
| "<source-to-target-key-field-association>\n" + |
| "<field-reference>\n" + |
| "<source-field name=\"@owner-ref-id\" xsi:type=\"node\"/>\n" + |
| "<target-field name=\"@employee-id\" xsi:type=\"node\"/>\n" + |
| "</field-reference>\n" + |
| "</source-to-target-key-field-association>\n" + |
| "<source-to-target-key-fields>\n" + |
| "<field name=\"@owner-ref-id\" xsi:type=\"node\"/>\n" + |
| "</source-to-target-key-fields>\n" + |
| "</attribute-mapping>\n" + |
| "</attribute-mappings>\n" + |
| "<descriptor-type>aggregate</descriptor-type>\n" + |
| "<default-root-element>phone</default-root-element>\n" + |
| "<namespace-resolver>" + |
| " <default-namespace-uri>urn:keymappings</default-namespace-uri>" + |
| "</namespace-resolver>" + |
| "<schema xsi:type=\"schema-url-reference\">" + |
| " <resource></resource>" + |
| " <schema-context>/phone</schema-context>" + |
| " <node-type>complex-type</node-type>" + |
| "</schema>" + |
| "</class-mapping-descriptor>\n" + |
| "<class-mapping-descriptor xsi:type=\"xml-class-mapping-descriptor\">\n" + |
| "<class>dbws.testing.keymappings.Address</class>\n" + |
| "<alias>address</alias>\n" + |
| "<primary-key>\n" + |
| "<field name=\"@address-id\" xsi:type=\"node\"/>\n" + |
| "</primary-key>\n" + |
| "<events xsi:type=\"event-policy\"/>\n" + |
| "<querying xsi:type=\"query-policy\"/>\n" + |
| "<attribute-mappings>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>addressId</attribute-name>\n" + |
| "<field name=\"@address-id\" xsi:type=\"node\">\n" + |
| "</field>\n" + |
| "<converter xsi:type=\"type-conversion-converter\">\n" + |
| "<object-class>java.lang.Integer</object-class>\n" + |
| "<data-class>java.lang.String</data-class>\n" + |
| "</converter>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>street</attribute-name>\n" + |
| "<field name=\"street/text()\" xsi:type=\"node\">\n" + |
| "<schema-type>{http://www.w3.org/2001/XMLSchema}string</schema-type>\n" + |
| "</field>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>city</attribute-name>\n" + |
| "<field name=\"city/text()\" xsi:type=\"node\">\n" + |
| "<schema-type>{http://www.w3.org/2001/XMLSchema}string</schema-type>\n" + |
| "</field>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>province</attribute-name>\n" + |
| "<field name=\"province/text()\" xsi:type=\"node\">\n" + |
| "<schema-type>{http://www.w3.org/2001/XMLSchema}string</schema-type>\n" + |
| "</field>\n" + |
| "</attribute-mapping>\n" + |
| "</attribute-mappings>\n" + |
| "<descriptor-type>aggregate</descriptor-type>\n" + |
| "<default-root-element>address</default-root-element>\n" + |
| "<namespace-resolver>" + |
| " <default-namespace-uri>urn:keymappings</default-namespace-uri>" + |
| "</namespace-resolver>" + |
| "<schema xsi:type=\"schema-url-reference\">" + |
| " <resource></resource>" + |
| " <schema-context>/address</schema-context>" + |
| " <node-type>complex-type</node-type>" + |
| "</schema>" + |
| "</class-mapping-descriptor>\n" + |
| "<class-mapping-descriptor xsi:type=\"xml-class-mapping-descriptor\">\n" + |
| "<class>dbws.testing.keymappings.Employee</class>\n" + |
| "<alias>employee</alias>\n" + |
| "<primary-key>\n" + |
| "<field name=\"@employee-id\" xsi:type=\"node\"/>\n" + |
| "</primary-key>\n" + |
| "<events xsi:type=\"event-policy\"/>\n" + |
| "<querying xsi:type=\"query-policy\"/>\n" + |
| "<attribute-mappings>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>employeeId</attribute-name>\n" + |
| "<field name=\"@employee-id\" xsi:type=\"node\">\n" + |
| "</field>\n" + |
| "<converter xsi:type=\"type-conversion-converter\">\n" + |
| "<object-class>java.lang.Integer</object-class>\n" + |
| "<data-class>java.lang.String</data-class>\n" + |
| "</converter>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>firstName</attribute-name>\n" + |
| "<field name=\"first-name/text()\" xsi:type=\"node\">\n" + |
| "<schema-type>{http://www.w3.org/2001/XMLSchema}string</schema-type>\n" + |
| "</field>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-direct-mapping\">\n" + |
| "<attribute-name>lastName</attribute-name>\n" + |
| "<field name=\"last-name/text()\" xsi:type=\"node\">\n" + |
| "<schema-type>{http://www.w3.org/2001/XMLSchema}string</schema-type>\n" + |
| "</field>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-object-reference-mapping\">\n" + |
| "<attribute-name>address</attribute-name>\n" + |
| "<reference-class>dbws.testing.keymappings.Address</reference-class>\n" + |
| "<source-to-target-key-field-association>\n" + |
| "<field-reference>\n" + |
| "<source-field name=\"@address-ref-id\" xsi:type=\"node\"/>\n" + |
| "<target-field name=\"@address-id\" xsi:type=\"node\"/>\n" + |
| "</field-reference>\n" + |
| "</source-to-target-key-field-association>\n" + |
| "<source-to-target-key-fields>\n" + |
| "<field name=\"@address-ref-id\" xsi:type=\"node\"/>\n" + |
| "</source-to-target-key-fields>\n" + |
| "</attribute-mapping>\n" + |
| "<attribute-mapping xsi:type=\"xml-collection-reference-mapping\">\n" + |
| "<attribute-name>phones</attribute-name>\n" + |
| "<reference-class>dbws.testing.keymappings.Phone</reference-class>\n" + |
| "<source-to-target-key-field-association>\n" + |
| "<field-reference>\n" + |
| "<source-field name=\"phones/phone-ref/@phone-id\" xsi:type=\"node\"/>\n" + |
| "<target-field name=\"@phone-id\" xsi:type=\"node\"/>\n" + |
| "</field-reference>\n" + |
| "</source-to-target-key-field-association>\n" + |
| "<source-to-target-key-fields>\n" + |
| "<field name=\"phones/phone-ref/@phone-id\" xsi:type=\"node\"/>\n" + |
| "</source-to-target-key-fields>\n" + |
| "<containerpolicy xsi:type=\"list-container-policy\">\n" + |
| "<collection-type>java.util.ArrayList</collection-type>\n" + |
| "</containerpolicy>\n" + |
| "<uses-single-node>false</uses-single-node>\n" + |
| "</attribute-mapping>\n" + |
| "</attribute-mappings>\n" + |
| "<descriptor-type>aggregate</descriptor-type>\n" + |
| "<default-root-element>employee</default-root-element>\n" + |
| "<namespace-resolver>" + |
| " <default-namespace-uri>urn:keymappings</default-namespace-uri>" + |
| "</namespace-resolver>" + |
| "<schema xsi:type=\"schema-url-reference\">" + |
| " <resource></resource>" + |
| " <schema-context>/employee</schema-context>" + |
| " <node-type>complex-type</node-type>" + |
| "</schema>" + |
| "</class-mapping-descriptor>\n" + |
| "<class-mapping-descriptor xsi:type=\"xml-class-mapping-descriptor\">\n" + |
| "<class>org.eclipse.persistence.internal.xr.XRDynamicEntity_CollectionWrapper</class>\n" + |
| "<alias>XRDynamicEntity_CollectionWrapper</alias>\n" + |
| "<events xsi:type=\"event-policy\"/>\n" + |
| "<querying xsi:type=\"query-policy\"/>\n" + |
| "<attribute-mappings>\n" + |
| "<attribute-mapping xsi:type=\"xml-any-collection-mapping\">\n" + |
| "<attribute-name>items</attribute-name>\n" + |
| "<container xsi:type=\"list-container-policy\">\n" + |
| "<collection-type>java.util.ArrayList</collection-type>\n" + |
| "</container>\n" + |
| "<keep-as-element-policy>KEEP_NONE_AS_ELEMENT</keep-as-element-policy>\n" + |
| "</attribute-mapping>\n" + |
| "</attribute-mappings>\n" + |
| "<descriptor-type>aggregate</descriptor-type>\n" + |
| "<instantiation/>\n" + |
| "<copying xsi:type=\"instantiation-copy-policy\"/>\n" + |
| "<change-policy xsi:type=\"deferred-detection-change-policy\"/>\n" + |
| "<default-root-element>employee-address-phone-system</default-root-element>\n" + |
| "<namespace-resolver>" + |
| "<namespaces>\n" + |
| "<namespace>\n" + |
| "<prefix>xsd</prefix>\n" + |
| "<namespace-uri>http://www.w3.org/2001/XMLSchema</namespace-uri>\n" + |
| "</namespace>\n" + |
| "<namespace>\n" + |
| "<prefix>xsi</prefix>\n" + |
| "<namespace-uri>http://www.w3.org/2001/XMLSchema-instance</namespace-uri>\n" + |
| "</namespace>\n" + |
| "</namespaces>\n" + |
| "<default-namespace-uri>urn:keymappings</default-namespace-uri>" + |
| "</namespace-resolver>" + |
| "</class-mapping-descriptor>\n" + |
| "</class-mapping-descriptors>\n" + |
| "<login xsi:type=\"xml-login\">\n" + |
| "<platform-class>org.eclipse.persistence.oxm.platform.DOMPlatform</platform-class>\n" + |
| "</login>\n" + |
| "</object-persistence>"; |
| |
| // test fixtures |
| public static XMLComparer comparer = new XMLComparer(); |
| public static XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform(); |
| public static XMLParser xmlParser = xmlPlatform.newXMLParser(); |
| public static XRServiceAdapter xrService = null; |
| static boolean ddlCreate = false; |
| static boolean ddlDrop = false; |
| static boolean ddlDebug = false; |
| |
| @BeforeClass |
| public static void setUp() { |
| final String ddlCreateProp = System.getProperty(DATABASE_DDL_CREATE_KEY, DEFAULT_DATABASE_DDL_CREATE); |
| if ("true".equalsIgnoreCase(ddlCreateProp)) { |
| ddlCreate = true; |
| } |
| final String ddlDropProp = System.getProperty(DATABASE_DDL_DROP_KEY, DEFAULT_DATABASE_DDL_DROP); |
| if ("true".equalsIgnoreCase(ddlDropProp)) { |
| ddlDrop = true; |
| } |
| final String ddlDebugProp = System.getProperty(DATABASE_DDL_DEBUG_KEY, DEFAULT_DATABASE_DDL_DEBUG); |
| if ("true".equalsIgnoreCase(ddlDebugProp)) { |
| ddlDebug = true; |
| } |
| |
| final String username = System.getProperty(DATABASE_USERNAME_KEY); |
| if (username == null) { |
| fail("error retrieving database username"); |
| } |
| final String password = System.getProperty(DATABASE_PASSWORD_KEY); |
| if (password == null) { |
| fail("error retrieving database password"); |
| } |
| final String url = System.getProperty(DATABASE_URL_KEY); |
| if (url == null) { |
| fail("error retrieving database url"); |
| } |
| final String driver = System.getProperty(DATABASE_DRIVER_KEY); |
| if (driver == null) { |
| fail("error retrieving database driver"); |
| } |
| |
| XRServiceFactory factory = new XRServiceFactory() { |
| @Override |
| public XRServiceAdapter buildService(XRServiceModel xrServiceModel) { |
| parentClassLoader = this.getClass().getClassLoader(); |
| xrSchemaStream = new ByteArrayInputStream(KEYMAPPINGS_SCHEMA.getBytes()); |
| return super.buildService(xrServiceModel); |
| } |
| @Override |
| public void buildSessions() { |
| XRDynamicClassLoader xrdecl = new XRDynamicClassLoader(parentClassLoader); |
| XMLContext context = new XMLContext( |
| new EclipseLinkObjectPersistenceRuntimeXMLProject(),xrdecl); |
| XMLUnmarshaller unmarshaller = context.createUnmarshaller(); |
| Project orProject = (Project)unmarshaller.unmarshal( |
| new StringReader(KEYMAPPINGS_OR_PROJECT)); |
| DatasourceLogin login = new DatabaseLogin(); |
| login.setUserName(username); |
| login.setPassword(password); |
| ((DatabaseLogin)login).setConnectionString(url); |
| ((DatabaseLogin)login).setDriverClassName(driver); |
| Platform platform = new MySQLPlatform(); |
| ConversionManager conversionManager = platform.getConversionManager(); |
| if (conversionManager != null) { |
| conversionManager.setLoader(xrdecl); |
| } |
| login.setDatasourcePlatform(platform); |
| ((DatabaseLogin)login).bindAllParameters(); |
| orProject.setDatasourceLogin(login); |
| Project oxProject = (Project)unmarshaller.unmarshal( |
| new StringReader(KEYMAPPINGS_OX_PROJECT)); |
| login = (DatasourceLogin)oxProject.getDatasourceLogin(); |
| if (login != null) { |
| platform = login.getDatasourcePlatform(); |
| if (platform != null) { |
| conversionManager = platform.getConversionManager(); |
| if (conversionManager != null) { |
| conversionManager.setLoader(xrdecl); |
| } |
| } |
| } |
| ProjectHelper.fixOROXAccessors(orProject, oxProject); |
| xrService.setORSession(orProject.createDatabaseSession()); |
| xrService.getORSession().dontLogMessages(); |
| xrService.setXMLContext(new XMLContext(oxProject)); |
| xrService.setOXSession(xrService.getXMLContext().getSession(0)); |
| } |
| }; |
| XMLContext context = new XMLContext(new DBWSModelProject()); |
| XMLUnmarshaller unmarshaller = context.createUnmarshaller(); |
| DBWSModel model = (DBWSModel)unmarshaller.unmarshal(new StringReader(KEYMAPPINGS_DBWS)); |
| xrService = factory.buildService(model); |
| |
| if (ddlCreate) { |
| try { |
| AllTests.runDdl(CREATE_DDL, ddlDebug); |
| } catch (Exception e) { |
| // e.printStackTrace(); |
| } |
| } |
| } |
| |
| @AfterClass |
| public static void tearDown() { |
| if (ddlDrop) { |
| try { |
| AllTests.runDdl(DROP_DDL, ddlDebug); |
| } catch (Exception e) { |
| // e.printStackTrace(); |
| } |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Test |
| public void getAllEmployees() { |
| Invocation invocation = new Invocation("getAllEmployees"); |
| Operation op = xrService.getOperation(invocation.getName()); |
| Object result = op.invoke(xrService, invocation); |
| assertNotNull("result is null", result); |
| Vector<DynamicEntity> resultVector = (Vector<DynamicEntity>)result; |
| XRDynamicEntity_CollectionWrapper xrDynEntityCol = new XRDynamicEntity_CollectionWrapper(); |
| for (DynamicEntity employee : resultVector) { |
| xrDynEntityCol.add(employee); |
| xrDynEntityCol.add(employee.get("address")); |
| Vector<DynamicEntity> phones = employee.get("phones"); |
| phones.size(); // trigger IndirectList |
| for (DynamicEntity phone : phones) { |
| xrDynEntityCol.add(phone); |
| } |
| } |
| Document doc = xmlPlatform.createDocument(); |
| XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller(); |
| marshaller.marshal(xrDynEntityCol, doc); |
| Document controlDoc = xmlParser.parse(new StringReader(EMPLOYEE_COLLECTION_XML)); |
| assertTrue("control document not same as XRService instance document", |
| comparer.isNodeEqual(controlDoc, doc)); |
| } |
| |
| @Test |
| public void buildEmployees() { |
| XMLUnmarshaller unMarshaller = xrService.getXMLContext().createUnmarshaller(); |
| Reader reader = new StringReader(EMPLOYEE_COLLECTION_XML); |
| InputSource inputSource = new InputSource(reader); |
| Object result = unMarshaller.unmarshal(inputSource); |
| assertNotNull("result is null", result); |
| XRDynamicEntity_CollectionWrapper xrDynEntityCol = (XRDynamicEntity_CollectionWrapper)result; |
| DynamicEntity employee1 = (DynamicEntity)xrDynEntityCol.iterator().next(); |
| assertNotNull("employee1 address is null", employee1.get("address")); |
| assertTrue("employee1 __pk incorrent", Integer.valueOf(1).equals(employee1.get("employeeId"))); |
| assertTrue("employee1 first name incorrent", "Mike".equals(employee1.get("firstName"))); |
| assertTrue("employee1 last name incorrent", "Norman".equals(employee1.get("lastName"))); |
| ArrayList<DynamicEntity> phones = employee1.get("phones"); // phones |
| assertTrue("employee1 has wrong number of phones", phones.size() == 2); |
| } |
| |
| public static final String EMPLOYEE_COLLECTION_XML = |
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
| "<employee-address-phone-system xmlns=\"urn:keymappings\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + |
| "<employee address-ref-id=\"1\" employee-id=\"1\">" + |
| "<first-name>Mike</first-name>" + |
| "<last-name>Norman</last-name>" + |
| "<phones>" + |
| "<phone-ref phone-id=\"1\"/>" + |
| "<phone-ref phone-id=\"2\"/>" + |
| "</phones>" + |
| "</employee>" + |
| "<address address-id=\"1\">" + |
| "<street>20 Pinetrail Cres.</street>" + |
| "<city>Nepean</city>" + |
| "<province>Ont</province>" + |
| "</address>" + |
| "<phone owner-ref-id=\"1\" phone-id=\"1\">" + |
| "<area-code>613</area-code>" + |
| "<phone-number>2281808</phone-number>" + |
| "<type>Home</type>" + |
| "</phone>" + |
| "<phone owner-ref-id=\"1\" phone-id=\"2\">" + |
| "<area-code>613</area-code>" + |
| "<phone-number>2884638</phone-number>" + |
| "<type>Work</type>" + |
| "</phone>" + |
| "<employee address-ref-id=\"2\" employee-id=\"2\">" + |
| "<first-name>Rick</first-name>" + |
| "<last-name>Barkhouse</last-name>" + |
| "<phones>" + |
| "<phone-ref phone-id=\"3\"/>" + |
| "<phone-ref phone-id=\"4\"/>" + |
| "</phones>" + |
| "</employee>" + |
| "<address address-id=\"2\">" + |
| "<street>Davis Side Rd.</street>" + |
| "<city>Carleton Place</city>" + |
| "<province>Ont</province>" + |
| "</address>" + |
| "<phone owner-ref-id=\"2\" phone-id=\"3\">" + |
| "<area-code>613</area-code>" + |
| "<phone-number>2832684</phone-number>" + |
| "<type>Home</type>" + |
| "</phone>" + |
| "<phone owner-ref-id=\"2\" phone-id=\"4\">" + |
| "<area-code>613</area-code>" + |
| "<phone-number>2884613</phone-number>" + |
| "<type>Work</type>" + |
| "</phone>" + |
| "</employee-address-phone-system>"; |
| } |