Package de.iritgo.aktera.base.database

Source Code of de.iritgo.aktera.base.database.UpdateHelper

/**
* This file is part of the Iritgo/Aktera Framework.
*
* Copyright (C) 2005-2011 Iritgo Technologies.
* Copyright (C) 2003-2005 BueroByte GbR.
*
* Iritgo licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package de.iritgo.aktera.base.database;


import de.iritgo.aktera.configuration.preferences.KeelPreferencesManager;
import de.iritgo.aktera.event.EventManager;
import de.iritgo.aktera.model.Model;
import de.iritgo.aktera.model.ModelException;
import de.iritgo.aktera.model.ModelRequest;
import de.iritgo.aktera.model.ModelResponse;
import de.iritgo.aktera.model.Output;
import de.iritgo.aktera.persist.ModuleVersion;
import de.iritgo.aktera.persist.PersistenceException;
import de.iritgo.aktera.persist.Persistent;
import de.iritgo.aktera.persist.PersistentFactory;
import de.iritgo.aktera.persist.PersistentMetaData;
import de.iritgo.aktera.persist.UpdateHandler;
import de.iritgo.aktera.spring.SpringTools;
import de.iritgo.aktera.tools.SystemTools;
import de.iritgo.simplelife.process.NullStreamHandler;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.commons.dbutils.DbUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import java.util.Properties;


/**
*
*/
public class UpdateHelper
{
  public static boolean updateChecked = false;

  public static boolean updateNeeded = false;

  synchronized public static boolean needUpdate(ModelRequest req) throws ModelException, ConfigurationException
  {
    if (updateChecked)
    {
      return updateNeeded;
    }

    createVersionTableIfNotExists(req);

    PersistentFactory pf = (PersistentFactory) req.getService(PersistentFactory.ROLE, req.getDomain());

    List<Configuration> moduleConfigs = de.iritgo.aktera.base.module.ModuleInfo
            .moduleConfigsSortedByDependency(req);

    for (Configuration moduleConfig : moduleConfigs)
    {
      String moduleId = moduleConfig.getAttribute("id", "unkown");
      ModuleVersion newVersion = new ModuleVersion(moduleConfig.getChild("version").getValue());

      ModuleVersion currentVersion = new ModuleVersion();

      try
      {
        Persistent version = pf.create("aktera.Version");

        version.setField("type", "M");
        version.setField("name", moduleId);

        if (version.find())
        {
          currentVersion = new ModuleVersion(version.getFieldString("version"));
        }
        else
        {
          currentVersion = new ModuleVersion("0.0.0");
        }
      }
      catch (Exception x)
      {
      }

      if (newVersion.greater(currentVersion))
      {
        updateChecked = true;
        updateNeeded = true;

        return true;
      }
    }

    updateChecked = true;
    updateNeeded = false;

    return false;
  }

  public static void createVersionTableIfNotExists(ModelRequest request) throws ModelException
  {
    PersistentFactory pf = (PersistentFactory) request.getService(PersistentFactory.ROLE, request.getDomain());

    Persistent version = null;

    try
    {
      version = pf.create("aktera.Version");
      version.setField("type", "M");
      version.setField("name", "dummy");
      version.find();
    }
    catch (Exception x)
    {
      try
      {
        PersistentMetaData versionMeta = version.getMetaData();

        versionMeta.getDatabaseType().createTable(versionMeta, versionMeta.getDataSource());
      }
      catch (PersistenceException xx)
      {
        throw new ModelException(xx);
      }
    }
  }

