001 /** 002 * Copyright 2005-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.coreservice.test; 017 018 import org.apache.commons.lang.StringUtils; 019 020 import javax.xml.bind.JAXBContext; 021 import javax.xml.bind.Marshaller; 022 import javax.xml.bind.Unmarshaller; 023 import java.io.BufferedReader; 024 import java.io.IOException; 025 import java.io.InputStream; 026 import java.io.InputStreamReader; 027 import java.io.StringReader; 028 import java.io.StringWriter; 029 030 import static org.junit.Assert.assertEquals; 031 032 /** 033 * A class with some assertion utilities for JAXB-related operations. 034 * 035 * @author Kuali Rice Team (rice.collab@kuali.org) 036 */ 037 public final class JAXBAssert { 038 039 private JAXBAssert() {} 040 041 /** 042 * Performs the following steps and assertions: 043 * 044 * <ol> 045 * <li>Creates a new JAXBContext with the given list of classesToBeBound.</li> 046 * <li>Marshals the provided objectToMarshall to XML.</li> 047 * <li>Unmarshals the marshaled XML to recreate the original object.<li> 048 * <li>Asserts that the newly unmarhsaled object and the original provided object are equal by invoking {@link Object#equals(Object)}.</li> 049 * <li>Unmarshals the given expectedXml to an object and asserts that it is equal with the original unmarshaled object by invoking {@link Object#equals(Object)}.</li> 050 * </ol> 051 * 052 * @param objectToMarshal the object to marshal to XML using JAXB 053 * @param expectedXml an XML string that will be unmarshaled to an Object and compared with objectToMarshal using {@link Object#equals(Object)} 054 * @param classesToBeBound - list of java classes to be recognized by the created JAXBContext 055 * 056 */ 057 public static void assertEqualXmlMarshalUnmarshal(Object objectToMarshal, String expectedXml, Class<?> ... classesToBeBound) { 058 String marshaledXml = null; 059 try { 060 JAXBContext jaxbContext = JAXBContext.newInstance(classesToBeBound); 061 Marshaller marshaller = jaxbContext.createMarshaller(); 062 063 StringWriter stringWriter = new StringWriter(); 064 065 marshaller.marshal(objectToMarshal, stringWriter); 066 067 marshaledXml = stringWriter.toString(); 068 069 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 070 071 Object actual = unmarshaller.unmarshal(new StringReader(stringWriter.toString())); 072 assertEquals("Unmarshalled object should be equal to original objectToMarshall.", objectToMarshal, actual); 073 074 if (StringUtils.isBlank(expectedXml)) { 075 throw new IllegalArgumentException("Expected XML must be specified."); 076 } 077 078 Object expected = unmarshaller.unmarshal(new StringReader(expectedXml.trim())); 079 assertEquals("Unmarshalled objects should be equal.", expected, actual); 080 } catch (Throwable e) { 081 System.err.println("Outputting marshaled XML from failed assertion:\n" + marshaledXml); 082 if (e instanceof RuntimeException) { 083 throw (RuntimeException)e; 084 } else if (e instanceof Error) { 085 throw (Error)e; 086 } 087 throw new RuntimeException("Failed to marshall/unmarshall with JAXB. See the nested exception for details.", e); 088 } 089 } 090 091 public static void assertEqualXmlMarshalUnmarshalWithResource(Object objectToMarshal, InputStream expectedXml, Class<?> ... classesToBeBound) throws IOException { 092 BufferedReader reader = new BufferedReader(new InputStreamReader(expectedXml)); 093 StringWriter writer = new StringWriter(); 094 int data = -1; 095 while ((data = reader.read()) != -1) { 096 writer.write(data); 097 } 098 assertEqualXmlMarshalUnmarshal(objectToMarshal, writer.toString(), classesToBeBound); 099 } 100 101 102 }