/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.workbench.common.forms.dynamic.backend.server.context.generation.dynamic.impl.fieldProcessors;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConstructorUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.kie.workbench.common.forms.dynamic.service.context.generation.dynamic.BackendFormRenderingContext;
import org.kie.workbench.common.forms.dynamic.service.context.generation.dynamic.FieldValueProcessor;
import org.kie.workbench.common.forms.dynamic.service.context.generation.dynamic.FormValuesProcessor;
import org.kie.workbench.common.forms.dynamic.service.shared.impl.MapModelRenderingContext;
import org.kie.workbench.common.forms.model.FieldDefinition;
import org.kie.workbench.common.forms.model.FormDefinition;
import org.slf4j.Logger;
public abstract class NestedFormFieldValueProcessor<F extends FieldDefinition, RAW_VALUE, FLAT_VALUE> implements FieldValueProcessor<F, RAW_VALUE, FLAT_VALUE> {
protected FormValuesProcessor processor;
public abstract Logger getLogger();
public void init(FormValuesProcessor processor) {
this.processor = processor;
}
protected void prepareNestedRawValues(final Map<String, Object> valuesMap,
final FormDefinition nestedForm,
final Object value) {
nestedForm.getFields().forEach(field -> {
if (!valuesMap.containsKey(field.getBinding())) {
valuesMap.put(field.getBinding(),
readValue(field.getBinding(),
value));
}
});
}
protected Object writeObjectValues(Object originalValue,
Map<String, Object> formValues,
FieldDefinition field,
BackendFormRenderingContext context) {
if (originalValue != null && originalValue.getClass().getName().equals(field.getStandaloneClassName())) {
writeValues(formValues,
originalValue);
} else {
Class clazz = null;
try {
clazz = context.getClassLoader().loadClass(field.getStandaloneClassName());
} catch (ClassNotFoundException e) {
// Maybe the nested class it is not on the classLoader context... let's try on the app classloader
try {
clazz = Class.forName(field.getStandaloneClassName());
} catch (ClassNotFoundException e1) {
getLogger().warn("Unable to find class '{}' on classLoader for field '{}'",
field.getStandaloneClassName(),
field.getBinding());
}
}
if (clazz != null) {
originalValue = writeValues(formValues,
clazz);
}
}
return originalValue;
}
protected Object writeValues(Map<String, Object> values,
Class clazz) {
try {
Object value = ConstructorUtils.invokeConstructor(clazz,
null);
writeValues(values,
value);
return value;
} catch (Exception e) {
getLogger().warn("Unable to create instance for class {}: ",
clazz.getName());
}
return null;
}
protected void writeValues(Map<String, Object> values,
Object model) {
if (model == null) {
return;
}
values.forEach((property, value) -> {
try {
if (property.equals(MapModelRenderingContext.FORM_ENGINE_OBJECT_IDX) || property.equals(
MapModelRenderingContext.FORM_ENGINE_EDITED_OBJECT)) {
return;
}
if (PropertyUtils.getPropertyDescriptor(model,
property) != null) {
BeanUtils.setProperty(model,
property,
value);
}
} catch (Exception e) {
getLogger().warn("Error modifying object '{}': cannot set value '{}' to property '{}'",
model,
value,
property);
getLogger().warn("Caused by:",
e);
}
});
}
protected Object readValue(String property,
Object model) {
try {
if (PropertyUtils.getPropertyDescriptor(model,
property) != null) {
return PropertyUtils.getProperty(model,
property);
}
} catch (Exception e) {
getLogger().warn("Error getting property '{}' from object '{}'",
property,
model);
getLogger().warn("Caused by:",
e);
}
return null;
}
}