/**
 * (C) Copyright 2012 Chiral Behaviors, LLC. All Rights Reserved
 *
 
 * This file is part of Ultrastructure.
 *
 *  Ultrastructure is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  ULtrastructure 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with Ultrastructure.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.chiralbehaviors.CoRE.kernel;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;

import javax.persistence.EntityManager;

import org.hibernate.internal.SessionImpl;

import com.chiralbehaviors.CoRE.workspace.WorkspaceSnapshot;

/**
 * Repository of immutable kernal rules
 *
 * This used to be the standard. Now we use workspaces. However, kernel is a
 * fundamental workspace, and it's needed a lot. Consequently, because of the
 * way we do Java stored procedures, reentrancy requires a new image of the
 * kernel workspace in the context of the entity manager. Sucks to be us.
 *
 * Utilities for the Kernel
 *
 * @author hhildebrand
 *
 */
public class KernelUtil {

    public static final String KERNEL_WORKSPACE_RESOURCE = "/kernel-workspace.2.json";

    public static final String SELECT_TABLE = "SELECT table_schema || '.' || table_name AS name FROM information_schema.tables WHERE table_schema='ruleform' AND table_type='BASE TABLE' ORDER BY table_name";

    public static void clear(EntityManager em) throws SQLException {
        boolean committed = false;
        Connection connection = em.unwrap(SessionImpl.class)
                                  .connection();
        em.getTransaction()
          .begin();
        try {
            connection.setAutoCommit(false);
            ResultSet r = connection.createStatement()
                                    .executeQuery(KernelUtil.SELECT_TABLE);
            while (r.next()) {
                String table = r.getString("name");
                if (!table.equals("ruleform.agency")) {
                    String query = String.format("TRUNCATE TABLE %s CASCADE",
                                                 table);
                    connection.createStatement()
                              .execute(query);
                }
            }
            connection.createStatement()
                      .execute("TRUNCATE TABLE ruleform.agency CASCADE");
            r.close();
            connection.commit();
            em.getTransaction()
              .commit();
            committed = true;
        } finally {
            if (!committed) {
                connection.rollback();
                em.getTransaction()
                  .rollback();
            }
        }
    }

    public static void clearAndLoadKernel(EntityManager em) throws SQLException,
                                                            IOException {
        clear(em);
        loadKernel(em);
    }

    public static void loadKernel(EntityManager em) throws IOException {
        if (!em.getTransaction()
               .isActive()) {
            em.getTransaction()
              .begin();
        }
        WorkspaceSnapshot.load(em,
                               Arrays.asList(KernelUtil.class.getResource(KERNEL_WORKSPACE_RESOURCE)));
        em.getTransaction()
          .commit();
    }
}

@@ -859,32 +859,53 @@
 io.IOException;%0A
+import java.net.URL;%0A
 import java.sql.
@@ -997,16 +997,105 @@
 .Arrays;
+%0Aimport java.util.Collections;%0Aimport java.util.List;%0Aimport java.util.stream.Collectors;
 %0A%0Aimport
@@ -1679,29 +1679,30 @@
 til %7B%0A%0A    p
-ublic
+rivate
  static fina
@@ -1713,16 +1713,18 @@
 ring
+%5B%5D
  KERNEL_
 WORK
@@ -1723,28 +1723,20 @@
 NEL_
-WORKSPACE_RESOURCE =
+VERSIONS = %7B
  %22/k
@@ -1758,16 +1758,66 @@
 .2.json%22
+ %7D;%0A    public static final List%3CURL%3E KERNEL_LOADS
 ;%0A%0A    p
@@ -2019,16 +2019,378 @@
 name%22;%0A%0A
+    static %7B%0A        KERNEL_LOADS = Collections.unmodifiableList(Arrays.asList(KERNEL_VERSIONS)%0A                                                          .stream()%0A                                                          .map(s -%3E KernelUtil.class.getResource(s))%0A                                                          .collect(Collectors.toList()));%0A    %7D%0A%0A
     publ
@@ -4125,110 +4125,21 @@
 (em,
-%0A                               Arrays.asList(KernelUtil.class.getResource(KERNEL_WORKSPACE_RESOURCE))
+ KERNEL_LOADS
 );%0A 

Define versions for kernel loading