/** * 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.cxf.aegis.type.encoded; import java.util.Map; import java.util.TreeMap; import javax.xml.namespace.QName; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.apache.cxf.aegis.AegisContext; import org.apache.cxf.aegis.Context; import org.apache.cxf.aegis.type.basic.BeanTypeInfo; import org.apache.cxf.aegis.xml.stax.ElementReader; import org.apache.cxf.helpers.DOMUtils; import org.junit.Test; public class StructTypeTest extends AbstractEncodedTest { private StructType addressType; private StructType purchaseOrderType; private Context getLocalContext() { AegisContext aegisContext = new AegisContext(); return new Context(aegisContext); } public void setUp() throws Exception { super.setUp(); // address type BeanTypeInfo addressInfo = new BeanTypeInfo(Address.class, "urn:Bean"); addressInfo.setTypeMapping(mapping); addressType = new StructType(addressInfo); addressType.setTypeClass(Address.class); addressType.setSchemaType(new QName("urn:Bean", "address")); mapping.register(addressType); // purchase order type BeanTypeInfo poInfo = new BeanTypeInfo(PurchaseOrder.class, "urn:Bean"); poInfo.setTypeMapping(mapping); purchaseOrderType = new StructType(poInfo); purchaseOrderType.setTypeClass(PurchaseOrder.class); purchaseOrderType.setTypeMapping(mapping); purchaseOrderType.setSchemaType(new QName("urn:Bean", "po")); mapping.register(purchaseOrderType); } @Test public void testSimpleStruct() throws Exception { // Test reading ElementReader reader = new ElementReader(getClass().getResourceAsStream("struct1.xml")); Address address = (Address) addressType.readObject(reader, getLocalContext()); validateShippingAddress(address); reader.getXMLStreamReader().close(); // Test reading - no namespace on nested elements reader = new ElementReader(getClass().getResourceAsStream("struct2.xml")); address = (Address) addressType.readObject(reader, getLocalContext()); validateShippingAddress(address); reader.getXMLStreamReader().close(); // Test writing Element element = writeObjectToElement(addressType, address, getLocalContext()); validateShippingAddress(element); } @Test public void testComplexStruct() throws Exception { // Test reading ElementReader reader = new ElementReader(getClass().getResourceAsStream("struct3.xml")); PurchaseOrder po = (PurchaseOrder) purchaseOrderType.readObject(reader, getLocalContext()); validatePurchaseOrder(po); reader.getXMLStreamReader().close(); // Test reading - no namespace on nested elements reader = new ElementReader(getClass().getResourceAsStream("struct4.xml")); po = (PurchaseOrder) purchaseOrderType.readObject(reader, getLocalContext()); validatePurchaseOrder(po); reader.getXMLStreamReader().close(); // Test writing Element element = writeRef(po); validatePurchaseOrder(element); // Test reading - no namespace on nested elements, xsi:nil (CXF-2695) reader = new ElementReader(getClass().getResourceAsStream("struct5.xml")); po = (PurchaseOrder) purchaseOrderType.readObject(reader, getLocalContext()); validatePurchaseOrder(po, true); reader.getXMLStreamReader().close(); } @Test public void testStructRef() throws Exception { PurchaseOrder purchaseOrder; // Simple nested ref purchaseOrder = (PurchaseOrder) readRef("ref1.xml"); validatePurchaseOrder(purchaseOrder); // Strings referenced purchaseOrder = (PurchaseOrder) readRef("ref2.xml"); validatePurchaseOrder(purchaseOrder); // completely unrolled purchaseOrder = (PurchaseOrder) readRef("ref3.xml"); validatePurchaseOrder(purchaseOrder); // Test writing Element element = writeRef(purchaseOrder); validatePurchaseOrder(element); } public static void validateShippingAddress(Element shipping) { assertNotNull("shipping is null", shipping); assertChildEquals("1234 Riverside Drive", shipping, "street"); assertChildEquals("Gainesville", shipping, "city"); assertChildEquals("FL", shipping, "state"); assertChildEquals("30506", shipping, "zip"); } public static void validateBillingAddress(Element billing) { assertNotNull("billing is null", billing); assertChildEquals("1234 Fake Street", billing, "street"); assertChildEquals("Las Vegas", billing, "city"); assertChildEquals("NV", billing, "state"); assertChildEquals("89102", billing, "zip"); } private void validatePurchaseOrder(PurchaseOrder purchaseOrder) { validatePurchaseOrder(purchaseOrder, false); } private void validatePurchaseOrder(PurchaseOrder purchaseOrder, boolean nilZip) { assertNotNull(purchaseOrder); assertNotNull(purchaseOrder.getShipping()); assertEquals("1234 Riverside Drive", purchaseOrder.getShipping().getStreet()); assertEquals("Gainesville", purchaseOrder.getShipping().getCity()); assertEquals("FL", purchaseOrder.getShipping().getState()); if (nilZip) { assertNull(purchaseOrder.getShipping().getZip()); } else { assertEquals("30506", purchaseOrder.getShipping().getZip()); } assertNotNull(purchaseOrder.getBilling()); assertEquals("1234 Fake Street", purchaseOrder.getBilling().getStreet()); assertEquals("Las Vegas", purchaseOrder.getBilling().getCity()); assertEquals("NV", purchaseOrder.getBilling().getState()); assertEquals("89102", purchaseOrder.getBilling().getZip()); } private void validatePurchaseOrder(Element element) throws Exception { Element poRefElement = null; Map<String, Element> blocks = new TreeMap<String, Element>(); for (Node n = element.getFirstChild(); n != null; n = n.getNextSibling()) { if (n instanceof Element) { Element child = (Element) n; if (poRefElement == null) { poRefElement = child; } else { String id = getId("Trailing block ", child); blocks.put(id, child); } } } Element po = getReferencedElement("poRef", poRefElement, blocks); Element shippingRef = (Element)DOMUtils.getChild(po, "shipping"); Element shipping = getReferencedElement("shipping", shippingRef, blocks); validateShippingAddress(shipping); Element billingRef = (Element)DOMUtils.getChild(po, "billing"); Element billing = getReferencedElement("billing", billingRef, blocks); validateBillingAddress(billing); } private Element getReferencedElement(String childName, Element element, Map<String, Element> blocks) { assertNotNull(childName + " is null", element); assertNotNull("element is null", element); String refId = getRef(childName, element); Element refElement = blocks.get(refId); assertNotNull(childName + " referenced non-existant element " + refId, refElement); return refElement; } private static void assertChildEquals(String expected, Element element, String childName) { assertEquals(expected, DOMUtils.getChild(element, childName).getTextContent()); } private String getId(String childName, Element child) { assertNotNull(childName + " is null", child); Attr idAttribute = child.getAttributeNode("id"); assertNotNull(childName + " id is null \n", idAttribute); String id = idAttribute.getValue(); assertNotNull(childName + " id is null \n", id); return id; } private String getRef(String childName, Element child) { assertNotNull(childName + " is null", child); String hrefAttribute = child.getAttribute("href"); assertNotSame("", childName + " href is null \n", hrefAttribute); return hrefAttribute; } }