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 }