  public static void update(ModelRequest request, ModelResponse response, Logger logger)
    throws ModelException, ServiceException
  {
    Output outModuleList = response.createOutput("modules");

    response.add(outModuleList);

    PersistentFactory pf = (PersistentFactory) request.getService(PersistentFactory.ROLE, request.getDomain());

    DataSourceComponent dataSourceComponent = (DataSourceComponent) request.getService(DataSourceComponent.ROLE,
            "keel-dbpool");

    updatePreProcessing(request, dataSourceComponent);

    boolean needReboot = false;
    boolean newUserPreferences = false;

    List<Configuration> moduleConfigs = de.iritgo.aktera.base.module.ModuleInfo
            .moduleConfigsSortedByDependency(request);

    for (Configuration moduleConfig : moduleConfigs)
    {
      String moduleId = moduleConfig.getAttribute("id", "unkown");
      String moduleName = moduleConfig.getChild("name").getValue("unkown");
      ModuleVersion newVersion = new ModuleVersion(moduleConfig.getChild("version").getValue(null));

      Output outModule = response.createOutput("module_" + moduleConfig.getAttribute("id", "unknown"));

      outModuleList.add(outModule);
      outModule.setAttribute("name", moduleName);
      outModule.setAttribute("description", moduleConfig.getChild("description").getValue(""));
      outModule.setAttribute("newVersion", newVersion.toString());

      ModuleVersion currentVersion = new ModuleVersion();

      try
      {
        Persistent version = pf.create("aktera.Version");

        version.setField("type", "M");
        version.setField("name", moduleId);

        if (version.find())
        {
          currentVersion = new ModuleVersion(version.getFieldString("version"));
        }
        else
        {
          currentVersion = new ModuleVersion("0.0.0");
        }
      }
      catch (Exception x)
      {
        outModule.setAttribute("oldVersion", currentVersion.toString());
        outModule.setAttribute("error", "unableToRetrieveCurrentVersion");
        outModule.setAttribute("errorException", x.toString());

        response.addOutput("updateError", "Y");

        continue;
      }

      outModule.setAttribute("oldVersion", currentVersion.toString());

      String updateHandlerClassName = moduleConfig.getChild("update").getAttribute("class", null);

      if (updateHandlerClassName != null)
      {
        try
        {
          System.out.println("UpdateDatabase: Updating module '" + moduleId + "' with handler '"
                  + updateHandlerClassName + "'");

          Class klass = Class.forName(updateHandlerClassName);

          if (klass != null)
          {
            UpdateHandler updateHandler = (UpdateHandler) klass.newInstance();

            Connection con = null;

            try
            {
              con = dataSourceComponent.getConnection();
              updateHandler.setConnection(con);
              updateHandler.updateDatabase(request, logger, con, pf, (ModuleVersion) currentVersion
                      .clone(), newVersion);
            }
            finally
            {
              con.close();
            }

            needReboot = needReboot || updateHandler.needReboot();
            newUserPreferences = newUserPreferences || updateHandler.hasNewUserPreferences();
          }
          else
          {
            System.out.println("UpdateDatabase: Unable to find update handler for module '" + moduleId
                    + "'");
          }
        }
        catch (ClassNotFoundException x)
        {
          System.out
                  .println("UpdateDatabase: Unable call update handler for module '" + moduleId
                          + "': " + x);
        }
        catch (Exception x)
        {
          outModule.setAttribute("error", "errorDuringUpdate");
          outModule.setAttribute("errorException", x.toString());

          response.addOutput("updateError", "Y");

          continue;
        }
      }

      try
      {
        Persistent version = pf.create("aktera.Version");

        version.setField("type", "M");
        version.setField("name", moduleId);

        if (version.find())
        {
          version.setField("version", newVersion.toString());
          version.update();
        }
        else
        {
          version.setField("version", newVersion.toString());
          version.add();
        }
      }
      catch (Exception x)
      {
        outModule.setAttribute("error", "unableToUpdateVersion");
        outModule.setAttribute("errorException", x.toString());
        response.addOutput("updateError", "Y");
      }
    }

    if (newUserPreferences)
    {
      try
      {
        Persistent sample = pf.create("keel.user");

        for (Persistent user : sample.query())
        {
          KeelPreferencesManager.createDefaultValues(request, user.getFieldInt("uid"));
        }
      }
      catch (PersistenceException x)
      {
        response.addOutput("updateError", "Y");
        response.addOutput("databaseError", x.getMessage());

        StringWriter stw = new StringWriter();
        PrintWriter pw = new PrintWriter(stw);

        x.printStackTrace(pw);
        response.addOutput("databaseErrorStackTrace", stw.getBuffer().toString().replaceAll("\n", "<br>"));
      }
    }

    if (response.get("updateError") == null)
    {
      try
      {
        Model appInfo = (Model) request.getService(Model.ROLE, "aktera.app-info");

        Configuration[] appConfigs = appInfo.getConfiguration().getChildren("app");

        for (int i = 0; i < appConfigs.length; ++i)
        {
          Configuration appConfig = appConfigs[i];

          Persistent version = pf.create("aktera.Version");

          version.setField("type", "A");
          version.setField("name", appConfig.getAttribute("id", "unkown"));

          if (version.find())
          {
            version.setField("version", appConfig.getChild("version").getValue("0.0.0"));
            version.update();
          }
          else
          {
            version.setField("version", appConfig.getChild("version").getValue("0.0.0"));
            version.add();
          }
        }
      }
      catch (Exception x)
      {
        System.out.println(x.toString());
      }
    }

    updatePostProcessing(request, dataSourceComponent);

    if (response.get("updateError") == null)
    {
      updateChecked = false;
      updateNeeded = false;

      if (needReboot)
      {
        response.addOutput("needReboot", "Y");

        try
        {
          new Thread()
          {
            public void run()
            {
              try
              {
                sleep(5000);

                Process proc = SystemTools.startAkteraProcess("/usr/bin/sudo", "/sbin/shutdown -r now");

                new NullStreamHandler(proc.getInputStream());
                new NullStreamHandler(proc.getErrorStream());
              }
              catch (Exception x)
              {
              }
            }
          }.start();
        }
        catch (Exception x)
        {
        }
      }
    }
  }

