/*
 * The MIT License
 * 
 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.jvnet.hudson.test;

import hudson.remoting.Which;
import hudson.FilePath;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

/**
 * Ensures that <tt>hudson.war</tt> is exploded.
 *
 * <p>
 * Depending on where the test is run (for example, inside Maven vs IDE), this code attempts to
 * use hudson.war from the right place, thereby improving the productivity.
 *
 * @author Kohsuke Kawaguchi
 */
final class WarExploder {

    public static File getExplodedDir() throws Exception {
        // rethrow an exception every time someone tries to do this, so that when explode()
        // fails, you can see the cause no matter which test case you look at.
        // see http://www.nabble.com/Failing-tests-in-test-harness-module-on-hudson.ramfelt.se-td19258722.html
        if(FAILURE !=null)   throw new Exception("Failed to initialize exploded war", FAILURE);
        return EXPLODE_DIR;
    }

    private static File EXPLODE_DIR;
    private static Exception FAILURE;

    static {
        try {
            EXPLODE_DIR = explode();
        } catch (Exception e) {
            FAILURE = e;
        }
    }

    /**
     * Explodes hudson.war, if necesasry, and returns its root dir.
     */
    private static File explode() throws Exception {
        // are we in the hudson main workspace? If so, pick up hudson/main/war/resources
        // this saves the effort of packaging a war file and makes the debug cycle faster

        File d = new File(".").getAbsoluteFile();

        // just in case we were started from hudson instead of from hudson/main/...
        if (new File(d, "main/war/target/hudson").exists()) {
            return new File(d, "main/war/target/hudson");
        }

        for( ; d!=null; d=d.getParentFile()) {
            if(new File(d,".hudson").exists())
                break;
        }
        if(d!=null) {
            File dir = new File(d,"war/target/hudson");
            if(dir.exists()) {
                System.out.println("Using hudson.war resources from "+dir);
                return dir;
            }
        }

        // locate hudson.war
        URL winstone = WarExploder.class.getResource("/winstone.jar");
        if(winstone==null)
        // impossible, since the test harness pulls in hudson.war
            throw new AssertionError("hudson.war is not in the classpath.");
        File war = Which.jarFile(Class.forName("executable.Executable"));

        File explodeDir = new File("./target/hudson-for-test").getAbsoluteFile();
        File timestamp = new File(explodeDir,".timestamp");

        if(!timestamp.exists() || (timestamp.lastModified()!=war.lastModified())) {
            System.out.println("Exploding hudson.war at "+war);
            new FilePath(explodeDir).deleteRecursive();
            new FilePath(war).unzip(new FilePath(explodeDir));
            if(!explodeDir.exists())    // this is supposed to be impossible, but I'm investigating HUDSON-2605
                throw new IOException("Failed to explode "+war);
            new FileOutputStream(timestamp).close();
            timestamp.setLastModified(war.lastModified());
        } else {
            System.out.println("Picking up existing exploded hudson.war at "+explodeDir.getAbsolutePath());
        }

        return explodeDir;
    }
}

@@ -3045,64 +3045,15 @@
 s())
+ %7B
 %0A    
-            break;%0A        %7D%0A        if(d!=null) %7B%0A
     
@@ -3116,16 +3116,20 @@
         
+    
 if(dir.e
@@ -3131,32 +3131,36 @@
 dir.exists()) %7B%0A
+    
                 
@@ -3231,24 +3231,28 @@
             
+  
+  
 return dir;%0A
@@ -3247,24 +3247,42 @@
 return dir;%0A
+                %7D%0A
             

this is more natural.