FileArchivatorKit.java
package sk.iway.iwcm.components.file_archiv;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.digest.DigestUtils;
import sk.iway.iwcm.Adminlog;
import sk.iway.iwcm.Cache;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.DB;
import sk.iway.iwcm.FileTools;
import sk.iway.iwcm.Identity;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.PkeyGenerator;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.common.CloudToolsForCore;
import sk.iway.iwcm.common.DocTools;
import sk.iway.iwcm.database.SimpleQuery;
import sk.iway.iwcm.helpers.BeanDiff;
import sk.iway.iwcm.helpers.BeanDiffPrinter;
import sk.iway.iwcm.i18n.Prop;
import sk.iway.iwcm.io.IwcmFile;
import sk.iway.iwcm.io.IwcmInputStream;
import sk.iway.iwcm.system.cluster.ClusterDB;
import sk.iway.iwcm.users.UserDetails;
import sk.iway.iwcm.users.UsersDB;
/**
* FileArchivatorKit.java
*
*
* Title webjet7
* Company Interway s.r.o. (www.interway.sk)
* Copyright Interway s.r.o. (c) 2001-2015
* @author $Author: jeeff $(prau)
* @version Revision: 1.3 11.2.2015
* created Date: 11.2.2015 14:40:05
* modified Date: 11.2.2015 14:40:05
* Ticket Number: #17263
*/
public class FileArchivatorKit
{
private Prop prop = Prop.getInstance();
private List<String> errorsList;
public FileArchivatorKit(Prop paramProp)
{
if(paramProp != null)
{
prop = paramProp;
}
}
/** Skontroluje ci je modul File Archiv povoleny pre aktualneho usera
*
*/
public static boolean isArchivEnabled(HttpServletRequest request)
{
return isArchivEnabled(UsersDB.getCurrentUser(request));
}
/** Skontroluje ci je modul File Archiv povoleny pre usera
*
* @param userIdentity Identity
*/
public static boolean isArchivEnabled(Identity userIdentity)
{
return userIdentity != null && userIdentity.isEnabledItem("cmp_file_archiv");
}
public static String getArchivPath()
{
//robi lokalne problem pri zapnutej konf. premennej "enableStaticFilesExternalDir"
String defaultArchivPath = "files/archiv/";
if(Tools.isEmpty(Constants.getString("fileArchivDefaultDirPath")))
return defaultArchivPath;
return Constants.getString("fileArchivDefaultDirPath");
}
public static String getInsertLaterPath()
{
String defaultInsertLaterPath = "files/archiv_insert_later/";
if(Tools.isEmpty(Constants.getString("fileArchivInsertLaterDirPath")))
return defaultInsertLaterPath;
return Constants.getString("fileArchivInsertLaterDirPath");
}
public static String getFullInsertLaterPath()
{
return getArchivPath() + getInsertLaterPath();
}
/** Vrati unikatne meno suboru
*
* @param file - subor
* @param directoryPath - cesta k suboru
* @param preferredDate - null / preferovany datum
*/
public static String getUniqueFileName(String fileNameParam, String directoryPath, String preferredDate)
{
String dirPath = directoryPath;
if(Tools.isAnyEmpty(fileNameParam, dirPath) == false)
{
if(!dirPath.endsWith("/"))
dirPath += "/";
String ext = DB.internationalToEnglish(FileTools.getFileExtension(fileNameParam));
if(Tools.isNotEmpty(ext)) ext = "."+ext;
String fileName = DocTools.removeChars(FileTools.getFileNameWithoutExtension(fileNameParam), false);
int version = 0;
int loopSafe = 10000;
String str_version;
String dateStamp = "";
//funkcia nebola ziadana
if(Constants.getBoolean(FileArchivatorDB.getConstantsPrefix()+"CreateFileDateStamp"))
{
dateStamp = getDateStampAsString();
if(Tools.isNotEmpty(preferredDate))
dateStamp = preferredDate;
}
String fullFileName = fileName+ext;
if(FileTools.isFile(dirPath+fullFileName))
{
do
{
version++;
str_version = version+"";
fullFileName = fileName+"_v_"+str_version+dateStamp+ext;
}while( FileTools.isFile(dirPath+fullFileName) && version < loopSafe);
return fullFileName;
}
return fileName+ext;
}
return null;
}
/** vytvori bean pre novy subor, upravi referenciu (referenceId) u starych suborov
*
* @return true ak vsetko prebehlo v poriadku
*/
public static boolean setFilePropertiesAfterUpload(FileArchivatorBean newFab, int oldId, boolean uploadLater, HttpServletRequest req)
{
boolean result = true;
//pri nahravani neskor existenciu kontrolujeme skor kvoli multidomain
if(uploadLater == false && !FileTools.isFile(newFab.getFilePath()+newFab.getFileName()))
{
return false;
}
newFab.setDomainId(CloudToolsForCore.getDomainId());
//always set referenceId, if provided. For main file it will be fixed in reSetReference method.
newFab.setReferenceId(oldId);
if(!newFab.save())
{
Logger.debug(FileArchivatorKit.class, " new FileArchivatorBean(...) !newFab.save() "+newFab.toString());
return false;
}
boolean newVersion = false;
//ak uz existuje nejaka starsia verzia naseho suboru
if(oldId > 0)
{
newVersion = true;
FileArchivatorBean oldFab = FileArchivatorDB.getInstance().getById(oldId);
if(oldFab == null)
{
Logger.debug(FileArchivatorKit.class, "setFilePropertiesAfterUpload() fileBean == null");
return false;
}
//ak sa ma subor nahrat neskor, to je vsetko
if(uploadLater)
return result;
//premenujeme (vymenime) subory stary->novy a novy->stary
if(renameFile(newFab.getFilePath(), newFab.getFileName(), oldFab))
{
//premenujeme v DB
String tempNameUrl = oldFab.getFileName();
oldFab.setFileName(newFab.getFileName());
newFab.setFileName(tempNameUrl);
//premenujeme aj cestu
tempNameUrl = oldFab.getFilePath();
oldFab.setFilePath(newFab.getFilePath());
newFab.setFilePath(tempNameUrl);
//zmenime referenciu v hlavnom subore
oldFab.setReferenceId(newFab.getId());
//globalne id je rovnake pre vsetky subory vo vlakne.
newFab.setGlobalId(oldFab.getGlobalId());
newFab.setDateInsert(new Date());
if(!oldFab.save() || !newFab.save())
result = false;
//zmenime referenciu u suborov, ktore na neho odkazuju (a po novom budu odkazovat na novy subor)
if(!reSetReference(oldId, newFab.getId()))
result = false;
//posunieme order_id o jednu uroven
incrementOrderId(newFab.getId());
//return result;
}
else
{
Logger.debug(FileArchivatorKit.class, "nezbehlo renameFile: "+newFab.getVirtualPath()+" vs. "+oldFab.getVirtualPath());
return false;
}
}
else
{
//ak uz existuju subory s rovnakym hashom, na frontende ponukneme moznosti riesenia
List<FileArchivatorBean> sameFilesList = existSameFiles(newFab, true);
if(req!=null)
{
req.setAttribute("fileArchivSameFiles", sameFilesList);
//kvoli mfsr potrebujem setovat vzdy
req.setAttribute("fileArchivLastFile", newFab);
FileArchivValidator fav = (FileArchivValidator)req.getAttribute("validator");
if(fav == null)
fav = new FileArchivDefaultValidator();
if(!fav.validatePropertiesAfterUpload(newFab,req))
{
Logger.debug(FileArchivatorKit.class, "nezbehlo validatePropertiesAfterUpload: "+newFab.getVirtualPath());
return false;
}
}
//novemu suboru vo vlakne nastavime nove globalne ID
newFab.setGlobalId(generateNextGlobalId());
newFab.save();
}
if (req != null) req.setAttribute("after_save_fab", newFab);
addSaveLogToAdminlog(newFab, newVersion);
return result;
}
/**
* Method is called when we are replacing existing file without creating new version in history
* @param newFab
* @param oldId
* @param userId
* @param req
* @return
*/
public static boolean setFilePropertiesAfterUploadReplace(FileArchivatorBean newFab, int oldId, HttpServletRequest req)
{
if(!FileTools.isFile(newFab.getFilePath()+newFab.getFileName()))
{
return false;
}
newFab.setId(oldId);
newFab.setDateInsert(new Date());
//ak uz existuju subory s rovnakym hashom, na frontende ponukneme moznosti riesenia
List<FileArchivatorBean> sameFilesList = existSameFiles(newFab, false);
req.setAttribute("fileArchivSameFiles", sameFilesList);
if(sameFilesList != null)
{
req.setAttribute("fileArchivLastFile", newFab);
}
FileArchivValidator fav = (FileArchivValidator)req.getAttribute("validator");
if(fav == null)
fav = new FileArchivDefaultValidator();
if(!fav.validateAfterUploadReplace(newFab,req))
{
Logger.debug(FileArchivatorKit.class, " new FileArchivatorBean(...) !newFab.save() "+newFab.toString());
return false;
}
if(!newFab.save())
{
Logger.debug(FileArchivatorKit.class, " new FileArchivatorBean(...) !newFab.save() "+newFab.toString());
return false;
}
addSaveLogToAdminlog(newFab, false, true);
//delete cache
FileArchivatorKit.deleteFileArchiveCache();
return true;
}
/**
* zamena obsahu suborov dirPath+fileName <-> oldFileBean.getFilePath()+oldFileBean.getFileName()
* BHR: musel som prerobit z Tools.renameFile, pretoze sa stalo, ze niekedy nezmazalo zdrojovy subor a teda sa premenovanie nedokoncilo
*/
public static boolean renameFile(String dirPath, String fileName, FileArchivatorBean oldFileBean)
{
boolean renamed = true;
IwcmFile oldFile = new IwcmFile(Tools.getRealPath(oldFileBean.getFilePath()+oldFileBean.getFileName()));
IwcmFile newFile = new IwcmFile(Tools.getRealPath(dirPath+fileName));
IwcmFile tmpFile = new IwcmFile(Tools.getRealPath(dirPath+"empty_file_for_rename_only"+getFileExtension(fileName)));
try
{
//copy old file to temp file for later usage
if(FileTools.copyFile(oldFile, tmpFile) == false)
{
Logger.error(FileArchivatorKit.class, "renameFile: nepodarilo sa premenovat "+oldFile.getVirtualPath()+" > "+tmpFile.getVirtualPath());
renamed = false;
}
//owerwrite old file with new file
if(FileTools.copyFile(newFile, oldFile) == false)
{
Logger.error(FileArchivatorKit.class, "renameFile: nepodarilo sa premenovat "+newFile.getVirtualPath()+" > "+oldFile.getVirtualPath());
renamed = false;
}
//copy temp (old) file over new file
if(FileTools.copyFile(tmpFile, newFile) == false)
{
Logger.error(FileArchivatorKit.class, "renameFile: nepodarilo sa premenovat "+tmpFile.getVirtualPath()+" > "+newFile.getVirtualPath());
renamed = false;
}
}
catch(Exception e)
{
renamed = false;
sk.iway.iwcm.Logger.error(e);
}
finally
{
if(renamed && tmpFile.exists())
tmpFile.delete();
}
return renamed;
}
public static boolean reSetReference(int oldReferenceId, int newReferenceId)
{
List<FileArchivatorBean> files = FileArchivatorDB.getByReferenceId(oldReferenceId);
if(files != null)
{
for(FileArchivatorBean file:files)
{
Logger.debug(FileArchivatorKit.class, "Change reference from "+oldReferenceId+" to "+newReferenceId+" file: "+file.getFilePath()+file.getFileName());
file.setReferenceId(newReferenceId);
if(!file.save())
{
return false;
}
}
}
FileArchivatorBean newBean = FileArchivatorDB.getInstance().getById(newReferenceId);
if (newBean != null)
{
newBean.setReferenceId(-1);
//force save to call FullTextIndexer
newBean.save();
}
return true;
}
/** Zisti ci sa nejde menit hlavny (aktualny) subor na ktory odkazuju ostatne. napriklad pri editacii viacerymi pouzivatelmi
*
*/
public static boolean isConcurrentModification(int oldId)
{
if(oldId > 0)
{
FileArchivatorBean fileBean = FileArchivatorDB.getInstance().getById(oldId);
if(fileBean != null && fileBean.getReferenceId() != -1)
{
Logger.debug(FileArchivatorKit.class, "Pozor !!! Moze nastat ConcurrentModification pri id: "+oldId+" subor: "+fileBean.getFileName());
return true;
}
}
return false;
}
public static String getMD5(IwcmFile iwcmFile)
{
String md5Hex = "null";
if(iwcmFile == null || iwcmFile.exists() == false)
{
return md5Hex;
}
try
{
md5Hex = DigestUtils.md5Hex(new IwcmInputStream(iwcmFile));
}
catch(Exception exc)
{
Logger.debug(FileArchivatorKit.class, "Zlyhalo generovanie MD5 odtlacku");
sk.iway.iwcm.Logger.error(exc);
}
return md5Hex;
}
/** Vrati datum ako String.
*
*/
public static String getDateStampAsString()
{
return getDateStampAsString(null);
}
/** Vrati datum a cas ako String.
*
*/
public static String getDateStampAsString(Date date)
{
Calendar now = Calendar.getInstance();
if(date != null)
now.setTime(date);
StringBuilder dateString = new StringBuilder();
dateString.append(now.get(Calendar.YEAR)).append(".").append(now.get(Calendar.MONTH)+1).append(".").append(now.get(Calendar.DAY_OF_MONTH)).append("_").append(now.get(Calendar.HOUR_OF_DAY)).append(".").append(now.get(Calendar.MINUTE));
return dateString.toString();
}
public static String getFileExtension(String fileName)
{
if(fileName == null)
return "empty";
if(fileName.lastIndexOf(".") != -1)
return fileName.toLowerCase().substring(fileName.lastIndexOf("."));
return "nul";
}
public static String getFileExtension(String fileName, boolean allowNull)
{
if(fileName == null)
{
if(allowNull)
return null;
return "empty";
}
if(fileName.lastIndexOf(".") != -1)
return fileName.toLowerCase().substring(fileName.lastIndexOf("."));
if(allowNull)
return null;
return "nul";
}
public static void incrementOrderId(int referenceId)
{
//DB.execute("UPDATE file_archiv SET order_id = order_id+1 WHERE reference_id = ? AND order_id >= 0", referenceId);
//DB.execute("UPDATE file_archiv SET order_id = 1 WHERE reference_id = ? AND order_id < 0", referenceId);
//USE JPA API to update because of JPA cache/object state
List<FileArchivatorBean> files = FileArchivatorDB.getByReferenceId(referenceId);
int oldOrder = -1;
if(files != null)
{
for(FileArchivatorBean file:files)
{
oldOrder = file.getOrderId();
if(file.getOrderId() == -1)
file.setOrderId(2);
else
file.setOrderId(file.getOrderId()+1);
Logger.debug(FileArchivatorKit.class, "Increment orderId from "+oldOrder+" to "+file.getOrderId()+" file: "+file.getFilePath()+file.getFileName());
file.save();
}
}
//musim tu vymazat cache
FileArchivatorKit.deleteFileArchiveCache();
Logger.debug(FileArchivatorKit.class, "Increment orderId for referenceId = "+referenceId);
}
public static String[] getDomainNames()
{
return Tools.getTokens(Constants.getString("fileArchivDomainsName"), ",");
}
/** Mazanie za podmienky ze na subor NEexistuje referencia
*
*/
public static boolean deleteFile(int fabId, UserDetails user)
{
List<FileArchivatorBean> fabList = FileArchivatorDB.getByReferenceId(fabId);
if(fabList == null || fabList.size() == 0)
{
FileArchivatorBean fabToDelete = FileArchivatorDB.getInstance().getById(fabId);
if(fabToDelete != null)
{
if(user == null || !user.isFolderWritable("/"+fabToDelete.getFilePath()))
{
Logger.debug(FileArchivatorKit.class, "Pouzivatel "+((user != null)?"id: "+user.getUserId():"null")+" nema pravo na zmazanie suboru: "+fabToDelete.getFilePath()+fabToDelete.getFileName()+" ");
return false;
}
boolean isSuccess = false;
IwcmFile iFile = new IwcmFile(Tools.getRealPath(fabToDelete.getFilePath()+fabToDelete.getFileName()));
if(iFile.exists() && iFile.delete())
{
isSuccess = true;
deletePattern(FileArchivatorDB.getPatern(fabToDelete.getFilePath()+fabToDelete.getFileName()), user);
}
else
{
Logger.debug(FileArchivatorKit.class, "Subor :"+fabToDelete.getFilePath()+fabToDelete.getFileName()+" sa nepodarilo zmazat.");
}
if(isSuccess && fabToDelete.delete())
{
String fileDescription = "Subor "+fabToDelete.getFilePath()+fabToDelete.getFileName()+" zmazany \n "+fabToDelete.toString();
Adminlog.add(Adminlog.TYPE_FILE_ARCHIVE, fileDescription, -1, -1);
return true;
}
}
}
return false;
}
public static boolean deleteStructure(int fabId,UserDetails user)
{
boolean isSuccess = true;
//najskorej zmazeme referencie
List<FileArchivatorBean> fabList = FileArchivatorDB.getByReferenceId(fabId);
if(fabList != null)
{
//ak na niektory z mazanych suborov nemame pravo, nezmazeme ani tie na ktore mame pravo.
for(FileArchivatorBean fab:fabList)
{
if(user == null || !user.isFolderWritable("/"+fab.getFilePath()))
{
Logger.debug(FileArchivatorKit.class, "Pouzivatel "+((user != null)?"id: "+user.getUserId():"null")+" nema pravo na zmazanie suboru (v liste): "+fab.getFilePath()+fab.getFileName()+" ");
return false;
}
}
for(FileArchivatorBean fab:fabList)
{
isSuccess = deleteFile(fab, "Sub ", user);
}
}
if(!isSuccess)
return false;
//a teraz zmazeme hlavny subor
FileArchivatorBean fabToDelete = FileArchivatorDB.getInstance().getById(fabId);
if(fabToDelete != null)
{
//prava na zmazanie sa vykonava v metode deleteFile(String ,String );
//zmazeme vzor
deletePattern(FileArchivatorDB.getPatern(fabToDelete.getFilePath()+fabToDelete.getFileName()),user);
isSuccess = deleteFile(fabToDelete,"Hlavny ", user);
}
return isSuccess;
}
/** Ak je bean vzorom (ma vyplnene "reference_to_main") tak bude zmazany
*
*/
private static boolean deletePattern(FileArchivatorBean fabPattern, UserDetails user)
{
if(fabPattern == null || Tools.isEmpty(fabPattern.getReferenceToMain()) || !Constants.getBoolean(FileArchivatorDB.getConstantsPrefix() + "AutoDeletePattern"))
return false;
return deleteFile(fabPattern, "Vzor ", user);
}
/** Skontroluje prava na subory, zmaze subor fyzicky z disku a zmaze aj Bean
*
*/
private static boolean deleteFile(FileArchivatorBean fabToDelete, String prefixText, UserDetails user)
{
if(fabToDelete == null)
{
Logger.debug(FileArchivatorKit.class, prefixText+" FAB je null ");
return false;
}
if(user == null || !user.isFolderWritable("/"+fabToDelete.getFilePath()))
{
Logger.debug(FileArchivatorKit.class, "Pouzivatel "+((user != null)?"id: "+user.getUserId():"null")+" nema pravo na zmazanie ("+prefixText+") suboru: "+fabToDelete.getFilePath()+fabToDelete.getFileName()+" ");
return false;
}
boolean isSuccess = true;
IwcmFile iFile = new IwcmFile(Tools.getRealPath(fabToDelete.getFilePath()+fabToDelete.getFileName()));
if(iFile == null || !iFile.exists() || !iFile.delete())
{
isSuccess = false;
Logger.debug(FileArchivatorKit.class, prefixText+" subor :"+fabToDelete.getFilePath()+fabToDelete.getFileName()+" sa nepodarilo zmazat.");
}
else
{
// delete file index
new SimpleQuery().execute("DELETE FROM documents WHERE external_link=?", "'/" + fabToDelete.getFilePath()+fabToDelete.getFileName() + "'");
if(fabToDelete.delete()) {
String fileDescription = "Subor "+fabToDelete.getFilePath()+fabToDelete.getFileName()+" zmazany \n "+fabToDelete.toString();
Adminlog.add(Adminlog.TYPE_FILE_ARCHIVE, fileDescription, user.getUserId(), -1);
}
}
return isSuccess;
}
/** Zisti ci na subor ktory chceme nahrat uz v databaze neexistovala URL a subor bol zmazany bez zmazania zaznamu o subore
*
*/
public static boolean existsPathInDB(String path)
{
if(path != null && path.lastIndexOf("/")+1 < path.length())
{
String filePath = path.substring(0,path.lastIndexOf("/")+1);
String fileName = path.substring(path.lastIndexOf("/")+1);
return FileArchivatorDB.getByPath(filePath, fileName) != null;
}
return false;
}
/**Skontroluje konzisteciu suborov, ak niektory chyba, vrati naplneny string. Pozor ! Vypoctovo narocne, prechadza vsetky zaznamy v DB a fyzicky kontroluje ci subory existuju
*
*/
public static String checkFileConsistency()
{
StringBuilder result = new StringBuilder();
for(FileArchivatorBean fab: FileArchivatorDB.getInstance().getAll())
{
if(!FileTools.isFile(fab.getFilePath()+fab.getFileName()))
result.append("Error file ").append(fab.getFilePath()).append(fab.getFileName()).append(" is missing ! Id: ")
.append(fab.getId()).append("<br>");
}
return result.toString();
}
/** Ziska security hash zo stringu, pri chybe vrati prazdny string
*
*/
public static String getSecurityHash(String input)
{
String ret = "";
try{
String source = input + input.length();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(source.getBytes());
byte[] byteData = md.digest();
StringBuilder sb = new StringBuilder();
for (byte byteDatum : byteData) {
sb.append(Integer.toString((byteDatum & 0xff) + 0x100, 16).substring(1));
}
ret = sb.toString();
}
catch (Exception e)
{
Logger.debug(FileArchivatorKit.class, "Problem generating security hash. Cause: " + e.getMessage());
}
return ret;
}
/** Ak uz fyzicky existuje subor s rovnakym hash-om, vratime list beanov, inak null
*
*/
public static List<FileArchivatorBean> existSameFiles(FileArchivatorBean newFab, boolean removePattern)
{
List<FileArchivatorBean> returnList = new ArrayList<>();
List<FileArchivatorBean> fabHashList = FileArchivatorDB.getByHash(newFab);
// fabHashList.size() > 1 preto, lebo 1 je newFab
if(fabHashList != null && fabHashList.size() > 1)
{
for(FileArchivatorBean fab: fabHashList )
{
//odstranime prave nahraty subor, archivy a vzory
if(fab.getId() != newFab.getId() && fab.getReferenceId() == -1 && (!removePattern || Tools.isEmpty(fab.getReferenceToMain())))
{
returnList.add(fab);
}
}
if(returnList.size() > 0)
return returnList;
}
return null;
}
/** Zmaze celu cache archivu suborov na vsetkych nodoch ak je systemova premenna "fileArchiv-delete-cache-public-node"
*
*
*/
public static void deleteFileArchiveCache()
{
//refresh aktualneho nodu node
Cache.getInstance().removeObjectStartsWithName(FileArchivatorDB.getCachePrefix());
//refresh nodov clustra
if(ClusterDB.isServerRunningInClusterMode() &&
Constants.getBoolean(FileArchivatorDB.getCachePrefix()+"delete-cache-public-node"))
{
ClusterDB.addRefresh("sk.iway.iwcm.Cache-" + FileArchivatorDB.getCachePrefix());
}
}
public static int generateNextGlobalId()
{
return PkeyGenerator.getNextValue("file_archiv_global_id");//nn_file_archives_global_id
}
/**
* vymazanie aktualneho suboru z vlakna a jeho nahradenie predchadzajucim suborom z vlakna
*
*/
public static boolean rollback(int fabId, UserDetails user)
{
boolean result = true;
FileArchivatorBean actualFab = FileArchivatorDB.getInstance().getById(fabId);
if(user == null || !user.isFolderWritable("/"+actualFab.getFilePath()))
{
Logger.debug(FileArchivatorKit.class, "Pouzivatel "+((user != null)?"id: "+user.getUserId():"null")+" nema pravo na ROLLBACK suboru: "+actualFab.getFilePath()+actualFab.getFileName()+" ");
return false;
}
FileArchivatorBean previousFab = FileArchivatorDB.getPrevious(fabId);
if(previousFab != null)
{
IwcmFile iFileActual = new IwcmFile(Tools.getRealPath(actualFab.getFilePath()+actualFab.getFileName()));
IwcmFile renamed = new IwcmFile(Tools.getRealPath(actualFab.getFilePath()+actualFab.getFileName()));
IwcmFile iFilePrevious = new IwcmFile(Tools.getRealPath(previousFab.getFilePath()+previousFab.getFileName()));
if(iFilePrevious.exists() && iFileActual.exists() && iFileActual.delete() && iFilePrevious.renameTo(renamed))
{
previousFab.setFilePath(actualFab.getFilePath());
previousFab.setFileName(actualFab.getFileName());
previousFab.setReferenceId(-1);
previousFab.setOrderId(-1);
int reference = actualFab.getId();
if(actualFab.delete())
{
if(previousFab.save())
{
List<FileArchivatorBean> files = FileArchivatorDB.getByReferenceId(reference);
if(files!=null)
{
for(FileArchivatorBean file:files)
{
file.setReferenceId(previousFab.getId());
file.setOrderId(file.getOrderId()-1);
if(!file.save())
{
Logger.error(FileArchivatorKit.class, "Chyba pri editacii vlakna :"+file.toString());
result = false;
}
}
}
Adminlog.add(Adminlog.TYPE_FILE_ARCHIVE, "EDIT: File Archiv ROLLBACK zmeny:"+FileArchivatorKit.getPojoZmeny(previousFab, actualFab), actualFab.getId(), previousFab.getId());
return result;
}
else
Logger.error(FileArchivatorKit.class, "Chyba pri ukladani do DB :"+previousFab.toString());
}
else
Logger.error(FileArchivatorKit.class, "Chyba pri vymazavani z DB :"+actualFab.toString());
}
else
Logger.error(FileArchivatorKit.class, "Chyba pri premenovani suboru :"+previousFab.getFilePath()+actualFab.getFileName()+" na "+actualFab.getFilePath()+actualFab.getFileName());
}
else
Logger.error(FileArchivatorKit.class, "Nepodarilo sa vykonat rollback: neexistujuci hlavny subor, alebo ziadny predchadzajuci subor vo vlakne. Id :"+fabId);
return false;
}
public static Collection<String> createCollection(String paramName, HttpServletRequest req)
{
String[] propertyArray = Tools.getTokens(Tools.getParameter(req,paramName), "+");
if(propertyArray != null && propertyArray.length > 0)
return Arrays.asList(propertyArray);
return null;
}
public static String getVal(HttpServletRequest request, String parameterName)
{
if(request.getParameter(parameterName) == null)
return "";
return Tools.getParameter(request,parameterName);
}
public static String getIconClass(FileArchivatorBean fab)
{
String extension = FileArchivatorKit.getFileExtension(fab.getFileName());
if(".pdf".equals(extension))
return "pdf";
if(".rtf".equals(extension))
return "rtf";
if(".mp3".equals(extension))
return "mp3";
if(".xls".equals(extension) || ".xlsx".equals(extension))
return "xls";
if(".doc".equals(extension) || ".docx".equals(extension))
return "doc";
if(".csv".equals(extension))
return "csv";
if(".exe".equals(extension))
return "exe";
if(".txt".equals(extension))
return "txt";
if(".zip".equals(extension))
return "zip";
if(".rar".equals(extension))
return "rar";
return "notFound";
}
/** bean ulozeny v ResultArchivBean.fab je potrebne ulozit.
*
* @param fab FileArchivatorBean (Musi mat vyplneny filePath - cestu k subroru bez lomitka na zaciatku (napr files/archiv/89/) a fileName - nazov suboru s priponou (priloha_1.pdf) a userId - id usera ktory subor nahrava)
* @param oldId - id suboru, ktory aktualizujeme
* @return ResultArchivBean
*/
//prepareAndValidate
public ResultArchivBean prepareAndValidate(FileArchivatorBean fab, int oldId, UserDetails user)
{
return prepareAndValidate(fab, oldId, user, false) ;
}
public ResultArchivBean prepareAndValidate(FileArchivatorBean fab, int oldId, UserDetails user, boolean isEdit)
{
ResultArchivBean resultBean = new ResultArchivBean();
if(errorsList == null)
errorsList = new ArrayList<>();
else
errorsList.clear();
if(user == null)
{
return addErrorMessageAndReturnFalse("error.userNotLogged");
}
if(!isEdit && FileArchivatorKit.existsPathInDB(fab.getFilePath()+fab.getFileName()))
{
return addErrorMessageAndReturnFalse("components.file_archiv.file_exists");
}
if(Tools.isEmpty(fab.getVirtualFileName()))
{
return addErrorMessageAndReturnFalse("components.file_archiv.file_virtual_cannot_be_empty");
}
IwcmFile file = new IwcmFile(Tools.getRealPath(fab.getFilePath()+fab.getFileName()));
fab.setUserId(user.getUserId());
fab.setMd5(FileArchivatorKit.getMD5(file));
fab.setFileSize(file.length());
fab.setDomainId(CloudToolsForCore.getDomainId());
resultBean.setFab(fab);
// Logger.debug(SaveFileAction.class, "saveFile() IP: "+Tools.getRemoteIP(getRequest())+" file: "+fileName+","+param_oldId_name+":"+getOldId());
boolean isDestinationFolderWritable = true;
//kontrola prav na zapis do suboru
if(!user.isFolderWritable(fab.getFilePath()))
{
Logger.debug(FileArchivatorKit.class, "User nema pravo na zapis do priecinku: "+fab.getFilePath());
setError("components.elfinder.commands.upload.error");
isDestinationFolderWritable = false;
}
if (isDestinationFolderWritable && checkFileProperties(file.getName(), file.getLength(), fab.getFilePath()+fab.getFileName(),oldId))
{
if(setFilePropertiesAfterUpload(fab,oldId))
{
resultBean.setSuccess(true);
return resultBean;
}
}
resultBean.setErrors(errorsList);
resultBean.setSuccess(false);
return resultBean;
}
private ResultArchivBean addErrorMessageAndReturnFalse(String propText)
{
setError(propText);
ResultArchivBean rab = new ResultArchivBean();
rab.setErrors(errorsList);
rab.setSuccess(false);
return rab;
}
protected void setError(String key)
{
addErrorText(prop.getText(key));
}
private void setError(String key, String param1)
{
addErrorText(prop.getText(key, param1));
}
private void setError(String key, String param1, String param2)
{
addErrorText(prop.getText(key, param1, param2));
}
private void addErrorText(String text)
{
if(errorsList == null)
errorsList = new ArrayList<>();
errorsList.add(text);
}
public boolean checkFileProperties(String fileName, long length, String pathName, int oldId)
{
// errorsList = new ArrayList<String>();
if(fileName == null || fileName.length() < 5)
{
Logger.debug(SaveFileAction.class, "checkFileProperties() fileName je null alebo ma kratky nazov. Subor: "+fileName);
setError("components.file_archiv.upload.file_not_exists_or_short_name", fileName);
return false;
}
if(!hasAllowedExtensions(fileName, oldId))
{
return false;
}
if(length >= getMaxFileSize())
{
Logger.debug(SaveFileAction.class, "Velkost suboru je prekrocena. Aktualna velkost: "+length+" maximalna velkost: "+getMaxFileSize());
setError("components.file_archiv.upload.file_is_too_big", length+"", getMaxFileSize()+"");
return false;
}
//ak uz existuje referencia v databaze k suboru ktory este len ideme nahrat, tak je to problem. Niekto zmazal subor rucne.
//subor nemozeme nahrat pretoze by mohol byt zmazany inym zaznamom v databaze - omylom
if(FileArchivatorKit.existsPathInDB(pathName) && !FileTools.isFile(pathName) )
{
setError("components.file_archiv.upload.db_enrty_exists");
return false;
}
return true;
}
/** Sluzi na validaciu {@link FileArchivatorBean} pred ulozenim. Skontroluje velkost suboru, priponu atd.
* @return Ak vrati true, mozeme {@link FileArchivatorBean} ulozit.
*/
public boolean hasAllowedExtensions(String fileName, int oldId)
{
if(Tools.isEmpty(fileName))
{
setError("components.file_archiv.upload.file_is_null");
return false;
}
//nahravam novu verziu dokumentu, musia ma rovnaku priponu
if(oldId > 0)
{
FileArchivatorBean fab = FileArchivatorDB.getInstance().getById(oldId);
if(fab != null)
{
if(getFileExtension(fab.getFileName()).equalsIgnoreCase(getFileExtension(fileName)))
return true;
else
setError("components.file_archiv.upload.file_shoud_have_end_with",getFileExtension(fab.getFileName()));
}
else
{
setError("components.file_archiv.upload.wrong_oldId", String.valueOf(oldId));
}
}
else
{
if(Tools.containsOneItem(Tools.getTokens(Constants.getString("fileArchivAllowExt"), ","), getFileExtension(fileName)))
return true;
else
{
Logger.debug(SaveFileAction.class, "File "+fileName+" has not allowed extension. Allowed extensions : "+Constants.getString("fileArchivAllowExt"));
setError("components.file_archiv.upload.file_not_allowed_extensions", Constants.getString("fileArchivAllowExt") , getFileExtension(fileName));
}
}
return false;
}
public static long getMaxFileSize()
{
return Tools.getIntValue(Constants.getString("fileArchivMaxUploadFileSize"), 60000000);
}
public boolean setFilePropertiesAfterUpload(FileArchivatorBean newFab, int oldId)
{
if(!FileTools.isFile(newFab.getFilePath()+newFab.getFileName()))
{
addErrorText(prop.getText("components.import_web_pages.import_error"));
return false;
}
newFab.setDomainId(CloudToolsForCore.getDomainId());
//ak uz existuje nejaka starsia verzia naseho suboru
boolean result = true;
boolean newVersion = false;
if(oldId > 0)
{
newVersion = true;
FileArchivatorBean oldFab = FileArchivatorDB.getInstance().getById(oldId);
if(oldFab == null)
{
Logger.debug(FileArchivatorKit.class, "setFilePropertiesAfterUpload() fileBean == null");
addErrorText(prop.getText("components.file_archiv.older_file_not_exists"));
return false;
}
if(!newFab.getFilePath().equals(oldFab.getFilePath()))
{
Logger.debug(FileArchivatorKit.class, "zdrojovy a cielovy priecinok, nie su rovnake");
addErrorText(prop.getText("components.file_archiv.source_and_destination_file_different"));
return false;
}
//premenujeme (vymenime) subory stary->novy a novy->stary
if(FileArchivatorKit.renameFile(newFab.getFilePath(), newFab.getFileName(), oldFab))
{
//premenujeme v DB
String tempNameUrl = oldFab.getFileName();
oldFab.setFileName(newFab.getFileName());
newFab.setFileName(tempNameUrl);
//premenujeme aj cestu
tempNameUrl = oldFab.getFilePath();
oldFab.setFilePath(newFab.getFilePath());
newFab.setFilePath(tempNameUrl);
//ak ideme na newFab nastavovat referenciu, musi byt ulozeny aby mal vytvorene ID.
if(newFab.getId() <= 0)
newFab.save();
//zmenime referenciu v hlavnom subore
oldFab.setReferenceId(newFab.getId());
newFab.setCategory(oldFab.getCategory());
newFab.setVirtualFileName(oldFab.getVirtualFileName());
newFab.setFieldA(oldFab.getFieldA());
newFab.setFieldB(oldFab.getFieldB());
//globalne id je rovnake pre vsetky subory vo vlakne.
newFab.setGlobalId(oldFab.getGlobalId());
if(!oldFab.save() || !newFab.save())
{
result = false;
}
else
{
addSaveLogToAdminlog(newFab, newVersion);
}
//zmenime referenciu u suborov, ktore na neho odkazuju (a po novom budu odkazovat na novy subor)
if(!FileArchivatorKit.reSetReference(oldId, newFab.getId()))
result = false;
//posunieme order_id o jednu uroven
FileArchivatorKit.incrementOrderId(newFab.getId());
return result;
}
else
{
addErrorText(prop.getText("components.file_archiv.rename_error"));
return false;
}
}
else
{
//novemu suboru vo vlakne nastavime nove globalne ID
newFab.setGlobalId(FileArchivatorKit.generateNextGlobalId());
addSaveLogToAdminlog(newFab, newVersion);
newFab.save();
}
return true;
}
private static void addSaveLogToAdminlog(FileArchivatorBean fab, boolean newVersion)
{
addSaveLogToAdminlog(fab, newVersion, false);
}
private static void addSaveLogToAdminlog(FileArchivatorBean fab, boolean newVersion, boolean replace)
{
String strNewVersion = "";
if(newVersion)
strNewVersion = "(Aktualizacia existujuceho suboru) ";
if(replace)
strNewVersion = "(Nahradenie povodneho suboru) ";
Adminlog.add(Adminlog.TYPE_FILE_ARCHIVE, "EDIT: File Archiv "+strNewVersion+"ulozenie:\n"+fab.toString(true), fab.getId(), -1);
}
public static String getPojoZmeny(Object newObj,Object originalObj)
{
if(newObj == null || originalObj == null)
return "Bez zmeny";
BeanDiff diff = new BeanDiff().setNew(newObj).setOriginal(originalObj);
return new BeanDiffPrinter(diff).toString();
}
public List<String> getErrorsList()
{
return errorsList;
}
}