private void saveReport(SystemInstallationReport report) throws BeansException {
   if (null == report || report.getReports().isEmpty()) {
     return;
   }
   try {
     InstallationReportDAO dao = new InstallationReportDAO();
     DataSource dataSource = (DataSource) this.getBeanFactory().getBean("portDataSource");
     dao.setDataSource(dataSource);
     dao.saveConfigItem(report.toXml(), this.getConfigVersion());
   } catch (Throwable t) {
     _logger.error("Error saving report", t);
     throw new FatalBeanException("Error saving report", t);
   }
 }
  @Override
  public boolean uninstallComponent(Component component) throws ApsSystemException {
    ServletContext servletContext =
        ((ConfigurableWebApplicationContext) _applicationContext).getServletContext();
    ClassLoader cl = (ClassLoader) servletContext.getAttribute("componentInstallerClassLoader");
    List<ClassPathXmlApplicationContext> ctxList =
        (List<ClassPathXmlApplicationContext>) servletContext.getAttribute("pluginsContextsList");
    ClassPathXmlApplicationContext appCtx = null;
    if (ctxList != null) {
      for (ClassPathXmlApplicationContext ctx : ctxList) {
        if (component.getCode().equals(ctx.getDisplayName())) {
          appCtx = ctx;
        }
      }
    }
    String appRootPath = servletContext.getRealPath("/");
    String backupDirPath =
        appRootPath + "componentinstaller" + File.separator + component.getArtifactId() + "-backup";
    Map<File, File> resourcesMap = new HashMap<File, File>();
    try {
      ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
      try {
        if (cl != null) {
          Thread.currentThread().setContextClassLoader(cl);
        }
        if (null == component || null == component.getUninstallerInfo()) {
          return false;
        }
        this.getDatabaseManager().createBackup(); // backup database
        SystemInstallationReport report = super.extractReport();
        ComponentUninstallerInfo ui = component.getUninstallerInfo();
        // remove records from db
        String[] dataSourceNames = this.extractBeanNames(DataSource.class);
        for (int j = 0; j < dataSourceNames.length; j++) {
          String dataSourceName = dataSourceNames[j];
          Resource resource = (null != ui) ? ui.getSqlResources(dataSourceName) : null;
          String script = (null != resource) ? this.readFile(resource) : null;
          if (null != script && script.trim().length() > 0) {
            DataSource dataSource = (DataSource) this.getBeanFactory().getBean(dataSourceName);
            String[] queries = QueryExtractor.extractDeleteQueries(script);
            TableDataUtils.executeQueries(dataSource, queries, true);
          }
        }
        this.executePostProcesses(ui.getPostProcesses());

        // drop tables
        Map<String, List<String>> tableMapping = component.getTableMapping();
        if (tableMapping != null) {
          for (int j = 0; j < dataSourceNames.length; j++) {
            String dataSourceName = dataSourceNames[j];
            List<String> tableClasses = tableMapping.get(dataSourceName);
            if (null != tableClasses && tableClasses.size() > 0) {
              List<String> newList = new ArrayList<String>();
              newList.addAll(tableClasses);
              Collections.reverse(newList);
              DataSource dataSource = (DataSource) this.getBeanFactory().getBean(dataSourceName);
              IDatabaseManager.DatabaseType type =
                  this.getDatabaseManager().getDatabaseType(dataSource);
              TableFactory tableFactory = new TableFactory(dataSourceName, dataSource, type);
              tableFactory.dropTables(newList);
            }
          }
        }

        // move resources (jar, files and folders) on temp folder
        List<String> resourcesPaths = ui.getResourcesPaths();
        if (resourcesPaths != null) {
          for (String resourcePath : resourcesPaths) {
            try {
              String fullResourcePath = servletContext.getRealPath(resourcePath);
              File resFile = new File(fullResourcePath);
              String relResPath = FilenameUtils.getPath(resFile.getAbsolutePath());
              File newResFile =
                  new File(backupDirPath + File.separator + relResPath + resFile.getName());
              if (resFile.isDirectory()) {
                FileUtils.copyDirectory(resFile, newResFile);
                resourcesMap.put(resFile, newResFile);
                FileUtils.deleteDirectory(resFile);
              } else {
                FileUtils.copyFile(resFile, newResFile);
                resourcesMap.put(resFile, newResFile);
                FileUtils.forceDelete(resFile);
              }
            } catch (Exception e) {
            }
          }
        }

        // upgrade report
        ComponentInstallationReport cir = report.getComponentReport(component.getCode(), true);
        cir.getDataSourceReport()
            .upgradeDatabaseStatus(SystemInstallationReport.Status.UNINSTALLED);
        cir.getDataReport().upgradeDatabaseStatus(SystemInstallationReport.Status.UNINSTALLED);
        this.saveReport(report);

        // remove plugin's xmlapplicationcontext if present
        if (appCtx != null) {
          appCtx.close();
          ctxList.remove(appCtx);
        }
        InitializerManager initializerManager =
            (InitializerManager) _applicationContext.getBean("InitializerManager");
        initializerManager.reloadCurrentReport();
        ComponentManager componentManager =
            (ComponentManager) _applicationContext.getBean("ComponentManager");
        componentManager.refresh();
      } catch (Exception e) {
        _logger.error("Unexpected error in component uninstallation process", e);
        throw new ApsSystemException("Unexpected error in component uninstallation process.", e);
      } finally {
        Thread.currentThread().setContextClassLoader(currentClassLoader);
        ApsWebApplicationUtils.executeSystemRefresh(servletContext);
      }
    } catch (Throwable t) {
      // restore files on temp folder
      try {
        for (Object object : resourcesMap.entrySet()) {
          File resFile = ((Map.Entry<File, File>) object).getKey();
          File newResFile = ((Map.Entry<File, File>) object).getValue();
          if (newResFile.isDirectory()) {
            FileUtils.copyDirectoryToDirectory(newResFile, resFile.getParentFile());
          } else {
            FileUtils.copyFile(newResFile, resFile.getParentFile());
          }
        }
      } catch (Exception e) {
      }
      _logger.error("Unexpected error in component uninstallation process", t);
      throw new ApsSystemException("Unexpected error in component uninstallation process.", t);
    } finally {
      // clean temp folder
    }
    return true;
  }