/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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 (at your option) any later version.
 *
 * This software 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 software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.test;

import junit.extensions.TestSetup;
import junit.framework.Test;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.taskdefs.ExecTask;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * JUnit TestSetup extension that starts/stops XWiki using a script passed using System Properties.
 * These properties are meant to be passed by the underlying build system. This class is meant to
 * wrap a JUnit TestSuite. For example:
 * 
 * <pre><code>
 * public static Test suite()
 * {
 *     // Create some TestSuite object here
 *     return new XWikiTestSetup(suite);
 * }
 * </code></pre>
 * 
 * <p>
 * Note: We could start XWiki using Java directly but we're using a script so that we can test the
 * exact same script used by XWiki users who download the standalone distribution.
 * </p>
 * 
 * @version $Id: $
 */
public class XWikiTestSetup extends TestSetup
{
    private static final String EXECUTION_DIRECTORY =
        System.getProperty("xwikiExecutionDirectory");

    private static final String START_COMMAND = System.getProperty("xwikiExecutionStartCommand");

    private static final String STOP_COMMAND = System.getProperty("xwikiExecutionStopCommand");

    private static final String PORT = System.getProperty("xwikiPort", "8080");

    private static final boolean DEBUG =
        System.getProperty("debug", "false").equalsIgnoreCase("true");

    private static final int TIMEOUT_SECONDS = 120;

    private Project project;

    public XWikiTestSetup(Test test)
    {
        super(test);

        this.project = new Project();
        this.project.init();
        this.project.addBuildListener(new AntBuildListener(DEBUG));
    }

    protected void setUp() throws Exception
    {
        startXWikiInSeparateThread();
        waitForXWikiToLoad();
    }

    private void startXWikiInSeparateThread()
    {
        Thread startThread = new Thread(new Runnable()
        {
            public void run()
            {
                try {
                    startXWiki();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
        startThread.start();
    }

    private void startXWiki() throws Exception
    {
        File dir = new File(EXECUTION_DIRECTORY);
        if (dir.exists()) {
            ExecTask execTask = (ExecTask) this.project.createTask("exec");
            execTask.setDir(new File(EXECUTION_DIRECTORY));
            Commandline commandLine = new Commandline(START_COMMAND);
            execTask.setCommand(commandLine);
            execTask.execute();
        } else {
            throw new Exception("Invalid directory from where to start XWiki [" + EXECUTION_DIRECTORY + "]");
        }
    }

    private Task createStopTask() throws Exception
    {
        ExecTask execTask;
        File dir = new File(EXECUTION_DIRECTORY);
        if (dir.exists()) {
            execTask = (ExecTask) this.project.createTask("exec");
            execTask.setDir(new File(EXECUTION_DIRECTORY));
            Commandline commandLine = new Commandline(STOP_COMMAND);
            execTask.setCommand(commandLine);
        } else {
            throw new Exception("Invalid directory from where to stop XWiki [" + EXECUTION_DIRECTORY + "]");
        }
        return execTask;
    }

    private void waitForXWikiToLoad() throws Exception
    {
        // Wait till the main page becomes available which means the server is started fine
        System.out.println("Checking that XWiki is up and running...");
        URL url = new URL("http://localhost:" + PORT + "/xwiki/bin/view/Main/WebHome");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        boolean connected = false;
        boolean timedOut = false;
        long startTime = System.currentTimeMillis();
        while (!connected && !timedOut) {
            try {
                connection.connect();
                int responseCode = connection.getResponseCode();
                if (DEBUG) {
                    System.out.println("Result of pinging [" + url + "] = [" + responseCode
                        + "], Message = [" + connection.getResponseMessage() + "]");
                }
                // check the http response code is either not an error, either "unauthorized"
                // (which is the case for products that deny view for guest, for example).
                connected = (responseCode < 400 || responseCode == 401);
            } catch (IOException e) {
                // Do nothing as it simply means the server is not ready yet...
            }
            Thread.sleep(100L);
            timedOut = (System.currentTimeMillis() - startTime > TIMEOUT_SECONDS * 1000L);
        }
        if (timedOut) {
            String message = "Failed to start XWiki in [" + TIMEOUT_SECONDS + "] seconds";
            System.out.println(message);
            tearDown();
            throw new RuntimeException(message);
        }
    }

    protected void tearDown() throws Exception
    {
        // Stop XWiki
        createStopTask().execute();
    }
}

@@ -1324,19 +1324,16 @@
 perties.
-%0A *
  These p
@@ -1345,16 +1345,19 @@
 ties are
+%0A *
  meant t
@@ -1422,19 +1422,16 @@
 meant to
-%0A *
  wrap a 
@@ -1730,19 +1730,16 @@
 test the
-%0A *
  exact s
@@ -1748,16 +1748,19 @@
 e script
+%0A *
  used by
@@ -1950,24 +1950,16 @@
 ECTORY =
-%0A       
  System.
@@ -2316,24 +2316,16 @@
  DEBUG =
-%0A       
  System.
@@ -2663,32 +2663,138 @@
 DEBUG));%0A    %7D%0A%0A
+    /**%0A     * %7B@inheritDoc%7D%0A     * %0A     * @see junit.extensions.TestSetup#setUp()%0A     */%0A    @Override%0A
     protected vo
@@ -4381,32 +4381,33 @@
 %22%5D%22);%0A        %7D%0A
+%0A
         return e
@@ -5221,16 +5221,35 @@
 onseCode
+ + %22%5D, Message = %5B%22
 %0A       
@@ -5270,27 +5270,8 @@
    +
- %22%5D, Message = %5B%22 +
  con
@@ -6090,24 +6090,133 @@
    %7D%0A    %7D%0A%0A
+    /**%0A     * %7B@inheritDoc%7D%0A     * %0A     * @see junit.extensions.TestSetup#tearDown()%0A     */%0A    @Override%0A
     protecte

Improve codestyle