Skip to content

Commit

Permalink
make query parameter SUMMARY instead of SUMMARY_SIZE
Browse files Browse the repository at this point in the history
clean
  • Loading branch information
austin007008 committed Dec 6, 2024
1 parent 057188b commit 2eac9ae
Show file tree
Hide file tree
Showing 18 changed files with 333 additions and 322 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public class QueryParameters {
/**
* Used to specify summaries that should be returned.
*/
public static final String SUMMARY_SIZE = "summary.size";
public static final String SUMMARY_OPTIONS = "summary.options";

/**
* Used to specify model or DB fields that should be treated as lenient (can be skipped if normalization fails)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package datawave.query.attributes;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

import datawave.query.Constants;
import datawave.query.postprocessing.tf.PhraseIndexes;

/**
* Represents options for a summary that have been specified within an #SUMMARY_SIZE function. An instance of {@link SummaryOptions} can easily be captured as a
* parameter string using {@link SummaryOptions#toString()}, and transformed back into a {@link SummaryOptions} instance via
* {@link SummaryOptions#from(String)}.
*/
public class SummaryOptions implements Serializable {

private static final long serialVersionUID = 6769159729743311079L;

private static final Logger log = LoggerFactory.getLogger(SummaryOptions.class);

public static final String SIZE_PARAMETER = "SIZE";
public static final String VIEWS_PARAMETER = "VIEWS";

private static final int DEFAULT_SIZE = 150;

private int summarySize;
private ArrayList<String> viewNamesList;
private boolean only;

public SummaryOptions() {
summarySize = 0;
viewNamesList = new ArrayList<>();
only = false;
}

/**
* Returns a new {@link SummaryOptions} parsed from the string. The provided string is expected to have the format returned by
* {@link SummaryOptions#toString()}.
* <ul>
* <li>Given null, null will be returned.</li>
* <li>Given an empty or blank string, a {@link SummaryOptions} with a size of DEFAULT_SIZE (currently 150) will be returned.</li>
* <li>Given {@code SIZE:50/ONLY/VIEWS:CONTENT1,CONTENT2}, an {@link SummaryOptions} will be returned with a size of 50 (size is number of characters), only
* using the specified view names, and list of view names of (CONTENT1, CONTENT2).
* <li>Given malformed input, will return an empty {@link SummaryOptions}.</li>
* </ul>
*
* @param string
* the string to parse
* @return the parsed {@link SummaryOptions}
*/
@JsonCreator
public static SummaryOptions from(String string) {
if (string == null) {
return null;
}
// Strip whitespaces.
string = PhraseIndexes.whitespacePattern.matcher(string).replaceAll("");

SummaryOptions summaryOptions = new SummaryOptions();

// if passed no parameters, return of summary of default size
if (string.isBlank()) {
summaryOptions.summarySize = DEFAULT_SIZE;
return summaryOptions;
}

try {
// split on / to get the separate options
String[] parameterParts = string.split(Constants.FORWARD_SLASH);

// go through each option and try to set them
for (String parameterPart : parameterParts) {
// for options that are "key:value", split on colon to get the key
String[] parts = parameterPart.split(Constants.COLON);
// if we have the "size" option...
if (parts[0].equalsIgnoreCase(SIZE_PARAMETER)) {
summaryOptions.summarySize = Integer.parseInt(parts[1]);
}
// if we have the "only" option...
else if (parts[0].equalsIgnoreCase("ONLY")) {
summaryOptions.only = true;
}
// if we have the "views" option...
else if (parts[0].equalsIgnoreCase(VIEWS_PARAMETER)) {
// the view names are split by commas. split them, uppercase them, then add the to the list.
String[] names = parts[1].split(Constants.COMMA);
for (String name : names) {
summaryOptions.viewNamesList.add(name.toUpperCase());
}
}
}
} catch (Exception e) {
log.warn("Unable to parse summary size string, returning empty SummaryOptions: {}", string, e);
return new SummaryOptions();
}

return summaryOptions;
}

/**
* Returns a copy of the given {@link SummaryOptions}
*
* @param other
* the instance to copy
* @return the copy
*/
public static SummaryOptions copyOf(SummaryOptions other) {
if (other == null) {
return null;
}
SummaryOptions summaryOptions = new SummaryOptions();
summaryOptions.summarySize = other.summarySize;
summaryOptions.viewNamesList = new ArrayList<>(other.viewNamesList);
summaryOptions.only = other.only;
return summaryOptions;
}

public int getSummarySize() {
return summarySize;
}

public boolean onlyListedViews() {
return only;
}

/**
* Replace a view name with another view name
*
* @param viewName
* the one to replace
* @param replacement
* the one to replace the other
*/
public void replace(String viewName, String replacement) {
int index = viewNamesList.indexOf(viewName);
if (index != -1) {
viewNamesList.set(index, replacement);
}
}

/**
* Return whether this {@link SummaryOptions} view names list is empty.
*
* @return true if empty, or false otherwise
*/
public boolean isEmpty() {
return viewNamesList.isEmpty();
}

public String viewNamesListToString() {
if (viewNamesList.isEmpty()) {
return "";
}

StringBuilder sb = new StringBuilder();
for (String viewName : viewNamesList) {
sb.append(viewName).append(Constants.COMMA);
}
return sb.substring(0, sb.length() - 1);
}

public static String[] viewNamesListFromString(String string) {
return string.split(Constants.COMMA);
}

/**
* Returns this {@link SummaryOptions} as a formatted string that can later be parsed back into a {@link SummaryOptions} using
* {@link SummaryOptions#from(String)}. This is also what will be used when serializing a {@link SummaryOptions} to JSON/XML. The string will have the
* format {@code SIZE:size/[only]/[NAMES:contentName1, contentName2, ....]}.
*
* @return a formatted string
*/
@JsonValue
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(SIZE_PARAMETER).append(":").append(summarySize);
if (only) {
sb.append("/").append("ONLY");
}
if (!viewNamesList.isEmpty()) {
sb.append("/").append(VIEWS_PARAMETER).append(":");
for (String viewName : viewNamesList) {
sb.append(viewName).append(Constants.COMMA);
}
return sb.substring(0, sb.length() - 1);
}
return sb.toString();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SummaryOptions that = (SummaryOptions) o;
return Objects.equals(summarySize, that.summarySize) && Objects.equals(viewNamesList, that.viewNamesList) && Objects.equals(only, that.only);
}

@Override
public int hashCode() {
return Objects.hash(summarySize, viewNamesList, only);
}
}
Loading

0 comments on commit 2eac9ae

Please sign in to comment.