update setBlobValuesToDownloadUrls to not do that if the field is set to use a downloadUrlDyanmic.

This commit is contained in:
2025-02-24 10:46:39 -06:00
parent 35c4049174
commit 80c286ab00
2 changed files with 111 additions and 7 deletions

View File

@ -23,8 +23,6 @@ package com.kingsrook.qqq.backend.core.actions.values;
import java.io.Serializable; import java.io.Serializable;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
@ -34,7 +32,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.logging.QLogger;
@ -48,6 +45,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.core.utils.ValueUtils; import com.kingsrook.qqq.backend.core.utils.ValueUtils;
import org.apache.commons.lang3.BooleanUtils;
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
@ -488,6 +486,8 @@ public class QValueFormatter
String fileNameFormat = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.FILE_NAME_FORMAT)); String fileNameFormat = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.FILE_NAME_FORMAT));
String defaultExtension = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.DEFAULT_EXTENSION)); String defaultExtension = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.DEFAULT_EXTENSION));
Boolean downloadUrlDynamic = ValueUtils.getValueAsBoolean(adornmentValues.get(AdornmentType.FileDownloadValues.DOWNLOAD_URL_DYNAMIC));
for(QRecord record : records) for(QRecord record : records)
{ {
if(!doesFieldHaveValue(field, record)) if(!doesFieldHaveValue(field, record))
@ -495,6 +495,11 @@ public class QValueFormatter
continue; continue;
} }
if(BooleanUtils.isTrue(downloadUrlDynamic))
{
continue;
}
Serializable primaryKey = record.getValue(table.getPrimaryKeyField()); Serializable primaryKey = record.getValue(table.getPrimaryKeyField());
String fileName = null; String fileName = null;
@ -544,10 +549,7 @@ public class QValueFormatter
|| adornmentValues.containsKey(AdornmentType.FileDownloadValues.SUPPLEMENTAL_CODE_REFERENCE) || adornmentValues.containsKey(AdornmentType.FileDownloadValues.SUPPLEMENTAL_CODE_REFERENCE)
|| adornmentValues.containsKey(AdornmentType.FileDownloadValues.SUPPLEMENTAL_PROCESS_NAME)) || adornmentValues.containsKey(AdornmentType.FileDownloadValues.SUPPLEMENTAL_PROCESS_NAME))
{ {
record.setValue(field.getName(), "/data/" + table.getName() + "/" record.setValue(field.getName(), AdornmentType.FileDownloadValues.makeFieldDownloadUrl(table.getName(), primaryKey, field.getName(), fileName));
+ URLEncoder.encode(ValueUtils.getValueAsString(primaryKey), StandardCharsets.UTF_8) + "/"
+ field.getName() + "/"
+ URLEncoder.encode(Objects.requireNonNullElse(fileName, ""), StandardCharsets.UTF_8));
} }
record.setDisplayValue(field.getName(), fileName); record.setDisplayValue(field.getName(), fileName);
} }

View File

