/*
 * 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.tool.backup;

import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiConfig;
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.web.Utils;
import com.xpn.xwiki.web.XWikiServletRequestStub;
import com.xpn.xwiki.web.XWikiServletURLFactory;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import org.xwiki.component.embed.EmbeddableComponentManager;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.context.Execution;
import org.xwiki.context.ExecutionContext;
import org.xwiki.context.ExecutionContextException;
import org.xwiki.context.ExecutionContextManager;
import org.xwiki.model.reference.DocumentReference;

/**
 * Common code for importing and exporting.
 * 
 * @version $Id$
 */
public class AbstractPackager
{
    /**
     * @param databaseName some database name (TODO: find out what this name is really)
     * @param hibernateConfig the Hibernate config fill containing the database definition (JDBC driver, username and
     *            password, etc)
     * @return a valid XWikiContext using the passed Hibernate configuration and passed database name
     * @throws Exception failed to initialize context.
     * @todo Replace the Hibernate config file with a list of parameters required for the packaging operation
     */
    protected XWikiContext createXWikiContext(String databaseName, File hibernateConfig) throws Exception
    {
        EmbeddableComponentManager ecm = new EmbeddableComponentManager();
        ecm.initialize(this.getClass().getClassLoader());
        Utils.setComponentManager(ecm);

        // We need to initialize the Component Manager so that the components can be looked up
        XWikiContext xcontext = new XWikiContext();
        xcontext.put(ComponentManager.class.getName(), ecm);

        // Initialize the Container fields (request, response, session).
        ExecutionContextManager ecim = Utils.getComponent(ExecutionContextManager.class);
        try {
            ExecutionContext econtext = new ExecutionContext();

            // Bridge with old XWiki Context, required for old code.
            econtext.setProperty("xwikicontext", xcontext);

            ecim.initialize(econtext);
        } catch (ExecutionContextException e) {
            throw new Exception("Failed to initialize Execution Context.", e);
        }

        xcontext.setDatabase(databaseName);
        xcontext.setMainXWiki(databaseName);

        // Use a dummy Request even in daemon mode so that XWiki's initialization can create a Servlet URL Factory.
        xcontext.setRequest(new XWikiServletRequestStub());

        // Use a dummy URL so that XWiki's initialization can create a Servlet URL Factory. We could also have
        // registered a custom XWikiURLFactory against XWikiURLFactoryService but it's more work.
        xcontext.setURL(new URL("http://localhost/xwiki/bin/DummyAction/DumySpace/DummyPage"));

        // Set a dummy Document in the context to act as the current document since when a document containing
        // objects is imported it'll generate Object diff events and the algorithm to compute an object diff
        // currently requires rendering object properties, which requires a current document in the context.
        xcontext.setDoc(new XWikiDocument(new DocumentReference(databaseName, "dummySpace", "dummyPage")));

        XWikiConfig config = new XWikiConfig();
        config.put("xwiki.store.class", "com.xpn.xwiki.store.XWikiHibernateStore");

        // The XWikiConfig object requires path to be in unix format (i.e. with forward slashes)
        String hibernateConfigInUnixFormat = hibernateConfig.getPath().replace('\\', '/');
        config.put("xwiki.store.hibernate.path", hibernateConfigInUnixFormat);

        config.put("xwiki.store.hibernate.updateschema", "1");
        config.put("xwiki.virtual", "1");

        // Enable backlinks so that when documents are imported their backlinks will be saved too
        config.put("xwiki.backlinks", "1");

        new XWiki(config, xcontext, null, true);

        xcontext.setUserReference(new DocumentReference("xwiki", "XWiki", "superadmin"));

        try {
            xcontext.setURLFactory(new XWikiServletURLFactory(new URL("http://localhost:8080"), "xwiki/", "bin/"));
        } catch (MalformedURLException e) {
            // TODO: Remove that way of creating exceptions in XWiki as it's a real plain and
            // doesn't work with external code.
            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS, XWikiException.ERROR_XWIKI_UNKNOWN,
                "Failed to set up URL Factory", e);
        }

        return xcontext;
    }
}

@@ -927,314 +927,8 @@
 p;%0A%0A
-import com.xpn.xwiki.XWikiException;%0Aimport com.xpn.xwiki.XWikiContext;%0Aimport com.xpn.xwiki.XWikiConfig;%0Aimport com.xpn.xwiki.XWiki;%0Aimport com.xpn.xwiki.doc.XWikiDocument;%0Aimport com.xpn.xwiki.web.Utils;%0Aimport com.xpn.xwiki.web.XWikiServletRequestStub;%0Aimport com.xpn.xwiki.web.XWikiServletURLFactory;%0A%0A
 impo
@@ -944,16 +944,16 @@
 o.File;%0A
+
 import j
@@ -1123,44 +1123,8 @@
 er;%0A
-import org.xwiki.context.Execution;%0A
 impo
@@ -1256,32 +1256,32 @@
 ContextManager;%0A
-
 import org.xwiki
@@ -1317,16 +1317,322 @@
 rence;%0A%0A
+import com.xpn.xwiki.XWiki;%0Aimport com.xpn.xwiki.XWikiConfig;%0Aimport com.xpn.xwiki.XWikiContext;%0Aimport com.xpn.xwiki.XWikiException;%0Aimport com.xpn.xwiki.doc.XWikiDocument;%0Aimport com.xpn.xwiki.web.Utils;%0Aimport com.xpn.xwiki.web.XWikiServletRequestStub;%0Aimport com.xpn.xwiki.web.XWikiServletURLFactory;%0A%0A
 /**%0A * C

Fix checkstyle