IwcmFile.java
package sk.iway.iwcm.io;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.commons.lang.StringUtils;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.DBPool;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.database.SimpleQuery;
import sk.iway.iwcm.system.cluster.ClusterDB;
/**
* IwcmFile.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.19 $
* @created Date: 24.6.2008 17:05:58
* @modified $Date: 2010/01/20 11:14:46 $
*/
public class IwcmFile
{
private int fatId = -1;
private String fileName = null;
private String virtualPath = null;
private File file = null;
private boolean isDBStorage = false; // ak je false zapisuje sa na disk,ak
private boolean isJarPackaging = false; //ak je true je subor v JAR archive
// true do db storage
/**
* filename je skutocna cesta napr. C:\foo\bar.jpg
*/
public IwcmFile(String filename)
{
this.fileName = filename;
virtualPath = IwcmFsDB.getVirtualPath(filename);
isDBStorage = IwcmFsDB.useDBStorage(virtualPath);
isJarPackaging = JarPackaging.isJarPackaging(virtualPath);
if (!isDBStorage)
{
file = new File(filename);
}
}
public IwcmFile(String basename, String filename)
{
this.fileName = basename + File.separator + filename;
virtualPath = IwcmFsDB.getVirtualPath(basename + File.separator + filename);
isDBStorage = IwcmFsDB.useDBStorage(virtualPath);
isJarPackaging = JarPackaging.isJarPackaging(virtualPath);
if (!isDBStorage)
{
file = new File(basename + File.separator + filename);
}
}
public IwcmFile(File file)
{
fileName = file.getPath();
virtualPath = IwcmFsDB.getVirtualPath(file.getPath());
isDBStorage = IwcmFsDB.useDBStorage(virtualPath);
isJarPackaging = JarPackaging.isJarPackaging(virtualPath);
if (!isDBStorage)
{
this.file = file;
}
}
public IwcmFile(IwcmFile parent,String child)
{
this(parent.getAbsolutePath(),child);
}
public static IwcmFile fromVirtualPath(String path)
{
return new IwcmFile(Tools.getRealPath(path));
}
public static IwcmFile fromVirtualPath(String path, String fileName)
{
return new IwcmFile(Tools.getRealPath(path), fileName);
}
public boolean createNewFile() throws IOException
{
if (isDBStorage)
{
if (isDirectory())
{
delete();
IwcmFsDB.createDirectory(virtualPath);
return true;
}
delete();
// createnewFile() sa vola v pripadoch kedy nie je obsah suboru
// dolezity a necita sa z neho, lebo bude o chvilu prepisany,
// ale potrebujeme aby existoval.
IwcmFsDB.getFatIdTable().put(virtualPath, 0);
IwcmFsDB.getModifiedTable().put(virtualPath, (long) 0);
ClusterDB.addRefresh(IwcmFsDB.class);
return true;
}
else
{
return file.createNewFile();
}
}
public boolean isDirectory()
{
if (isDBStorage)
{
if (exists() && IwcmFsDB.getModifiedTable().get(virtualPath) == 0)
{
return true;
}
else
{
if (fileName.substring(fileName.lastIndexOf(File.separator), fileName.length()).contains(".prilohy") //v tomto pripade je to adresar -> WebDav integracia do dokument manazmentu (#8185)
|| !fileName.substring(fileName.lastIndexOf(File.separator), fileName.length()).contains("."))
{
return true;
}
return false;
}
}
else if (isJarPackaging)
{
return JarPackaging.isDirectory(virtualPath);
}
else
{
return file.isDirectory();
}
}
public boolean delete()
{
if (isDBStorage)
{
if (Tools.isEmpty(fileName))
return true;
Integer fatIdToDelete = IwcmFsDB.getFatIdTable().get(virtualPath);
if (fatIdToDelete == null)
{
return true;
}
Connection db_conn = null;
PreparedStatement ps = null;
try
{
db_conn = DBPool.getConnection();
if (IwcmFsDB.useVersioning() && IwcmFsDB.useDBStorage())
{
ps = db_conn.prepareStatement("update file_fat set is_deleted = ?, last_modified = ? where file_fat_id = ? "); // nastavi
// sa
// priznak
// zmazaneho
// suboru
ps.setBoolean(1, true);
ps.setLong(2, new java.util.Date().getTime());
ps.setInt(3, fatIdToDelete.intValue());
ps.execute();
ps.close();
}
else
{
ps = db_conn.prepareStatement("delete from file_fat where file_fat_id = ? "); // zmaze
// sa
// z
// tabuliek
ps.setInt(1, fatIdToDelete.intValue());
ps.execute();
ps.close();
ps = db_conn.prepareStatement("delete from file_data where file_fat_id = ? ");
ps.setInt(1, IwcmFsDB.getFatIdTable().get(virtualPath));
ps.execute();
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);
}
}
IwcmFsDB.getModifiedTable().remove(virtualPath);
IwcmFsDB.getFatIdTable().remove(virtualPath);
//ak je to adresar tak rekuzivne zmazeme podadresare
if (isDirectory())
{
for (IwcmFile f:this.listFiles())
{
f.delete();
}
}
ClusterDB.addRefresh(IwcmFsDB.class);
return true;
}
else
{
if (file.exists() && IwcmFsDB.useVersioning() && IwcmFsDB.useDBStorage())
{
IwcmFsDB.writeFileToDB(file);
}
return file.delete();
}
}
public boolean exists()
{
if (isDBStorage)
{
if (IwcmFsDB.getFatIdTable().get(virtualPath) != null)
{
return true;
}
else
{
return false;
}
}
else if (isJarPackaging)
{
return JarPackaging.exists(virtualPath);
}
else
{
return file.exists();
}
}
public String getPath()
{
return fileName;
}
public int getFatId()
{
return fatId;
}
public void setFatId(int fatId)
{
this.fatId = fatId;
}
public String getVirtualPath()
{
return Tools.replace(virtualPath, "//", "/");
}
public void setVirtualPath(String virtualPath)
{
this.virtualPath = virtualPath;
}
public IwcmFile[] listFiles(final IwcmFileFilter filter)
{
if (!this.isDirectory())
return new IwcmFile[0];
if (isDBStorage)
{
List<IwcmFile> resultList = new ArrayList<>();
Set<String> paths = IwcmFsDB.getFatIdTable().keySet();
int slashesInParent = StringUtils.countMatches(virtualPath, "/");
for (String s:paths)
{
if (s.startsWith(virtualPath))
{
int slashesInSubfile = StringUtils.countMatches(s, "/");
if (slashesInParent +1 != slashesInSubfile)
continue;
IwcmFile f = new IwcmFile(Tools.getRealPath(s));
if (filter.accept(f))
{
resultList.add(f);
}
}
}
return resultList.toArray(new IwcmFile[0]);
}
else if (isJarPackaging)
{
IwcmFile[] files = JarPackaging.listFiles(virtualPath);
List<IwcmFile> resultList = new ArrayList<>();
for (IwcmFile f : files) {
if (filter.accept(f)) resultList.add(f);
}
return resultList.toArray(new IwcmFile[0]);
}
else
{
File[] files = file.listFiles(new FileFilter()
{
@Override
public boolean accept(File pathname)
{
if (filter.accept(new IwcmFile(pathname)))
{
return true;
}
return false;
}
});
if (files==null) return null;
IwcmFile[] result = new IwcmFile[files.length];
int i = 0;
for (File f : files)
{
result[i++] = new IwcmFile(f);
}
return result;
}
}
public IwcmFile[] listFiles()
{
return listFiles(new IwcmFileFilter(){
@Override
public boolean accept(IwcmFile pathname)
{
return true;
}
});
}
public String getName()
{
if (isDBStorage)
{
return fileName.substring(fileName.lastIndexOf(File.separator) + 1);
}
else
{
return file.getName();
}
}
public boolean isFile()
{
if (isDBStorage)
{
if (exists() && IwcmFsDB.getModifiedTable().get(virtualPath) > 0)
{
return true;
}
else
{
return false;
}
}
else if (isJarPackaging)
{
return JarPackaging.isFile(virtualPath);
}
else
{
return file.isFile();
}
}
public boolean mkdir()
{
return mkdirs();
}
public String getParent()
{
String fName = fileName;
if (isDirectory() && !fName.endsWith(File.separator))
{
fName += File.separator;
}
return fName.substring(0, fName.lastIndexOf(File.separatorChar));
}
/**
* Vrati virtualnu cestu k suboru, bez mena suboru
* doplnene 5.2. 2009 - kmarton - kvoli rekurzivnej kontrole pouzitia suborov, vo funkcii priamo pouzite "/" ako file
* separator kvoli tomu, ze predtym to prechadza cez getVirtualPath a tam su vsetky "\" nahradzane "/" ako cesta v prehliadacoch
* @author kmarton
* @return String napr. ak je virtualna path /templates/webjet/temp_2.jsp, tak funkcia vrati /templates/webjet
* ak je to adresar napr. /templates/webjet/, vrati /templates
*/
public String getVirtualParent()
{
String fName = this.getVirtualPath();
if (isDirectory() && fName.endsWith("/") && fName.length()>1)
{
fName = fName.substring(0, (fName.length()-1));
}
String result = fName.substring(0, fName.lastIndexOf('/'));
//ak cesta obsahovala len jedlo '/' napr. /images tak z toho spravi prazdny string, pritom parent je /
if (result.length()==0)
{
return "/";
}
else
{
return result;
}
}
@JsonIgnore
public IwcmFile getParentFile()
{
if (isDBStorage)
{
return new IwcmFile(fileName.substring(0, fileName.lastIndexOf(File.separatorChar)));
}
else
{
return new IwcmFile(file.getParentFile());
}
}
public boolean mkdirs()
{
if (!isDBStorage)
{
return file.mkdirs();
}
else
{
String path = virtualPath;
if (!path.endsWith("/"))
{
path += "/";
}
//int length = path.split("/").length;
StringBuilder rootBuf = new StringBuilder();
for (String dir : path.split("/"))
{
if (Tools.isEmpty(dir))
continue;
rootBuf.append('/').append(dir);
IwcmFsDB.createDirectory(rootBuf.toString());
}
return true;
}
}
public String getAbsolutePath()
{
if (isDBStorage)
{
return getPath();
}
else
{
return file.getAbsolutePath();
}
}
public long getLength() {
return length();
}
public long length()
{
if (isDBStorage)
{
try
{
long size = new SimpleQuery().forLong("select fsize from file_fat where file_fat_id = ? ",
IwcmFsDB.getFatIdTable().get(virtualPath));
return size;
}
catch (Exception e)
{
return -1;
}
}
else if (isJarPackaging)
{
return JarPackaging.getSize(virtualPath);
}
else
{
return file.length();
}
}
public long lastModified()
{
if (isDBStorage)
{
if (IwcmFsDB.getModifiedTable().get(virtualPath) == null)
{
return 0;
}
return IwcmFsDB.getModifiedTable().get(virtualPath);
}
else if (isJarPackaging)
{
return JarPackaging.getLastMofified(virtualPath);
}
else
{
return file.lastModified();
}
}
public boolean setLastModified(long time)
{
if (isDBStorage)
{
return IwcmFsDB.updateLastModified(virtualPath, time);
}
else
{
return file.setLastModified(time);
}
}
public boolean renameTo(IwcmFile out)
{
if (isDBStorage)
{
if (out.isDBStorage)
{
if (exists())
{
Connection db_conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
db_conn = DBPool.getConnection();
//premenujeme adresar samotny
ps = db_conn.prepareStatement("update file_fat set virtual_path = ? where virtual_path = ? ");
ps.setString(1, out.getVirtualPath());
ps.setString(2, virtualPath);
ps.execute();
ps.close();
//mysql oracle
if (Constants.DB_TYPE == Constants.DB_ORACLE || Constants.DB_TYPE == Constants.DB_MYSQL || Constants.DB_TYPE == Constants.DB_PGSQL)
{
ps = db_conn
.prepareStatement("update file_fat set virtual_path =CONCAT( ?,SUBSTR(virtual_path,?)) where virtual_path like ? ");
int index = 1;
ps.setString(index++, out.getVirtualPath());
ps.setInt(index++, virtualPath.length()+1);
ps.setString(index++, virtualPath +"/"+ "%");
ps.executeUpdate();
ps.close();
}
else
{
//ina syntax substring a concat
if (Constants.DB_TYPE == Constants.DB_MSSQL)
{
ps = db_conn
.prepareStatement("update file_fat set virtual_path = ? + SUBSTRING(virtual_path,?,LEN(virtual_path)-?) where virtual_path like ? ");
int index = 1;
ps.setString(index++, out.getVirtualPath());
ps.setInt(index++, virtualPath.length()+1);
ps.setInt(index++, virtualPath.length());
ps.setString(index++, virtualPath+"/" + "%");
ps.executeUpdate();
ps.close();
}
}
ps = fixDepth(out.getVirtualPath(),db_conn);
// vyberieme vsetky subory a podadresare
ps = db_conn.prepareStatement("select * from file_fat where virtual_path like ? ");
ps.setString(1,out.getVirtualPath()+"/"+"%");
rs = ps.executeQuery();
while (rs.next())
{
final String newVirtualPath = rs.getString("virtual_path");
final String oldPath = virtualPath+newVirtualPath.substring(out.getVirtualPath().length());
// odstranime stare cesty a vlozime nove
IwcmFsDB.getFatIdTable().remove(oldPath);
IwcmFsDB.getModifiedTable().remove(oldPath);
IwcmFsDB.getFatIdTable().put(newVirtualPath,rs.getInt("file_fat_id"));
IwcmFsDB.getModifiedTable().put(newVirtualPath,rs.getLong("last_modified") );
}
int dataId = IwcmFsDB.getFatIdTable().get(virtualPath);
long lastModified = IwcmFsDB.getModifiedTable().get(virtualPath);
//ulozime do hash table novu cestu pre adresar
IwcmFsDB.getFatIdTable().remove(virtualPath);
IwcmFsDB.getModifiedTable().remove(virtualPath);
virtualPath = out.getVirtualPath();
fileName = out.getPath();
IwcmFsDB.getFatIdTable().put(virtualPath, dataId);
IwcmFsDB.getModifiedTable().put(virtualPath, lastModified);
ClusterDB.addRefresh(IwcmFsDB.class);
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);
}
}
}
}
else
{
IwcmFsDB.writeFileToDisk(new File(this.getAbsolutePath()), new File(out.getAbsolutePath()));
this.delete();
}
}
else
{
if (out.isDBStorage)
{
IwcmFsDB.writeFileToDB(file,new File(out.getAbsolutePath()));
this.delete();
}
else
{
if(file.renameTo(new File(out.getPath())) == false) return false;
}
}
return true;
}
private static PreparedStatement fixDepth(String path, Connection db_conn) throws SQLException
{
PreparedStatement ps;
//opravime depth
//mysql oracle
if (Constants.DB_TYPE == Constants.DB_ORACLE || Constants.DB_TYPE == Constants.DB_MYSQL || Constants.DB_TYPE == Constants.DB_PGSQL)
{
ps = db_conn
.prepareStatement("update file_fat set depth = length(virtual_path) - length(replace(virtual_path,'/','')) where virtual_path like ? ");
ps.setString(1, path + "%");
ps.execute();
ps.close();
}
else
{
ps = db_conn
.prepareStatement("update file_fat set depth = LEN(virtual_path) - LEN(replace(virtual_path,'/','')) where virtual_path like ? ");
ps.setString(1, path + "%");
ps.execute();
ps.close();
}
return ps;
}
public boolean canRead()
{
if (isDBStorage)
{
return true;
}
else if (isJarPackaging)
{
return exists();
}
else
{
return file.canRead();
}
}
@Override
public String toString()
{
return getVirtualPath();
}
/**
* @return
*/
public String getCanonicalPath()
{
if (isDBStorage)
{
return getAbsolutePath();
}
else
{
try
{
return file.getCanonicalPath();
}
catch (IOException e)
{
sk.iway.iwcm.Logger.error(e);
}
}
return null;
}
public boolean isJarPackaging()
{
return isJarPackaging;
}
}