@ -30,19 +30,23 @@ import java.time.LocalTime;
import java.time.Month; import java.time.Month;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import com.kingsrook.qqq.backend.core.BaseTest; import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
import com.kingsrook.qqq.backend.core.model.metadata.fields.DateTimeDisplayValueBehavior; import com.kingsrook.qqq.backend.core.model.metadata.fields.DateTimeDisplayValueBehavior;
import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat; import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat;
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.utils.TestUtils; import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
@ -237,4 +241,102 @@ class QValueFormatterTest extends BaseTest
assertEquals("2024-04-04 02:12:00 PM CDT", record.getDisplayValue("createDate")); assertEquals("2024-04-04 02:12:00 PM CDT", record.getDisplayValue("createDate"));
} }
/*******************************************************************************
**
*******************************************************************************/
@Test
void testBlobValuesToDownloadUrls()
{
byte[] blobBytes = "hello".getBytes();
{
QTableMetaData table = new QTableMetaData()
.withName("testTable")
.withPrimaryKeyField("id")
.withField(new QFieldMetaData("id", QFieldType.INTEGER))
.withField(new QFieldMetaData("blobField", QFieldType.BLOB)
.withFieldAdornment(new FieldAdornment().withType(AdornmentType.FILE_DOWNLOAD)
.withValue(AdornmentType.FileDownloadValues.FILE_NAME_FORMAT, "blob-%s.txt")
.withValue(AdornmentType.FileDownloadValues.FILE_NAME_FORMAT_FIELDS, new ArrayList<>(List.of("id")))));
//////////////////////////////////////////////////////////////////
// verify display value gets set to formated file-name + fields //
// and raw value becomes URL for downloading the byte //
//////////////////////////////////////////////////////////////////
QRecord record = new QRecord().withValue("id", 47).withValue("blobField", blobBytes);
QValueFormatter.setBlobValuesToDownloadUrls(table, List.of(record));
assertEquals("/data/testTable/47/blobField/blob-47.txt", record.getValueString("blobField"));
assertEquals("blob-47.txt", record.getDisplayValue("blobField"));
////////////////////////////////////////////////////////
// verify that w/ no blob value, we don't do anything //
////////////////////////////////////////////////////////
QRecord recordWithoutBlobValue = new QRecord().withValue("id", 47);
QValueFormatter.setBlobValuesToDownloadUrls(table, List.of(recordWithoutBlobValue));
assertNull(recordWithoutBlobValue.getValue("blobField"));
assertNull(recordWithoutBlobValue.getDisplayValue("blobField"));
}
{
FieldAdornment adornment = new FieldAdornment().withType(AdornmentType.FILE_DOWNLOAD)
.withValue(AdornmentType.FileDownloadValues.FILE_NAME_FIELD, "fileName");
QTableMetaData table = new QTableMetaData()
.withName("testTable")
.withPrimaryKeyField("id")
.withField(new QFieldMetaData("id", QFieldType.INTEGER))
.withField(new QFieldMetaData("fileName", QFieldType.STRING))
.withField(new QFieldMetaData("blobField", QFieldType.BLOB)
.withFieldAdornment(adornment));
////////////////////////////////////////////////////
// here get the file name directly from one field //
////////////////////////////////////////////////////
QRecord record = new QRecord().withValue("id", 47).withValue("blobField", blobBytes).withValue("fileName", "myBlob.txt");
QValueFormatter.setBlobValuesToDownloadUrls(table, List.of(record));
assertEquals("/data/testTable/47/blobField/myBlob.txt", record.getValueString("blobField"));
assertEquals("myBlob.txt", record.getDisplayValue("blobField"));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// switch to use dynamic url, rerun, and assert we get the values as they were on the record before the call //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
adornment.withValue(AdornmentType.FileDownloadValues.DOWNLOAD_URL_DYNAMIC, true);
record = new QRecord().withValue("id", 47).withValue("blobField", blobBytes).withValue("fileName", "myBlob.txt")
.withDisplayValue("blobField:" + AdornmentType.FileDownloadValues.DOWNLOAD_URL_DYNAMIC, "/something-custom/")
.withDisplayValue("blobField", "myDisplayValue");
QValueFormatter.setBlobValuesToDownloadUrls(table, List.of(record));
assertArrayEquals(blobBytes, record.getValueByteArray("blobField"));
assertEquals("myDisplayValue", record.getDisplayValue("blobField"));
}
{
FieldAdornment adornment = new FieldAdornment().withType(AdornmentType.FILE_DOWNLOAD);
QTableMetaData table = new QTableMetaData()
.withName("testTable")
.withLabel("Test Table")
.withPrimaryKeyField("id")
.withField(new QFieldMetaData("id", QFieldType.INTEGER))
.withField(new QFieldMetaData("blobField", QFieldType.BLOB).withLabel("Blob").withFieldAdornment(adornment));
///////////////////////////////////////////////////////////////////////////////////////////
// w/o file name format or whatever, generate a file name from table & id & field labels //
///////////////////////////////////////////////////////////////////////////////////////////
QRecord record = new QRecord().withValue("id", 47).withValue("blobField", blobBytes);
QValueFormatter.setBlobValuesToDownloadUrls(table, List.of(record));
assertEquals("/data/testTable/47/blobField/Test+Table+47+Blob", record.getValueString("blobField"));
assertEquals("Test Table 47 Blob", record.getDisplayValue("blobField"));
////////////////////////////////////////
// add a default extension and re-run //
////////////////////////////////////////
adornment.withValue(AdornmentType.FileDownloadValues.DEFAULT_EXTENSION, "html");
record = new QRecord().withValue("id", 47).withValue("blobField", blobBytes);
QValueFormatter.setBlobValuesToDownloadUrls(table, List.of(record));
assertEquals("/data/testTable/47/blobField/Test+Table+47+Blob.html", record.getValueString("blobField"));
assertEquals("Test Table 47 Blob.html", record.getDisplayValue("blobField"));
}
}
} }