package org.jblooming.ontology; import org.jblooming.waf.settings.ApplicationState; import org.jblooming.waf.view.PageSeed; import org.jblooming.waf.view.PageState; import org.jblooming.waf.constants.Fields; import org.jblooming.system.SystemConstants; import org.jblooming.utilities.StringUtilities; import org.jblooming.utilities.HttpUtilities; import org.jblooming.utilities.file.FileUtilities; import org.jblooming.persistence.PersistenceHome; import org.jblooming.persistence.hibernate.PersistenceContext; import org.jblooming.persistence.exceptions.FindByPrimaryKeyException; import org.jblooming.persistence.exceptions.StoreException; import org.jblooming.PlatformRuntimeException; import java.io.*; import net.sf.json.JSONObject; /** * @author Pietro Polsinelli ppolsinelli@open-lab.com */ public class PersistentFile implements Serializable { public static final String TYPE_DB = "DB"; public static final String TYPE_FILESTORAGE = "FR"; // this is relative to the REPOSITORY_URL parameter public static final String TYPE_FILESTORAGE_ABSOLUTE = "FS"; // this is absolute e.g. c:\tmp public static final String TYPE_WEBAPP_FILESTORAGE = "WF"; // relative to root private int UID; private String type = TYPE_DB; private String originalFileName; /** * this is the complete path to the file, file inclusive */ private String fileLocation; /** * this is the complete path to the file, file exclusive; not persisted */ public String fileDir; public static final String PERSISTENTFILE_ID = "PERSISTENTFILE_ID"; // not persisted is used only to get a un-persisted reference private BinaryLargeObject blob=null; /** * @deprecated use constructor with type */ public PersistentFile(int UID, String originalFileName) { this.setOriginalFileName(originalFileName); this.setUID(UID); } public PersistentFile(int UID, String originalFileName, String type) { this.setOriginalFileName(originalFileName); this.setUID(UID); this.type = type; } public int getUID() { return UID; } public void setUID(int UID) { this.UID = UID; } public boolean equals(Object o) { return this.compareTo(o) == 0; } public int hashCode() { return serialize().hashCode(); } public int compareTo(Object o) { if (this == o) return 0; if (o == null) return -1; else { return serialize().compareTo(((PersistentFile) o).serialize()); } } public String getType() { return type; } /** * @deprecated use constructor */ public void setType(String type) { this.type = type; } public String getOriginalFileName() { return originalFileName; } public void setOriginalFileName(String originalFileName) { this.originalFileName = originalFileName; } /** * @return the file location relative to PersistentFile.type complete with file name */ public String getFileLocation() { return fileLocation; } public void setFileLocation(String fileLocation) { this.fileLocation = fileLocation; } public String serialize() { String ser = type + "_" + UID + "_" + originalFileName; if (TYPE_FILESTORAGE_ABSOLUTE.equals(type) || TYPE_FILESTORAGE.equals(type) || TYPE_WEBAPP_FILESTORAGE.equals(type)) ser = ser + "+++" + fileLocation; return ser; } public String getName() { String name = ""; if (TYPE_DB.equals(type)) { name = originalFileName; } else { String fileLocNorm = StringUtilities.replaceAllNoRegex(fileLocation, "\\", "/"); name = fileLocNorm.substring(Math.max(0, fileLocNorm.lastIndexOf("/") + 1)); } return name; } /* public void makedirs(){ new File( ApplicationState.getApplicationSetting(SystemConstants.FLD_REPOSITORY_URL) + File.separator + "photos").mkdirs(); } */ public static PersistentFile deserialize(String serObj) { PersistentFile pf = null; if (serObj != null) { int first_ = serObj.indexOf("_"); if (first_ > 0) { String type = serObj.substring(0, first_); int second_ = serObj.indexOf("_", first_ + 1); int third = serObj.length(); if (TYPE_FILESTORAGE.equals(type) || TYPE_WEBAPP_FILESTORAGE.equals(type) || TYPE_FILESTORAGE_ABSOLUTE.equals(type)) third = serObj.indexOf("+++"); if (second_ > 0) { int UID = Integer.parseInt(serObj.substring(first_ + 1, second_)); String originalFileName = serObj.substring(second_ + 1, third); pf = new PersistentFile(UID, originalFileName); pf.type = type; } if (TYPE_FILESTORAGE.equals(type) || TYPE_WEBAPP_FILESTORAGE.equals(type) || TYPE_FILESTORAGE_ABSOLUTE.equals(type)) { String fileLoc = serObj.substring(serObj.indexOf("+++") + 3); pf.fileLocation = fileLoc; File file = new File(fileLoc); pf.fileDir = file.getParent(); } } } return pf; } public PageSeed getPageSeed() { PageSeed ps = null; if (!PersistentFile.TYPE_WEBAPP_FILESTORAGE.equals(getType())) { ps = new PageSeed(ApplicationState.contextPath + "/commons/layout/partUploaderView.jsp"); ps.addClientEntry(Fields.FILE_TO_UPLOAD, serialize()); } else { ps = new PageSeed(ApplicationState.contextPath + "/" + StringUtilities.replaceAllNoRegex(getFileLocation(), "\\", "/")); } return ps; } public BinaryLargeObject getBlob(PersistenceContext pc) throws FindByPrimaryKeyException { if (TYPE_DB.equals(getType())){ if (blob==null){ blob= (BinaryLargeObject) PersistenceHome.findByPrimaryKey(BinaryLargeObject.class, getUID(), pc); } return blob; } else{ throw new PlatformRuntimeException("Blob object can be used in case of TYPE_DB only."); } } public InputStream getInputStream() throws FileNotFoundException, FindByPrimaryKeyException { // if you are using multiple connection with BLOB use in both DB you may be in trouble return getInputStream(PersistenceContext.getDefaultPersistenceContext()); } public InputStream getInputStream(PersistenceContext pc) throws FileNotFoundException, FindByPrimaryKeyException { InputStream inputStream = null; if (PersistentFile.TYPE_DB.equals(getType())) { if (pc == null) throw new PlatformRuntimeException("Invalid use of getInputStream(null) with DB type PersistentFile"); BinaryLargeObject blo = getBlob(pc); try { inputStream = blo.getInputStream(); } catch (Throwable e) { throw new PlatformRuntimeException(e); } } else if (PersistentFile.TYPE_FILESTORAGE.equals(getType())) { String repositoryUrl = ApplicationState.getApplicationSetting(SystemConstants.FLD_REPOSITORY_URL); String fileLocation = getFileLocation(); String separator = (repositoryUrl.endsWith(File.separator) || repositoryUrl.endsWith("/") || fileLocation.startsWith(File.separator) || fileLocation.startsWith("/")) ? "" : File.separator; //String url = StringUtilities.replaceAllNoRegex(repositoryUrl + separator + fileLocation, "/", File.separator); String url = repositoryUrl + separator + fileLocation; inputStream = new FileInputStream(url); } else if (PersistentFile.TYPE_FILESTORAGE_ABSOLUTE.equals(getType())) { inputStream = new FileInputStream(getFileLocation()); } else if (PersistentFile.TYPE_WEBAPP_FILESTORAGE.equals(getType())) { inputStream = new FileInputStream(ApplicationState.webAppFileSystemRootPath + File.separator + getFileLocation()); } else { throw new PlatformRuntimeException("Unsupported Persistent File Type: " + getType()); } return inputStream; } /** * * @param persistentFileType determine where the final file will be placed. In case of DB type a BinaryLargeObject will be created and stored. Remember to assign referral ID and CLASS and store the blob again. * @param inputStream * @param originalFileName * @param relativePathFileName instruct the method on where to place the real file * file is created starting from the REPOSITORY_URL in case of TYPE_FILESTORAGE. e.g.: [REPOSITORY_URL] + / + "myfoder1/myfolder2/myfile.ext". * file is created starting from web-app root in case of TYPE_WEBAPP_FILESTORAGE. e.g.: [REPOSITORY_URL] + / + "myfoder1/myfolder2/myfile.ext". * file is created where specified (as-is) in case of TYPE_FILESTORAGE_ABSOLUTE e.g.: "c:\myfolder1\myfolder2\myfile.ext" or "/usr/myfoder1/myfolder2/myfile.ext" * the parameter is ignored in case of DB type. * @param pc is used only in case of DB type. Use the PersistenceContext.get(MyObject.Class) where myObject.setPersistentFile() * @return a PersistentFile created correctly basing on type, relative path etc.. * The final real path where the file will be created will [SystemConstants.FLD_REPOSITORY_URL] + / + relativePath */ public static PersistentFile createPersistentFileFromStream(String persistentFileType, InputStream inputStream, String originalFileName, String relativePathFileName, PersistenceContext pc) throws IOException { PersistentFile pf = new PersistentFile(0,originalFileName,persistentFileType); pf.setFileLocation(relativePathFileName); if (PersistentFile.TYPE_DB.equals(persistentFileType)) { if (pc == null) throw new PlatformRuntimeException("Invalid use of createPersistentFileFromStream with DB type when pc is null"); // create BLOB BinaryLargeObject blo = new BinaryLargeObject() ; blo.feed(inputStream); try { blo.store(pc); } catch (StoreException e) { throw new PlatformRuntimeException(e); } pf.blob=blo; pf.setUID(blo.getIntId()); } else if (PersistentFile.TYPE_FILESTORAGE.equals(persistentFileType)) { String repositoryUrl = ApplicationState.getApplicationSetting(SystemConstants.FLD_REPOSITORY_URL); String separator = (repositoryUrl.endsWith("\\") || repositoryUrl.endsWith("/") || relativePathFileName.startsWith("\\") || relativePathFileName.startsWith("/")) ? "" : File.separator; String destination = repositoryUrl + separator + relativePathFileName; File destFile=new File(destination); File parent=destFile.getParentFile(); parent.mkdirs(); FileOutputStream fout = new FileOutputStream(destFile); FileUtilities.copy(inputStream,fout); fout.close(); } else if (PersistentFile.TYPE_FILESTORAGE_ABSOLUTE.equals(persistentFileType)) { FileOutputStream fout = new FileOutputStream(relativePathFileName); FileUtilities.copy(inputStream,fout); fout.close(); } else if (PersistentFile.TYPE_WEBAPP_FILESTORAGE.equals(persistentFileType)) { // be carefull the separator for a webapp is always / String repositoryUrl =ApplicationState.webAppFileSystemRootPath; String separator = (repositoryUrl.endsWith("\\") || repositoryUrl.endsWith("/") || relativePathFileName.startsWith("\\") || relativePathFileName.startsWith("/")) ? "" : File.separator; String destination = repositoryUrl + separator + relativePathFileName; File destFile=new File(destination); File parent=destFile.getParentFile(); parent.mkdirs(); FileOutputStream fout = new FileOutputStream(destFile); FileUtilities.copy(inputStream,fout); fout.close(); } else { throw new PlatformRuntimeException("Unsupported Persistent File Type: " + persistentFileType); } return pf; } public JSONObject jsonify() { JSONObject ret = new JSONObject(); ret.element("uid", serialize()); ret.element("type", getType()); ret.element("name", getOriginalFileName()); ret.element("img",HttpUtilities.getContentType(getName()).replace('/', '_')); return ret; } }