/*
 * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the
 * License at http://www.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.web;

import com.arsdigita.util.Assert;
import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.web.Application;
import com.arsdigita.kernel.PackageType;
import com.arsdigita.dispatcher.RequestContext;
import com.arsdigita.dispatcher.Dispatcher;
import com.arsdigita.dispatcher.DispatcherHelper;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;

/**
 * <p>An application servlet that does what SiteNodeDispatcher does
 * but in the context of the newer CCM dispatcher.  Gets the package
 * type associated with an application and uses its dispatcher.</p>
 *
 * <p>Use web.xml entries like the following to deploy this
 * servlet:</p>
 *
 * <blockquote><pre>
 * &lt;servlet&gt;
 *   &lt;servlet-name&gt;legacy-adapter&lt;/servlet-name&gt;
 *   &lt;servlet-class&gt;com.arsdigita.web.LegacyAdapterServlet&lt;/servlet-class&gt;
 * &lt;/servlet&gt;
 *
 * &lt;servlet-mapping&gt;
 *   &lt;servlet-name&gt;legacy-adapter&lt;/servlet-name&gt;
 *   &lt;url-pattern&gt;/__ccm__/servlet/legacy-adapter/*&lt;/url-pattern&gt;
 * &lt;/servlet-mapping&gt;
 * </pre></blockquote>
 *
 * @author Justin Ross &lt;<a href="mailto:jross@redhat.com">jross@redhat.com</a>&gt;
 * @see com.arsdigita.web.DispatcherServlet
 * @see com.arsdigita.sitenode.SiteNodeDispatcher
 */
public class LegacyAdapterServlet extends BaseApplicationServlet {
    public static final String versionId =
        "$Id: //core-platform/dev/src/com/arsdigita/web/LegacyAdapterServlet.java#10 $" +
        "$Author: dennis $" +
        "$DateTime: 2004/04/07 16:07:11 $";

    private static final Logger s_log = Logger.getLogger
        (LegacyAdapterServlet.class);

    /**
     * <p>Fetches the dispatcher for the package type of the current
     * application and dispatches to it with the {@link
     * RequestContext} constructed in {@link
     * com.arsdigita.web.BaseApplicationServlet}.</p>
     *
     * @param app The application which is being served.
     */
    public void doService(HttpServletRequest sreq,
                          HttpServletResponse sresp,
                          Application app)
            throws ServletException, IOException {
        s_log.debug("LegacyAdapterServlet.doService called for request " +
                    sreq);

        PackageType type = app.getApplicationType().getPackageType();

        if (s_log.isDebugEnabled()) {
            s_log.debug("Using package type '" + type.getKey() + "'");
        }

        Assert.assertNotNull(type, "PackageType type");

        String jsp = "/packages/" + type.getKey() + "/www" + sreq.getPathInfo();
        File file = new File(getServletContext().getRealPath(jsp));

        if (file.exists() && !file.isDirectory()) {
            // XXX Need to handle welcome files.

            RequestDispatcher rd = sreq.getRequestDispatcher(jsp);

            Assert.assertNotNull(rd, "RequestDispatcher rd");

            rd.forward(sreq, sresp);
        } else {
            try {
                RequestContext rc = DispatcherHelper.getRequestContext();

                Assert.assertNotNull(rc, "RequestContext rc");

                Dispatcher dispatcher = type.getDispatcher();

                Assert.assertNotNull(dispatcher, "Dispatcher dispatcher");

                if (s_log.isDebugEnabled()) {
                    s_log.debug
                        ("Dispatching using dispatcher '" + dispatcher + "'");
                }

                dispatcher.dispatch(sreq, sresp, rc);
            } catch (ClassNotFoundException cnfe) {
                throw new UncheckedWrapperException(cnfe);
            } catch (InstantiationException ie) {
                throw new UncheckedWrapperException(ie);
            } catch (IllegalAccessException iae) {
                throw new UncheckedWrapperException(iae);
            } catch (InvocationTargetException ite) {
                throw new UncheckedWrapperException(ite);
            }
        }
    }
}
