package pt.ist.renderers.validators;
import pt.ist.renderers.components.HtmlInputFile;
import pt.ist.renderers.plugin.RenderersRequestProcessorImpl;
import pt.ist.renderers.servlets.commons.UploadedFile;
import pt.ist.renderers.utils.RenderUtils;
/**
* This validator can be used to validate uploaded files. It allows you to
* restrict the file maximum size, extension, and type.
*
* @author cfgi
*/
public class FileValidator extends HtmlValidator {
private boolean required;
private String maxSize;
private String acceptedExtensions;
private String acceptedTypes;
private String typeMessage;
private String extensionMessage;
private String sizeMessage;
private String bundle;
private Object[] arguments;
public FileValidator() {
super();
setTypeMessage("renderers.validator.file.type");
setExtensionMessage("renderers.validator.file.extension");
setSizeMessage("renderers.validator.file.size");
}
public FileValidator(HtmlChainValidator htmlChainValidator) {
super(htmlChainValidator);
setTypeMessage("renderers.validator.file.type");
setExtensionMessage("renderers.validator.file.extension");
setSizeMessage("renderers.validator.file.size");
}
public boolean isRequired() {
return this.required;
}
public void setRequired(boolean required) {
this.required = required;
}
public String getAcceptedExtensions() {
return this.acceptedExtensions;
}
/**
* The list file extensions allowed separated by a comma. For example
* "gif,jpg,png"
. If the extension is specified then it has
* priority over the accepted types. If the file has no extension then the
* accepted types are used if provided.
*/
public void setAcceptedExtensions(String acceptedExtensions) {
this.acceptedExtensions = acceptedExtensions.toLowerCase();
}
public String getAcceptedTypes() {
return this.acceptedTypes != null ? this.acceptedTypes.toLowerCase() : null;
}
/**
* List of accepted types separated by a comma. For example
* "image/gif,image/jpg,image/png"
. You can also use wildcards
* like "image/*"
.
*/
public void setAcceptedTypes(String acceptedTypes) {
this.acceptedTypes = acceptedTypes;
}
public String getMaxSize() {
return this.maxSize;
}
/**
* The maximum size allowed for files. You can specify the units using the
* suffix "MB"
, "KB"
, or "B"
. If no
* units are given the value is considered to be in bytes.
*/
public void setMaxSize(String maxSize) {
this.maxSize = maxSize;
}
public String getExtensionMessage() {
return extensionMessage;
}
public void setExtensionMessage(String extensionMessage) {
this.extensionMessage = extensionMessage;
}
public String getSizeMessage() {
return sizeMessage;
}
public void setSizeMessage(String sizeMessage) {
this.sizeMessage = sizeMessage;
}
public String getTypeMessage() {
return typeMessage;
}
public void setTypeMessage(String typeMessage) {
this.typeMessage = typeMessage;
}
@Override
public String getBundle() {
return bundle;
}
@Override
public void setBundle(String bundle) {
this.bundle = bundle;
}
private long convertedMaxSize() {
String maxSize = getMaxSize().trim().toLowerCase();
long value;
long multiplier = 1;
if (maxSize.matches("[0-9]+(m|k)?b")) {
int index;
index = maxSize.indexOf("mb");
if (index != -1) {
multiplier = 1024 * 1024;
} else {
index = maxSize.indexOf("kb");
if (index != -1) {
multiplier = 1024;
} else {
index = maxSize.indexOf("b");
}
}
value = Long.parseLong(maxSize.substring(0, index));
} else {
value = Long.parseLong(maxSize);
}
return value * multiplier;
}
@Override
protected String getResourceMessage(String message) {
if (this.arguments == null || this.arguments.length == 0) {
return RenderUtils.getResourceString(getBundle(), message);
} else {
return RenderUtils.getFormatedResourceString(getBundle(), message, this.arguments);
}
}
@Override
public void performValidation() {
HtmlInputFile fileField = (HtmlInputFile) getComponent();
UploadedFile file = RenderersRequestProcessorImpl.getUploadedFile(fileField.getName());
if (file == null && isRequired()) {
setInvalid("renderers.validator.required");
return;
}
if (file == null) {
return;
}
if (getMaxSize() != null) {
long size = file.getSize();
long maxSize = convertedMaxSize();
if (size > maxSize) {
setInvalid(getSizeMessage(), maxSize, getMaxSize());
return;
}
}
if (getAcceptedExtensions() != null) {
String fileName = file.getName();
int index = fileName.lastIndexOf(".");
if (index != -1) {
String extension = fileName.substring(index + 1).toLowerCase();
if (!getAcceptedExtensions().contains(extension)) {
setInvalid(getExtensionMessage(), getAcceptedExtensions(), extension);
return;
} else {
setValid(true);
return;
}
}
}
if (getAcceptedTypes() != null) {
if (!matchesMimeType(file.getContentType().toLowerCase())) {
String typesFormated = getAcceptedTypes().replace(",", ", ");
setInvalid(getTypeMessage(), typesFormated, file.getContentType());
return;
}
}
setValid(true);
}
private boolean matchesMimeType(String contentType) {
String[] acceptedTypes = getAcceptedTypes().split(",");
for (int i = 0; i < acceptedTypes.length; i++) {
String accepted = acceptedTypes[i];
if (accepted.contains("*")) {
accepted = accepted.replace("*", ".*");
}
if (contentType.matches(accepted)) {
return true;
}
}
return false;
}
private void setInvalid(String message, Object... args) {
setMessage(message);
this.arguments = args;
setValid(false);
}
}