Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
091f833
Lay groundwork for generic ListItem implementation
jloux-brapi Oct 12, 2026
5e18e83
Fix some bugs, add working example query
jloux-brapi Oct 13, 2026
9fd14f8
Clean out sample code, bolster SearchQueryBuilder attributes
jloux-brapi Oct 13, 2026
87f9608
Get /lists/{listDbId}/search/items into fully functional state
jloux-brapi Oct 14, 2026
3c08de5
Add @Formula for checking item position with 1 index
jloux-brapi Oct 14, 2026
6b906c9
Fix GermplasmService redline in IDE not causing compile or runtime er…
jloux-brapi Oct 14, 2026
abe7364
Merge branch 'epic/BI-2862' into feature/BI-3082
jloux-brapi Oct 15, 2026
bb71d95
Model edits
jloux-brapi Oct 15, 2026
4452596
Force type deserialization on client, changes to support this
jloux-brapi Oct 16, 2026
500a833
Validate fields in submitted search request to ensure proper searches
jloux-brapi Oct 16, 2026
6bb6f83
Simplify validation logic
jloux-brapi Oct 19, 2026
4a31b8e
Add clarifying comments
jloux-brapi Oct 19, 2026
677d759
Fix alias bug with synonyms
jloux-brapi Oct 19, 2026
aa58f06
Add comment to BrAPIRepositoryImpl
jloux-brapi Oct 19, 2026
84ec9bd
Add comments to SortAndFilterEntityColumnInfo
jloux-brapi Oct 19, 2026
1fc0445
Add comment for extra synonyms join
jloux-brapi Oct 19, 2026
f7593b2
Fix synonym wrong object setting/getting, SearchRequest sort/filter *…
jloux-brapi Oct 22, 2026
6e8e32d
Only re-add synonym join if filter present
jloux-brapi Oct 22, 2026
4db1b4f
Remove 202 from searchListByItemRequest, not relevant
jloux-brapi Oct 23, 2026
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
18 changes: 13 additions & 5 deletions src/main/java/io/swagger/api/core/ListsApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
*/
package io.swagger.api.core;

import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.model.BrAPIResponse;
import io.swagger.model.Model202AcceptedSearchResponse;
import io.swagger.model.core.ListNewRequest;
import io.swagger.model.core.ListResponse;
import io.swagger.model.core.ListSearchRequest;
import io.swagger.model.core.ListsListResponse;
import io.swagger.model.core.ListsSingleResponse;
import io.swagger.model.core.*;
import io.swagger.annotations.*;

import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException;
Expand Down Expand Up @@ -166,4 +163,15 @@ ResponseEntity<? extends BrAPIResponse> searchListsSearchResultsDbIdGet(
@ApiParam(value = "pageSize") @Valid @RequestParam(value = "pageSize", required = false) Integer pageSize,
@ApiParam(value = "HTTP HEADER - Token used for Authorization <strong> Bearer {token_string} </strong>") @RequestHeader(value = "Authorization", required = false) String authorization) throws BrAPIServerException;

@ApiOperation(value = "Submit a search request for List Items", nickname = "searchListByItemRequest", notes = "Advanced searching for the list item resource. See Search Services for additional implementation details.", response = ListItemsListResponse.class, authorizations = {
@Authorization(value = "AuthorizationToken") }, tags = { "Lists", })
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = ListItemsListResponse.class),
@ApiResponse(code = 400, message = "Bad Request", response = String.class),
@ApiResponse(code = 401, message = "Unauthorized", response = String.class),
@ApiResponse(code = 403, message = "Forbidden", response = String.class) })
@RequestMapping(value = "/search/lists/{listDbId}/items", produces = { "application/json" }, consumes = {
"application/json" }, method = RequestMethod.POST)
ResponseEntity<? extends BrAPIResponse> searchListByItemRequest(@ApiParam(value = "") @Valid @RequestBody JsonNode body,
@ApiParam(value = "Permanent unique identifier of list to perform search on", required = true) @PathVariable("listDbId") String listDbId,
@ApiParam(value = "HTTP HEADER - Token used for Authorization <strong> Bearer {token_string} </strong>") @RequestHeader(value = "Authorization", required = false) String authorization) throws BrAPIServerException;
}
18 changes: 9 additions & 9 deletions src/main/java/io/swagger/model/SearchRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.model.sort.SortBy;
import org.brapi.test.BrAPITestServer.exceptions.BrAPIServerException;
import org.brapi.test.BrAPITestServer.model.dto.EntityColumnNameAndType;
import org.brapi.test.BrAPITestServer.model.dto.SortAndFilterEntityColumnInfo;
import org.brapi.test.BrAPITestServer.model.dto.EntityType;
import org.springframework.http.HttpStatus;

