Skip to content

Commit

Permalink
#666 The number of the Beast! Add the capability to handle nested obj…
Browse files Browse the repository at this point in the history
…ects in Elements forms (needs more testing).

Also, refactor Groovy support out of Elements.
  • Loading branch information
alessiostalla committed Oct 3, 2023
1 parent 4d2e62f commit 59cb6e8
Show file tree
Hide file tree
Showing 27 changed files with 482 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public interface KeyValueAccessor {
Object get(String name);
void set(String name, Object value);
boolean has(String name);

KeyValueAccessor inner(Object value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ public void set(String name, Object value) {
public boolean has(String name) {
return map.containsKey(name);
}

@Override
public KeyValueAccessor inner(Object value) {
return new MapKeyValueAccessor((Map<String, Object>) value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public void readFromObject(Object obj) {
if (obj == null) {
booleanValue = null;
} else {
booleanValue = (Boolean)accessor.get(obj);
booleanValue = (Boolean) accessor.get(obj);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.manydesigns.elements.fields;

import com.manydesigns.elements.KeyValueAccessor;
import com.manydesigns.elements.Mode;
import com.manydesigns.elements.forms.Form;
import com.manydesigns.elements.forms.FormBuilder;
import com.manydesigns.elements.reflection.ClassAccessor;
import com.manydesigns.elements.reflection.PropertyAccessor;
import com.manydesigns.elements.reflection.factories.ClassAccessorFactories;
import com.manydesigns.elements.xml.XhtmlBuffer;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.servlet.http.HttpServletRequest;

public class ObjectField extends AbstractField<Object> {

protected final ClassAccessor classAccessor;
protected final Form form;
protected Object value;

public ObjectField(@NotNull PropertyAccessor accessor, @NotNull Mode mode, @Nullable String prefix) {
super(accessor, mode, prefix);
classAccessor = ClassAccessorFactories.get(accessor.getType());
form = new FormBuilder(classAccessor)
.configPrefix(StringUtils.defaultString(prefix) + accessor.getName() + ".")
.build();
}

public ObjectField(@NotNull PropertyAccessor accessor, @NotNull Mode mode) {
this(accessor, mode, null);
}

@Override
public boolean validate() {
return form.validate();
}

@Override
public void writeToObject(Object obj) {
form.writeToObject(accessor.get(obj));
}

@Override
public void valueToXhtml(XhtmlBuffer xb) {
form.toXhtml(xb);
}

@Override
public String getStringValue() {
return null;
}

@Override
public void setStringValue(String stringValue) {
throw new UnsupportedOperationException();
}

@Override
public Object getValue() {
return value;
}

@Override
public void setValue(Object value) {
this.value = value;
form.readFromObject(value);
}

@Override
public void readFromRequest(HttpServletRequest req) {
super.readFromRequest(req);
form.readFromRequest(req);
}

@Override
public void readFromObject(Object obj) {
super.readFromObject(obj);
if (obj == null) {
setValue(null);
} else {
setValue(accessor.get(obj));
}
}

@Override
public void readFrom(KeyValueAccessor keyValueAccessor) {
if (isReadOnly()) {
return;
}
if(!keyValueAccessor.has(accessor.getName())) {
return;
}
bulkChecked = true;
Object value = keyValueAccessor.get(accessor.getName());
if (value == null) {
setValue(null);
} else {
Object object = classAccessor.newInstance();
form.readFrom(keyValueAccessor.inner(value));
form.writeToObject(object);
this.value = object;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public TextField(PropertyAccessor accessor, Mode mode, String prefix) {
logger.debug("RichText annotation present with value: {}",
richText);
}

if (accessor.isAnnotationPresent(Status.class)) {
Status annotation = accessor.getAnnotation(Status.class);
red = annotation.red();
Expand Down Expand Up @@ -123,7 +123,7 @@ public void readFromObject(Object obj) {
if (obj == null) {
stringValue = null;
} else {
stringValue = (String)accessor.get(obj);
stringValue = (String) accessor.get(obj);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class FieldsManager implements FieldHelper {
elementsConfiguration.getString(
ElementsProperties.FIELDS_MANAGER);
InstanceBuilder<FieldsManager> builder =
new InstanceBuilder<FieldsManager>(
new InstanceBuilder<>(
FieldsManager.class,
FieldsManager.class,
logger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.manydesigns.elements.reflection.ClassAccessor;
import com.manydesigns.elements.reflection.JavaClassAccessor;
import com.manydesigns.elements.reflection.PropertyAccessor;
import com.manydesigns.elements.reflection.factories.ClassAccessorFactories;
import org.apache.commons.lang.ArrayUtils;

import java.util.*;
Expand Down Expand Up @@ -63,8 +64,8 @@ public class FormBuilder extends AbstractFormBuilder {
// Constructors
//**************************************************************************

public FormBuilder(Class aClass) {
this(JavaClassAccessor.getClassAccessor(aClass));
public FormBuilder(Class<?> aClass) {
this(ClassAccessorFactories.get(aClass));
}

public FormBuilder(ClassAccessor classAccessor) {
Expand Down Expand Up @@ -140,8 +141,8 @@ public FormBuilder configMode(Mode mode) {
public FormBuilder configReflectiveFields() {
logger.debug("configReflectiveFields");

groupedPropertyAccessors = new ArrayList<ArrayList<PropertyAccessor>>();
fieldSetNames = new ArrayList<String>();
groupedPropertyAccessors = new ArrayList<>();
fieldSetNames = new ArrayList<>();

ArrayList<PropertyAccessor> currentGroup = null;
String currentGroupName = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,8 @@ public boolean has(String name) {
return jsonObject.has(name);
}


@Override
public KeyValueAccessor inner(Object value) {
return new JsonKeyValueAccessor((JSONObject) value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void setCollectionClass(Class<? extends List> collectionClass) {
}

protected void computeProperties() {
List<PropertyAccessor> allProperties = new ArrayList<PropertyAccessor>();
List<PropertyAccessor> allProperties = new ArrayList<>();
int index = 0;
for(ClassAccessor accessor : getAccessors()) {
String alias = aliases.get(index);
Expand Down Expand Up @@ -278,7 +278,7 @@ public Annotation[] getDeclaredAnnotations() {
}
}

public class AliasPropertyAccessor implements PropertyAccessor {
public static class AliasPropertyAccessor implements PropertyAccessor {

protected final String name;
protected final int index;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@

import java.lang.reflect.AnnotatedElement;

/*
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
/**
* Describes the structure of a homogeneous group of objects, and allows accessing their properties.
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public interface ClassAccessor extends AnnotatedElement {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

/**
* A {@link ClassAccessor} targeting Java classes. Use {@link GroovyClassAccessor} for Groovy classes instead.
*
*
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
Expand Down Expand Up @@ -76,7 +76,7 @@ public class JavaClassAccessor implements ClassAccessor {
classAccessorCache = CacheBuilder.newBuilder().weakKeys().build();
}

public static JavaClassAccessor getClassAccessor(Class javaClass) {
public static JavaClassAccessor getClassAccessor(Class<?> javaClass) {
JavaClassAccessor cachedResult = classAccessorCache.getIfPresent(javaClass);
if (cachedResult == null) {
logger.debug("Cache miss for: {}", javaClass);
Expand Down Expand Up @@ -211,7 +211,7 @@ private boolean isPropertyPresent(List<PropertyAccessor> accessorList,
return false;
}


//**************************************************************************
// ClassAccessor implementation
//**************************************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public class JavaFieldAccessor<T> implements PropertyAccessor<Object, T> {
public class JavaFieldAccessor implements PropertyAccessor {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public class JavaPropertyAccessor<T> extends AbstractAnnotatedAccessor implements PropertyAccessor<Object, T> {
public class JavaPropertyAccessor extends AbstractAnnotatedAccessor implements PropertyAccessor {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@
import java.util.Map;
import java.util.Properties;

/*
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public class MapEntryAccessor<T> implements PropertyAccessor<Map, T> {
/**
* {@link PropertyAccessor} for {@link Map} entries.
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public class MapEntryAccessor implements PropertyAccessor {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";

Expand Down Expand Up @@ -80,11 +81,11 @@ public Annotation[] getDeclaredAnnotations() {
return getAnnotations();
}

public String get(Map obj) {
return OgnlUtils.convertValueToString(obj.get(name));
public String get(Object obj) {
return OgnlUtils.convertValueToString(((Map) obj).get(name));
}

public void set(Map obj, Object value) {
obj.put(name, value);
public void set(Object obj, Object value) {
((Map) obj).put(name, value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public class PropertiesEntryAccessor<T> implements PropertyAccessor<Properties, T> {
public class PropertiesEntryAccessor implements PropertyAccessor {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";

Expand Down Expand Up @@ -78,11 +78,11 @@ public Annotation[] getDeclaredAnnotations() {
return getAnnotations();
}

public String get(Properties obj) {
return obj.getProperty(name);
public String get(Object obj) {
return ((Properties) obj).getProperty(name);
}

public void set(Properties obj, Object value) {
obj.setProperty(name, (String)value);
public void set(Object obj, Object value) {
((Properties) obj).setProperty(name, (String)value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@

import java.lang.reflect.AnnotatedElement;

/*
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public interface PropertyAccessor<OBJ, TYPE> extends AnnotatedElement {
/**
* Describes and allows access to a property of an object.
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public interface PropertyAccessor extends AnnotatedElement {
public static final String copyright =
"Copyright (C) 2005-2020 ManyDesigns srl";

Expand All @@ -38,15 +39,15 @@ public interface PropertyAccessor<OBJ, TYPE> extends AnnotatedElement {
//**************************************************************************

String getName();
Class<TYPE> getType();
Class<?> getType();
int getModifiers();

//**************************************************************************
// Accessors
//**************************************************************************

Object get(OBJ obj);
void set(OBJ obj, TYPE value);
Object get(Object obj);
void set(Object obj, Object value);

default boolean isWritable() {
return true;
Expand Down
Loading

0 comments on commit 59cb6e8

Please sign in to comment.