/*
 * com.yodlee.soap.encoding.ser.NonBeanSerializer
 *
 * $Author: kharikumar $
 * $Date: 2004/06/15 $
 * $DateTime: 2004/06/15 01:02:01 $
 * $Id: //newarch/core/main/src/soap/com/yodlee/soap/encoding/ser/NonBeanSerializer.java#12 $
 *
 * Copyright (c) 2002 Yodlee Incorporated. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Yodlee, Inc. Use is subject to license terms.
 *
 */

package com.yodlee.soap.encoding.ser;

import com.yodlee.soap.encoding.EncodingHelper;
import com.yodlee.util.logging.MessageController;
import org.apache.axis.Constants;
import org.apache.axis.encoding.SerializationContext;
import org.apache.axis.encoding.Serializer;
import org.apache.axis.wsdl.fromJava.Types;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;

import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class NonBeanSerializer implements Serializer
{
    /** Fully qualified class name */
    private static final String FQCN = NonBeanSerializer.class.getName ();

    /** RCS version information */
    public static final String RCS_ID = "$Id: //newarch/core/main/src/soap/com/yodlee/soap/encoding/ser/NonBeanSerializer.java#12 $";

    /**
     * Default Constructor
     */
    public NonBeanSerializer ()
    {
    }

    /**
     * This methods calls EncodingHelper class to get all the fields of this object
     * that need to be serialized and calls serialize on each of them
     *
     * Serialize an element named name, with the indicated attributes
     * and value.
     * @param name is the element name
     * @param attributes are the attributes...serialize is free to add more.
     * @param value is the value
     * @param context is the SerializationContext
     */
    public void serialize (QName name, Attributes attributes,
                           Object value, SerializationContext context)
            throws IOException
    {
        //MessageController.debug (FQCN, "Enter NonBeanSerializer::serialize()");

        /**
         * Get map containing all the fields of the object that need to be serialized
         */
        Map fieldsToSerialize;
        try {
            fieldsToSerialize = EncodingHelper.getFieldsFromObject (value);
        } catch (RuntimeException e) {
            // unravel stack trace
            StringWriter sw = new StringWriter ();
            e.printStackTrace (new PrintWriter (sw));

            MessageController.log (FQCN,
                                   2559,
                                   "Encoding helper class for marshalling " + value.getClass ().getName () +
                                   " threw Exception " + e.getClass() +
                                   " with this message : " + e.getMessage () +
                                   " and stacktrace " + sw.toString(),
                                   MessageController.HIGH);
            throw new IOException ("Encoding Helper class for " +
                                   value.getClass ().getName () +
                                   " threw Exception " + e.getClass() +
                                   " with this message : " + e.getMessage () +
                                   " and stacktrace " + sw.toString());
        }

        context.startElement (name, attributes);

        /**
         * Call serialize on each field in the map
         */
        Set keys = fieldsToSerialize.keySet ();
        Iterator keyIterator = keys.iterator ();
        while (keyIterator.hasNext ()) {
            String preferenceKey = (String) keyIterator.next ();
            context.serialize (new QName ("", preferenceKey), null, fieldsToSerialize.get (preferenceKey));
        }

        context.endElement ();

/*
        MessageController.debug (FQCN, "Exit NonBeanSerializer::serialize() for " +
                                       value.getClass ().getName ());
*/

    }

    public String getMechanismType ()
    {
        return Constants.AXIS_SAX;
    }

    /**
     * Return XML schema for the specified type, suitable for insertion into
     * the <types> element of a WSDL document.
     *
     * @param types the Java2WSDL Types object which holds the context
     *              for the WSDL being generated.
     * @return true if we wrote a schema, false if we didn't.
     * @see Types
     */
    public Element writeSchema (Class javaType, Types types) throws Exception
    {
        return null;
    }
}
