package com.c2kernel.utils;
//Java
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.HashSet;
import java.util.StringTokenizer;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
import com.c2kernel.common.InvalidDataException;
import com.c2kernel.persistency.outcome.Outcome;
/**************************************************************************
* Loads all mapfiles, and wraps marshalling/unmarshalling
*
* @author $Author: abranson $ $Date: 2004/10/20 14:10:21 $
* @version $Revision: 1.12 $
**************************************************************************/
public class CastorXMLUtility
{
private static Mapping mMapping = new Mapping();
private static HashSet mMappingKeys = new HashSet();
/**
* Looks for a file called 'index.xml' at the given URL, and loads every file
* listed in there by relative path
*
* @param mapURL - map root
*/
static public void loadMapsFrom(URL mapURL) throws InvalidDataException {
// load index.xml
Logger.msg(3, "Loading maps from "+mapURL);
String index;
try {
index = FileStringUtility.url2String( new URL(mapURL, "index.xml") );
} catch (Exception e) {
Logger.warning("Could not load map index from "+mapURL.toString());
return;
}
StringTokenizer sTokenizer = new StringTokenizer(index);
while( sTokenizer.hasMoreTokens() ) {
String thisMap = sTokenizer.nextToken();
try {
addMapping( new URL(mapURL, thisMap));
} catch (Exception e) {
Logger.error(e);
throw new InvalidDataException("Error loading map '"+thisMap+"'", "");
}
}
Logger.msg("Loaded all maps from "+mapURL.toString());
}
/**************************************************************************
* Updates a mapping referenced by the mapID.
* The same mapping cannot be loaded many times as it generates an exception.
* That is the reason for this method as it maintains the HashSet of MappingKeys.
**************************************************************************/
static public void addMapping( URL mapID )
throws IOException,
MappingException,
MarshalException,
ValidationException
{
if( !mMappingKeys.contains(mapID) )
{
Logger.msg(7, "Added mapping file:"+mapID);
mMapping.loadMapping( mapID );
mMappingKeys.add( mapID );
}
else
{
Logger.msg("Map file already loaded:"+mapID);
}
}
/**************************************************************************
* Marshalls a mapped object to string. The mapping must be loaded before.
* See updateMapping().
**************************************************************************/
static public String marshall( Object obj )
throws IOException,
MappingException,
MarshalException,
ValidationException
{
if (obj == null) return "";
if (obj instanceof Outcome)
return ((Outcome)obj).getData();
StringWriter sWriter = new StringWriter();
Marshaller marshaller = new Marshaller( sWriter );
marshaller.setMapping( mMapping );
marshaller.setMarshalAsDocument( false );
marshaller.marshal( obj );
return sWriter.toString();
}
/**************************************************************************
* Unmarshalls a mapped object from string. The mapping must be loaded before.
* See updateMapping().
**************************************************************************/
static public Object unmarshall( String data )
throws IOException,
MappingException,
MarshalException,
ValidationException
{
StringReader sReader = new StringReader( data );
Unmarshaller unmarshaller = new Unmarshaller( mMapping );
if (data.equals("")) return null;
return unmarshaller.unmarshal( sReader );
}
}