/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.deployment.backend;

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException;
import java.util.logging.Level;

import com.sun.enterprise.deployment.WebBundleDescriptor;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.util.DOLUtils;
import com.sun.enterprise.deployment.io.WebDeploymentDescriptorFile;
import com.sun.enterprise.deployment.deploy.shared.FileArchive;
import com.sun.enterprise.deployment.util.DOLLoadingContextFactory;

import com.sun.enterprise.instance.InstanceEnvironment;
import com.sun.enterprise.server.ApplicationServer;

public class DOLLoadingContext {
    private static final String DEFAULT_WEB_XML = "default-web.xml";

    private static long defaultWebXMLLastModified = -1;

    /**
     * initialize the default WebBundleDescriptor from
     * default-web.xml
     */
    public static WebBundleDescriptor initDefaultWebBundleDescriptor() {
        DOLLoadingContextFactory.setParsingDefaultWebXML(true);

        FileInputStream fis = null; 

        WebBundleDescriptor wbd = null;
        try {
            // parse default-web.xml contents 
            // (this path will not be invoked by portable static verifier)
            if (ApplicationServer.getServerContext() != null) {
                File file = getDefaultWebXMLFile();
                if (file.exists()) {
                    fis = new FileInputStream(file);
                    WebDeploymentDescriptorFile wddf = 
                        new WebDeploymentDescriptorFile();
                    wddf.setXMLValidation(false);
                    wbd =  (WebBundleDescriptor) wddf.read(fis);
                    defaultWebXMLLastModified = file.lastModified();
                } else {
                    /*
                     * If we do not find the file then we record the current
                     * system time as the lastModified time for the (empty)
                     * cache.  This way, if the user had a default-web.xml
                     * during earlier deployments or system restarts but has
                     * removed it since then, the later deployments and system
                     * restarts will detect that the default descriptor
                     * contents that should be used (now, none) has changed
                     * since the serialized data files for those app's
                     * descriptors were written.  As we load those apps we will
                     * detect that their serialized data files are obsolete
                     * compared to the empty cache and so they
                     * will be loaded using the newer, now-empty defaults, rather than the
                     * earlier defaults that were in place when their serialized
                     * data files were written earlier.
                     *
                     * Note that if the user completely removes the default-web.xml
                     * file he or she will undermine the performance optimization
                     * of creating the serialized data files in the first place.
                     * This is because every time any app is loaded we will have to
                     * assume that its serialized data file is obsolete--we
                     * have no way of knowing whether the default-web.xml was
                     * also missing when the apps were loaded -- and their
                     * serialized data files written -- before.  So we must assume that
                     * those serialized files were written with some default-web.xml
                     * and now that file is gone, rendering those serialized
                     * data files obsolete.  Functionally everything is fine;
                     * the start-up performance optimization is lost, though.
                     */
                    defaultWebXMLLastModified = System.currentTimeMillis();
                }
            }
            return wbd;
        } catch (Exception e) {
            DOLUtils.getDefaultLogger().log(Level.WARNING, 
                "enterprise.deployment.default.web.xml.not.parsed", 
                 new Object[] {e.getMessage()});
            return null;
        } finally {
            DOLLoadingContextFactory.setParsingDefaultWebXML(false);
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException ioe) {
                // do nothing
            }
        }
    }

    /**
     * Returns the lastModified timestamp for the loaded default-web.xml
     * content.
     * <p>
     * The default-web.xml contents is loaded upon first access and then
     * cached for the duration of the server run.  Even if the user edits
     * the default-web.xml file during the server run, the server continues
     * to use the cached contents as loaded at first access.
     *
     * @return the time when the default-web.xml contents were loaded
     */
    public static long defaultWebXMLLastModified() {
        if (defaultWebXMLLastModified == -1) {
            File f = getDefaultWebXMLFile();
            defaultWebXMLLastModified = (f.exists() ? f.lastModified() : System.currentTimeMillis());
        }
        return defaultWebXMLLastModified;
    }
    
    /**
     * Provides a File object for the default-web.xml file in this domain's
     * config subdirectory.
     * @return File for the default-web.xml file
     */
    private static File getDefaultWebXMLFile() {
        InstanceEnvironment iEnv = ApplicationServer.getServerContext(
            ).getInstanceEnvironment();

        String defaultWebXMLPath = iEnv.getConfigDirPath() + 
            File.separator + DEFAULT_WEB_XML;
        File file = new File(defaultWebXMLPath);
        return file;
    }
}
