package com.processpuzzle.litest.template;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.jdom.Document;
import org.jdom.transform.JDOMResult;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import com.processpuzzle.commons.xml.ClasspathResourceResolver;
import com.processpuzzle.fundamental_types.domain.ServiceMessage;
import com.processpuzzle.litest.fixture.GenericTestFixture;
import com.processpuzzle.litest.fixture.TransientFreshFixture;
public abstract class ServiceMessageTestFixture<S extends ServiceMessage> extends GenericTestFixture<S> implements TransientFreshFixture<S> {
protected static final String CONTEXT_PATH = "com.cahoot";
protected Class<S> messageClass;
protected S messageAsObject;
protected Document messageAsXml;
protected String messagePath;
protected Resource messageResource;
protected Schema messageSchema;
protected ResourceLoader resourceLoader;
protected String schemaPath;
protected ServiceMessageTestFixture( String messagePath, String schemaPath ) {
this.messagePath = messagePath;
this.schemaPath = schemaPath;
}
// Properties
public Document getMessageAsXml() {
return messageAsXml;
}
// Protected, private helper methods
@Override
protected void configureBeforeSutInstantiation() {
resourceLoader = new DefaultResourceLoader();
determineMessageClass();
loadSchema();
}
@Override
protected S instantiateSUT() {
messageAsObject = setUpMessageObject();
sut = transformXmlToObject();
messageAsXml = transformObjectToXml();
return sut;
}
protected <T> Document marshall( Class<T> marshalledObjectClass, String schemaPath, ServiceMessage message ) {
JDOMResult marshallResult = new JDOMResult();
try{
JAXBContext jaxbContext = JAXBContext.newInstance( marshalledObjectClass );
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
//SchemaFactory sf = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
//Schema schema = sf.newSchema( new URL( SCHEMA_PATH ) );
//jaxbMarshaller.setSchema( schema );
jaxbMarshaller.marshal( messageAsObject, marshallResult );
}catch( Exception e ){
throw new RuntimeException( e );
}
return marshallResult.getDocument();
}
protected abstract S setUpMessageObject();
protected <T> T unmarshall( Class<T> docClass, String resourceName ) throws JAXBException, IOException {
messageResource = resourceLoader.getResource( resourceName );
return unmarshal( docClass, messageResource.getInputStream() );
}
@SuppressWarnings( "unchecked" )
protected <T> T unmarshal( Class<T> unmarshalledObjectClass, InputStream inputStream ) throws JAXBException, IOException {
JAXBContext jaxbContext = JAXBContext.newInstance( unmarshalledObjectClass );
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema( messageSchema );
T unmarshalledObject = (T) unmarshaller.unmarshal( inputStream );
inputStream.close();
return unmarshalledObject;
}
@SuppressWarnings( "unchecked" )
private void determineMessageClass() {
messageClass = (Class<S>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
private void loadSchema() {
SchemaFactory schemaFactory = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
try{
schemaFactory.setResourceResolver( new ClasspathResourceResolver() );
Resource schemaResource = resourceLoader.getResource( schemaPath );
messageSchema = schemaFactory.newSchema( schemaResource.getFile() );
}catch( Exception e ){
throw new RuntimeException( e );
}
}
private Document transformObjectToXml() {
return marshall( messageClass, schemaPath, messageAsObject );
}
private S transformXmlToObject() {
try{
sut = unmarshall( messageClass, messagePath );
}catch( JAXBException e ){
e.printStackTrace();
}catch( IOException e ){
e.printStackTrace();
}
return sut;
}
}