/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2004 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */
package org.ow2.jonas.generators.wsgen.generator.axis.wsdl2java;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.wsdl.WSDLException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.ow2.jonas.generators.wsgen.WsGenException;
import org.ow2.jonas.generators.wsgen.generator.axis.AxisWsClientGenerator;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import org.apache.axis.wsdl.WSDL2Java;
import org.apache.axis.wsdl.gen.Parser;


/**
 * Programmatic interface to the WSDL2Java Axis tool.
 * @author Guillaume Sauthier
 */
public class JOnASWSDL2Java extends WSDL2Java {

    /**
     * Field emitter
     */
    private JOnASEmitter jEmitter;

    /**
     * WSDL Localtion URL
     */
    private String wsdlURL = null;

    /**
     * Parsed WSDL Document
     */
    private Document wsdlDoc = null;

    /**
     * JOnASWSDL2Java Constructor.
     */
    public JOnASWSDL2Java() {
        super();
        // just cast it once
        jEmitter = (JOnASEmitter) getParser();
    }

    /**
     * @return Returns an extension of the Parser
     */
    protected Parser createParser() {
        return new JOnASEmitter();
    } // createParser

    /**
     * Setup the JOnASWSDL2Java generator.
     * @param wsc WsClientGenerator from wich the configuration will be read.
     * @throws WsGenException Cannot parse WSDL Document
     */
    private void setup(AxisWsClientGenerator wsc) throws WsGenException {
        setupEmitter(wsc);
        setupWSDL(wsc);
    }

    /**
     * Setup the WSDL Document before giving it to the Emitter.
     * @param wsc configuration
     * @throws WsGenException Cannot load WSDL
     */
    private void setupWSDL(AxisWsClientGenerator wsc) throws WsGenException {
        try {
            if (wsc.getArchive().isPacked()) {
                // URL Loading
                String jarpath = wsc.getArchive().getRootFile().getCanonicalFile().toURL().toExternalForm();
                wsdlURL = "jar:" + jarpath + "!/" + wsc.getRef().getWsdlFileName();
            } else {
                // File Loading
                wsdlURL = new File(wsc.getArchive().getRootFile(), wsc.getRef().getWsdlFileName()).toURL()
                        .toExternalForm();
            }

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            wsdlDoc = builder.parse(wsdlURL);
        } catch (ParserConfigurationException pce) {
            throw new WsGenException("", pce);
        } catch (IOException ioe) {
            throw new WsGenException("", ioe);
        } catch (SAXException se) {
            throw new WsGenException("", se);
        }
    }

    /**
     * Setup the JOnASEmitter instance.
     * @param wsc configuration
     */
    private void setupEmitter(AxisWsClientGenerator wsc) {
        jEmitter.setDebug(wsc.getConfig().isDebug());
        jEmitter.setVerbose(wsc.getConfig().isVerbose());
        jEmitter.setNamespaceMap(convert2HashMap(wsc.getRef().getMappingFile().getMappings()));
        jEmitter.setOutputDir(wsc.getSources().getPath());
    }

    /**
     * Converts Hashtable to HashMap.
     * @param m Hashtable to be converted
     * @return HashMap converted
     */
    private HashMap convert2HashMap(Map m) {
        HashMap ns2pkg = new HashMap();
        for (Iterator i = m.keySet().iterator(); i.hasNext();) {
            String ns = (String) i.next();
            ns2pkg.put(ns, m.get(ns));
        }
        return ns2pkg;
    }

    /**
     * Setup and runs the JOnASEmitter.
     *
     * @param wsc Configuration.
     *
     * @throws WsGenException When WSDL has not been properly parsed
     * @throws SAXException Cannot parse WSDL document
     * @throws WSDLException When WSDL is incorrect
     * @throws ParserConfigurationException Cannot Configure Parser
     * @throws IOException Import URL cannot be loaded
     */
    public void run(AxisWsClientGenerator wsc) throws WsGenException, IOException, SAXException, WSDLException, ParserConfigurationException {
        setup(wsc);
        parser.run(wsdlURL, wsdlDoc);
    } // run

}