Skip to content

Commit

Permalink
Merge pull request #308 from devgateway/task/3.x/locale-aware-file-si…
Browse files Browse the repository at this point in the history
…ze-validator

locale aware file size validator (3.x)
  • Loading branch information
mpostelnicu authored Oct 8, 2020
2 parents e39fcde + 6c72e5f commit 1ded699
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.devgateway.toolkit.forms.validators;

import org.apache.wicket.ThreadContext;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.IValidator;
import org.apache.wicket.validation.ValidationError;
import org.devgateway.toolkit.persistence.dao.FileMetadata;
import org.devgateway.toolkit.persistence.dto.FileSize;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Collection;

/**
* @author Nadejda Mandrescu
*/
public class MaxFileSizeValidator implements IValidator<Collection<FileMetadata>> {
private static final long serialVersionUID = -4386023418740650823L;

private FormComponent formComponent;
private FileSize maxFileSize;
private long maxFileSizeBytes;

public MaxFileSizeValidator(final FileSize maxFileSize, final FormComponent formComponent) {
this.maxFileSizeBytes = maxFileSize.toBytes();
this.maxFileSize = maxFileSize.toHighest();
this.formComponent = formComponent;
}

@Override
public void validate(final IValidatable<Collection<FileMetadata>> validatable) {
NumberFormat formatter = getNumberFormat();

validatable.getValue().stream().filter(m -> m.getSize() > maxFileSizeBytes).forEach(m -> {
String unitStr = formComponent.getString("fileUnit." + maxFileSize.getUnit().getName());
String valueStr = formatter.format(maxFileSize.getValue());

ValidationError error = new ValidationError(this);
error.setVariable("fileName", m.getName());
error.setVariable("maxFileSize", valueStr);
error.setVariable("sizeUnit", unitStr);
validatable.error(error);
});
}

private NumberFormat getNumberFormat() {
NumberFormat formatter = DecimalFormat.getInstance(ThreadContext.getSession().getLocale());
formatter.setMaximumFractionDigits(1);
formatter.setMinimumFractionDigits(0);
return formatter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MaxFileSizeValidator='${fileName}' file size must be at most ${maxFileSize}${sizeUnit}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ navbar.adminSettings=Settings
navbar.springendpoints=Spring Endpoints
navbar.lang=Language
navbar.javamelody=Javamelody
brandImageAltText=DG-Toolkit
brandImageAltText=DG-Toolkit

fileUnit.B=B
fileUnit.KB=KB
fileUnit.MB=MB
fileUnit.GB=GB
fileUnit.TB=TB
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.devgateway.toolkit.persistence.dto;

import java.io.Serializable;

/**
* This class together with FileSizeUnit is needed to allow locale formatting for both size and unit.
* It covers the limitations of FileUtils.byteCountToDisplaySize and org.apache.wicket.util.lang.Bytes.toString().
*
* @author Nadejda Mandrescu
*/
public class FileSize implements Serializable {
private static final long serialVersionUID = 5848568685865060136L;

private final double value;

private final FileSizeUnit unit;

public FileSize(final double sizeInBytes) {
this(sizeInBytes, FileSizeUnit.B);
}

public FileSize(final double sizePerUnit, final FileSizeUnit fileSizeUnit) {
this.value = sizePerUnit;
this.unit = fileSizeUnit;
}

public double getValue() {
return value;
}

public FileSizeUnit getUnit() {
return unit;
}

public long toBytes() {
return Math.round(value * Math.pow(FileSizeUnit.UNIT_DIVISOR, unit.ordinal()));
}

/**
* @return file size using highest unit with size >= 1
*/
public FileSize toHighest() {
double v = value;
FileSizeUnit u = this.unit;

while (v > FileSizeUnit.UNIT_DIVISOR && (FileSizeUnit.values().length > u.ordinal() + 1)) {
v = v / FileSizeUnit.UNIT_DIVISOR;
u = FileSizeUnit.values()[u.ordinal() + 1];
}
return new FileSize(v, u);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.devgateway.toolkit.persistence.dto;

/**
* Used for FileSize
* @author Nadejda Mandrescu
* @see FileSize
*/
public enum FileSizeUnit {
B("B"),
KB("KB"),
MB("MB"),
GB("GB"),
TB("TB");

// or can be UX standard of 1000
public static final long UNIT_DIVISOR = 1024;

private final String name;

FileSizeUnit(final String name) {
this.name = name;
}

public String getName() {
return name;
}
}

0 comments on commit 1ded699

Please sign in to comment.