use of org.webpieces.plugin.secure.properties.beans.BeanMeta in project webpieces by deanhiller.
the class PropertiesController method bean.
public Render bean(String category, String name) {
BeanMeta meta = beanMetaData.getBeanMeta(category, name);
ArrayList<Object> params = Lists.newArrayList("menu", menuCreator.getMenu(), "beanMeta", meta, "category", category, "name", name, "thisServerOnly", false);
List<PropertyInfo> properties = meta.getProperties();
for (PropertyInfo p : properties) {
params.add(p.getName());
String valueStr = invoker.readPropertyAsString(p);
params.add(valueStr);
}
Object[] paramsArray = params.toArray(new Object[0]);
return Actions.renderThis(paramsArray);
}
use of org.webpieces.plugin.secure.properties.beans.BeanMeta in project webpieces by deanhiller.
the class PropertiesController method postBean.
public Redirect postBean(String category, String name, boolean thisServerOnly) throws InterruptedException, ExecutionException {
Map<String, List<String>> multiPartFields = Current.getContext().getRequest().multiPartFields;
BeanMeta meta = beanMetaData.getBeanMeta(category, name);
List<PropertyInfo> props = meta.getProperties();
// first validate the strings are of the right type for each return type and gather error messages up
// 1. lookup converter. if not exist, add validation error
// 2. convert and catch conversion exception if needed and add validation error
// 3. store all values while doing 1 and 2. apply in next loop below
List<ValueInfo> values = new ArrayList<>();
for (PropertyInfo info : props) {
if (info.isReadOnly())
continue;
List<String> valueList = multiPartFields.get(info.getName());
String valueAsString = valueList.get(0);
Class<?> returnType = info.getGetter().getReturnType();
ObjectStringConverter<?> converter = invoker.fetchConverter(info);
try {
Object objectValue = converter.stringToObject(valueAsString);
values.add(new ValueInfo(info, objectValue, valueAsString));
} catch (Exception e) {
Current.validation().addError(info.getName(), "Converter=" + converter.getClass().getName() + " cannot convert String to " + returnType.getName());
}
}
RequestContext ctx = Current.getContext();
if (Current.validation().hasErrors()) {
ctx.moveFormParamsToFlash(new HashSet<>());
ctx.getFlash().keep(true);
ctx.getValidation().keep(true);
return Actions.redirect(PropertiesRouteId.BEAN_ROUTE, "category", category, "name", name);
}
ctx.getValidation().keep(false);
// KISS: not doing rollback code so if one prop fails to set, it does not save to database
// and is partially applied. (ie. keep your setter code simple!!).
// ALSO, we are taking an apply all properties type of approach to keep it simple for now. in the future,
// we could read all props and only call setXXX on changes (in case they wrote extra not idempotent type code so
// that code does not run on accident)
Map<String, String> propertiesToSaveToDatabase = new HashMap<>();
for (ValueInfo value : values) {
updateProperty(value.getInfo(), value.getValue());
String key = KeyUtil.formKey(category, name, value.getInfo().getName());
propertiesToSaveToDatabase.put(key, value.getValueAsString());
}
if (thisServerOnly) {
Current.flash().setMessage("Modified Bean '" + name + ".class' ONLY on this server in-memory. (Changes not applied to database for restarts)");
Current.flash().keep();
} else {
XFuture<Void> future = storage.save(KeyUtil.PLUGIN_PROPERTIES_KEY, propertiesToSaveToDatabase);
// synchronously wait in case it fails so user is told it failed to save to database
future.get();
Current.flash().setMessage("Modified Bean '" + name + ".class' and persisted to Database");
Current.flash().keep();
}
return Actions.redirect(PropertiesRouteId.MAIN_PROPERTIES);
}
Aggregations