001    /**
002     * Copyright 2005-2011 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.ksb.test;
017    
018    import static org.junit.Assert.assertEquals;
019    
020    import java.io.BufferedReader;
021    import java.io.IOException;
022    import java.io.InputStream;
023    import java.io.InputStreamReader;
024    import java.io.StringReader;
025    import java.io.StringWriter;
026    
027    import javax.xml.bind.JAXBContext;
028    import javax.xml.bind.Marshaller;
029    import javax.xml.bind.Unmarshaller;
030    
031    /**
032     * A class with some assertion utilities for JAXB-related operations. 
033     * 
034     * @author Kuali Rice Team (rice.collab@kuali.org)
035     */
036    public final class JAXBAssert {
037            
038            private JAXBAssert() {}
039            
040            /**
041             * Performs the following steps and assertions:
042             * 
043             * <ol>
044             *   <li>Creates a new JAXBContext with the given list of classesToBeBound.</li>
045             *   <li>Marshals the provided objectToMarshall to XML.</li>
046             *   <li>Unmarshals the marshaled XML to recreate the original object.<li>
047             *   <li>Asserts that the newly unmarhsaled object and the original provided object are equal by invoking {@link Object#equals(Object)}.</li>
048             *   <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>
049             * </ol>  
050             *  
051             * @param objectToMarshal the object to marshal to XML using JAXB
052             * @param expectedXml an XML string that will be unmarshaled to an Object and compared with objectToMarshal using {@link Object#equals(Object)}
053             * @param classesToBeBound - list of java classes to be recognized by the created JAXBContext
054             * 
055             */
056            public static void assertEqualXmlMarshalUnmarshal(Object objectToMarshal, String expectedXml, Class<?> ... classesToBeBound) {
057                    String marshaledXml = null;
058                    try {
059                      JAXBContext jaxbContext = JAXBContext.newInstance(classesToBeBound);
060                      Marshaller marshaller = jaxbContext.createMarshaller();
061                      
062                      StringWriter stringWriter = new StringWriter();
063                      
064                      marshaller.marshal(objectToMarshal, stringWriter);
065    
066                      marshaledXml = stringWriter.toString();
067                      
068                      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
069                      
070                      Object actual = unmarshaller.unmarshal(new StringReader(stringWriter.toString()));
071                      assertEquals("Unmarshalled object should be equal to original objectToMarshall.", objectToMarshal, actual);
072                      
073                      Object expected = unmarshaller.unmarshal(new StringReader(expectedXml.trim()));
074                      assertEquals("Unmarshalled objects should be equal.", expected, actual);
075                    } catch (Throwable e) {
076                            System.err.println("Outputting marshaled XML from failed assertion:\n" + marshaledXml);
077                            if (e instanceof RuntimeException) {
078                                    throw (RuntimeException)e;
079                            } else if (e instanceof Error) {
080                                    throw (Error)e;
081                            }
082                            throw new RuntimeException("Failed to marshall/unmarshall with JAXB.  See the nested exception for details.", e);
083                    }
084            }
085            
086            public static void assertEqualXmlMarshalUnmarshalWithResource(Object objectToMarshal, InputStream expectedXml, Class<?> ... classesToBeBound) throws IOException {
087                    BufferedReader reader = new BufferedReader(new InputStreamReader(expectedXml));
088                    StringWriter writer = new StringWriter();
089                    int data = -1;
090                    while ((data = reader.read()) != -1) {
091                            writer.write(data);
092                    }
093                    assertEqualXmlMarshalUnmarshal(objectToMarshal, writer.toString(), classesToBeBound);
094            }
095            
096    
097    }