  private static void updatePreProcessing(ModelRequest request, DataSourceComponent dataSourceComponent)
  {
    Connection connection = null;

    try
    {
      connection = dataSourceComponent.getConnection();
      UpdateHandler handler = new UpdateHandler();
      handler.setConnection(connection);
      handler.update("ALTER TABLE version ALTER COLUMN name TYPE varchar(255)");
      handler.update("UPDATE version set name='iritgo-aktera-address' where name='svc-address' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-aktario' where name='svc-aktario' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-authentication' where name='svc-authentication-persist' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-authorization' where name='svc-authorization-persist' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-base' where name='aktera' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-configuration' where name='svc-configuration' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-crypto-bas64' where name='svc-crypto-base64' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-email' where name='svc-email' and type='M'");
      handler.update("DELETE FROM version where name='svc-mail-javamail' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-event' where name='svc-event' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-fsm' where name='svc-fsm' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-hibernate' where name='svc-persist-hibernate' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-i18n' where name='svc-i18n' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-importer' where name='svc-importer' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-jpassgen' where name='svc-password-jpassgen' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-logger' where name='svc-logger' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-model' where name='svc-model-default' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-permissions' where name='svc-permissions' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-persist-base' where name='svc-persist-base' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-persist-default' where name='svc-persist-default' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-query-jdbc' where name='svc-query-jdbc' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-reporting' where name='svc-reporting' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-scheduler' where name='svc-scheduler' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-script' where name='svc-script' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-spring' where name='svc-spring' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-startup' where name='svc-startup' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-tools' where name='svc-tools' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera-ui' where name='svc-ui' and type='M'");
      handler
              .update("UPDATE version set name='iritgo-aktera-usergroup' where name='svc-usergroup-persist' and type='M'");
      handler.update("UPDATE version set name='iritgo-aktera' where name='iritgo' and type='A'");
      handler.update("UPDATE version set name='system' where name='system' and type='A'");
    }
    catch (Exception x)
    {
      System.out.println("[UpdateHelper.updatePreProcessing] Error: " + x.getMessage());
      x.printStackTrace();
    }
    finally
    {
      DbUtils.closeQuietly(connection);
    }

    EventManager em = (EventManager) SpringTools.getBean(EventManager.ID);
    Properties props = new Properties();

    props.put("request", request);
    props.put("datasource", dataSourceComponent);
    em.fire("aktera.database.update.pre", request, props);
  }

  private static void updatePostProcessing(ModelRequest request, DataSourceComponent dataSourceComponent)
  {
    EventManager em = (EventManager) SpringTools.getBean(EventManager.ID);
    Properties props = new Properties();

    props.put("request", request);
    props.put("datasource", dataSourceComponent);
    em.fire("aktera.database.update.post", request, props);
  }

  public static boolean databaseExists(ModelRequest request)
  {
    Connection connection = null;
    Statement stmt = null;
    ResultSet res = null;

    try
    {
      DataSourceComponent dataSourceComponent = (DataSourceComponent) request.getService(
              DataSourceComponent.ROLE, "keel-dbpool");

      connection = dataSourceComponent.getConnection();
      stmt = connection.createStatement();
      res = stmt
              .executeQuery("SELECT value FROM systemconfig where name = 'databaseCreated' and category = 'system'");

      if (res.next())
      {
        return "true".equals(res.getString("value"));
      }

      return false;
    }
    catch (Exception x)
    {
      System.out.println("[UpdateHelper.databaseExists] Error: " + x.getMessage());
    }
    finally
    {
      DbUtils.closeQuietly(res);
      DbUtils.closeQuietly(stmt);
      DbUtils.closeQuietly(connection);
    }

    return false;
  }
}
TOP

Related Classes of de.iritgo.aktera.base.database.UpdateHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.