package ini.trakem2.io;
import ini.trakem2.utils.IJError;
import ini.trakem2.utils.Utils;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import mpicbg.models.TransformList;
import mpicbg.trakem2.transform.CoordinateTransform;
import mpicbg.trakem2.transform.CoordinateTransformList;
import mpicbg.trakem2.transform.InvertibleCoordinateTransform;
import mpicbg.trakem2.transform.InvertibleCoordinateTransformList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
public class CoordinateTransformXML
{
static public CoordinateTransform parse(final String xmlPath) throws Exception {
InputStream istream = null;
try {
SAXParserFactory f = SAXParserFactory.newInstance();
f.setValidating(false);
SAXParser parser = f.newSAXParser();
istream = Utils.createStream(xmlPath);
Parser p = new Parser();
parser.parse(new InputSource(istream), p);
return p.ct;
} finally {
try {
if (null != istream) istream.close();
} catch (Exception e) {}
}
}
static private class Parser extends DefaultHandler {
/** A stack of potentially nested instances of {@link CoordinateTransformList}. */
final ArrayList<TransformList<Object>> ct_list_stack = new ArrayList<TransformList<Object>>();
/** The final result: the top-level {@link CoordinateTransform}. */
private CoordinateTransform ct = null;
public void startElement(String uri, String localName, String qName, Attributes attributes) {
final HashMap<String,String> t = new HashMap<String,String>();
for (int i=attributes.getLength() -1; i>-1; i--) {
t.put(attributes.getQName(i).toLowerCase(), attributes.getValue(i));
}
makeCoordinateTransform(qName.toLowerCase(), t);
}
public void endElement(String namespace_URI, String local_name, String qualified_name) {
if (qualified_name.endsWith("ict_transform_list")) {
ct_list_stack.remove( ct_list_stack.size() - 1 );
}
}
private final void makeCoordinateTransform(
final String type,
final HashMap<String,String> ht_attributes)
{
try
{
if ( type.equals( "ict_transform" ) )
{
final CoordinateTransform ct = ( CoordinateTransform )Class.forName( ht_attributes.get( "class" ) ).newInstance();
ct.init( ht_attributes.get( "data" ) );
if ( ct_list_stack.isEmpty() )
{
this.ct = ct;
}
else
{
ct_list_stack.get( ct_list_stack.size() - 1 ).add( ct );
}
}
else if ( type.equals( "iict_transform" ) )
{
final InvertibleCoordinateTransform ict = ( InvertibleCoordinateTransform )Class.forName( ht_attributes.get( "class" ) ).newInstance();
ict.init( ht_attributes.get( "data" ) );
if ( ct_list_stack.isEmpty() )
{
this.ct = ict;
}
else
{
ct_list_stack.get( ct_list_stack.size() - 1 ).add( ict );
}
}
else if ( type.equals( "ict_transform_list" ) )
{
final CoordinateTransformList< CoordinateTransform > ctl = new CoordinateTransformList< CoordinateTransform >();
if ( ct_list_stack.isEmpty() )
{
this.ct = ctl;
}
else
{
ct_list_stack.get( ct_list_stack.size() - 1 ).add( ctl );
}
ct_list_stack.add( ( TransformList )ctl );
}
else if ( type.equals( "iict_transform_list" ) )
{
final InvertibleCoordinateTransformList< InvertibleCoordinateTransform > ictl = new InvertibleCoordinateTransformList< InvertibleCoordinateTransform >();
if ( ct_list_stack.isEmpty() )
{
this.ct = ictl;
}
else
{
ct_list_stack.get( ct_list_stack.size() - 1 ).add( ictl );
}
ct_list_stack.add( ( TransformList )ictl );
}
}
catch ( Exception e ) { IJError.print(e); }
}
}
}