Package com.dotmarketing.util

Source Code of com.dotmarketing.util.MaintenanceUtil

package com.dotmarketing.util;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.dotcms.repackage.net.sf.hibernate.HibernateException;

import com.dotcms.repackage.org.apache.commons.io.FileUtils;

import com.dotmarketing.beans.Inode;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.CacheLocator;
import com.dotmarketing.business.DotCacheAdministrator;
import com.dotmarketing.cache.FieldsCache;
import com.dotmarketing.common.db.DotConnect;
import com.dotmarketing.db.DbConnectionFactory;
import com.dotmarketing.db.HibernateUtil;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.portlets.files.business.FileAPI;
import com.dotmarketing.portlets.structure.factories.StructureFactory;
import com.dotmarketing.portlets.structure.model.Field;
import com.dotmarketing.portlets.structure.model.Structure;
import com.liferay.util.FileUtil;

public class MaintenanceUtil {

  private static final FileAPI fileAPI = APILocator.getFileAPI();

  /**
   * Use to delete the velocity static store
   */
  public static void deleteStaticFileStore(){
    deleteStaticFileStore(false);
    deleteStaticFileStore(true);
  }

  /**
   * Use to delete the velocity static store either working or live
   * @param live
   */
  public static void deleteStaticFileStore(boolean live){
    String realPath = "";

    String velocityRootPath = ConfigUtils.getDynamicVelocityPath();

    if(live){
      realPath = velocityRootPath + File.separator + "live";
    }
    else{
      realPath = velocityRootPath + File.separator + "working";
    }
    File file = new File(realPath);
    if (file.isDirectory())  {
      FileUtil.deltree(file, false);
      Logger.debug(MaintenanceUtil.class,"The directory " + realPath + " has been deleted");
    }else{
      Logger.error(MaintenanceUtil.class,file.getPath() + " is not a directory");
    }
  }

  public static void deleteMenuCache(){
    String velocityRootPath =ConfigUtils.getDynamicVelocityPath();
    File file = new File(velocityRootPath + File.separator + "menus");
    if (file.isDirectory())  {
      FileUtil.deltree(file, false);
      Logger.debug(MaintenanceUtil.class,"The directory " + file.getPath() + " has been deleted");
    }else{
      Logger.error(MaintenanceUtil.class,file.getPath() + " is not a directory");
    }
    CacheLocator.getNavToolCache().clearCache();
  }


  public static int cleanMultiTreeTable(){
    final String countSQL = "select count(*) as count from multi_tree t";
    final String deleteChildFromSQL ="delete from multi_tree where child not in (select i.id from identifier i)";
    final String deleteParent1FromSQL ="delete from multi_tree where parent1 not in (select i.id from identifier i)";
    final String deleteParent2FromSQL ="delete from multi_tree where parent2 not in (select i.id from identifier i)";
    DotConnect dc = new DotConnect();
    dc.setSQL(countSQL);
    List<HashMap<String, String>> result=null;
    int before = 0;
    try {
      result = dc.getResults();
      before = Integer.parseInt(result.get(0).get("count"));
      dc.setSQL(deleteChildFromSQL);
      dc.getResult();
      dc.setSQL(deleteParent1FromSQL);
      dc.getResult();
      dc.setSQL(deleteParent2FromSQL);
      dc.getResult();
      dc.setSQL(countSQL);
      result = dc.getResults();
    } catch (Exception e) {
      Logger.error(MaintenanceUtil.class, e.getMessage(), e);
    }
    int after = Integer.parseInt(result.get(0).get("count"));
    return before - after;
  }

  public static int deleteAllAssetsWithNoIdentifier(){
    int count = 0;
    count += deleteContentletsWithNoIdentifier();
    count += deleteContainersWithNoIdentifier();
    count += deleteLinksWithNoIdentifier();
    count += deleteHTMLPagesWithNoIdentifier();
    count += deleteTemplatesWithNoIdentifier();
    count += deleteFileAssetsWithNoIdentifier();
    return count;
  }