Expand Down Expand Up @@ -150,7 +150,7 @@ public void setFilterBy(List<FilterBy> filterBy) throws BrAPIServerException {
return;
}

Map<String, EntityColumnNameAndType> allowedSortFilterNames = getEntityColAndTypeBySubmittedNameMap();
Map<String, SortAndFilterEntityColumnInfo> allowedSortFilterNames = getEntityColInfoBySubmittedNameMap();

for (FilterBy filterByItem : filterBy) {

Expand All @@ -162,17 +162,17 @@ public void setFilterBy(List<FilterBy> filterBy) throws BrAPIServerException {
throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "value attribute not provided in element of filterBy list.");
}

EntityColumnNameAndType entityColumnNameAndType = allowedSortFilterNames.get(filterByItem.getFilterOn());
SortAndFilterEntityColumnInfo sortAndFilterEntityColumnInfo = allowedSortFilterNames.get(filterByItem.getFilterOn());

if (entityColumnNameAndType == null) {
if (sortAndFilterEntityColumnInfo == null) {
throw new BrAPIServerException(HttpStatus.BAD_REQUEST,
String.format("Supplied filterColumn [%s] not available in allowed names [%s]", filterByItem.getFilterOn(), allowedSortFilterNames.keySet())
);
}

if (entityColumnNameAndType.getEntityType() == EntityType.BOOLEAN) {
if (sortAndFilterEntityColumnInfo.getEntityType() == EntityType.BOOLEAN) {
// TODO: Add support for this when it becomes relevant for BI or when there is time.
throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("Filtering not implemented for column name [%s] with associated data type [%s]", entityColumnNameAndType.getEntityColumnName(), EntityType.BOOLEAN));
throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("Filtering not implemented for column name [%s] with associated data type [%s]", sortAndFilterEntityColumnInfo.getEntityColumnName(), EntityType.BOOLEAN));
}
}
this.filterBy = filterBy;
Expand All @@ -188,14 +188,14 @@ public void setSortBy(List<SortBy> sortBy) throws BrAPIServerException {
return;
}

Map<String, EntityColumnNameAndType> allowedSortFilterNames = getEntityColAndTypeBySubmittedNameMap();
Map<String, SortAndFilterEntityColumnInfo> allowedSortFilterNames = getEntityColInfoBySubmittedNameMap();

