001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.kim.api.test;
017
018import javax.xml.bind.JAXBContext;
019import javax.xml.bind.Marshaller;
020import javax.xml.bind.Unmarshaller;
021import java.io.BufferedReader;
022import java.io.IOException;
023import java.io.InputStream;
024import java.io.InputStreamReader;
025import java.io.StringReader;
026import java.io.StringWriter;
027
028import static org.junit.Assert.assertEquals;
029
030/**
031 * A class with some assertion utilities for JAXB-related operations. 
032 * 
033 * TODO - copied this from the core api test module, find a better way to share this code!
034 * 
035 * @author Kuali Rice Team (rice.collab@kuali.org)
036 */
037public 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                  Object expected = unmarshaller.unmarshal(new StringReader(expectedXml.trim()));
075                  assertEquals("Unmarshalled objects should be equal.", expected, actual);
076                } catch (Throwable e) {
077                        System.err.println("Outputting marshaled XML from failed assertion:\n" + marshaledXml);
078                        if (e instanceof RuntimeException) {
079                                throw (RuntimeException)e;
080                        } else if (e instanceof Error) {
081                                throw (Error)e;
082                        }
083                        throw new RuntimeException("Failed to marshall/unmarshall with JAXB.  See the nested exception for details.", e);
084                }
085        }
086        
087        public static void assertEqualXmlMarshalUnmarshalWithResource(Object objectToMarshal, InputStream expectedXml, Class<?> ... classesToBeBound) throws IOException {
088                BufferedReader reader = new BufferedReader(new InputStreamReader(expectedXml));
089                StringWriter writer = new StringWriter();
090                int data = -1;
091                while ((data = reader.read()) != -1) {
092                        writer.write(data);
093                }
094                assertEqualXmlMarshalUnmarshal(objectToMarshal, writer.toString(), classesToBeBound);
095        }
096        
097
098}