package org.xwiki.platform.patchservice.storage;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.xwiki.platform.patchservice.api.Patch;
import org.xwiki.platform.patchservice.api.PatchId;
import org.xwiki.platform.patchservice.impl.PatchImpl;

import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.store.XWikiHibernateStore;

public class PatchStorage
{
    public static final String MAPPING_FILENAME = "/Patch.hbm.xml";

    private SessionFactory factory;

    private static final SimpleDateFormat DATE_FORMAT =
        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public PatchStorage(XWikiContext context) throws XWikiException
    {
        init(context);
    }

    private void init(XWikiContext context) throws XWikiException
    {
        XWikiHibernateStore storage = ((XWikiHibernateStore) context.getWiki().getStore());
        Configuration config = storage.getConfiguration();
        try {
            // Make sure the schema is updated to include the Patch mapping
            config.setProperty("hibernate.hbm2ddl.auto", "update");
            factory =
                config.addXML(
                    IOUtils.toString(this.getClass().getResourceAsStream(MAPPING_FILENAME)))
                    .buildSessionFactory();
        } catch (MappingException e) {
            throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
                XWikiException.ERROR_XWIKI_STORE_HIBERNATE_INVALID_MAPPING,
                "Invalid Patch mapping file",
                e);
        } catch (HibernateException e) {
            throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
                XWikiException.ERROR_XWIKI_UNKNOWN,
                "Unknown error initializing the Patch storage",
                e);
        } catch (IOException e) {
            throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
                XWikiException.ERROR_XWIKI_STORE_HIBERNATE_INVALID_MAPPING,
                "Cannot load Patch mapping file",
                e);
        }
    }

    public boolean storePatch(Patch p)
    {
        try {
            Session s = factory.openSession();
            Transaction t = s.beginTransaction();
            s.save(p);
            t.commit();
            s.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public List loadAllPatches()
    {
        return loadPatches("select patch.content from PatchImpl patch");
    }

    public List loadAllDocumentPatches(String documentId)
    {
        return loadPatches("select patch.content from PatchImpl patch where patch.id.documentId = '"
            + documentId + "'");
    }

    public List loadAllDocumentPatchesSince(PatchId id)
    {
        return loadPatches("select patch.content from PatchImpl patch where patch.id.documentId = '"
            + StringEscapeUtils.escapeSql(id.getDocumentId())
            + "' and patch.id.time > '"
            + DATE_FORMAT.format(id.getTime()) + "'");
    }

    public List loadAllPatchesSince(PatchId id)
    {
        return loadPatches("select patch.content from PatchImpl patch where patch.id.time > '"
            + DATE_FORMAT.format(id.getTime()) + "'");
    }

    protected List loadPatches(String query)
    {
        Session s = factory.openSession();
        List contents = s.createQuery(query).list();
        List patches = new ArrayList();
        for (Iterator it = contents.iterator(); it.hasNext();) {
            PatchImpl patch = new PatchImpl();
            patch.setContent(it.next().toString());
            patches.add(patch);
        }
        return patches;
    }
}

@@ -2796,32 +2796,39 @@
 %0A    public List
+%3CPatch%3E
  loadAllPatches(
@@ -2829,16 +2829,16 @@
 tches()%0A
-
     %7B%0A  
@@ -2922,32 +2922,39 @@
 %0A    public List
+%3CPatch%3E
  loadAllDocument
@@ -3134,32 +3134,39 @@
 %0A    public List
+%3CPatch%3E
  loadAllDocument
@@ -3472,24 +3472,31 @@
  public List
+%3CPatch%3E
  loadAllPatc
@@ -3697,16 +3697,23 @@
 ted List
+%3CPatch%3E
  loadPat
@@ -3845,16 +3845,23 @@
     List
+%3CPatch%3E
  patches
@@ -3876,16 +3876,23 @@
 rrayList
+%3CPatch%3E
 ();%0A    

Update code to Java 1.5 syntax