for (SortBy sortByItem : sortBy) {
if (sortByItem.getSortedOn() == null || sortByItem.getSortedOn().isEmpty()) {
throw new BrAPIServerException(HttpStatus.BAD_REQUEST, "sortedOn attribute not provided in element of sortBy list");
}

EntityColumnNameAndType sortColumnEntityNameAndType = getEntityColAndTypeBySubmittedNameMap().get(sortByItem.getSortedOn());
SortAndFilterEntityColumnInfo sortColumnEntityNameAndType = getEntityColInfoBySubmittedNameMap().get(sortByItem.getSortedOn());

if (sortColumnEntityNameAndType == null) {
throw new BrAPIServerException(HttpStatus.BAD_REQUEST,
Expand All @@ -208,7 +208,7 @@ public void setSortBy(List<SortBy> sortBy) throws BrAPIServerException {
}

@JsonIgnore
public Map<String, EntityColumnNameAndType> getEntityColAndTypeBySubmittedNameMap() throws BrAPIServerException {
public Map<String, SortAndFilterEntityColumnInfo> getEntityColInfoBySubmittedNameMap() throws BrAPIServerException {
throw new BrAPIServerException(HttpStatus.BAD_REQUEST, String.format("Sort/Filtering not implemented for %s", this.getClass().getSimpleName()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.swagger.model.core;

import io.swagger.model.germ.GermplasmSearchRequest;
import org.brapi.test.BrAPITestServer.model.dto.SortAndFilterEntityColumnInfo;
import org.brapi.test.BrAPITestServer.model.dto.EntityType;

import java.util.Collections;
import java.util.Map;

public class GermplasmListSearchRequest extends GermplasmSearchRequest {

// The only real difference in this request is that there's an extra sort/filter field that GermplasmSearchRequest doesn't have.
// It is specific to lists. In general, other EntityListSearchRequests like this one should look the same, but have different base search requests.
private static final Map<String, SortAndFilterEntityColumnInfo>
LIST_ALLOWED_FIELDS;

static {
Map<String, SortAndFilterEntityColumnInfo> fields =
copyAllowedSortAndFilterFields();

fields.put(
"listItemPosition",
new SortAndFilterEntityColumnInfo("*listItem.positionIndexedBy1", EntityType.NUMBER, false, true)
);

LIST_ALLOWED_FIELDS = Collections.unmodifiableMap(fields);
}

@Override
public Map<String, SortAndFilterEntityColumnInfo> getEntityColInfoBySubmittedNameMap() {
return LIST_ALLOWED_FIELDS;
}
}
95 changes: 95 additions & 0 deletions src/main/java/io/swagger/model/core/ListItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package io.swagger.model.core;

import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.validation.annotation.Validated;

/**
* ListItem
*/
@Validated
@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2020-03-20T16:31:52.030Z[GMT]")
public class ListItem {
@JsonProperty("listItemDbId")
private String listItemDbId = null;

@JsonProperty("position")
private Integer position = null;

// This represents the actual value stored in the list_item table
@JsonProperty("item")
private String item = null;

/**
* The unique identifier for a List
* @return listDbId
**/
@ApiModelProperty(example = "6f621cfa", required = true, value = "The unique identifier for a List")


public String getListItemDbId() {
return listItemDbId;
}

public void setListItemDbId(String listItemDbId) {
this.listItemDbId = listItemDbId;
}

public Integer getPosition() {
return position;
}

public void setPosition(Integer position) {
this.position = position;
}

public String getItem() {
return item;
}

public void setItem(String item) {
this.item = item;
}

@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ListItem ListItem = (ListItem) o;
return Objects.equals(this.listItemDbId, ListItem.listItemDbId) &&
super.equals(o);
}

@Override
public int hashCode() {
return Objects.hash(listItemDbId, super.hashCode());
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ListItem {\n");
sb.append(" ").append(toIndentedString(super.toString())).append("\n");
sb.append(" listDbId: ").append(toIndentedString(listItemDbId)).append("\n");
sb.append("}");
return sb.toString();
}

/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}


83 changes: 83 additions & 0 deletions src/main/java/io/swagger/model/core/ListItemWithFullItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package io.swagger.model.core;

import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.validation.annotation.Validated;

/**
* ListItemWithFullItem
*/
@Validated
@javax.annotation.processing.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2020-03-20T16:31:52.030Z[GMT]")
public class ListItemWithFullItem<T> {
@JsonProperty("listItem")
private ListItem listItem = null;

// The full actual BrAPI model object of the list item is supplied/written into here
@JsonProperty("item")
private T item = null;

/**
* The unique identifier for a List
* @return listItem
**/
@ApiModelProperty(example = "6f621cfa", required = true, value = "The unique identifier for a List")


public ListItem getListItem() {
return listItem;
}

public void setListItem(ListItem listItem) {
this.listItem = listItem;
}

public T getItem() {
return item;
}

public void setItem(T item) {
this.item = item;
}

@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ListItemWithFullItem<T> listItemWithFullItem = (ListItemWithFullItem<T>) o;
return Objects.equals(this.listItem, listItemWithFullItem.listItem) &&
super.equals(o);
}

@Override
public int hashCode() {
return Objects.hash(listItem, super.hashCode());
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ListItemWithFullItem {\n");
sb.append(" ").append(toIndentedString(super.toString())).append("\n");
sb.append(" listItem: ").append(toIndentedString(listItem)).append("\n");
sb.append("}");
return sb.toString();
}

/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

Loading