Skip to content

Commit

Permalink
#666 TableForm redesign, ListField compiles (but not integrated yet)
Browse files Browse the repository at this point in the history
  • Loading branch information
alessiostalla committed Jan 4, 2024
1 parent 9f7a92f commit 7222fd2
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
package com.manydesigns.elements;

import java.util.List;

/**
* Abstraction over key-value data for Elements forms (e.g. JSON objects, HTTP requests, etc.)
*
* @author Angelo Lupo - angelo.lupo@manydesigns.com
* @author Giampiero Granatella - giampiero.granatella@manydesigns.com
* @author Emanuele Poggi - emanuele.poggi@manydesigns.com
* @author Alessio Stalla - alessio.stalla@manydesigns.com
*/
public interface KeyValueAccessor {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";
String copyright = "Copyright (C) 2005-2024 ManyDesigns srl";

Object get(String name);
void set(String name, Object value);
boolean has(String name);

KeyValueAccessor object(String name);
List<KeyValueAccessor> list(String name);

KeyValueAccessor list(String name);

KeyValueAccessor atIndex(int index);

int length();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.manydesigns.elements;

import com.manydesigns.elements.json.JSONObjectAccessor;

public abstract class KeyValueListAccessor implements KeyValueAccessor {
protected KeyValueAccessor currentObjectAccessor;

@Override
public Object get(String name) {
return currentObjectAccessor != null ? currentObjectAccessor.get(name) : null;
}

@Override
public void set(String name, Object value) {
if (currentObjectAccessor != null) {
currentObjectAccessor.set(name, value);
} else {
throw new IllegalStateException("No element in the list");
}
}

@Override
public boolean has(String name) {
return currentObjectAccessor != null && currentObjectAccessor.has(name);
}

@Override
public KeyValueAccessor object(String name) {
return currentObjectAccessor != null ? currentObjectAccessor.object(name) : null;
}

@Override
public KeyValueAccessor list(String name) {
return currentObjectAccessor != null ? currentObjectAccessor.list(name) : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,19 @@ public KeyValueAccessor object(String name) {
Map<String, Object> inner = (Map<String, Object>) get(name);
return inner != null ? new MapKeyValueAccessor(inner) : null;
}

@Override
public KeyValueAccessor list(String name) {
throw new UnsupportedOperationException();
}

@Override
public KeyValueAccessor atIndex(int index) {
throw new UnsupportedOperationException();
}

@Override
public int length() {
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ public void readFrom(KeyValueAccessor keyValueAccessor) {
return;
}
bulkChecked = true;
Object value = keyValueAccessor.get(accessor.getName());
if (value == null) {
KeyValueAccessor inner = keyValueAccessor.list(accessor.getName());
if (inner == null) {
setValue(null);
} else {
ensureForm().readFrom(keyValueAccessor.inner(value));
ensureForm().readFrom(inner);
setValueFromForm();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ public void readFrom(KeyValueAccessor keyValueAccessor) {
return;
}
bulkChecked = true;
Object value = keyValueAccessor.get(accessor.getName());
if (value == null) {
KeyValueAccessor inner = keyValueAccessor.object(accessor.getName());
if (inner == null) {
setValue(null);
} else {
ensureForm().readFrom(keyValueAccessor.inner(value));
ensureForm().readFrom(inner);
setValueFromForm();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Supplier;

/** A form with multiple rows, where a row is a collection of fields. Every row has the same fields.
* @author Paolo Predonzani - paolo.predonzani@manydesigns.com
Expand All @@ -63,23 +65,18 @@ public class TableForm implements Element {
protected boolean condensed = false;
protected boolean striped = true;

private static final String SELECTION_CELL_CLASS = "selection-cell";
protected final BiFunction<TableForm, Integer, Row> rowBuilder;

//**************************************************************************
// Costruttori
//**************************************************************************
private static final String SELECTION_CELL_CLASS = "selection-cell";

public TableForm(PropertyAccessor... propertyAccessors) {
public TableForm(BiFunction<TableForm, Integer, Row> rowBuilder, PropertyAccessor... propertyAccessors) {
this.rowBuilder = rowBuilder;
columns = new Column[propertyAccessors.length];
for (int i = 0; i < columns.length; i++) {
columns[i] = new Column(propertyAccessors[i]);
}
}

//**************************************************************************
// Implementazione di Element
//**************************************************************************

public void toXhtml(@NotNull XhtmlBuffer xb) {
xb.openElement("table");
xb.addAttribute("class",
Expand Down Expand Up @@ -156,14 +153,12 @@ public void readFromRequest(HttpServletRequest req) {

@Override
public void readFrom(KeyValueAccessor keyValueAccessor) {
Object object = keyValueAccessor.get();
if (object instanceof Iterable) {
Iterator<?> iterator = ((Iterable<?>) object).iterator();
for (Row row : rows) {
if (iterator.hasNext()) {
row.readFrom(keyValueAccessor.inner(iterator.next()));
}
}
rows.clear();
for (int i = 0; i < keyValueAccessor.length(); i++) {
KeyValueAccessor inner = keyValueAccessor.atIndex(i);
Row row = rowBuilder.apply(this, i);
row.readFrom(inner);
rows.add(row);
}
}

Expand Down Expand Up @@ -407,6 +402,10 @@ public int getIndex() {
}
}

public Row newRow(int index) {
return new Row(index);
}

//**************************************************************************
// Inner class: Column
//**************************************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,18 @@
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

/*
* @author Paolo Predonzani - paolo.predonzani@manydesigns.com
* @author Angelo Lupo - angelo.lupo@manydesigns.com
* @author Giampiero Granatella - giampiero.granatella@manydesigns.com
* @author Alessio Stalla - alessio.stalla@manydesigns.com
*/
/**
* Builder for {@link TableForm}s.
*
* @author Paolo Predonzani - paolo.predonzani@manydesigns.com
* @author Angelo Lupo - angelo.lupo@manydesigns.com
* @author Giampiero Granatella - giampiero.granatella@manydesigns.com
* @author Alessio Stalla - alessio.stalla@manydesigns.com
*/
public class TableFormBuilder extends AbstractFormBuilder {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";
Expand All @@ -63,10 +68,6 @@ public class TableFormBuilder extends AbstractFormBuilder {
LoggerFactory.getLogger(TableFormBuilder.class);


//**************************************************************************
// Constructors
//**************************************************************************

public TableFormBuilder(Class aClass) {
this(JavaClassAccessor.getClassAccessor(aClass));
}
Expand All @@ -85,11 +86,10 @@ public TableFormBuilder(ClassAccessor classAccessor) {
//**************************************************************************

public TableFormBuilder configFields(String... fieldNames) {
propertyAccessors = new ArrayList<PropertyAccessor>();
propertyAccessors = new ArrayList<>();
for (String currentField : fieldNames) {
try {
PropertyAccessor accessor =
classAccessor.getProperty(currentField);
PropertyAccessor accessor = classAccessor.getProperty(currentField);
propertyAccessors.add(accessor);
} catch (NoSuchFieldException e) {
logger.warn("Field not found: {}", currentField);
Expand Down Expand Up @@ -176,7 +176,7 @@ public TableForm build() {
new PropertyAccessor[propertyAccessors.size()];
propertyAccessors.toArray(propertyAccessorsArray);

TableForm tableForm = new TableForm(propertyAccessorsArray);
TableForm tableForm = new TableForm(rowBuilder(), propertyAccessorsArray);

if (StringUtils.isNotBlank(prefix)) {
tableForm.setPrefix(prefix);
Expand All @@ -185,9 +185,6 @@ public TableForm build() {
// set up the columns
setupColumns(tableForm);

// set up the rows
setupRows(tableForm);

return tableForm;
}

Expand All @@ -202,9 +199,10 @@ protected void setupColumns(TableForm tableForm) {
}
}

protected void setupRows(TableForm tableForm) {
int index = 0;
for (TableForm.Row row : tableForm.getRows()) {
protected BiFunction<TableForm, Integer, TableForm.Row> rowBuilder() {
return (tableForm, index) -> {
TableForm.Row row = tableForm.newRow(index);

String rowPrefix =
StringUtils.join(new Object[]{prefix, "row", index, "_"});

Expand All @@ -224,8 +222,8 @@ protected void setupRows(TableForm tableForm) {
setupSelectionProvidersForRow(tableForm, row, current);
}

index++;
}
return row;
};
}

protected void setupSelectionProvidersForRow(TableForm tableForm, TableForm.Row row,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.manydesigns.elements.json;

import com.manydesigns.elements.KeyValueListAccessor;
import org.json.JSONArray;

public class JSONArrayAccessor extends KeyValueListAccessor {

private final JSONArray jsonArray;

public JSONArrayAccessor(JSONArray jsonArray) {
this.jsonArray = jsonArray;
if (!jsonArray.isEmpty()) {
currentObjectAccessor = new JSONObjectAccessor(jsonArray.getJSONObject(0));
}
}

protected JSONArrayAccessor(JSONArray jsonArray, JSONObjectAccessor currentAccessor) {
this.jsonArray = jsonArray;
this.currentObjectAccessor = currentAccessor;
}

@Override
public KeyValueListAccessor atIndex(int index) {
return new JSONArrayAccessor(jsonArray, new JSONObjectAccessor(jsonArray.getJSONObject(index)));
}

@Override
public int length() {
return jsonArray.length();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
* @author Emanuele Poggi - emanuele.poggi@manydesigns.com
* @author Alessio Stalla - alessio.stalla@manydesigns.com
*/
public class JsonKeyValueAccessor implements KeyValueAccessor {
public class JSONObjectAccessor implements KeyValueAccessor {

private final JSONObject jsonObject;

public JsonKeyValueAccessor(JSONObject jsonObject) {
public JSONObjectAccessor(JSONObject jsonObject) {
this.jsonObject = jsonObject;
}

Expand Down Expand Up @@ -42,6 +42,24 @@ public KeyValueAccessor object(String name) {
if (jsonObject.isNull(name)) {
return null;
}
return new JsonKeyValueAccessor(jsonObject.getJSONObject(name));
return new JSONObjectAccessor(jsonObject.getJSONObject(name));
}

@Override
public KeyValueAccessor list(String name) {
if (jsonObject.isNull(name)) {
return null;
}
return new JSONArrayAccessor(jsonObject.getJSONArray(name));
}

@Override
public KeyValueAccessor atIndex(int index) {
throw new UnsupportedOperationException("Not a list");
}

@Override
public int length() {
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import com.manydesigns.elements.fields.TextField;
import com.manydesigns.elements.forms.FieldSet;
import com.manydesigns.elements.forms.Form;
import com.manydesigns.elements.json.JsonKeyValueAccessor;
import com.manydesigns.elements.json.JSONObjectAccessor;
import org.apache.commons.lang.ObjectUtils;
import org.joda.time.DateTime;
import org.json.JSONException;
Expand Down Expand Up @@ -146,7 +146,7 @@ public static void writeToJson(Form form, JSONStringer js) {
}

public static Form readFromJson(Form form, JSONObject jsonObject) {
JsonKeyValueAccessor kv = new JsonKeyValueAccessor(jsonObject) {
JSONObjectAccessor kv = new JSONObjectAccessor(jsonObject) {
@Override
public Object get(String name) {
Object o = super.get(name);
Expand All @@ -155,7 +155,7 @@ public Object get(String name) {
if(subObj.has(JSON_TYPE)) {
return null; //TODO blobs - how to handle?
} else {
return new JsonKeyValueAccessor(subObj).get(JSON_VALUE);
return new JSONObjectAccessor(subObj).get(JSON_VALUE);
}
} else {
return o;
Expand All @@ -166,7 +166,7 @@ public Object get(String name) {
public void set(String name, Object value) {
Object o = super.get(name);
if(o instanceof JSONObject) {
new JsonKeyValueAccessor((JSONObject) o).set(JSON_VALUE, value);
new JSONObjectAccessor((JSONObject) o).set(JSON_VALUE, value);
} else {
super.set(name, value);
}
Expand Down
Loading

0 comments on commit 7222fd2

Please sign in to comment.