IwcmFsDB.java
package sk.iway.iwcm.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.DBPool;
import sk.iway.iwcm.FileTools;
import sk.iway.iwcm.InitServlet;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.PkeyGenerator;
import sk.iway.iwcm.RequestBean;
import sk.iway.iwcm.SetCharacterEncodingFilter;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.common.AdminTools;
import sk.iway.iwcm.common.FilePathTools;
import sk.iway.iwcm.sync.FileBean;
import sk.iway.iwcm.system.cluster.ClusterDB;
/**
* IwcmFsDB.java
*
* @Title webjet4
* @Company Interway s.r.o. (www.interway.sk)
* @Copyright Interway s.r.o. (c) 2001-2008
* @author $Author: jeeff $
* @version $Revision: 1.17 $
* @created Date: 24.6.2008 12:47:26
* @modified $Date: 2009/11/16 08:54:08 $
*/
public class IwcmFsDB
{
/**
* SQL pre zmenu deleted priznaku <code>UPDATE_FILE_FAT_SET_IS_DELETED_WHERE_FILE_FAT_ID</code>
*/
private static final String UPDATE_DELETED_FLAG_SQL = "update file_fat set is_deleted = ? where file_fat_id = ? ";
/**
* Nazov stplca s ID vo fat tabulke <code>FILE_FAT_ID</code>
*/
private static final String FAT_ID_COLUMN = "file_fat_id";
private static Map<String, Integer> virtualPathToFatId ;
private static Map<String, Long> virtualPathToLastModified;
private static int cacheTimeInMinutes;
private static long nextRefreshTime;
private static boolean useDBStorage;
private static String dirsInDB;
//private static final boolean useVersioning;
private static String tempDir;
private static int blockSize;
static
{
init();
}
public static void init() {
cacheTimeInMinutes = Tools.getIntValue(Constants.getString("iwfs_timeInCache"), 15);
useDBStorage=Constants.getBoolean("iwfs_useDB");
dirsInDB=Constants.getString("iwfs_dirsInDB");
//useVersioning=Constants.getBoolean("iwfs_useVersioning");
tempDir=Constants.getString("iwfs_tempDir");
blockSize=Tools.getIntValue(Constants.getString("iwfs_blockSize") , 1024*1024);
}
private IwcmFsDB()
{
}
/**
* ulozi hash tabuliek a do cache, fat_id a last modified pre kazdy subor v
* db
*/
protected static synchronized void loadHashTables(boolean refresh)
{
if (virtualPathToLastModified == null || virtualPathToFatId == null || refresh || nextRefreshTime < System.currentTimeMillis())
{
Logger.debug(IwcmFsDB.class, "loading hashtables");
Map<String, Integer> newVirtualPathToFatId = new Hashtable<>();
Map<String, Long> newVirtualPathToLastModified = new Hashtable<>();
Connection db_conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
db_conn = DBPool.getConnection();
ps = db_conn.prepareStatement("SELECT virtual_path, last_modified, file_fat_id FROM file_fat WHERE is_deleted = ? ORDER BY file_fat_id ASC");
ps.setBoolean(1, false);
rs = ps.executeQuery();
while (rs.next())
{
newVirtualPathToFatId.put(rs.getString("virtual_path"), rs.getInt(FAT_ID_COLUMN));
newVirtualPathToLastModified.put(rs.getString("virtual_path"), rs.getLong("last_modified"));
}
rs.close();
ps.close();
db_conn.close();
rs = null;
ps = null;
db_conn = null;
nextRefreshTime = System.currentTimeMillis() + (1000L * 60 * cacheTimeInMinutes);
virtualPathToFatId = newVirtualPathToFatId;
virtualPathToLastModified = newVirtualPathToLastModified;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (rs != null)
rs.close();
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
sk.iway.iwcm.Logger.error(ex2);
}
}
}
}
/**
* vrati tabulku s tabulku s casmi poslednej modifkacie vsetkych suborov,
* kluc je virtualna cesta k suboru
*
* @return
*/
public static Map<String, Long> getModifiedTable()
{
if (virtualPathToLastModified == null || nextRefreshTime < System.currentTimeMillis())
{
loadHashTables(false);
return virtualPathToLastModified;
}
else
{
return virtualPathToLastModified;
}
}
/**
* vrati tabulku s tabulku s fat_id vsetkych suborov , kluc je virtualna
* cesta k suboru
*
* @return
*/
public static Map<String, Integer> getFatIdTable()
{
if (virtualPathToFatId == null || nextRefreshTime < System.currentTimeMillis())
{
loadHashTables(false);
return virtualPathToFatId;
}
else
{
return virtualPathToFatId;
}
}
/**
* zapise subor z disku do Db storage
*
* @param file
*/
public static void writeFileToDB(File file)
{
writeFileToDB(file, file);
}
/**
* zapise subor z databazy do OutputStreamu
*
* @param src
* @param out
* @throws FileNotFoundException
*/
public static byte[] writeFileToOutputStream(File src, OutputStream out) throws FileNotFoundException
{
return writeFileToOutputStreamFromHistory(src, out, -1);
}
/**
* Zapise subor z databazy so zadanym fatIdHistory (ak je -1 zapise aktualnu verziu suboru)
* @param src
* @param out
* @param fatIdHistory
* @return
* @throws FileNotFoundException
*/
public static byte[] writeFileToOutputStreamFromHistory(File src, OutputStream out, int fatIdHistory) throws FileNotFoundException
{
byte[] result=new byte[0];
IwcmInputStream in = null;
String virtualPath = getVirtualPath(src.getAbsolutePath());
if (fatIdHistory != -1 && getFatIdTable().get(virtualPath) == null)
throw new FileNotFoundException(virtualPath);
try
{
long length = -1;
if (FileCache.useFileCache())
{
length=new IwcmFile(src).length();
if (length<=FileCache.getMaxFileSize())
{
result = new byte[(int)length];
}
}
in = new IwcmInputStream(src, fatIdHistory);
byte[] buffer = new byte[64000];
int bytesRead = 0;
int bytesCopied = 0;
while ((bytesRead = in.read(buffer, 0, 64000)) != -1)
{
//Logger.debug(IwcmFsDB.class, "writing "+bytesRead);
out.write(buffer, 0, bytesRead);
if (FileCache.useFileCache() && length<=FileCache.getMaxFileSize())
{
System.arraycopy(buffer, 0, result, bytesCopied, bytesRead);
bytesCopied+=bytesRead;
}
}
out.flush();
out.close();
out = null;
in.close();
in = null;
}
catch (SocketException e)
{
Logger.error(IwcmFsDB.class, src.getAbsolutePath() + ": " + e.getMessage());
}
catch (Exception e)
{
Logger.error(IwcmFsDB.class, src.getAbsolutePath());
sk.iway.iwcm.Logger.error(e);
}
finally
{
try
{
if (out != null)
out.close();
if (in != null)
in.close();
}
catch (Exception ex2)
{
}
}
return result;
}
/**
* Vytvori prazdny adresar v databaze podla nastavenej virtualPath
*
* @param virtualPath
*/
public static void createDirectory(String virtualPath)
{
if (getFatIdTable().get(virtualPath) != null)
{
return;
}
Connection db_conn = null;
PreparedStatement ps = null;
try
{
db_conn = DBPool.getConnection();
ps = db_conn
.prepareStatement("insert into file_fat (file_fat_id,fsize,virtual_path,is_directory,depth,last_modified) values (?,?,?,?,?,?) ");
int fatId = PkeyGenerator.getNextValue(FAT_ID_COLUMN);
ps.setInt(1, fatId);
ps.setInt(2, 0);
ps.setString(3, virtualPath);
ps.setBoolean(4, true);
ps.setInt(5, IwcmFsDB.getDepth(virtualPath));
ps.setLong(6, 0);
ps.execute();
getFatIdTable().put(virtualPath, fatId);
getModifiedTable().put(virtualPath, (long) 0);
ClusterDB.addRefresh(IwcmFsDB.class);
ps.close();
db_conn.close();
ps = null;
db_conn = null;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
}
}
}
/**
* vytvori prazdny adresar v db podla adresa na disku
*
* @param dir
*/
public static void writeDirectoryToDB(File dir)
{
createDirectory(getVirtualPath(dir.getAbsolutePath()));
}
/**
* Zapise adresar s disku spolu zo subormi, ak je recursive true, zapise aj
* podadresare so subormy.
*
* @param dir
* @param recursive
*/
public static void writeDirectoryToDB(File dir, boolean recursive)
{
Logger.debug(IwcmFsDB.class, "writing directory: " + dir.getAbsolutePath());
if (dir.isDirectory())
{
writeDirectoryToDB(dir);
for (File f : dir.listFiles())
{
if (recursive && f.isDirectory())
{
writeDirectoryToDB(f, recursive);
}
else if (f.isDirectory())
continue;
if (f.isFile())
{
writeFileToDB(f);
}
}
}
else
{
throw new RuntimeException("Not a directory");
}
}
/**
* Zapise subor z databazy na disk
*
* @param f
*/
public static void writeFileToDisk(File f)
{
writeFileToDisk(f, f);
}
/**
* Vrati virtualnu cestu
*
* @param realPath
* @return
*/
public static String getVirtualPath(String realPath)
{
if (InitServlet.isTypeCloud() || Constants.getBoolean("enableStaticFilesExternalDir"))
{
String domainVirtualPath = FilePathTools.getVirtualPathHellper(realPath);
if (domainVirtualPath != null) return domainVirtualPath;
}
if (realPath == null || realPath.length() < Tools.getRealPath("/").length())
{
return "/";
}
String path = "/" + realPath.substring(Tools.getRealPath("/").length()).replace('\\', '/'); //NOSONAR
if (path.endsWith("/") && !"/".equals(path))
{
path = path.substring(0, path.length() - 1);
}
return path;
}
/**
* vrati hlbku v strome virtualnych adresarov
*
* @param virtualPath
* @return
*/
public static int getDepth(String virtualPath)
{
int count = 0;
for (char c : virtualPath.toCharArray())
{
if (c == '/')
{
count++;
}
}
return count;
}
/**
* podla cesty zisti ci sa ma pouzit storage alebo nie.
*
* @param virtualPath
* virtualna cesta!
* @return
*/
public static boolean useDBStorage(String virtualPath) //NOSONAR
{
if (useDBStorage==false) return false;
if (virtualPath.startsWith("/admin") || virtualPath.endsWith(".jsp")) return false;
// ak ano, tak este skontrolujeme ci aj dany adresar/subor
String dirs = dirsInDB;
for (String d : dirs.split(";"))
{
if (d.endsWith("/"))
{
if (virtualPath.startsWith(d.substring(0, d.length() - 1)))
{
return true;
}
}
else
{
if (virtualPath.startsWith(d))
{
return true;
}
}
}
return false;
}
/**
* zisti ci sa ma pouzit storage
*
* @return
*/
public static boolean useDBStorage()
{
return useDBStorage;
}
/**
* Zapise obsah InputStreamu do file
*
* @param in
* vstupne data
* @param file
* vystupny subor
* @param size
* velkost vystupneho suboru
*/
public static void writeFiletoDest(InputStream in, File file, int size,boolean closeInStream)
{
if (useDBStorage(getVirtualPath(file.getPath())))
{
Logger.error(IwcmFsDB.class, "writeFileToDest:" + file.getPath());
IwcmFile iwFile=new IwcmFile(file);
iwFile.delete();
if (!iwFile.getParentFile().exists())
{
iwFile.mkdirs();
}
Connection db_conn = null;
PreparedStatement ps = null;
try
{
db_conn = DBPool.getConnection();
ps = db_conn
.prepareStatement("insert into file_fat (file_fat_id,fsize,virtual_path,depth,last_modified) values (?,?,?,?,?)");
int fatId = PkeyGenerator.getNextValue(FAT_ID_COLUMN);
ps.setInt(1, fatId);
ps.setLong(2, size);
ps.setString(3, getVirtualPath(file.getPath()));
ps.setInt(4, IwcmFsDB.getDepth(getVirtualPath(file.getPath())));
Date dt=new Date();
ps.setLong(5,dt.getTime());
ps.execute();
ps.close();
byte[] data = null;
ps = db_conn.prepareStatement("insert into file_data (file_fat_id,data) values (?,?)");
long numberOfBlocks = (long) Math.ceil((double) size / (double) getBlockSize());
for (int i = 0; i < numberOfBlocks; i++)
{
data = new byte[getBlockSize()];
int bytesRead = 0;
int bytesReadSum=0;
while (bytesRead != -1 && bytesReadSum < getBlockSize())
{
bytesRead=in.read(data, bytesReadSum, getBlockSize()-bytesReadSum);
bytesReadSum+=bytesRead;
}
ps.setInt(1, fatId);
if (i == numberOfBlocks - 1)
{
byte[] tmp = new byte[(int) (getBlockSize() - (numberOfBlocks * getBlockSize() - size))];
System.arraycopy(data,0, tmp, 0, tmp.length);
ps.setBytes(2, tmp);
}
else
ps.setBytes(2, data);
ps.execute();
data = null;
}
getFatIdTable().put(getVirtualPath(file.getPath()), fatId);
getModifiedTable().put(getVirtualPath(file.getPath()), dt.getTime());
ClusterDB.addRefresh(IwcmFsDB.class);
ps.close();
db_conn.close();
ps = null;
db_conn = null;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
sk.iway.iwcm.Logger.error(ex2);
}
}
}
else
{
try
{
byte[] buffer = new byte[64000];
int bytesRead = 0;
//fos by malo subor vytvorit, mal som ale hlasene, ze to u klienta hadzalo FileNot FoundException preto som pridal implicitne vytvorenie suboru a adresara
if (file.getParentFile().exists()==false)
{
boolean created = file.getParentFile().mkdirs();
Logger.debug(IwcmFsDB.class, "Parent file doesn't exists, path="+file.getParentFile().getAbsolutePath()+", created="+created);
}
if (file.exists()==false)
{
boolean created = file.createNewFile();
Logger.debug(IwcmFsDB.class, "File doesn't exists, path="+file.getAbsolutePath()+", creating="+created);
}
FileOutputStream fos = new FileOutputStream(file);
while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1)
{
fos.write(buffer, 0, bytesRead);
}
fos.close();
//ulozim subor aj do historie
IwcmFsDB.saveFileHistory(new IwcmFile(file), false);
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
}
try
{
if (closeInStream) //pouziva sa napr. pri rozbalovani zipu ked sa zapisuju na disk subory, a input stream musi zostat otvoreny
{
in.close();
}
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
}
public static void writeFiletoDest(InputStream in, File file, int size)
{
writeFiletoDest(in, file, size,true);
}
public static void writeFileToDisk(InputStream in, File file, boolean closeInStream)
{
try
{
byte[] buffer = new byte[64000];
int bytesRead = 0;
FileOutputStream fos = new FileOutputStream(file);
while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1)
{
fos.write(buffer, 0, bytesRead);
}
fos.close();
//ulozim subor aj do historie
IwcmFsDB.saveFileHistory(new IwcmFile(file), false);
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
try
{
if (closeInStream) //pouziva sa napr. pri rozbalovani zipu ked sa zapisuju na disk subory, a input stream musi zostat otvoreny
{
in.close();
}
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
}
/**
* skopiruje subory iba v ramci databazy
*
* @param src
* @param dest
*/
public static void copyTo(IwcmFile src, IwcmFile dest)
{
if (useDBStorage(src.getVirtualPath()))
{
try
{
InputStream in = new IwcmInputStream(src);
String virtualPath = src.getVirtualPath();
if (getFatIdTable().get(virtualPath) == null) {
in.close();
throw new FileNotFoundException(virtualPath);
}
writeFiletoDest(in, new File(dest.getPath()), (int) src.length());
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
}
}
/**
* zmeni zadanu cestu na cestu v temp adresari
*
* @return
* @throws IOException
*/
public static String getTempFilePath(String path) throws IOException
{
String tempDir = getTempDir();
if (!tempDir.endsWith(File.separator))
{
tempDir += File.separator;
}
if (!new File(tempDir).exists())
{
if(!(new File(tempDir).mkdirs()))
throw new IOException("Unable to create dir: "+tempDir);
}
return tempDir + path.substring(path.lastIndexOf(File.separator) + 1, path.length());
}
/**
* Vrati temp adresar
* @throws IOException
*/
public static String getTempDir() throws IOException
{
String result = Tools.getRealPath("/WEB-INF/tmp/");
if (Tools.isNotEmpty(tempDir))
{
if (tempDir.startsWith("/"))
{
result = Tools.getRealPath(tempDir);
}
else
{
result = tempDir;
}
}
if (!new File(result).exists())
{
if(!(new File(result).mkdirs()))
throw new IOException("Unable to create dir: "+result);
}
return result;
}
/**
* Zapise subor src z databazy na disk do outFile
*
* @param src
* @param outFile
*/
public static void writeFileToDisk(File src, File outFile) {
writeFileToDisk(src, outFile, false);
}
/**
* Zapise subor src z databazy na disk do outFile, ak je nastavene forceOwerwrite tak subor prepise bez ohladu na to, ci je novsi
* @param src
* @param outFile
* @param forceOwerwrite
*/
public static void writeFileToDisk(File src, File outFile, boolean forceOwerwrite)
{
if (useDBStorage(getVirtualPath(src.getPath())))
{
try
{
byte[] buffer = new byte[getBlockSize()];
if(!outFile.getParentFile().exists())
if(!outFile.getParentFile().mkdir())
throw new IOException("Unable to create dir: "+outFile.getParentFile().getAbsolutePath());
if(outFile.exists() && (outFile.lastModified() == src.lastModified()) && forceOwerwrite == false)
{
//do nothing
}
else
{
if(!outFile.exists())
if(!outFile.createNewFile())
throw new IOException("Unable to create file: "+outFile.getAbsolutePath());
InputStream in = new IwcmInputStream(src);
int bytesRead = 0;
FileOutputStream fos = new FileOutputStream(outFile);
while ((bytesRead = in.read(buffer, 0, getBlockSize())) != -1)
{
fos.write(buffer, 0, bytesRead);
}
in.close();
fos.close();
//jeeff: pretoze ak to tu nebolo, zapisalo, ale po restarte chcelo ulozit do DB!!!
outFile.setLastModified(src.lastModified()); //NOSONAR
}
//getModifiedTable().put(getVirtualPath(src.getPath()), outFile.lastModified());
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
}
}
/**
* zapise subor z disku (src) do Db storage s virtualnou cestou podla outFile
*
* @param src
* @param outFile
*/
public static void writeFileToDB(File src, File outFile)
{
Logger.debug(IwcmFsDB.class, "writeFileToDB2:" + outFile.getPath());
Connection db_conn = null;
PreparedStatement ps = null;
int fatId = -1;
try
{
db_conn = DBPool.getConnection();
if (getFatIdTable().get(getVirtualPath(outFile.getPath())) != null)
{
fatId = getFatIdTable().get(getVirtualPath(outFile.getPath()));
}
if (fatId > 0)
{
if (IwcmFsDB.useVersioning() && IwcmFsDB.useDBStorage())
{
ps = db_conn.prepareStatement("update file_fat set is_deleted = ? where file_fat_id = ? "); // nastavi sa priznak zmazaneho suboru
ps.setBoolean(1, true);
ps.setInt(2, IwcmFsDB.getFatIdTable().get(getVirtualPath(outFile.getPath())));
ps.execute();
ps.close();
}
else
{
ps = db_conn.prepareStatement("delete from file_fat where file_fat_id = ? "); //zmaze sa z tabuliek
ps.setInt(1, IwcmFsDB.getFatIdTable().get(getVirtualPath(outFile.getPath())));
ps.execute();
ps.close();
ps = db_conn.prepareStatement("delete from file_data where file_fat_id = ? ");
ps.setInt(1, IwcmFsDB.getFatIdTable().get(getVirtualPath(outFile.getPath())));
ps.execute();
ps.close();
}
}
ps = db_conn
.prepareStatement("insert into file_fat (file_fat_id,fsize,virtual_path,depth,last_modified) values (?,?,?,?,?)");
fatId = PkeyGenerator.getNextValue(FAT_ID_COLUMN);
ps.setInt(1, fatId);
ps.setLong(2, src.length());
ps.setString(3, getVirtualPath(outFile.getPath()));
ps.setInt(4, IwcmFsDB.getDepth(getVirtualPath(outFile.getPath())));
Date dt=new Date();
ps.setLong(5,dt.getTime());
ps.execute();
ps.close();
byte[] data = null;
FileInputStream in = new FileInputStream(src);
ps = db_conn.prepareStatement("insert into file_data (file_fat_id,data) values (?,?)");
long numberOfBlocks = (long) Math.ceil((double) src.length() / (double) getBlockSize());
for (int i = 0; i < numberOfBlocks; i++)
{
data = new byte[getBlockSize()];
in.read(data);
ps.setInt(1, fatId);
if (i == numberOfBlocks - 1)
{
byte[] tmp = new byte[(int) (getBlockSize() - (numberOfBlocks * getBlockSize() - src.length()))];
System.arraycopy(data, 0, tmp, 0, tmp.length);
ps.setBytes(2, tmp);
}
else
ps.setBytes(2, data);
ps.execute();
data = null;
}
getFatIdTable().put(getVirtualPath(outFile.getPath()), fatId);
getModifiedTable().put(getVirtualPath(outFile.getPath()), dt.getTime());
ClusterDB.addRefresh(IwcmFsDB.class);
ps.close();
in.close();
db_conn.close();
ps = null;
db_conn = null;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
sk.iway.iwcm.Logger.error(ex2);
}
}
}
/**
* vrati velkost blokov do ktorych sa ukladaju subory,ak bol subor ulozeny s
* inou velkostou ako je aktulne nastavena tak sa neprecita.
*
* @return
*/
public static int getBlockSize()
{
return blockSize;
}
public static boolean manageVersions(String virtualPath, boolean rollback, boolean update)
{
if (getFatIdTable().get(virtualPath) != null)
{
Connection db_conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
TreeMap<Integer, Boolean> idDeletedTable = new TreeMap<>();
db_conn = DBPool.getConnection();
String sql = "select file_fat_id,is_deleted from file_fat where virtual_path = ? order by file_fat_id desc";
ps = db_conn.prepareStatement(sql);
ps.setString(1, virtualPath);
rs = ps.executeQuery();
while (rs.next())
{
idDeletedTable.put(rs.getInt(FAT_ID_COLUMN), rs.getBoolean("is_deleted"));
}
rs.close();
ps.close();
Iterator<Integer> it = null;
if (rollback)
{
it = idDeletedTable.descendingKeySet().iterator();
}
else
{
it = idDeletedTable.keySet().iterator();
}
int newFatId = -1;
int oldFatId = -1;
while (it.hasNext())
{
int fatId = it.next();
if (!idDeletedTable.get(fatId).booleanValue() && it.hasNext())
{
oldFatId = fatId;
newFatId = it.next();
}
}
if (newFatId < 0 || oldFatId < 0)
{
return false;
}
ps = db_conn.prepareStatement(UPDATE_DELETED_FLAG_SQL);
ps.setBoolean(1, true);
ps.setInt(2, oldFatId);
ps.execute();
ps.close();
ps = db_conn.prepareStatement(UPDATE_DELETED_FLAG_SQL);
ps.setBoolean(1, false);
ps.setInt(2, newFatId);
ps.execute();
getFatIdTable().put(virtualPath, newFatId);
getModifiedTable().put(virtualPath, new Date().getTime());
ClusterDB.addRefresh(IwcmFsDB.class);
ps.close();
db_conn.close();
rs = null;
ps = null;
db_conn = null;
return true;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (rs != null)
rs.close();
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
sk.iway.iwcm.Logger.error(ex2);
}
}
}
return false;
}
/**
* nahradi terajsiu verziu novsou verziou suboru ak existuje
*
* @param virtualPath
* @return
*/
public static boolean update(String virtualPath)
{
return manageVersions(virtualPath, false, true);
}
/**
* nahradi terajsiu verziu starsou verziou.
*
* @param virtualPath
* @return
*/
public static boolean rollback(String virtualPath)
{
return manageVersions(virtualPath, true, false);
}
/**
* vrati ci sa ma pouzivat verzovanie suborov
*
* @return
*/
public static boolean useVersioning()
{
return Constants.getBoolean("iwfs_useVersioning");
}
/**
* @deprecated - use AdminTools.getVersionList
*/
@Deprecated
public static List<FileBean>getVersionList(String virtualPath)
{
return AdminTools.getVersionList(virtualPath);
}
public static void replaceActualVersionWithHistory(String virtualPath,int historyFatId)
{
int fatId=getFatIdTable().get(virtualPath);
if (fatId==historyFatId) return;
Connection db_conn = null;
PreparedStatement ps = null;
try
{
db_conn = DBPool.getConnection();
ps = db_conn.prepareStatement(UPDATE_DELETED_FLAG_SQL);
ps.setBoolean(1, true);
ps.setInt(2, fatId);
ps.execute();
ps.close();
ps = db_conn.prepareStatement(UPDATE_DELETED_FLAG_SQL);
ps.setBoolean(1, false);
ps.setInt(2, historyFatId);
ps.execute();
getFatIdTable().put(virtualPath, historyFatId);
getModifiedTable().put(virtualPath, new Date().getTime());
ClusterDB.addRefresh(IwcmFsDB.class);
ps.close();
db_conn.close();
ps = null;
db_conn = null;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
sk.iway.iwcm.Logger.error(ex2);
}
}
}
public static void getInstance(boolean refresh)
{
Logger.println(IwcmFsDB.class, "getInstance("+refresh+")");
loadHashTables(true);
}
/**
* Aktualizacia hodnoty last modified
* @param virtualPath
* @param time
* @return
*/
public static boolean updateLastModified(String virtualPath, long time)
{
Long vpid = IwcmFsDB.getModifiedTable().get(virtualPath);
if (vpid == null) return false;
Connection db_conn = null;
PreparedStatement ps = null;
try
{
db_conn = DBPool.getConnection();
ps = db_conn.prepareStatement("UPDATE file_fat SET last_modified=? WHERE file_fat_id=?");
ps.setLong(1, time);
ps.setLong(2, vpid.longValue());
int updated = ps.executeUpdate();
ps.close();
db_conn.close();
ps = null;
db_conn = null;
if (updated > 0) return true;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
sk.iway.iwcm.Logger.error(ex2);
}
}
return false;
}
public static List<IwcmFile> listRecursively(IwcmFile dir)
{
return listRecursively(dir, new IwcmFileFilter(){
@Override
public boolean accept(IwcmFile pathname){return true;}
});
}
public static List<IwcmFile> listRecursively(IwcmFile dir, IwcmFileFilter filter)
{
List<IwcmFile> resultList = new ArrayList<>();
if (!useDBStorage(dir.getVirtualPath()))
{
listRecursivelyInNormalFile(dir, resultList, filter);
}
else
{
listRecursivelyInDbStorage(dir, resultList, filter);
}
return resultList;
}
private static void listRecursivelyInDbStorage(IwcmFile dir, List<IwcmFile> resultList, IwcmFileFilter filter)
{
Connection db_conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
int count = IwcmFsDB.getDepth(dir.getVirtualPath());
try
{
db_conn = DBPool.getConnection();
String sql = "select distinct virtual_path from file_fat where virtual_path like ? and depth >= ? and is_deleted = ? order by virtual_path ";
ps = db_conn.prepareStatement(sql);
ps.setString(1, dir + "%");
ps.setInt(2, count);
ps.setBoolean(3, false);
rs = ps.executeQuery();
while (rs.next())
{
IwcmFile file = new IwcmFile(Tools.getRealPath(rs.getString("virtual_path")));
if (filter.accept(file))
resultList.add(file);
}
rs.close();
ps.close();
db_conn.close();
rs = null;
ps = null;
db_conn = null;
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
finally
{
try
{
if (rs != null)
rs.close();
if (ps != null)
ps.close();
if (db_conn != null)
db_conn.close();
}
catch (Exception ex2)
{
sk.iway.iwcm.Logger.error(ex2);
}
}
}
private static void listRecursivelyInNormalFile(IwcmFile dir, List<IwcmFile> resultList, IwcmFileFilter filter)
{
for (IwcmFile file : dir.listFiles())
{
if (!filter.accept(file))
continue;
if (file.isDirectory())
listRecursivelyInNormalFile(file, resultList, filter);
resultList.add(file);
}
}
/**
* Ulozi historiu suboru na file systeme, v pripade, ze nie je zapnute DBStorage
* @param file
* @return true if ok, else false
*/
public static boolean saveFileHistory(IwcmFile file, boolean deleted)
{
if (file == null || file.getVirtualPath()==null) return false;
if(useVersioning() && !useDBStorage(file.getVirtualPath())) //ak je zapnute versiovanie a ak sa subor neuklada do db storage
{
String fileHistory = Constants.getString("fileHistoryPath");
if(fileHistory.charAt(fileHistory.length()-1) == '/')
{
fileHistory = fileHistory.substring(0, fileHistory.length()-1); //odstranim /
}
String virtualPath = file.getVirtualPath();
//imgcache nebudeme ukladat, nema to zmysel
if (virtualPath.contains("/WEB-INF/imgcache")) return false;
if (virtualPath.indexOf(fileHistory) == -1)
{ // kvoli zacykleniu - do historie neukladam subory zadresara historie
FileHistoryBean fhb = new FileHistoryBean();
fhb.setChangeDate(new Date());
fhb.setFileUrl(virtualPath);
RequestBean rb = SetCharacterEncodingFilter.getCurrentRequestBean();
if (rb == null) {
rb = new RequestBean();
rb.setUserId(-1);
}
fhb.setUserId(rb.getUserId());
fhb.setDeleted(deleted);
fhb.setIpAddress(rb.getRemoteIP());
if(!deleted)
{
fhb.setHistoryPath(fileHistory + getVirtualPath(file.getParent()) + "/");
}
// zapisanie zaznamu do historie - tabulka file_history
boolean saveOk = new FileHistoryDB().save(fhb);
RequestBean.addAuditValue("fileHistoryId", String.valueOf(fhb.getId()));
RequestBean.addAuditValue("path", fhb.getFileUrl()+"?fHistoryId="+fhb.getId());
if (saveOk)
{
if(!deleted) //subor kopirujem iba v pripade, ze ide o jeho vytvorenie a editaciu, nie zmazanie
{
// ulozim kopiu suboru pod /WEB-INF/filehistory/ alebo cestu
// urcenu konstantou
String historyPath = fhb.getHistoryPath() + fhb.getId();
IwcmFile dest = new IwcmFile(Tools.getRealPath(historyPath));
boolean copyOk = FileTools.copyFile(file, dest);
if (copyOk)
{
Logger.debug(IwcmFile.class,"Prekopirovanie suboru " + virtualPath + " do "
+ historyPath + " prebehlo uspesne!");
return true;
}
else
{
Logger.debug(IwcmFile.class,"Prekopirovanie suboru " + virtualPath + " do "
+ historyPath + " nebolo uspesne!");
return false;
}
}
return true;
}
else
{
Logger.debug(IwcmFile.class, "Ukladanie zaznamu pre subor " + virtualPath + " sa nezdarilo!");
return false;
}
}
else return false; //ak je to subor z historie preskocim a vratim hodnotu false
}
else return false; //ak sa subor uklada do dbStorage preskocim a vratim hodnotu false
}
}