Commit 3247d8bd authored by Roger Barton's avatar Roger Barton
Browse files

Implemented parsing of event additional_fields into java class (AdditFields)

Also fixed small bug with wrong title being renamed in intro_pref screen
parent 44c02427
Pipeline #8449 passed with stages
in 2 minutes and 14 seconds
"$schema":"http://json-schema.org/draft-04/schema#"
"additionalProperties":false
"title":"Additional Fields"
"type":"object"
"properties":{
"SBB_Abo":
{
"type":"string"
"enum":["None", "GA", "Halbtax", "Gleis 7"]
}
"Food":
{
"type":"string"
"enum":["Omnivor", "Vegi", "Vegan", "Other"]
}
"Special Food Requirements":
{
"type":"string"
}
}
"required":["SBB_Abo", "Food"]
{
"$schema":"http://json-schema.org/draft-04/schema#",
"additionalProperties":false,
"title":"Additional Fields",
"type":"object",
"properties":
{
"SBB_Abo":
{
"type":"string",
"enum":["None","GA","Halbtax","Gleis 7"]
},
"Food":
{
"type":"string",
"enum":["Omnivor","Vegi","Vegan","Other"]
},
"Special Food Requirements":
{
"type":"string"
}
},
"required":["SBB_Abo","Food"]
}
\ No newline at end of file
{
"id": "http://json-schema.org/draft-04/schema#",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Core schema meta-schema",
"definitions": {
"schemaArray": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#" }
},
"positiveInteger": {
"type": "integer",
"minimum": 0
},
"positiveIntegerDefault0": {
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
},
"simpleTypes": {
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
},
"stringArray": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}
},
"type": "object",
"properties": {
"id": {
"type": "string"
},
"$schema": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"default": {},
"multipleOf": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"maximum": {
"type": "number"
},
"exclusiveMaximum": {
"type": "boolean",
"default": false
},
"minimum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "boolean",
"default": false
},
"maxLength": { "$ref": "#/definitions/positiveInteger" },
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
"pattern": {
"type": "string",
"format": "regex"
},
"additionalItems": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"items": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/schemaArray" }
],
"default": {}
},
"maxItems": { "$ref": "#/definitions/positiveInteger" },
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
"uniqueItems": {
"type": "boolean",
"default": false
},
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
"required": { "$ref": "#/definitions/stringArray" },
"additionalProperties": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"definitions": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"properties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"patternProperties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"dependencies": {
"type": "object",
"additionalProperties": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/stringArray" }
]
}
},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"type": {
"anyOf": [
{ "$ref": "#/definitions/simpleTypes" },
{
"type": "array",
"items": { "$ref": "#/definitions/simpleTypes" },
"minItems": 1,
"uniqueItems": true
}
]
},
"format": { "type": "string" },
"allOf": { "$ref": "#/definitions/schemaArray" },
"anyOf": { "$ref": "#/definitions/schemaArray" },
"oneOf": { "$ref": "#/definitions/schemaArray" },
"not": { "$ref": "#" }
},
"dependencies": {
"exclusiveMaximum": [ "maximum" ],
"exclusiveMinimum": [ "minimum" ]
},
"default": {}
}
......@@ -125,11 +125,11 @@
</activity>
<!-- Demo -->
<activity
<!--<activity
android:name=".demo.MainActivity"
android:configChanges="layoutDirection|locale"
android:parentActivityName=".core.MainActivity"
android:screenOrientation="portrait" />
android:screenOrientation="portrait" /> -->
</application>
</manifest>
\ No newline at end of file
package ch.amiv.android_app.events;
import android.graphics.drawable.AdaptiveIconDrawable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* A data class for storing a single additional Field for an event. See the SampleEventAdditFields file.
* An instance of this class represents one variable.
* Use an array of this type to generate a form for the event
*/
public class AdditField {
//The types of fields we can have, according to the json schema, see SampleJsonSchemaAdditFields
public static final class FieldType {
public static final int ARRAY = 0;
public static final int BOOLEAN = 1;
public static final int INTEGER = 2;
public static final int NULL = 3;
public static final int NUMBER = 4;
public static final int OBJECT = 5;
public static final int STRING = 6;
}
public int type; //Use the FieldType constants, the currentValue should then be of that type
public String name;
public boolean required;
public String[] possibleValues;
public String currentValue;
/**
*
* @param additional_fields The 'additional_fields' JsonObject from the event json
* @return A parsed array of AdditFields. Empty array if we failed to parse
*/
public static AdditField[] ParseFromJson(JSONObject additional_fields){
ArrayList<AdditField> fields;
JSONObject properties;
List<String> requiredFields = null;
//Get the properties json
try {
properties = additional_fields.getJSONObject("properties");
fields = new ArrayList<>(properties.length());
} catch (JSONException e) {
e.printStackTrace();
return new AdditField[0];//return empty array if we cannot parse
}
//parse which fields are required
try {
JSONArray requiredFieldsJson = additional_fields.getJSONArray("required");
requiredFields = Arrays.asList(ParseStringArray(requiredFieldsJson));
} catch (JSONException e) { }
//If we have the data, parse it
Iterator<String> iter = properties.keys(); //iterate over all items in the properties array, which each represent one AdditField
while (iter.hasNext()) {
String key = iter.next();
try {
JSONObject o = properties.getJSONObject(key);
AdditField f = new AdditField();
f.name = key;
f.type = ParseFieldType(o.getString("type"));
//Get possible values from enum
if(o.has("enum"))
f.possibleValues = ParseStringArray(o.getJSONArray("enum"));
//Check if this field is in the required list
if(requiredFields != null && requiredFields.contains(f.name))
f.required = true;
fields.add(f);
}
catch (JSONException e){
e.printStackTrace();
}
}
return (AdditField[]) fields.toArray();
}
/**
* Will convert a type string from the json to a FieldType
* @param type Type string from the AdditionalFields Json
* @return FieldType
*/
private static int ParseFieldType(String type){
if(type == null) return FieldType.STRING;
switch (type){
case "array":
return FieldType.ARRAY;
case "boolean":
return FieldType.BOOLEAN;
case "integer":
return FieldType.INTEGER;
case "null":
return FieldType.NULL;
case "number":
return FieldType.NUMBER;
case "object":
return FieldType.OBJECT;
case "string":
return FieldType.STRING;
default:
return FieldType.STRING;
}
}
/**
* Will parse a json String array to a java string array
* @param array
*/
private static String[] ParseStringArray(JSONArray array){
String[] result = new String[array.length()];
for (int i = 0; i < result.length; ++i){
try {
result[i] = array.getString(i);
} catch (JSONException e) {
e.printStackTrace();
}
}
return result;
}
}
......@@ -35,7 +35,6 @@ public class EventInfo implements Serializable{
public String location;
public String price;
public String priority;
public String additional_fields;
public String selection_strategy;
public int signup_count;
......@@ -60,6 +59,8 @@ public class EventInfo implements Serializable{
public Date time_created;
public Date time_updated;
private ArrayList<String[]> infos = new ArrayList<>();
//===Signup related===
......@@ -68,6 +69,8 @@ public class EventInfo implements Serializable{
public boolean confirmed;
public enum CheckinState {none, in, out}
public CheckinState checked_in = CheckinState.none;
public AdditField[] additional_fields;
//endregion
public EventInfo(JSONObject json) {
......@@ -90,7 +93,9 @@ public class EventInfo implements Serializable{
location = json.optString("location");
price = json.optString("price");
priority = json.optString("priority");
additional_fields = json.optString("additional_fields");
try {
additional_fields = AdditField.ParseFromJson(json.getJSONObject("additional_fields"));
} catch (JSONException e) { additional_fields = new AdditField[0]; }
selection_strategy = json.optString("selection_strategy");
signup_count = json.optInt("signup_count");
......
......@@ -17,7 +17,7 @@ public class EnumViewGenerator {
}
public static void InitialiseEnumList(final Activity activity, int header, final OnButtonIndexClicked onClick, String[] titles, boolean addOtherField){
TextView titleView = activity.findViewById(R.id.title);
TextView titleView = activity.findViewById(R.id.title_enum_view);
titleView.setText(header);
ViewGroup parent = activity.findViewById(R.id.listParent);
......
......@@ -7,7 +7,7 @@
android:background="@color/primary">
<TextView
android:id="@+id/title"
android:id="@+id/title_enum_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
......@@ -34,7 +34,7 @@
android:background="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
app:layout_constraintTop_toBottomOf="@+id/title_enum_view" />
<ScrollView
android:layout_width="match_parent"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment