package org.jboss.remoting.marshal;
import org.jboss.logging.Logger;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.marshal.http.HTTPMarshaller;
import org.jboss.remoting.marshal.http.HTTPUnMarshaller;
import org.jboss.remoting.marshal.serializable.SerializableMarshaller;
import org.jboss.remoting.marshal.serializable.SerializableUnMarshaller;
import java.util.HashMap;
import java.util.Map;
public class MarshalFactory
{
private static Map marshallers = new HashMap();
private static Map unmarshallers = new HashMap();
private static Map classMarshallers = new HashMap();
private static Map classUnmarshallers = new HashMap();
protected final static Logger log = Logger.getLogger(MarshalFactory.class);
static
{
try
{
marshallers.put(SerializableMarshaller.DATATYPE, new SerializableMarshaller());
unmarshallers.put(SerializableUnMarshaller.DATATYPE, new SerializableUnMarshaller());
marshallers.put(HTTPMarshaller.DATATYPE, new HTTPMarshaller());
unmarshallers.put(HTTPUnMarshaller.DATATYPE, new HTTPUnMarshaller());
}
catch(Exception e)
{
log.error("Could not statically load default marshallers.", e);
}
}
public static void addMarshaller(Class classType, Marshaller marshaller, UnMarshaller unMarshaller)
{
classMarshallers.put(classType, marshaller);
classUnmarshallers.put(classType, unMarshaller);
}
public static void addMarshaller(String dataType, Marshaller marshaller, UnMarshaller unMarshaller)
{
marshallers.put(dataType, marshaller);
unmarshallers.put(dataType, unMarshaller);
}
public static Marshaller getMarshaller(Class classType)
{
Marshaller marshaller = null;
Object obj = classMarshallers.get(classType);
if(obj != null && obj instanceof Marshaller)
{
marshaller = (Marshaller) obj;
}
else
{
log.warn("Could not find marshaller for class type '" + classType + "'. Object in collection is " + obj);
}
return marshaller;
}
public static UnMarshaller getUnMarshaller(Class classType)
{
UnMarshaller unmarshaller = null;
Object obj = classUnmarshallers.get(classType);
if(obj != null && obj instanceof UnMarshaller)
{
unmarshaller = (UnMarshaller) obj;
}
else
{
log.warn("Could not find unmarshaller for class type '" + classType + "'. Object in collection is " + obj);
}
return unmarshaller;
}
public static Marshaller getMarshaller(String dataType)
{
Marshaller marshaller = null;
Object obj = marshallers.get(dataType);
if(obj != null && obj instanceof Marshaller)
{
marshaller = (Marshaller) obj;
}
else
{
log.warn("Could not find marshaller for data type '" + dataType + "'. Object in collection is " + obj);
}
return marshaller;
}
public static UnMarshaller getUnMarshaller(String dataType)
{
UnMarshaller unmarshaller = null;
Object obj = unmarshallers.get(dataType);
if(obj != null && obj instanceof UnMarshaller)
{
unmarshaller = (UnMarshaller) obj;
}
else
{
log.warn("Could not find unmarshaller for data type '" + dataType + "'. Object in collection is " + obj);
}
return unmarshaller;
}
public static Marshaller getMarshaller(InvokerLocator locator, ClassLoader classLoader)
{
Marshaller marshaller = null;
if(locator != null)
{
Map params = locator.getParameters();
if(params != null)
{
String dataType = (String) params.get(InvokerLocator.DATATYPE);
if(dataType != null)
{
marshaller = getMarshaller(dataType);
}
if(marshaller == null)
{
log.debug("Could not find data type to lookup by marshaller class");
String marshallerFQN = (String) params.get(InvokerLocator.MARSHALLER);
marshaller = loadMarshaller(marshallerFQN);
if(marshaller != null)
{
String unmarshallerFQN = (String) params.get(InvokerLocator.UNMARSHALLER);
UnMarshaller unmarshaller = loadUnMarshaller(unmarshallerFQN);
if(unmarshaller != null)
{
addMarshaller(dataType, marshaller, unmarshaller);
}
}
}
if(log.isDebugEnabled() && marshaller == null)
{
log.debug("Tried to find marshaller from locator by both data type and class name but was unsuccessful. " +
"Will try to load it from remote server.");
}
if(marshaller == null && dataType != null)
{
InvokerLocator loaderLocator = MarshallLoaderFactory.convertLocator(locator);
if(loaderLocator != null)
{
marshaller = MarshallerLoaderClient.getMarshaller(loaderLocator, dataType, classLoader);
UnMarshaller unmarshaller = MarshallerLoaderClient.getUnMarshaller(loaderLocator, dataType, classLoader);
if(unmarshaller != null)
{
unmarshaller.setClassLoader(classLoader);
}
if(log.isTraceEnabled())
{
log.trace("Remotely loaded marshaller: " + marshaller);
log.trace("Remotely loaded unmarshaller: " + unmarshaller);
}
if(marshaller != null && unmarshaller != null)
{
addMarshaller(dataType, marshaller, unmarshaller);
}
}
}
}
}
return marshaller;
}
private static Marshaller loadMarshaller(String marshallerFQN)
{
Marshaller marshaller = null;
if(marshallerFQN != null)
{
try
{
Class marshallerClass = Class.forName(marshallerFQN);
marshaller = (Marshaller) marshallerClass.newInstance();
}
catch(Exception e)
{
log.warn("Found marshaller fully qualified class name within locator parameters, but was unable " +
"to load class: " + marshallerFQN);
}
}
return marshaller;
}
public static UnMarshaller getUnMarshaller(InvokerLocator locator, ClassLoader classLoader)
{
UnMarshaller unmarshaller = null;
if(locator != null)
{
Map params = locator.getParameters();
if(params != null)
{
String dataType = (String) params.get(InvokerLocator.DATATYPE);
if(dataType != null)
{
unmarshaller = getUnMarshaller(dataType);
}
if(unmarshaller == null)
{
log.debug("Could not find data type to lookup by unmarshaller class");
String unmarshallerFQN = (String) params.get(InvokerLocator.UNMARSHALLER);
unmarshaller = loadUnMarshaller(unmarshallerFQN);
if(unmarshaller != null)
{
String marshallerFQN = (String) params.get(InvokerLocator.MARSHALLER);
Marshaller marshaller = loadMarshaller(marshallerFQN);
if(marshaller != null)
{
addMarshaller(dataType, marshaller, unmarshaller);
}
}
}
if(log.isDebugEnabled() && unmarshaller == null)
{
log.debug("Tried to find unmarshaller from locator by both data type and class name but was unsuccessful.");
}
if(unmarshaller == null && dataType != null)
{
InvokerLocator loaderLocator = MarshallLoaderFactory.convertLocator(locator);
unmarshaller = MarshallerLoaderClient.getUnMarshaller(loaderLocator, dataType, classLoader);
if(unmarshaller != null)
{
unmarshaller.setClassLoader(classLoader);
}
Marshaller marshaller = MarshallerLoaderClient.getMarshaller(loaderLocator, dataType, classLoader);
if(log.isTraceEnabled())
{
log.trace("Remotely loaded marshaller: " + marshaller);
log.trace("Remotely loaded unmarshaller: " + unmarshaller);
}
if(marshaller != null && unmarshaller != null)
{
addMarshaller(dataType, marshaller, unmarshaller);
}
}
}
}
return unmarshaller;
}
private static UnMarshaller loadUnMarshaller(String unmarshallerFQN)
{
UnMarshaller unmarshaller = null;
if(unmarshallerFQN != null)
{
try
{
Class unmarshallerClass = Class.forName(unmarshallerFQN);
unmarshaller = (UnMarshaller) unmarshallerClass.newInstance();
}
catch(Exception e)
{
log.error("Found unmarshaller fully qualified class name within locator parameters, but was unable " +
"to load class: " + unmarshallerFQN, e);
}
}
return unmarshaller;
}
}