/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2003-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: EjbJarModifier.java 15428 2008-10-07 11:20:29Z sauthieg $
 * --------------------------------------------------------------------------
 */
package org.ow2.jonas.generators.wsgen.modifier;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.jar.Attributes;

import org.objectweb.util.monolog.api.BasicLevel;
import org.ow2.jonas.Version;
import org.ow2.jonas.deployment.ws.ServiceDesc;
import org.ow2.jonas.deployment.ws.ServiceRefDesc;
import org.ow2.jonas.generators.genbase.GenBaseException;
import org.ow2.jonas.generators.genbase.archive.Application;
import org.ow2.jonas.generators.genbase.archive.Archive;
import org.ow2.jonas.generators.genbase.archive.DummyApplication;
import org.ow2.jonas.generators.genbase.archive.DummyWebApp;
import org.ow2.jonas.generators.genbase.archive.Ejb;
import org.ow2.jonas.generators.genbase.archive.EjbJar;
import org.ow2.jonas.generators.genbase.archive.WebApp;
import org.ow2.jonas.generators.genbase.modifier.ArchiveModifier;
import org.ow2.jonas.generators.wsgen.ddmodifier.ContextDDModifier;
import org.ow2.jonas.generators.wsgen.ddmodifier.WebJettyDDModifier;
import org.ow2.jonas.generators.wsgen.ddmodifier.WsClientDDModifier;
import org.ow2.jonas.generators.wsgen.ddmodifier.WsEndpointDDModifier;
import org.ow2.jonas.generators.wsgen.generator.Generator;
import org.ow2.jonas.generators.wsgen.generator.GeneratorFactory;
import org.ow2.jonas.generators.wsgen.generator.SecurityGenerator;
import org.w3c.dom.Document;

/**
 * Modify a given EjbJar.
 *
 * @author Guillaume Sauthier
 */
public class EjbJarModifier extends ArchiveModifier {

    /** modified ejbjar */
    private EjbJar ejbjar = null;

    /**
     * Creates a new EjbJarModifier object.
     *
     * @param ejbjar EjbJar Archive
     */
    public EjbJarModifier(final EjbJar ejbjar) {
        super(ejbjar);
        this.ejbjar = ejbjar;
    }

    /**
     * modify the current EjbJar. If EjbJar is contained in not an application
     * and have webservices endpoints, A DummyApplication is created and
     * modification process launched against the newly created application. If
     * EjbJar is contained in an application + webservices endpoints, a
     * DummyWebApp is created to hold "facade" servlet managing SOAP processing.
     *
     * @return an EjbJar or an Application Archive
     *
     * @throws GenBaseException When generation or storing fails
     */
    @Override
    public Archive modify() throws GenBaseException {

        getLogger().log(BasicLevel.INFO, "Processing EjbJar " + ejbjar.getName());

        // MANIFEST attributes
        Attributes main = this.ejbjar.getManifest().getMainAttributes();

        // Add all MANIFEST entries from parent
        if (this.getArchive() != null && this.getArchive().getArchive() != null) {
            main.putAll(this.getArchive().getArchive().getManifest().getMainAttributes());
        }

        // Update MANIFEST with Version Number
        // used to say if WsGen has already been applied to this Module
        main.put(new Attributes.Name(WsGenModifierConstants.WSGEN_JONAS_VERSION_ATTR), Version.getNumber());

        GeneratorFactory gf = GeneratorFactory.getInstance();
        Document jejbjar = ejbjar.getJonasEjbJarDoc();

        // Webservices endpoint
        List sds = ejbjar.getServiceDescs();

        if (sds.size() != 0) {
            if (ejbjar.getApplication() == null) {
                // we have webservices outside of an application

                /**
                 * Process : - create a default Application - add EjbJar within -
                 * return ApplicationModifier.modify()
                 */
                String ejbName = ejbjar.getRootFile().getName();
                String earName = ejbName.substring(0, ejbName.length() - ".jar".length()) + ".ear";
                Application application = new DummyApplication(earName);
                ejbjar.setApplication(application);
                application.addEjbJar(ejbjar);
                ApplicationModifier am = new ApplicationModifier(application);

                return am.modify();

            } else {
                // we have webservices inside of an application

                /**
                 * Process : - create a default WebApp - add in Application -
                 * iterate over the services - add files in web instead of
                 * ejbjar
                 */

                String warName = null;
                String war = ejbjar.getWarName();
                if (war != null) {
                    warName = war;
                } else {
                    String ejbName = ejbjar.getRootFile().getName();
                    String contextName = ejbName.substring(0, ejbName.length() - ".jar".length());
                    warName = contextName + ".war";
                }

                Application application = ejbjar.getApplication();
                WebApp web = new DummyWebApp(application, warName);

                for (Iterator i = sds.iterator(); i.hasNext();) {
                    ServiceDesc sd = (ServiceDesc) i.next();

                    // create dd modifier
                    WsEndpointDDModifier ddm = new WsEndpointDDModifier(web.getWebAppDoc());

                    // launch generation
                    Generator g = gf.newGenerator(sd, ddm, null, ejbjar);
                    g.generate();
                    g.compile();
                    // add files in web archive
                    g.addFiles(web);

                    //Now generate the security for the web app
                    Document context = web.getContextDoc();
                    if (context == null) {
                        context = web.newContextDoc();
                    }
                    ContextDDModifier cddm = new ContextDDModifier(context);
                    Document webJetty = web.getWebJettyDoc();
                    if (webJetty == null) {
                        webJetty = web.newWebJettyDoc();
                    }
                    WebJettyDDModifier wjddm = new WebJettyDDModifier(webJetty);
                    Document jonaswebservices = ejbjar.getJonasWebservicesDoc();
                    SecurityGenerator  sm = new SecurityGenerator(jonaswebservices);
                    sm.generate(ddm, cddm, wjddm);


                }
                // save webapp
                application.addWebApp(new WebApp(save(gf.getConfiguration(),
                        "webapps" + File.separator + web.getName(), web)), ejbjar.getContextRoot());
            }
        }

        // add client files
        List ejbs = ejbjar.getEjbs();
        for (Iterator i = ejbs.iterator(); i.hasNext();) {
            Ejb ejb = (Ejb) i.next();
            List refs = ejb.getServiceRefDescs();
            for (Iterator j = refs.iterator(); j.hasNext();) {
                ServiceRefDesc ref = (ServiceRefDesc) j.next();

                // create dd modifier
                WsClientDDModifier ddm = new WsClientDDModifier(ref.getServiceRefName(), jejbjar, ejb.getJonasBeanElement());

                // launch generation
                Generator g = gf.newGenerator(ref, ddm, ejbjar);
                g.generate();
                g.compile();
                // add files in web archive
                g.addFiles(ejbjar);
            }
        }

        return save(gf.getConfiguration(), "ejbjars" + File.separator + ejbjar.getRootFile().getName());

    }
}