  public static void cleanInodeTableData()throws DotDataException{
    Map map = new HashMap();
    try {
      map = HibernateUtil.getSession().getSessionFactory().getAllClassMetadata();
    } catch (HibernateException e) {
      throw new DotDataException(e.getMessage(),e);
    }
    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry pairs = (Map.Entry) it.next();
      Class x = (Class) pairs.getKey();
      if (!x.equals(Inode.class)){
        Object o;
        try {
          o = x.newInstance();
        } catch (Exception e) {
          Logger.info(MaintenanceUtil.class, "Unable to instaniate object");
          Logger.debug(MaintenanceUtil.class,"Unable to instaniate object", e);
          continue;
        }
        if(o instanceof Inode){
          Inode i = (Inode)o;
          String type = i.getType();
          String tableName = ((com.dotcms.repackage.net.sf.hibernate.persister.AbstractEntityPersister)map.get(x)).getTableName();
          cleanInodeTableData(tableName, type);
        }
      }
    }
    it = map.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry pairs = (Map.Entry) it.next();
      Class x = (Class) pairs.getKey();
      if (!x.equals(Inode.class)){
        Object o;
        try {
          o = x.newInstance();
        } catch (Exception e) {
          Logger.info(MaintenanceUtil.class,"Unable to instaniate object");
          Logger.debug(MaintenanceUtil.class,"Unable to instaniate object", e);
          continue;
        }
        if(o instanceof Inode){
          Inode i = (Inode)o;
          String type = i.getType();
          String tableName = ((com.dotcms.repackage.net.sf.hibernate.persister.AbstractEntityPersister)map.get(x)).getTableName();
          removeOphanedInodes(tableName, type);
        }
      }
    }
  }

  /**
   * Will update inode type column in db
   * @return
   */
  public static void cleanInodeTableData(String tableName, String inodeType){
    String sql = "update inode set type = ? where inode in " +
           "(select inode from " + tableName + ") and type <> ?";
    String inodesToDeleteSql = "select inode from inode where type = ? and inode not in " +
                  "(select inode from " + tableName + ")";
    String deleteSQL = "delete from inode where type = ? and inode not in " +
              "(select inode from " + tableName + ")";
    DotConnect dc = new DotConnect();
    dc.setSQL(sql);
    dc.addParam(inodeType);
    dc.addParam(inodeType);
    dc.getResult();
  }

  protected static int cleanPermissionReferences(List<String> inodes, int offset) {
    final String BASE_DELETE_ASSETID="delete from permission where inode_id in (";
    DotConnect dc = new DotConnect();
    StringBuffer deletePermissionAssetConSQL = new StringBuffer(BASE_DELETE_ASSETID);
    int i = 0;
    List<String> inodesAux =  new ArrayList<String>();
    boolean first = true;
    for (String inode : inodes) {
      inodesAux.add(inode);
      if(!first){
        deletePermissionAssetConSQL.append("," +"'"+ inode+"'");
      }else{
        deletePermissionAssetConSQL.append("'"+inode+"'");
      }
      first = false;
       if((i % offset) == 0 && i != 0)
       {
         deletePermissionAssetConSQL.append(")");
         dc.setSQL(deletePermissionAssetConSQL.toString());
         dc.getResult();
         deletePermissionAssetConSQL  = new StringBuffer(BASE_DELETE_ASSETID);
         inodesAux.clear();
         first = true;
       }
       i++;
    }


    if(!(inodes.size() % offset == 0) && inodesAux.size()>0)
    {
      deletePermissionAssetConSQL.append(")");
      dc.setSQL(deletePermissionAssetConSQL.toString());
      dc.getResult();
    }
    return 0;
  }
 
  /**
   * Will update inode type column in db
   * @return
   */
  public static void removeOphanedInodes(String tableName, String inodeType){
    String inodesToDeleteSql = "select inode from inode where type = ? and inode not in " +
                  "(select inode from " + tableName + ")";
    String deleteSQL = "delete from inode where type = ? and inode not in " +
              "(select inode from " + tableName + ")";
    DotConnect dc = new DotConnect();

    dc.setSQL(inodesToDeleteSql);
    dc.addParam(inodeType);
    List<HashMap<String, String>> results =null;
    try {
      results = dc.getResults();
    } catch (DotDataException e) {
      Logger.error(MaintenanceUtil.class,e.getMessage(), e);
    }
    List<String> inodesToDelete = new ArrayList<String>();
    for (HashMap<String, String> r : results) {
      inodesToDelete.add(r.get("inode"));
    }

    cleanInodesFromTree(inodesToDelete, 500);
    cleanPermissionReferences(inodesToDelete, 500);

    dc.setSQL(deleteSQL);
    dc.addParam(inodeType);
    if(tableName.contains("event")){
      Logger.info(MaintenanceUtil.class,inodeType);
    }
    dc.getResult();
  }

  /**
   * Delete from db all content with no identifier.  It will try to update identifiers from tree table first though
   */
  public static int deleteContentletsWithNoIdentifier(){
    return deleteAssetsWithNoIdentifier("contentlet");
  }

  /**
   * Delete from db all content with no identifier.  It will try to update identifiers from tree table first though
   */
  public static int deleteContainersWithNoIdentifier(){
    return deleteAssetsWithNoIdentifier("containers");
  }

  /**
   * Delete from db all content with no identifier.  It will try to update identifiers from tree table first though
   */
  public static int deleteFileAssetsWithNoIdentifier(){
    return deleteAssetsWithNoIdentifier("file_asset");
  }

  /**
   * Delete from db all content with no identifier.  It will try to update identifiers from tree table first though
   */
  public static int deleteHTMLPagesWithNoIdentifier(){
    return deleteAssetsWithNoIdentifier("htmlpage");
  }

  /**
   * Delete from db all content with no identifier.  It will try to update identifiers from tree table first though
   */
  public static int deleteLinksWithNoIdentifier(){
    return deleteAssetsWithNoIdentifier("links");
  }

  /**
   * Delete from db all content with no identifier.  It will try to update identifiers from tree table first though
   */
  public static int deleteTemplatesWithNoIdentifier(){
    return deleteAssetsWithNoIdentifier("template");
  }

  /**
   * Will delete all content where the structure =0 or the structure doesn't exist
   */
  public static int deleteContentletsWithNoStructure(){
    final String countSQL = "select count(*) as count from contentlet t";
    String selectSQL = "select inode from contentlet where structure_inode not in (select inode from structure)";
    DotConnect dc = new DotConnect();
    dc.setSQL(countSQL);
    List<HashMap<String, String>> result =null;
    int before = 0;
    try {
      result = dc.getResults();
      before = Integer.parseInt(result.get(0).get("count"));
      dc.setSQL(selectSQL);
      List<HashMap<String, String>> results =  dc.getResults();
      List<String> inodesToClean = new ArrayList<String>();
      boolean runDelete = false;
      for (HashMap<String, String> r : results) {
        inodesToClean.add(r.get("inode"));
        runDelete = true;
      }
      if(runDelete){
        deleteAssets(inodesToClean, "contentlet", 500);
      }
      dc.setSQL(countSQL);
      result = dc.getResults();
    } catch (Exception e) {
      Logger.error(MaintenanceUtil.class,e.getMessage(), e);
    }
    int after = Integer.parseInt(result.get(0).get("count"));
    return before - after;
  }

  public static void flushCache(){
    DotCacheAdministrator cache = CacheLocator.getCacheAdministrator();
    cache.flushAll();
  }

  public static void deleteAssets(List<String> inodes, String tableName, int offset){
    if(inodes == null || inodes.size() < 1){
      return;
    }
    DotConnect dc = new DotConnect();
    StringBuffer deleteInodeSQL = new StringBuffer("delete from inode where inode in (");
    StringBuffer deleteConSQL = new StringBuffer("delete from " + tableName + " where inode in (");
    List<String> inodesAux =  new ArrayList<String>();
    int i = 0;
    boolean first = true;
    for (String inode : inodes) {
      inodesAux.add(inode);
      if(!first){
        deleteInodeSQL.append("," +"'"+ inode+"'");
        deleteConSQL.append("," + "'"+inode+"'");
      }else{
        deleteInodeSQL.append("'"+inode+ "'");
        deleteConSQL.append("'"+inode+ "'");
      }
      first = false;

     if((i % offset) == 0 && i != 0)
     {
       deleteInodeSQL.append(")");
       deleteConSQL.append(")");
       dc.setSQL(deleteConSQL.toString());
       dc.getResult();
       cleanInodesFromTree(inodes, offset);
       dc.setSQL(deleteInodeSQL.toString());
       dc.getResult();
       deleteInodeSQL = new StringBuffer("delete from inode where inode in (");
       deleteConSQL = new StringBuffer("delete from " + tableName + " where inode in (");
       inodesAux.clear();
       first = true;
     }
     i++;

    }
    if(!(inodes.size() % offset == 0) && inodesAux.size()>0)
    {
      deleteInodeSQL.append(")");
      deleteConSQL.append(")");
      dc.setSQL(deleteConSQL.toString());
      dc.getResult();
      cleanInodesFromTree(inodes, offset);
      dc.setSQL(deleteInodeSQL.toString());
      dc.getResult();
    }
  }

  /**
   * Use to delete rows from tree containing a collection of inodes.
   * Usually need to use this to delete tree records because of the foreign key to inode
   * @param inodes
   */
  public static void cleanInodesFromTree(List<String> inodes, int offset){
    DotConnect dc = new DotConnect();
    StringBuffer deleteTreeChildConSQL = new StringBuffer("delete from tree where child in (");
    StringBuffer deleteTreeParentConSQL = new StringBuffer("delete from tree where parent in (");
    int i = 0;
    List<String> inodesAux =  new ArrayList<String>();
    boolean first = true;
    for (String inode : inodes) {
      inodesAux.add(inode);
      if(!first){
        deleteTreeChildConSQL.append("," +"'"+ inode+"'");
        deleteTreeParentConSQL.append("," +"'"+inode+"'");
      }else{
        deleteTreeChildConSQL.append("'"+inode+"'");
        deleteTreeParentConSQL.append("'"+inode+"'");
      }
      first = false;
       if((i % offset) == 0 && i != 0)
       {
         deleteTreeChildConSQL.append(")");
         deleteTreeParentConSQL.append(")");
         dc.setSQL(deleteTreeChildConSQL.toString());
         dc.getResult();
         dc.setSQL(deleteTreeParentConSQL.toString());
         dc.getResult();
         deleteTreeChildConSQL  = new StringBuffer("delete from tree where child in (");
         deleteTreeParentConSQL = new StringBuffer("delete from tree where parent in (");
         inodesAux.clear();
         first = true;
       }
       i++;
    }


    if(!(inodes.size() % offset == 0) && inodesAux.size()>0)
    {
      deleteTreeChildConSQL.append(")");
      deleteTreeParentConSQL.append(")");
      dc.setSQL(deleteTreeChildConSQL.toString());
      dc.getResult();
      dc.setSQL(deleteTreeParentConSQL.toString());
      dc.getResult();
    }
  }

  /**
   * Will replace text in the DB within the following com.dotcms.repackage.jruby.tables.
   * NOTE: This is intended to replace code so we only go after columns/tables that could have HTML or Velocity code in them.
   * Contentlet - text and text_area columns
   * Containers - code,pre_loop and post_loop
   * Template - body
   * Field - field_values for the widget code
   * Link - url
   *
   * @param textToSearchFor - Cannot be NULL or Empty String
   * @param textToReplaceWith - Cannot be NULL
   *
   * @return boolean if the method found errors.  It will catch DB errors so that the replace will run everywhere it can.
   */
  public static boolean DBSearchAndReplace(String textToSearchFor, String textToReplaceWith){
    boolean hasErros = false;
    if(!UtilMethods.isSet(textToSearchFor)){
      Logger.info(MaintenanceUtil.class, "Returning because text to search for is null or empty");
    }
    if(textToReplaceWith == null){
      Logger.info(MaintenanceUtil.class, "Returning because text to replace is null");
    }
    DotConnect dc = new DotConnect();
    Logger.info(MaintenanceUtil.class, "ABOUT TO UPDATE COLUMNS text[1-25] ON THE CONTENTLET TABLE");
    int count = 1;   
    StringBuilder SQL = new StringBuilder("UPDATE contentlet SET ");
    while(count<26){
      if(count>1){
        SQL.append(",");
      }
      if(DbConnectionFactory.isMsSql()){
        SQL.append("text" + count + " = replace(cast(text" + count + " as varchar(max)),?,?)");
      }else{
        SQL.append("text" + count + " = replace(text" + count + ",?,?)");
      }
      count++;
    }

    dc.setSQL(SQL.toString() + " WHERE contentlet.inode = (SELECT working_inode FROM contentlet_version_info cvi WHERE (cvi.working_inode = contentlet.inode OR cvi.live_inode =contentlet.inode)) ");
    count = 1;
    while(count<26){
      dc.addParam(textToSearchFor);
      dc.addParam(textToReplaceWith);
      count++;
    }
    try{
      dc.loadResult();
    } catch (DotDataException e) {
      hasErros = true;
      Logger.error(MaintenanceUtil.class,"Problem updating contentlet table : " + e.getMessage(),e);
    }

    Logger.info(MaintenanceUtil.class, "ABOUT TO UPDATE COLUMNS text_area[1-25] ON THE CONTENTLET TABLE");
    count = 1;
    SQL = new StringBuilder("UPDATE contentlet SET ");
    while(count<26){
      if(count>1){
        SQL.append(",");
      }
      if(DbConnectionFactory.isMsSql()){
        SQL.append("text_area" + count + " = replace(cast(text_area" + count + " as varchar(max)),?,?)");
      }else{
        SQL.append("text_area" + count + " = replace(text_area" + count + ",?,?)");
      }
      count++;
    }

    dc.setSQL(SQL.toString() + "WHERE contentlet.inode = (SELECT working_inode FROM contentlet_version_info cvi WHERE (cvi.working_inode = contentlet.inode OR cvi.live_inode =contentlet.inode)) ");
    count = 1;
    while(count<26){
      dc.addParam(textToSearchFor);
      dc.addParam(textToReplaceWith);
      count++;
    }
    try{
      dc.loadResult();
    } catch (DotDataException e) {
      hasErros = true;
      Logger.error(MaintenanceUtil.class,"Problem updating contentlet table : " + e.getMessage(),e);
    }
    Logger.info(MaintenanceUtil.class, "ABOUT TO UPDATE COLUMNS code, pre_loop, and post_loop ON THE containers TABLE");
    if(DbConnectionFactory.isMsSql()){
      dc.setSQL("UPDATE containers SET code=replace(cast(code as varchar(max)),?,?),pre_loop=replace(cast(pre_loop as varchar(max)),?,?),post_loop=replace(cast(post_loop as varchar(max)),?,?) WHERE containers.inode = (SELECT working_inode FROM container_version_info cvi WHERE (cvi.working_inode = containers.inode OR cvi.live_inode =containers.inode)) ");
    }else{
      dc.setSQL("UPDATE containers SET code=replace(code,?,?),pre_loop=replace(pre_loop,?,?),post_loop=replace(post_loop,?,?) WHERE containers.inode = (SELECT working_inode FROM container_version_info cvi WHERE (cvi.working_inode = containers.inode OR cvi.live_inode =containers.inode)) ");
    }
    dc.addParam(textToSearchFor);
    dc.addParam(textToReplaceWith);
    dc.addParam(textToSearchFor);
    dc.addParam(textToReplaceWith);
    dc.addParam(textToSearchFor);
    dc.addParam(textToReplaceWith);
    try{
      dc.loadResult();
    } catch (DotDataException e) {
      hasErros = true;
      Logger.error(MaintenanceUtil.class,"Problem updating containers table : " + e.getMessage(),e);
    }
    Logger.info(MaintenanceUtil.class, "ABOUT TO UPDATE body COLUMN ON THE template TABLE");
    if(DbConnectionFactory.isMsSql()){
      dc.setSQL("UPDATE template SET body=replace(cast(body as varchar(max)),?,?) WHERE template.inode = (SELECT working_inode FROM template_version_info tvi WHERE (tvi.working_inode = template.inode OR tvi.live_inode = template.inode)) ");
    }else{
      dc.setSQL("UPDATE template SET body=replace(body,?,?) WHERE template.inode = (SELECT working_inode FROM template_version_info tvi WHERE (tvi.working_inode = template.inode OR tvi.live_inode = template.inode)) ");
    }
    dc.addParam(textToSearchFor);
    dc.addParam(textToReplaceWith);
    try{
      dc.loadResult();
    } catch (DotDataException e) {
      hasErros = true;
      Logger.error(MaintenanceUtil.class,"Problem updating template table : " + e.getMessage(),e);
    }
    Logger.info(MaintenanceUtil.class, "ABOUT TO UPDATE field_values COLUMN ON THE field TABLE");
    if(DbConnectionFactory.isMsSql()){
      dc.setSQL("UPDATE field SET field_values=replace(cast(field_values as varchar(max)),?,?)");
    }else{
      dc.setSQL("UPDATE field SET field_values=replace(field_values,?,?)");
    }
    dc.addParam(textToSearchFor);
    dc.addParam(textToReplaceWith);
    try{
      dc.loadResult();
    } catch (DotDataException e) {
      hasErros = true;
      Logger.error(MaintenanceUtil.class,"Problem updating field table : " + e.getMessage(),e);
    }
    Logger.info(MaintenanceUtil.class, "ABOUT TO UPDATE url COLUMN ON THE links TABLE");
    if(DbConnectionFactory.isMsSql()){
      dc.setSQL("UPDATE links SET url=replace(cast(url as varchar(max)),?,?) WHERE links.inode = (SELECT working_inode FROM link_version_info lvi WHERE (lvi.working_inode = links.inode OR lvi.live_inode = links.inode)) ");
    }else{
      dc.setSQL("UPDATE links SET url=replace(url,?,?) WHERE links.inode = (SELECT working_inode FROM link_version_info lvi WHERE (lvi.working_inode = links.inode OR lvi.live_inode = links.inode)) ");
    }
    dc.addParam(textToSearchFor);
    dc.addParam(textToReplaceWith);
    try{
      dc.loadResult();
    } catch (DotDataException e) {
      hasErros = true;
      Logger.error(MaintenanceUtil.class,"Problem updating links table : " + e.getMessage(),e);
    }
    Logger.info(MaintenanceUtil.class, "Finished Updating DB");
    return hasErros;
  }

  /**
   * Will find all working/live Text in the DB and Search/Replace them. so the mimetype in db would need to be text/...
   * @param textToSearchFor
   * @param textToReplaceWith
   * @return boolean if there is an error found while running
   */
  public static boolean textAssetsSearchAndReplace(String textToSearchFor, String textToReplaceWith){
    return fileAssetSearchAndReplace(textToSearchFor, textToReplaceWith, "text");
  }

  /**
   * Will find all working/live VTLs in the DB and Search/Replace them
   * @param textToSearchFor
   * @param textToReplaceWith
   * @return boolean if there is an error found while running
   */
  public static boolean VTLSearchAndReplace(String textToSearchFor, String textToReplaceWith){
    return fileAssetSearchAndReplace(textToSearchFor, textToReplaceWith, "text/velocity");
  }

  /**
   * Will pull only working/live from the DB to search/replace on the FS
   * @param textToSearchFor
   * @param textToReplaceWith
   * @param mimeTypesOfFile Will search for things like text/Velocity in the DB. It will put a % after what you pass so text would pass text% in the like to the DB
   * @return
   */
  private static boolean fileAssetSearchAndReplace(String textToSearchFor, String textToReplaceWith,String mimeTypesOfFile){
    Logger.info(MaintenanceUtil.class, "Starting Search and Replace");
    boolean hasErrors = false;
    DotConnect dc = new DotConnect();
    dc.setSQL("SELECT inode,file_name FROM file_asset fa, fileasset_version_info fvi WHERE mime_type LIKE '"+ mimeTypesOfFile +"%' AND (fa.inode = fvi.working_inode OR fa.inode = fvi.live_inode)");
    List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
    try {
      results = dc.loadResults();
    } catch (DotDataException e) {
      Logger.error(MaintenanceUtil.class,"Unable to pull files from DB to search for on filesystem : " + e.getMessage(),e);
      hasErrors = true;
      Logger.info(MaintenanceUtil.class, "Finished Search and Replace With Errors");
      return true;
    }
    File f = null;
    String s = null;
    for (Map<String,Object> result : results) {
      if(!UtilMethods.isSet(result.get("inode").toString())){
        hasErrors = true;
        Logger.error(MaintenanceUtil.class, "Empty or null file inode found");
        continue;
      }
      try{
        f = new File(fileAPI.getRealAssetPath(result.get("inode").toString(), UtilMethods.getFileExtension(result.get("file_name").toString())));
      }catch (Exception e) {
        hasErrors = true;
        Logger.error(MaintenanceUtil.class, "Unable to load the file with inode " + result.get("inode").toString() + " : " + e.getMessage(),e);
        f=null;
        continue;
      }
      if(!f.exists() || f.length() > 1310712000){
        hasErrors = true;
        Logger.error(MaintenanceUtil.class, "Unable to load the file with inode " + result.get("inode").toString());
        f=null;
        continue;
      }
      try{
        s = FileUtils.readFileToString(f,"UTF-8");
        s = s.replace(textToSearchFor, textToReplaceWith);
        FileUtils.writeStringToFile(f, s,"UTF-8");
      }catch (Exception e) {
        hasErrors = true;
        Logger.error(MaintenanceUtil.class, "Unable to replace file contents for " + f.getPath());
      }
      s = null;
      f = null;
    }
    Logger.info(MaintenanceUtil.class, "Finished Search and Replace");
    return hasErrors;
  }

  /**
   * Delete from db all content with no identifier.  It will try to update identifiers from tree table first though
   */
  private static int deleteAssetsWithNoIdentifier(String tableNameOfAsset){
    final String countSQL = "select count(*) as count from " + tableNameOfAsset + " t";
    final String selectNullIdentsSQL = "select inode from " + tableNameOfAsset + " where identifier IS NULL";

    DotConnect dc = new DotConnect();
    dc.setSQL(countSQL);
    List<HashMap<String, String>> result =null;
    int before = 0;
    try {
      result = dc.getResults();
      before = Integer.parseInt(result.get(0).get("count"));
      dc.setSQL(selectNullIdentsSQL);
      List<HashMap<String, String>> results = dc.getResults();
      List<String> inodesToClean = new ArrayList<String>();
      boolean runDelete = false;
      for (HashMap<String, String> r : results) {
        inodesToClean.add(r.get("inode"));
        runDelete = true;
      }
      if(runDelete){
        deleteAssets(inodesToClean, tableNameOfAsset,500);
      }
      dc.setSQL(countSQL);
      result = dc.getResults();
    } catch (Exception e) {
      Logger.error(MaintenanceUtil.class, e.getMessage(), e);
    }
    int after = Integer.parseInt(result.get(0).get("count"));
    return before - after;
  }


  /**
   *
   * @param folder This is the folder where the assets are stored
   * @param fileAssetsList This is the list of all the file assets
   * @return
   */
  private static List<String> findFileAssetsList(File folder, List<String> fileAssetsList){
    File[] files = folder.listFiles();
    if (0 < files.length) {
      List<Structure> structures = StructureFactory.getStructures();
      List<Field> binaryFields = new ArrayList<Field>();
      List<Field> fields;
      for (Structure structure: structures) {
        fields = FieldsCache.getFieldsByStructureInode(structure.getInode());

        for (Field field: fields) {
          if (field.getFieldType().equals(Field.FieldType.BINARY.toString()))
            binaryFields.add(field);
        }
      }

      boolean isBinaryField;
          for(int j = 0; j < files.length; j++) {
              fileAssetsList.add(files[j].getPath());
              if(files[j].isDirectory()) {

                isBinaryField = false;
                for (Field field: binaryFields) {
                  if (field.getVelocityVarName().equals(files[j].getName())) {
                    isBinaryField = true;
                    break;
                  }
                }

                if (!isBinaryField)
                  findFileAssetsList(files[j], fileAssetsList);
              }
          }
    }
        return fileAssetsList;
  }

  public static void fixImagesTable() throws SQLException{
    DotConnect dc = new DotConnect();
    List<String> imageIds = new ArrayList<String>();
    final String selectImageIdsSQL = "select i.imageid from image i";
    String deleteImageSQL = "delete from image where imageid like '' or imageid is null";
    dc.setSQL(selectImageIdsSQL);
    List<HashMap<String, String>> results =null;
    try {
      results = dc.getResults();
    } catch (DotDataException e) {
      Logger.error(MaintenanceUtil.class,e.getMessage(), e);
    }
    for(HashMap<String, String> r : results){
      imageIds.add(r.get("imageid").toString());
    }

    for(int i = 0; i < imageIds.size(); i++){
      if(!UtilMethods.isSet(imageIds.get(i))){
        dc.setSQL(deleteImageSQL);
        dc.getResult();
      }

    }
  }

}
TOP

Related Classes of com.dotmarketing.util.MaintenanceUtil

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.