/**
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 *
 * Copyright (C)
 * <a href="http://www.inab.org">Spanish National Institute of Bioinformatics (INB)</a>
 * <a href="http://www.bsc.es">Barcelona Supercomputing Center (BSC)</a>
 * <a href="http://inb.bsc.es">Computational Node 6</a>
 */

package org.inb.biomoby;

import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.JAXBIntrospector;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import org.inb.biomoby.shared.message.AbstractMobyObject;
import org.inb.biomoby.shared.message.AnyMobyObject;

/**
 * Utility class with cached JAXBContext.
 * Contains various useful methods to find a relationship between
 * Java 'moby' objects and their ontology names
 * 
 * @author Dmitry Repchevsky
 */

public class MobyMessageContext
{
    private static MobyClassLoader loader = new MobyClassLoader(MobyClassLoader.class.getClassLoader());
    
    private static JAXBContext jc;
    private static JAXBIntrospector introspector;
    
    private MobyMessageContext() {}
    
    public static synchronized JAXBContext getContext() throws JAXBException
    {
        if (jc == null)
        {
            jc = JAXBContext.newInstance("org.inb.biomoby.shared.message:org.inb.biomoby.shared.datatypes:org.inb.lsae:org.inb.wsrf.bf2:org.inb.wsrf.r2:org.inb.wsrf.rl2:org.inb.wsrf.rp2:org.inb.biomoby.shared.wsrf:org.inb.biomoby.shared.ontology" , loader);
        }
        
        return jc;
    }

    public static synchronized String getMobyName(AbstractMobyObject mobyObject) throws JAXBException
    {
        if (mobyObject instanceof AnyMobyObject)
        {
            AnyMobyObject anyMobyObject = (AnyMobyObject)mobyObject;
            return anyMobyObject.type;
        }
        
        if (introspector == null)
        {
            introspector = getContext().createJAXBIntrospector();
        }
        
        QName name = introspector.getElementName(mobyObject);
        
        if (name == null)
        {
            throw new JAXBException("fatal error: not a jaxb element - " + mobyObject.getClass().getName());
        }
        
        return name.getLocalPart();
    }

    public static String marshall(Object message) throws JAXBException
    {
        if (message == null)
        {
            return "";
        }
        
        Marshaller m = getContext().createMarshaller();
        
        StringWriter sw = new StringWriter();
        m.marshal(message, sw);
        
        return sw.toString();        
    }
}
