package de.geeksfactory.opacclient.searchfields;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Comparator;
/**
* A SearchField is the abstract representation of a criteria input available in the search form.
*/
public abstract class SearchField {
protected String id;
protected String displayName;
protected boolean advanced;
protected boolean visible = true;
/**
* Optional attribute, describes the meaning of the search field. Used for sorting the search
* fields in the form. Will be assigned automatically by the MeaningDetector if you use it.
*/
protected Meaning meaning;
/**
* A JSONObject where you can save arbitrary data about this Search field. If you add a
* "meaning" attribute, MeaningDetector will search for that string in the meanings list instead
* of the displayName.
*/
protected JSONObject data;
public SearchField() {
}
public SearchField(String id, String displayName, boolean advanced) {
this.id = id;
this.displayName = displayName;
this.advanced = advanced;
}
/**
* Initialize a SearchField from its JSON-serialized counterpart
*/
public static SearchField fromJSON(JSONObject json) throws JSONException {
String id = json.getString("id");
String type = json.getString("type");
String displayName = json.getString("displayName");
JSONObject data = null;
if (json.has("data")) {
data = json.getJSONObject("data");
}
Meaning meaning = null;
if (json.has("meaning")) {
meaning = Meaning.valueOf(json.getString("meaning"));
}
boolean advanced = json.getBoolean("advanced");
boolean visible = json.getBoolean("visible");
SearchField field = null;
switch (type) {
case "text": {
String hint = json.getString("hint");
boolean freeSearch = json.getBoolean("freeSearch");
boolean number = json.getBoolean("number");
boolean halfWidth = json.getBoolean("halfWidth");
field = new TextSearchField(id, displayName, advanced, halfWidth,
hint, freeSearch, number);
break;
}
case "barcode": {
String hint = json.getString("hint");
boolean halfWidth = json.getBoolean("halfWidth");
field = new BarcodeSearchField(id, displayName, advanced,
halfWidth, hint);
break;
}
case "checkbox":
field = new CheckboxSearchField(id, displayName, advanced);
break;
case "dropdown":
JSONArray array = json.getJSONArray("dropdownValues");
field = new DropdownSearchField(id, displayName, advanced, null);
for (int i = 0; i < array.length(); i++) {
JSONObject value = array.getJSONObject(i);
((DropdownSearchField) field).addDropdownValue(
value.getString("key"), value.getString("value"));
}
break;
}
if (field != null) {
field.setData(data);
field.setMeaning(meaning);
field.setVisible(visible);
}
return field;
}
/**
* Get this field's internal ID
*/
public String getId() {
return id;
}
/**
* Set this field's internal ID
*/
public void setId(String id) {
this.id = id;
}
/**
* Get the name of this field to be displayed
*/
public String getDisplayName() {
return displayName;
}
/**
* Set the name of this field to be displayed
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
/**
* Get whether this field should only be displayed in "advanced mode".
*/
public boolean isAdvanced() {
return advanced;
}
/**
* Set whether this field should only be displayed in "advanced mode".
*/
public void setAdvanced(boolean advanced) {
this.advanced = advanced;
}
/**
* Get whether this field is visible on the UI
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean isVisible() {
return visible;
}
/**
* Set whether this field is visible on the UI
*/
public void setVisible(boolean visible) {
this.visible = visible;
}
/**
* Serialize a SearchField to a JSONObject.
*/
public JSONObject toJSON() throws JSONException {
JSONObject json = new JSONObject();
json.put("id", id);
json.put("displayName", displayName);
json.put("advanced", advanced);
json.put("visible", visible);
if (data != null) {
json.put("data", data);
}
if (meaning != null) {
json.put("meaning", meaning.toString());
}
return json;
}
/**
* Get raw additional SearchField data
*/
public JSONObject getData() {
return data;
}
/**
* Set raw additional SearchField data
*/
public void setData(JSONObject data) {
this.data = data;
}
/**
* Returns the SearchField's guessed or specified meaning
*/
public Meaning getMeaning() {
return meaning;
}
/**
* Set the SearchField's meaning
*/
public void setMeaning(Meaning meaning) {
this.meaning = meaning;
}
@Override
public String toString() {
return "SearchField [id=" + id + "]";
}
/**
* A SearchField can have one of the following meanings. They are used for field ordering and
* providing additional UI features.
*/
public enum Meaning {
FREE, TITLE, AUTHOR, DIGITAL, AVAILABLE, ISBN, BARCODE, YEAR, BRANCH, HOME_BRANCH, CATEGORY,
PUBLISHER, KEYWORD, SYSTEM, AUDIENCE, LOCATION, ORDER, DATABASE
}
/**
* Sorts search fields by the order of the {@link SearchField.Meaning} enum.
*/
public static class OrderComparator implements Comparator<SearchField> {
@Override
public int compare(SearchField a, SearchField b) {
if (a.getMeaning() == null || b.getMeaning() == null) {
return 0;
} else {
return a.getMeaning().compareTo(b.getMeaning());
}
}
}
}