Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/996 default formats #998

Merged
merged 2 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,38 @@
import java.util.HashMap;
import java.util.Map;

final class ContentTypeAliasMap
{
private final Map<String, ContentType> _contentTypeMap = new HashMap<>();
private static final Map<Class<? extends CwmsDTOBase>, ContentTypeAliasMap> ALIAS_MAP = new HashMap<>();

private ContentTypeAliasMap()
{
}

private ContentTypeAliasMap(Class<? extends CwmsDTOBase> dtoClass)
{
FormattableWith[] formats = dtoClass.getAnnotationsByType(FormattableWith.class);
for (FormattableWith format : formats)
{
ContentType type = new ContentType(format.contentType());

for (String alias : format.aliases())
{
_contentTypeMap.put(alias, type);
}
}
}

public static ContentTypeAliasMap forDtoClass(@NotNull Class<? extends CwmsDTOBase> dtoClass)
{
return ALIAS_MAP.computeIfAbsent(dtoClass, ContentTypeAliasMap::new);
}

public static ContentTypeAliasMap empty()
{
return new ContentTypeAliasMap();
}

public ContentType getContentType(String alias)
{
return _contentTypeMap.get(alias);
}
final class ContentTypeAliasMap {
private final Map<ContentType, ContentType> contentTypeMap = new HashMap<>();
private static final Map<Class<? extends CwmsDTOBase>, ContentTypeAliasMap> ALIAS_MAP = new HashMap<>();

private ContentTypeAliasMap()
{
}

private ContentTypeAliasMap(Class<? extends CwmsDTOBase> dtoClass) {
FormattableWith[] formats = dtoClass.getAnnotationsByType(FormattableWith.class);
for (FormattableWith format : formats) {
ContentType type = new ContentType(format.contentType());

for (String alias : format.aliases()) {
contentTypeMap.put(new ContentType(alias), type);
}
}
}

public static ContentTypeAliasMap forDtoClass(@NotNull Class<? extends CwmsDTOBase> dtoClass) {
return ALIAS_MAP.computeIfAbsent(dtoClass, ContentTypeAliasMap::new);
}

public static ContentTypeAliasMap empty() {
return new ContentTypeAliasMap();
}

public ContentType getContentType(ContentType alias) {
return contentTypeMap.get(alias);
}

public ContentType getContentType(String alias) {
return contentTypeMap.get(new ContentType(alias));
}
}
16 changes: 10 additions & 6 deletions cwms-data-api/src/main/java/cwms/cda/formatters/Formats.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public static String getLegacyTypeFromContentType(ContentType contentType)
private String getFormatted(ContentType type, CwmsDTOBase toFormat) throws FormattingException {
Objects.requireNonNull(toFormat, "Object to be formatted should not be null");
formatters.keySet().forEach(k -> logger.fine(k::toString));
OutputFormatter outputFormatter = getOutputFormatter(type, toFormat.getClass());
OutputFormatter outputFormatter = getOutputFormatterInternal(type, toFormat.getClass());

if (outputFormatter != null) {
return outputFormatter.format(toFormat);
Expand All @@ -134,7 +134,7 @@ private String getFormatted(ContentType type, List<? extends CwmsDTOBase> dtos,
logger.finest(() -> key.toString());
}

OutputFormatter outputFormatter = getOutputFormatter(type, rootType);
OutputFormatter outputFormatter = getOutputFormatterInternal(type, rootType);

if (outputFormatter != null) {
return outputFormatter.format(dtos);
Expand All @@ -147,7 +147,7 @@ private String getFormatted(ContentType type, List<? extends CwmsDTOBase> dtos,

private <T extends CwmsDTOBase> T parseContentFromType(ContentType type, String content, Class<T> rootType)
throws FormattingException {
OutputFormatter outputFormatter = getOutputFormatter(type, rootType);
OutputFormatter outputFormatter = getOutputFormatterInternal(type, rootType);
if (outputFormatter != null) {
T retval = outputFormatter.parseContent(content, rootType);
retval.validate();
Expand All @@ -161,7 +161,7 @@ private <T extends CwmsDTOBase> T parseContentFromType(ContentType type, String

private <T extends CwmsDTOBase> T parseContentFromType(ContentType type, InputStream content, Class<T> rootType)
throws FormattingException {
OutputFormatter outputFormatter = getOutputFormatter(type, rootType);
OutputFormatter outputFormatter = getOutputFormatterInternal(type, rootType);
if (outputFormatter != null) {
T retval = outputFormatter.parseContent(content, rootType);
retval.validate();
Expand All @@ -175,7 +175,7 @@ private <T extends CwmsDTOBase> T parseContentFromType(ContentType type, InputSt

private <T extends CwmsDTOBase> List<T> parseContentListFromType(ContentType type, String content, Class<T> rootType)
throws FormattingException {
OutputFormatter outputFormatter = getOutputFormatter(type, rootType);
OutputFormatter outputFormatter = getOutputFormatterInternal(type, rootType);
if (outputFormatter != null) {
List<T> retval = outputFormatter.parseContentList(content, rootType);
if (retval == null) {
Expand All @@ -192,7 +192,7 @@ private <T extends CwmsDTOBase> List<T> parseContentListFromType(ContentType typ
}
}

private OutputFormatter getOutputFormatter(ContentType type,
private OutputFormatter getOutputFormatterInternal(ContentType type,
Class<? extends CwmsDTOBase> klass) {
OutputFormatter outputFormatter = null;
Map<Class<? extends CwmsDTOBase>, OutputFormatter> contentFormatters = formatters.get(type);
Expand All @@ -219,6 +219,10 @@ private OutputFormatter getOutputFormatter(ContentType type,
return outputFormatter;
}

public static OutputFormatter getOutputFormatter(ContentType ct, Class<? extends CwmsDTOBase> klass) {
return formats.getOutputFormatterInternal(ct, klass);
}

public static String format(ContentType type, CwmsDTOBase toFormat) throws FormattingException {
return formats.getFormatted(type, toFormat);
}
Expand Down
35 changes: 32 additions & 3 deletions cwms-data-api/src/test/java/cwms/cda/formatters/FormatsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
import cwms.cda.data.dto.basinconnectivity.Basin;
import cwms.cda.data.dto.project.LockRevokerRights;
import cwms.cda.data.dto.project.Project;
import cwms.cda.formatters.json.JsonV2;
import cwms.cda.formatters.xml.XMLv2;
import cwms.cda.formatters.xml.XMLv2Office;
import io.swagger.v3.oas.annotations.Parameter;

import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -183,7 +188,7 @@ void testParseHeaderFromFirefox() {
//The following header comes from firefox
ContentType contentType = Formats.parseHeader(FIREFOX_HEADER, Catalog.class);
assertNotNull(contentType);
assertEquals(Formats.DEFAULT, contentType.toString());
assertEquals(Formats.XML, contentType.toString());
}

@EnumSource(ParseHeaderClassAliasTest.class)
Expand Down Expand Up @@ -270,7 +275,6 @@ enum ParseQueryOrParamTest {
final String query;
final Class<? extends CwmsDTOBase> dto;
final String type;


ParseQueryOrParamTest(String header, String query, Class<? extends CwmsDTOBase> dto, String type)
{
Expand All @@ -279,7 +283,32 @@ enum ParseQueryOrParamTest {
this.dto = dto;
this.type = type;
}


}


@ParameterizedTest
@EnumSource(ContentTypeFormatterSource.class)
void test_formatter_retrieval(ContentTypeFormatterSource test) {
ContentType ct = Formats.parseHeader(test.contentType, test.dto);
OutputFormatter formatterActual = Formats.getOutputFormatter(ct, test.dto);
assertNotNull(formatterActual, "No formatters available for given Content-Type and DTO.");
assertEquals(test.formatter, formatterActual.getClass(), "Expected Formatter was not returned.");
}

public enum ContentTypeFormatterSource {
OFFICE_DEFAULT("*/*", Office.class, JsonV2.class),
OFFICE_FIREFOX_DEFAULT("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", Office.class, XMLv2Office.class)

;
final String contentType;
final Class<? extends CwmsDTOBase> dto;
final Class<? extends OutputFormatter> formatter;

ContentTypeFormatterSource(String contentType, Class<? extends CwmsDTOBase> dto, Class<? extends OutputFormatter> formatter) {
this.contentType = contentType;
this.dto = dto;
this.formatter = formatter;
}
}
}
Loading