package org.jblooming.waf.html.input;
import org.jblooming.ApplicationException;
import org.jblooming.PlatformRuntimeException;
import org.jblooming.tracer.Tracer;
import org.jblooming.system.SystemConstants;
import org.jblooming.ontology.BinaryLargeObject;
import org.jblooming.ontology.Identifiable;
import org.jblooming.ontology.PersistentFile;
import org.jblooming.ontology.IdentifiableSupport;
import org.jblooming.persistence.PersistenceHome;
import org.jblooming.persistence.exceptions.FindByPrimaryKeyException;
import org.jblooming.persistence.exceptions.PersistenceException;
import org.jblooming.uidgen.CounterHome;
import org.jblooming.utilities.HttpUtilities;
import org.jblooming.utilities.StringUtilities;
import org.jblooming.utilities.file.FileUtilities;
import org.jblooming.waf.UploadHelper;
import org.jblooming.waf.exceptions.ActionException;
import org.jblooming.waf.settings.ApplicationState;
import org.jblooming.waf.constants.Fields;
import org.jblooming.waf.html.core.JspHelper;
import org.jblooming.waf.html.layout.Skin;
import org.jblooming.waf.html.state.Form;
import org.jblooming.waf.view.ClientEntry;
import org.jblooming.waf.view.PageState;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
import javax.mail.internet.MimeUtility;
import java.io.*;
import java.net.URLEncoder;
public class Uploader extends JspHelper {
public Skin skin;
public String fieldName;
public boolean disabled = false;
public int size;
public String label;
public String className="formElements";
public String classLabelName;
public String separator;
public String jsScript;
public boolean required = false;
public String toolTip;
public boolean doFeedBackError = true;
public Form form;
/**
* key control
*/
public String actionListened;
public int keyToHandle;
public String launchedJsOnActionListened;
public boolean translateError = true;
public boolean readOnly = false;
public boolean treatAsAttachment = true;
public Uploader(String fieldName, PageState pageState) {
this.id = fieldName + "_upl";
this.urlToInclude = "/commons/layout/partUploader.jsp";
this.fieldName = fieldName;
this.skin = pageState.getSkin();
this.required = pageState.getEntry(fieldName).required;
}
@Deprecated
public Uploader(String fieldName, Form form, PageState pageState) {
this.id = fieldName + "_upl";
this.urlToInclude = "/commons/layout/partUploader.jsp";
this.fieldName = fieldName;
this.skin = pageState.getSkin();
this.form = form;
this.required = pageState.getEntry(fieldName).required;
}
// of great elegance
public static String getHiddenFieldName(String ceName) {
return "sp_fi_br_" + ceName + "_upl";
}
public String getDiscriminator() {
return SmartCombo.class.getName();
}
public void toHtml(PageContext pageContext) {
pageContext.getRequest().setAttribute(ACTION, "");
super.toHtml(pageContext);
}
public static void displayFile(PageState pageState, HttpServletResponse response) throws IOException, FindByPrimaryKeyException {
displayFile(true, pageState, response);
}
public static void displayFile(boolean treatAsAttachment, PageState pageState, HttpServletResponse response) throws IOException, FindByPrimaryKeyException {
String pfSer = pageState.getEntry(Fields.FILE_TO_UPLOAD).stringValueNullIfEmpty();
if (pfSer != null) {
PersistentFile pf = PersistentFile.deserialize(pfSer);
response.setContentType(HttpUtilities.getContentType(pf.getOriginalFileName()));
String filename = pf.getOriginalFileName();
InputStream inputStream = pf.getInputStream();
// this fantastic trick fixes the problem of non US filenames
String filenameEncoded = pageState.sessionState.isFirefox() ? MimeUtility.encodeText(filename, "UTF8", "B") : URLEncoder.encode(filename, "UTF8");
filenameEncoded = StringUtilities.replaceAllNoRegex(StringUtilities.replaceAllNoRegex(filenameEncoded, "+", "_"), " ", "_");
// sets header with original file name
if (treatAsAttachment) {
response.setHeader("content-disposition", "attachment; filename=" + filenameEncoded);
} else
response.setHeader("content-disposition", "inline; filename=" + filenameEncoded);
// write data to stream and close it
FileUtilities.writeStream(inputStream, response.getOutputStream());
inputStream.close();
} else {
throw new PlatformRuntimeException("Unsupported PersistentFile type.");
}
}
public static PersistentFile save(String formFieldName, PageState pageState) throws PersistenceException, ApplicationException, ActionException {
return save(formFieldName, PersistentFile.TYPE_FILESTORAGE, pageState);
}
public static PersistentFile save(String formFieldName, String type, PageState pageState) throws PersistenceException, ApplicationException, ActionException {
PersistentFile persistentFile = new PersistentFile(0, null);
persistentFile.setType(type);
persistentFile.fileDir = "";//ApplicationState.getApplicationSetting(SystemConstants.FLD_REPOSITORY_URL);
return save(null, persistentFile, formFieldName, pageState);
}
public static PersistentFile save(Identifiable mainObject, PersistentFile persistentFile, String formFieldName, PageState pageState) throws PersistenceException, ApplicationException, ActionException {
return save(mainObject, persistentFile, formFieldName, null, pageState);
}
public static PersistentFile save(Identifiable mainObject, PersistentFile persistentFile, String formFieldName, String nameToGiveToFileInRepository, PageState pageState) throws PersistenceException, ApplicationException, ActionException {
if (!pageState.multipart)
Tracer.platformLogger.warn("Seems attempted upload on a non-multipart form:"+pageState.href);
final ClientEntry entry = pageState.getEntry(formFieldName);
String value = entry.stringValue();
if (value != null && value.trim().length() <= 0) {
value = null;
// aprile 2007 teoros:: il nome serializzato del persistent file rischia di superare 255 caratteri ==> data truncation
// vedi anche:: UploadHelper.getInstance()
} else if (value!=null && value.trim().length()>50) {
String extension = FileUtilities.getFileExt(value);
value = value.substring(0, 50) + extension;
}
boolean fileSelected = value != null;
boolean uploadEntryMissing = entry.name == null; //only the first time is shown the page, after we have always the entry.name... thanks to filter
boolean alreadyPersisted = (persistentFile != null && persistentFile.getUID() != 0);
//creating a file
boolean creatingAFile = fileSelected && !alreadyPersisted;
//updating a file
boolean updatingAFile = fileSelected && alreadyPersisted;
//leave it as it is
boolean leaveItAlone = uploadEntryMissing && alreadyPersisted;
//removing a file
boolean removeIt = !uploadEntryMissing && alreadyPersisted && !fileSelected;
//DO NOT TOUCH THIS WITHOUT ASKING PIETRO
if (!fileSelected && !alreadyPersisted) {
persistentFile = null;
return null;
}
//DO NOT TOUCH THIS WITHOUT ASKING PIETRO
if (leaveItAlone) {
pageState.addClientEntry(formFieldName, persistentFile.serialize());
return persistentFile;
}
boolean isBlob = persistentFile == null || PersistentFile.TYPE_DB.equals(persistentFile.getType());
boolean isWebApp = persistentFile != null && PersistentFile.TYPE_WEBAPP_FILESTORAGE.equals(persistentFile.getType());
if (persistentFile != null) {
if (creatingAFile || updatingAFile) {
if (isBlob) {
UploadHelper uh = UploadHelper.getInstance(entry.name, pageState);
if (uh != null && uh.originalFileName != null && uh.originalFileName.trim().length() > 0) {
BinaryLargeObject blo = null;
if (updatingAFile) {
blo = (BinaryLargeObject) PersistenceHome.findByPrimaryKey(BinaryLargeObject.class, persistentFile.getUID());
//we are forced to create always a new one, as at least in Oracle the update of multiple blobs in the same trans seems broken.
if (blo!=null)
blo.remove();
}
blo = new BinaryLargeObject();
try {
blo.feed(new FileInputStream(uh.temporaryFile));
blo.setReferral(mainObject);
blo.setOriginalFileName(uh.originalFileName);
blo.store();
persistentFile = new PersistentFile(Integer.parseInt(blo.getId().toString()), uh.originalFileName);
entry.setValue(persistentFile.serialize());
} catch (FileNotFoundException e) {
throw new ApplicationException(e);
}
}
} else {
if (updatingAFile) {
String path = "";
if (PersistentFile.TYPE_WEBAPP_FILESTORAGE.equals(persistentFile.getType())) {
String location = persistentFile.getFileLocation();
location = StringUtilities.replaceAllNoRegex(location, "/", File.separator);
location = StringUtilities.replaceAllNoRegex(location, "\\", File.separator);
path = ApplicationState.webAppFileSystemRootPath + location;
} else if (PersistentFile.TYPE_FILESTORAGE.equals(persistentFile.getType()))
path = ApplicationState.getApplicationSetting(SystemConstants.FLD_REPOSITORY_URL) + persistentFile.getFileLocation();
else
path = persistentFile.getFileLocation();
File delendo = new File(path);
FileUtilities.tryHardToDeleteFile(delendo);
}
try {
persistentFile.setUID(CounterHome.next(PersistentFile.PERSISTENTFILE_ID));
String folderLocation = null;
//this is the relative path
String fileDir = persistentFile.fileDir != null ? persistentFile.fileDir : "";
String type = persistentFile.getType();
//this is the complete path
if (isWebApp){
fileDir = StringUtilities.replaceAllNoRegex(fileDir, "/", File.separator);
fileDir = StringUtilities.replaceAllNoRegex(fileDir, "\\", File.separator);
folderLocation = ApplicationState.webAppFileSystemRootPath + File.separator + fileDir;
} else if (PersistentFile.TYPE_FILESTORAGE.equals(persistentFile.getType()))
folderLocation = ApplicationState.getApplicationSetting(SystemConstants.FLD_REPOSITORY_URL) + (fileDir.trim().length() > 0 ? File.separator + fileDir : "");
else
folderLocation = fileDir;
UploadHelper uh = UploadHelper.saveInFolder(formFieldName, persistentFile.getUID(), null, folderLocation, null, nameToGiveToFileInRepository, pageState);
persistentFile.setType(type);
if (isWebApp)
persistentFile.setFileLocation(fileDir + "/" + uh.repositoryFileName);//File.separator
else if (PersistentFile.TYPE_FILESTORAGE.equals(persistentFile.getType()))
persistentFile.setFileLocation(fileDir + File.separator + uh.repositoryFileName);
else
persistentFile.setFileLocation(uh.repositoryPath);
if (uh.originalFileName != null) {
persistentFile.setOriginalFileName(value);
entry.setValue(nameToGiveToFileInRepository);
}
} catch (IOException e) {
throw new ApplicationException(e);
}
}
}
}
if (removeIt) {
if (persistentFile != null) {
if (isBlob)
((IdentifiableSupport) PersistenceHome.findByPrimaryKey(BinaryLargeObject.class, persistentFile.getUID())).remove();
else {
File delendo = new File(persistentFile.getFileLocation());
FileUtilities.tryHardToDeleteFile(delendo);
}
persistentFile = null;
}
} else {
if (persistentFile != null) {
int index = persistentFile.serialize().length();
for (int i = 0; i < 3; i++) {
index = persistentFile.serialize().lastIndexOf(".", index);
}
pageState.addClientEntry(formFieldName, persistentFile.serialize());
}
}
return persistentFile;
}
}